Add files via upload

This commit is contained in:
nmset
2018-04-25 20:43:41 +02:00
committed by GitHub
parent 8fc04fbbb6
commit 428cc9099e
80 changed files with 11718 additions and 0 deletions

2362
L7/L7.dox Normal file

File diff suppressed because it is too large Load Diff

111
L7/LBoundCheckBox.cpp Normal file
View File

@@ -0,0 +1,111 @@
/*
* File: LBoundCheckBox.cpp
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 2 juin 2014, 16:03
*/
#include "LBoundCheckBox.h"
LBoundCheckBox::LBoundCheckBox(wxWindow* parent, wxWindowID id, long style)
: wxCheckBox(parent, id, _T("LCheckBox"), wxDefaultPosition, wxDefaultSize, style)
{
m_sqlQuote = wxEmptyString;
SetNull();
}
LBoundCheckBox::~LBoundCheckBox()
{
if (m_rs) m_rs->UnRegisterControl(this);
}
const wxAny LBoundCheckBox::GetData() {
if (Is3State()) {
if (Get3StateValue() == wxCHK_UNDETERMINED) return L_SQLNULL;
if (Get3StateValue() == wxCHK_CHECKED) return 1;
if (Get3StateValue() == wxCHK_UNCHECKED) return 0;
} else {
if (GetValue() == wxCHK_UNCHECKED) return 0;
if (GetValue() == wxCHK_CHECKED) return 1;
}
}
bool LBoundCheckBox::SetData(const wxAny& newData) {
/* The interpretation of literal non is not documented
* as it's for internal use.
*/
wxString snewData;
newData.GetAs<wxString>(&snewData);
if (Is3State()) {
if (snewData.IsEmpty()
|| snewData == L_SQLNULL) {
Set3StateValue(wxCHK_UNDETERMINED);
return true;
}
if (snewData == _T("0")
|| snewData.Lower() == _T("no")) {
Set3StateValue(wxCHK_UNCHECKED);
} else {
Set3StateValue(wxCHK_CHECKED);
}
return true;
} else {
if (snewData == _T("0")
|| snewData.IsEmpty()
|| snewData.Lower() == _T("no")) {
SetValue(wxCHK_UNCHECKED);
} else {
SetValue(wxCHK_CHECKED);
}
}
return false;
}
void LBoundCheckBox::SetResultSet(LResultSet* newResultSet)
{
m_rs = newResultSet;
if (m_rs == NULL) return;
m_rs->RegisterControl(this);
}
bool LBoundCheckBox::IsNull() {
if (Is3State()) {
return (Get3StateValue() == wxCHK_UNDETERMINED);
} else {
return false;
}
}
bool LBoundCheckBox::SetNull() {
return SetData(wxEmptyString);
}
bool LBoundCheckBox::IsDirty() {
wxASSERT_MSG(m_rs != NULL, "m_rs est NULL.");
wxAny ctrlData = GetData(); // 0, 1 or L_SQLNULL
wxAny BEData = m_rs->GetData(m_columnName);
int iBEData; BEData.GetAs(&iBEData);
if (Is3State()) {
if (BEData.IsNull()
|| BEData.As<wxString>().IsEmpty()) {
BEData = L_SQLNULL;
} else if (iBEData != 0) {
BEData = 1;
}
} else {
if (BEData.IsNull()
|| iBEData == 0
|| BEData.As<wxString>().IsEmpty()) {
BEData = 0;
} else {
BEData = 1;
}
}
return (ctrlData.As<wxString>() != BEData.As<wxString>());
}
const wxString LBoundCheckBox::GetDisplayedData() {
if (Is3State()) {
if (Get3StateValue() == wxCHK_UNDETERMINED) return L_SQLNULL;
if (Get3StateValue() == wxCHK_CHECKED) return _("Yes");
if (Get3StateValue() == wxCHK_UNCHECKED) return _("No");
} else {
if (GetValue() == wxCHK_CHECKED) return _("Yes");
if (GetValue() == wxCHK_UNCHECKED) return _("No");
}
}

68
L7/LBoundCheckBox.h Normal file
View File

@@ -0,0 +1,68 @@
/*
* File: LBoundCheckBox.h
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 2 juin 2014, 16:02
*/
#ifndef LBOUNDCHECKBOX_H
#define LBOUNDCHECKBOX_H
#include <wx/checkbox.h>
#include "LBoundControl.h"
#include "LResultSet.h"
class LBoundCheckBox : public wxCheckBox, public LBoundControl
{
public:
LBoundCheckBox(wxWindow* parent, wxWindowID id = wxID_ANY, long style = 0);
virtual ~LBoundCheckBox();
/**
*
* @return 0 or 1, or literal NULL if the control is tristate with undetermined state.
*/
const wxAny GetData();
/**
* If the control is tristate and newData is literal NULL, it's state is set to undetermined.
* If the control is dualstate, wxEmptyString is mapped to unchecked status.
*
* Regardless of the control being dualstate or trisate, 0 is mapped to unchecked status,
* and any other value to checked status.
*
* @param newData
* @return
*/
bool SetData(const wxAny& newData);
/**
* Sets the resultset member and registers the control in the resultset.
* @param newResultSet
*/
void SetResultSet(LResultSet * newResultSet);
/**
*
* @return true if the control is trisate with state undetermined, false otherwise.
*/
bool IsNull();
/**
* If control is tristate, it is set to undetermined state. Else, it is set to unchecked state.
* @return
*/
bool SetNull();
bool IsDirty();
/**
* If the control is checked, returns literal Oui
*
* If the control is unchecked, returns literal Non
*
* If the control is tristate with undetermined state, returns literal NULL
* @return
*/
const wxString GetDisplayedData();
private:
};
#endif /* LBOUNDCHECKBOX_H */

282
L7/LBoundComboBox.cpp Normal file
View File

@@ -0,0 +1,282 @@
/*
* File: LBoundComboBox.cpp
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 3 juin 2014, 19:00
*/
#include "LBoundComboBox.h"
#include "LItemData.h"
LBoundComboBox::LBoundComboBox(wxWindow* parent, wxWindowID id)
: wxComboBox(parent, id, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY)
{
m_sqlQuote = wxEmptyString;
SetNull();
}
LBoundComboBox::~LBoundComboBox()
{
if (m_rs) m_rs->UnRegisterControl(this);
}
bool LBoundComboBox::IsTranslated() const
{
if (HasClientObjectData())
{
for (unsigned int i = 0; i < GetCount(); i++)
{
LItemData * x = static_cast<LItemData*> (GetClientObject(i));
if (x != NULL) return true;
}
}
return false;
}
bool LBoundComboBox::SelectionIsTranslated() const
{
if (IsTranslated())
{
LItemData * x = static_cast<LItemData*> (GetClientObject(GetSelection()));
return (x != NULL);
}
else
{
return false;
}
}
const wxAny LBoundComboBox::GetDataOfIndex(unsigned int idx) const
{
if (IsTranslated())
{
LItemData * x = static_cast<LItemData*> (GetClientObject(idx));
if (x != NULL) return x->GetData();
return wxEmptyString;
}
else
{
return GetString(idx);
}
}
const int LBoundComboBox::GetIndexOfData(const wxAny& data) const
{
const wxString sdata = data.As<wxString>();
if (IsTranslated())
{
/* C001 Can be costly if there are thousands of items !
* In such a case, the control's usefulness is doubtful.
*/
for (unsigned int i = 0; i < GetCount(); i++)
{
LItemData * x = static_cast<LItemData*> (GetClientObject(i));
if (x)
{
if (x->GetData().As<wxString>() == sdata)
{
return i;
}
}
}
return wxNOT_FOUND;
}
else
{
return FindString(sdata);
}
}
const wxString LBoundComboBox::GetItemOfData(const wxAny& data) const
{
if (IsTranslated())
{
// See C001
const wxString sdata = data.As<wxString>();
for (unsigned int i = 0; i < GetCount(); i++)
{
LItemData * x = static_cast<LItemData*> (GetClientObject(i));
if (x != NULL)
{
if (x->GetData().As<wxString>() == sdata)
{
return GetString(i);
}
}
}
}
return wxEmptyString;
}
const wxAny LBoundComboBox::GetDataOfItem(const wxString& item) const
{
if (IsTranslated())
{
const int idx = FindString(item, true);
LItemData * x = static_cast<LItemData*> (GetClientObject(idx));
if (x != NULL) return x->GetData();
return wxEmptyString;
}
else
{
return item;
}
}
const wxString LBoundComboBox::GetItemOfNull() const
{
if (IsTranslated())
{
// See C001
for (unsigned int i = 0; i < GetCount(); i++)
{
LItemData * x = static_cast<LItemData*> (GetClientObject(i));
if (x == NULL) return GetString(i);
}
}
return wxEmptyString;
}
const int LBoundComboBox::GetIndexOfNull() const
{
if (IsTranslated())
{
// See C001
for (unsigned int i = 0; i < GetCount(); i++)
{
LItemData * x = static_cast<LItemData*> (GetClientObject(i));
if (x == NULL) return i;
}
}
return wxNOT_FOUND;
}
void LBoundComboBox::Clear()
{
wxComboBox::Clear();
const long wsflags = GetWindowStyleFlag();
SetWindowStyleFlag(0);
SetSelection(wxNOT_FOUND);
SetValue(wxEmptyString);
SetWindowStyleFlag(wsflags);
}
bool LBoundComboBox::SetData(const wxAny& data)
{
const wxString sData = data.As<wxString>();
if (IsTranslated())
{
if (data.IsNull()
|| sData.IsEmpty()
|| sData == L_SQLNULL)
{
SetNull();
return (GetSelection() != wxNOT_FOUND); // ?
}
for (unsigned int i = 0; i < GetCount(); i++)
{
LItemData * x = static_cast<LItemData*> (GetClientObject(i));
if (x)
{
if (x->GetData().As<wxString>() == sData)
{
SetSelection(i);
return true;
}
}
}
}
else
{
bool hasData = FindString(sData, true);
SetValue(sData);
return hasData;
}
return false;
}
const wxAny LBoundComboBox::GetData()
{
if (IsNull()) return L_SQLNULL;
if (IsTranslated())
{
LItemData * x = static_cast<LItemData*> (GetClientObject(GetSelection()));
if (x != NULL)
{
return x->GetData();
}
else
{
return L_SQLNULL;
}
}
else
{
return GetValue();
}
}
void LBoundComboBox::SetResultSet(LResultSet* newResultSet)
{
m_rs = newResultSet;
if (m_rs == NULL) return;
m_rs->RegisterControl(this);
}
bool LBoundComboBox::IsNull()
{
if (IsTranslated())
{
if (GetSelection() != wxNOT_FOUND)
{
if (SelectionIsTranslated())
{
LItemData * x = static_cast<LItemData*> (GetClientObject(GetSelection()));
if (x != NULL) return false;
}
}
return true;
}
else
{
return (GetValue().IsEmpty());
}
}
bool LBoundComboBox::SetNull()
{
if (IsTranslated())
{
for (unsigned int i = 0; i < GetCount(); i++)
{
wxClientData * x = GetClientObject(i);
if (x == NULL)
{
SetSelection(i);
return true;
}
}
return false;
}
long wsflags = GetWindowStyleFlag();
SetWindowStyleFlag(0);
SetSelection(wxNOT_FOUND);
SetValue(wxEmptyString);
SetWindowStyleFlag(wsflags);
return true;
}
bool LBoundComboBox::IsDirty()
{
wxASSERT_MSG(m_rs != NULL, "m_rs est NULL.");
wxAny BEData = m_rs->GetData(m_columnName);
if (BEData.As<wxString>().IsEmpty()) BEData = L_SQLNULL;
return (GetData().As<wxString>() != BEData.As<wxString>());
}
const wxString LBoundComboBox::GetDisplayedData()
{
return GetValue();
}

129
L7/LBoundComboBox.h Normal file
View File

@@ -0,0 +1,129 @@
/*
* File: LBoundComboBox.h
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 3 juin 2014, 19:00
*/
#ifndef LBOUNDCOMBOBOX_H
#define LBOUNDCOMBOBOX_H
#include <wx/combobox.h>
#include "LBoundControl.h"
#include "LResultSet.h"
/**
* The control is called 'translated' if its items have associated client data that are instances of LItemData.
* The item strings are then only descriptive.
*/
class LBoundComboBox : public wxComboBox, public LBoundControl
{
public:
LBoundComboBox(wxWindow* parent, wxWindowID id = wxID_ANY);
virtual ~LBoundComboBox();
/**
*
* @return true if any of the items is associated with an instance of LItemData
*/
bool IsTranslated() const;
bool SelectionIsTranslated() const;
/**
* If the control is not translated, returns the string item at idx.
*
* Else, returns the associated data of the item at idx, or wxEmptyString.
* @param idx
* @return
*/
const wxAny GetDataOfIndex(unsigned int idx) const;
/**
* If the control is not translated, calls FindString(idx).
*
* Else, returns the index of the item whose associated data equals the parameter, or wxNOT_FOUND.
* @param data
* @return
*/
const int GetIndexOfData(const wxAny& data) const;
/**
* If the control is not translated, returns wxEmptyString (there is no data associated with any item).
*
* Else, returns the item whose associated data equals the parameter, or wxEmptyString.
* @param data
* @return
*/
const wxString GetItemOfData(const wxAny& data) const;
/**
* If the control is not translated, returns the parameter itself.
*
* Else, returns the associated data of the parameter, or wxEmptyString.
* @param item
* @return
*/
const wxAny GetDataOfItem(const wxString& item) const;
/**
* If the control is not translated, returns wxEmptyString.
*
* Else, returns the first item that does not have an associated data, or wxEmptyString.
* @return
*/
const wxString GetItemOfNull() const;
/**
* If the control is not translated, returns wxNOT_FOUND.
*
* Else, returns the index of the first item that does not have an associated data, or wxNOT_FOUND.
* @return
*/
const int GetIndexOfNull() const;
/**
* Deletes all items, sets selection to wxNOT_FOUND and wxEmptyString.
*/
void Clear();
/**
* If IsNull() is true, returns literal NULL.
*
* If the control is not translated, returns GetValue().
*
* Else, returns the associated client data value of the selection.
* @return
*/
const wxAny GetData();
/**
* If the control is not translated, calls SetValue() and returns FindString().
*
* If newData is empty or literal NULL, calls SetNull().
* Else, selects the first item whose associated client data equals newData.
* @param newData
* @return false if no item can be matched with newData, true otherwise.
*/
bool SetData(const wxAny& newData);
/**
* Sets the resultset member and registers the control in the resultset.
* @param newResultSet
*/
void SetResultSet(LResultSet * newResultSet);
/**
* If the control is not translated, returns true if the selected item is empty.
*
* Else, return true if the selected item does not have any associated client data.
* @return
*/
bool IsNull();
/**
* If the control is not translated, sets its value to wxEmptyString with wxNOT_FOUND selection.
*
* Else, selects the first item that does not have an associated client data.
* @return
*/
bool SetNull();
bool IsDirty();
/**
* Alias for GetValue().
* @return
*/
const wxString GetDisplayedData();
private:
};
#endif /* LBOUNDCOMBOBOX_H */

19
L7/LBoundControl.cpp Normal file
View File

@@ -0,0 +1,19 @@
/*
* File: LBoundControl.cpp
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 28 mai 2014, 15:16
*/
#include "LBoundControl.h"
LBoundControl::LBoundControl()
{
}
LBoundControl::~LBoundControl()
{
}

90
L7/LBoundControl.h Normal file
View File

@@ -0,0 +1,90 @@
/*
* File: LBoundControl.h
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 28 mai 2014, 15:15
*/
#ifndef LBOUNDCONTROL_H
#define LBOUNDCONTROL_H
#include <wx/wx.h>
#include "LResultSet.h"
#define L_SQLNULL wxString(_T("NULL"))
class LResultSet;
/**
* Abstract base class for controls interacting with database table columns.
*
*
*/
class LBoundControl
{
public:
LBoundControl();
virtual ~LBoundControl();
/**
* Do not use column aliases.
* @param newColName
*/
void SetColumnName(const wxString& newColName)
{
m_columnName = newColName;
}
const wxString& GetColumnName() const
{
return m_columnName;
}
/**
* The data that will be saved in the database table, which may not be the displayed value.
*
* @return
*/
virtual const wxAny GetData() = 0;
virtual bool SetData(const wxAny& newData) = 0;
virtual void SetResultSet(LResultSet * newResultSet) = 0;
LResultSet* GetResultSet() const
{
return m_rs;
}
virtual bool IsNull() = 0;
virtual bool SetNull() = 0;
/**
* If the database column is numeric, use wxEmptystring, else, use a single quote ' .
*
* @param newQuote
*/
void SetSQLQuote(const wxString& newQuote)
{
m_sqlQuote = newQuote;
}
const wxString& GetSQLQuote()
{
return m_sqlQuote;
}
/**
* Is GetData() different from the table value ?
*
* @return
*/
virtual bool IsDirty() = 0;
/**
* Data shown on screen, which is not always the data stored in the database table.
* @return
*/
virtual const wxString GetDisplayedData() = 0;
protected:
wxWeakRef<LResultSet> m_rs;
wxString m_sqlQuote;
wxString m_columnName;
private:
};
#endif /* LBOUNDCONTROL_H */

View File

@@ -0,0 +1,88 @@
/*
* File: LBoundDatePickerCtrl.cpp
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 3 juin 2014, 16:37
*/
#include "LBoundDatePickerCtrl.h"
#include <wx/tokenzr.h>
LBoundDatePickerCtrl::LBoundDatePickerCtrl(wxWindow* parent, wxWindowID id)
: wxDatePickerCtrl(parent, id, wxInvalidDateTime, wxDefaultPosition, wxDefaultSize, wxDP_DEFAULT|wxDP_ALLOWNONE|wxDP_SHOWCENTURY)
{
m_sqlQuote = _T("'");
SetValue(wxInvalidDateTime);
}
LBoundDatePickerCtrl::~LBoundDatePickerCtrl()
{
if (m_rs) m_rs->UnRegisterControl(this);
}
const wxAny LBoundDatePickerCtrl::GetData() {
if (IsNull()) return L_SQLNULL;
return GetValue().GetDateOnly().FormatISODate();
}
bool LBoundDatePickerCtrl::SetData(const wxAny& newData) {
if (newData.IsNull()) {
SetValue(wxInvalidDateTime);
return false;
}
if (newData.As<wxString>() == L_SQLNULL || newData.As<wxString>().IsEmpty()) {
SetValue(wxInvalidDateTime);
return true;
}
wxString s; newData.GetAs(&s);
const wxDateTime dt = BuildDate(s);
if (!dt.IsValid()) {
SetValue(wxInvalidDateTime);
return false;
}
SetValue(dt);
return true;
}
void LBoundDatePickerCtrl::SetResultSet(LResultSet* newResultSet)
{
m_rs = newResultSet;
if (m_rs == NULL) return;
m_rs->RegisterControl(this);
}
bool LBoundDatePickerCtrl::IsNull() {
return !(GetValue().IsValid());
}
bool LBoundDatePickerCtrl::SetNull() {
return SetData(L_SQLNULL);
}
bool LBoundDatePickerCtrl::IsDirty() {
wxASSERT_MSG(m_rs != NULL, "m_rs est NULL.");
wxAny BEData = m_rs->GetData(m_columnName);
if (BEData.As<wxString>().IsEmpty()) BEData = L_SQLNULL;
return (GetData().As<wxString>() != BEData.As<wxString>());
}
const wxString LBoundDatePickerCtrl::GetDisplayedData() {
if (IsNull()) return wxEmptyString;
return GetValue().GetDateOnly().FormatDate();
}
wxDateTime LBoundDatePickerCtrl::BuildDate(const wxString& ISODate) {
wxDateTime dt = wxDateTime::Today();
if (!dt.ParseISODate(ISODate)) return wxInvalidDateTime;
unsigned int * res = new unsigned int[3];
unsigned int i = 0;
wxAny token;
wxStringTokenizer tkz(ISODate, _T("-"));
while ( tkz.HasMoreTokens() )
{
token = tkz.GetNextToken();
token.GetAs(&res[i]);
i++;
}
dt.Set(res[2], (wxDateTime::Month) (res[1] - 1), res[0]);
wxDELETEA(res);
if (!dt.IsValid()) return wxInvalidDateTime;
dt.ResetTime();
return dt;
}

77
L7/LBoundDatePickerCtrl.h Normal file
View File

@@ -0,0 +1,77 @@
/*
* File: LBoundDatePickerCtrl.h
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 3 juin 2014, 16:37
*/
#ifndef LBOUNDDATEPICKERCTRL_H
#define LBOUNDDATEPICKERCTRL_H
#include <wx/datectrl.h>
#include "LBoundControl.h"
#include "LResultSet.h"
/**
* Initialised with wxInvalidDateTime. The underlying toolkit must allow wxDP_ALLOWNONE.
*
* @param parent
* @param id
*/
class LBoundDatePickerCtrl : public wxDatePickerCtrl, public LBoundControl
{
public:
LBoundDatePickerCtrl(wxWindow* parent, wxWindowID id = wxID_ANY);
virtual ~LBoundDatePickerCtrl();
/**
*
* @return The current ISO date string, or literal NULL.
*/
const wxAny GetData();
/**
*
* @param newData
* @return false if newData is not a valid ISO date string.
* True if newData is empty, or literal NULL, or a valid ISO date string.
*/
bool SetData(const wxAny& newData);
/**
* Sets the resultset member and registers the control in the resultset.
* @param newResultSet
*/
void SetResultSet(LResultSet * newResultSet);
/**
*
* @return True if the control contains an invalid date, false otherwise.
*/
bool IsNull();
/**
* Sets the control to invalid date.
* @return
*/
bool SetNull();
bool IsDirty();
/**
* If IsNull() is true, returns wxEmptyString.
*
* Else, returns FormatDate() from the control's value.
* @return
*/
const wxString GetDisplayedData();
/**
* Builds a wxDateTime object from a valid ISO date string.
*
* Returns wxInvalidDateTime if the parameter is not a valid ISO date string.
*
* @param ISODate
* @return
*/
static wxDateTime BuildDate(const wxString& ISODate);
private:
};
#endif /* LBOUNDDATEPICKERCTRL_H */

820
L7/LBoundGrid.cpp Normal file
View File

@@ -0,0 +1,820 @@
/*
* File: LBoundGrid.cpp
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 9 juin 2014, 16:40
*/
#include "LBoundGrid.h"
#include "LGridCheckEditor.h"
#include "LGridCheckRenderer.h"
#include "LGridComboEditor.h"
#include "LGridComboRenderer.h"
#include "LGridDateEditor.h"
#include "LGridDateRenderer.h"
#include "LGridTextEditor.h"
#include "LGridTextRenderer.h"
#include "LGridSpinEditor.h"
#include "LGridSpinRenderer.h"
LBoundGrid::LBoundGrid(wxWindow* parent, wxWindowID id)
: wxGrid(parent, id, wxDefaultPosition, wxDefaultSize, wxHSCROLL | wxVSCROLL)
{
m_rs = NULL;
m_formClientSizer = NULL;
m_gridFormEVH = NULL;
m_scaleFactor = (wxGetDisplayPPI().GetY() / 96.0);
SetDefaultCellAlignment(wxALIGN_LEFT, wxALIGN_CENTRE);
m_stringTable = new wxGridStringTable();
m_stringTable->CanHaveAttributes();
HideRowLabels();
SetUseNativeColLabels();
SetTable(m_stringTable);
SetSelectionMode(wxGridSelectRows);
CreateMenu();
Bind(wxEVT_GRID_RANGE_SELECT, &LBoundGrid::ForceSingleLineRange, this);
Bind(wxEVT_GRID_SELECT_CELL, &LBoundGrid::CellSelected, this);
Bind(wxEVT_GRID_CELL_RIGHT_CLICK, &LBoundGrid::ShowMenu, this);
}
LBoundGrid::~LBoundGrid()
{
delete m_menu;
delete m_formClientSizer;
ClearGrid();
}
void LBoundGrid::SetResultSet(LResultSet* newResultSet)
{
m_rs = newResultSet;
if (m_rs == NULL) return;
wxASSERT_MSG(m_rs->GetConnection() != NULL, _T("GetConnection() = NULL."));
if (!m_menu) return;
if (m_rs->GetConnection()->IsReadOnly() || m_rs->IsReadOnly())
{
m_menu->FindItemByPosition(0)->Enable(false);
m_menu->FindItemByPosition(2)->Enable(false);
}
else
{
m_menu->FindItemByPosition(0)->Enable(true);
m_menu->FindItemByPosition(2)->Enable(true);
}
}
void LBoundGrid::ClearGrid()
{
Unbind(wxEVT_GRID_RANGE_SELECT, &LBoundGrid::ForceSingleLineRange, this);
Unbind(wxEVT_GRID_SELECT_CELL, &LBoundGrid::CellSelected, this);
if (GetNumberRows()) DeleteRows(0, GetNumberRows());
if (GetNumberCols()) DeleteCols(0, GetNumberCols());
}
void LBoundGrid::FillGrid()
{
wxASSERT_MSG(m_rs != NULL, _("RS = NULL"));
wxASSERT_MSG(m_rs->GetConnection() != NULL, _T("GetConnection() = NULL."));
wxGridUpdateLocker locker(this);
// Starting again, the grid's resultset must free itself from any registered controls.
RestoreEditorControls();
Unbind(wxEVT_GRID_RANGE_SELECT, &LBoundGrid::ForceSingleLineRange, this);
Unbind(wxEVT_GRID_SELECT_CELL, &LBoundGrid::CellSelected, this);
// Remember some states
const wxGridSizesInfo colSizes = GetColSizes();
const int col = GetGridCursorCol() > -1 ? GetGridCursorCol() : 0;
// Create enough cells
if (GetNumberRows()) DeleteRows(0, GetNumberRows());
const bool firstTime = (m_stringTable->GetNumberCols() == 0);
const int nbCols = m_rs->GetColumnCount();
if (firstTime) m_stringTable->AppendCols(nbCols);
const int nbRows = m_rs->GetRowCount();
m_stringTable->AppendRows(nbRows);
// Add an insert row
if (!m_rs->GetConnection()->IsReadOnly() && !m_rs->IsReadOnly())
{
m_stringTable->AppendRows(1);
}
// Grid header labels default to database table column names.
if (firstTime)
{
for (unsigned int c = 0; c < nbCols; c++)
{
m_stringTable->SetColLabelValue(c, m_rs->GetColumnName(c));
}
}
// Set each cell's value.
for (unsigned int r = 0; r < nbRows; r++)
{
for (unsigned int c = 0; c < nbCols; c++)
{
m_stringTable->SetValue(r, c, (m_rs->GetData(r, c)).As<wxString>());
}
}
Bind(wxEVT_GRID_SELECT_CELL, &LBoundGrid::CellSelected, this);
Bind(wxEVT_GRID_RANGE_SELECT, &LBoundGrid::ForceSingleLineRange, this);
// Restore
SetColSizes(colSizes);
// synchronize with the resultset
const int targetRow = m_rs->GetRow() > -1 ? m_rs->GetRow() : 0;
if (GetNumberRows())
{
// Triggers CellSelected event. If no data, we are on insert row, we must call LResultSet::AddNew()
GoToCell(targetRow, col);
SelectRow(targetRow);
}
}
void LBoundGrid::CreateCheckBoxColumn(const wxString& newColName,
const wxString& newLabel,
unsigned int width,
bool readOnly,
bool isDualstate,
wxString newNullLabel)
{
wxASSERT_MSG(m_rs != NULL, _("RS = NULL"));
const int col = m_rs->GetColumnIndex(newColName);
wxASSERT_MSG(col > -1, _("Invalid column name : ") + newColName);
wxGridCellAttr * colAtt = m_stringTable->GetAttr(GetGridCursorRow(), col, wxGridCellAttr::Col);
if (colAtt == NULL) colAtt = new wxGridCellAttr();
LGridCheckEditor * ed = new LGridCheckEditor(newColName, isDualstate, newNullLabel);
colAtt->SetEditor(ed);
LGridCheckRenderer * rn = new LGridCheckRenderer(isDualstate, newNullLabel);
colAtt->SetRenderer(rn);
colAtt->SetReadOnly(readOnly);
m_stringTable->SetColAttr(colAtt, col);
m_stringTable->SetColLabelValue(col, newLabel);
SetColSize(col, width);
}
void LBoundGrid::CreateComboBoxColumn(const wxString& newColName,
const wxString& newLabel,
unsigned int width,
bool readOnly)
{
wxASSERT_MSG(m_rs != NULL, _("RS = NULL"));
const int col = m_rs->GetColumnIndex(newColName);
wxASSERT_MSG(col > -1, _("Invalid column name : ") + newColName);
wxGridCellAttr * colAtt = m_stringTable->GetAttr(GetGridCursorRow(), col, wxGridCellAttr::Col);
if (colAtt == NULL) colAtt = new wxGridCellAttr();
LGridComboEditor * ed = new LGridComboEditor(newColName);
colAtt->SetEditor(ed);
LGridComboRenderer * rn = new LGridComboRenderer;
colAtt->SetRenderer(rn);
colAtt->SetReadOnly(readOnly);
m_stringTable->SetColAttr(colAtt, col);
m_stringTable->SetColLabelValue(col, newLabel);
SetColSize(col, width);
}
void LBoundGrid::CreateDateColumn(const wxString& newColName,
const wxString& newLabel,
unsigned int width,
bool readOnly)
{
wxASSERT_MSG(m_rs != NULL, _("RS = NULL"));
const int col = m_rs->GetColumnIndex(newColName);
wxASSERT_MSG(col > -1, _("Invalid column name : ") + newColName);
wxGridCellAttr * colAtt = m_stringTable->GetAttr(GetGridCursorRow(), col, wxGridCellAttr::Col);
if (colAtt == NULL) colAtt = new wxGridCellAttr();
LGridDateEditor * ed = new LGridDateEditor(newColName);
colAtt->SetEditor(ed);
LGridDateRenderer * rn = new LGridDateRenderer();
colAtt->SetRenderer(rn);
colAtt->SetReadOnly(readOnly);
colAtt->SetAlignment(wxALIGN_RIGHT, wxALIGN_CENTRE);
m_stringTable->SetColAttr(colAtt, col);
m_stringTable->SetColLabelValue(col, newLabel);
SetColSize(col, width);
}
void LBoundGrid::CreateTextColumn(const wxString& newColName,
const wxString& newLabel,
unsigned int width,
bool newMultiline,
bool readOnly)
{
wxASSERT_MSG(m_rs != NULL, _("RS = NULL"));
const int col = m_rs->GetColumnIndex(newColName);
wxASSERT_MSG(col > -1, _("Invalid column name : ") + newColName);
wxGridCellAttr * colAtt = m_stringTable->GetAttr(GetGridCursorRow(), col, wxGridCellAttr::Col);
if (colAtt == NULL) colAtt = new wxGridCellAttr();
LGridTextEditor * ed = new LGridTextEditor(newColName, newMultiline);
colAtt->SetEditor(ed);
LGridTextRenderer * rn = new LGridTextRenderer();
colAtt->SetRenderer(rn);
colAtt->SetReadOnly(readOnly);
m_stringTable->SetColAttr(colAtt, col);
m_stringTable->SetColLabelValue(col, newLabel);
SetColSize(col, width);
}
void LBoundGrid::CreateSpinColumn(const wxString& newColName,
const wxString& newLabel,
unsigned int width,
int newMin,
int newMax,
int newInitial,
bool readOnly)
{
wxASSERT_MSG(m_rs != NULL, _("RS = NULL"));
const int col = m_rs->GetColumnIndex(newColName);
wxASSERT_MSG(col > -1, _("Invalid column name : ") + newColName);
wxGridCellAttr * colAtt = m_stringTable->GetAttr(GetGridCursorRow(), col, wxGridCellAttr::Col);
if (colAtt == NULL) colAtt = new wxGridCellAttr();
LGridSpinEditor * ed = new LGridSpinEditor(newColName, newMin, newMax, newInitial);
colAtt->SetEditor(ed);
LGridSpinRenderer * rn = new LGridSpinRenderer();
colAtt->SetRenderer(rn);
colAtt->SetReadOnly(readOnly);
colAtt->SetAlignment(wxALIGN_RIGHT, wxALIGN_CENTRE);
m_stringTable->SetColAttr(colAtt, col);
m_stringTable->SetColLabelValue(col, newLabel);
SetColSize(col, width);
}
const wxString LBoundGrid::GetColName(const unsigned int col)
{
wxASSERT_MSG(m_rs != NULL, _("RS = NULL"));
InitEditor(GetGridCursorRow(), col, false);
LGridColEditor * gce = GetColEditor(GetGridCursorRow(), col);
if (gce == NULL) return wxEmptyString;
return gce->GetColumnName();
}
int LBoundGrid::GetColIndex(const wxString& colName)
{
wxASSERT_MSG(m_rs != NULL, _("RS = NULL"));
for (unsigned int col = 0; col < GetNumberCols(); col++)
{
LGridColEditor * gce = GetColEditor(GetGridCursorRow(), col);
if (gce == NULL) continue;
if (gce->GetColumnName().Lower() == colName.Lower()) return col;
}
return -1;
}
LBoundControl* LBoundGrid::GetBoundControl(const unsigned int row,
const unsigned int col,
bool keepRegistered)
{
wxASSERT_MSG(row >= 0 && row < GetNumberRows(), _("Invalid row parameter"));
wxASSERT_MSG(col >= 0 && col < GetNumberCols(), _("Invalid col parameter"));
wxObjectDataPtr<wxGridCellAttr> cellAttr;
cellAttr = m_stringTable->GetAttr(row, col, wxGridCellAttr::Col);
if (cellAttr.get() == NULL) return NULL;
wxObjectDataPtr<wxGridCellEditor> ed;
ed = cellAttr->GetEditor(this, row, col);
if (ed.get() == NULL) return NULL;
ed->BeginEdit(row, col, this);
ed->Show(false);
LGridColEditor* gce = dynamic_cast<LGridColEditor*> (ed.get()); // CROSS CASTING
if (!gce) return NULL; // APP CAN ADD AN UNBOUND COLUMN
if (!keepRegistered)
{
wxASSERT_MSG(m_rs != NULL, _("RS = NULL"));
m_rs->UnRegisterControl(gce->GetBoundControl());
}
return gce->GetBoundControl();
}
LBoundControl* LBoundGrid::GetBoundControl(const unsigned int row,
const wxString& colName,
bool keepRegistered)
{
wxASSERT_MSG(m_rs != NULL, _("RS = NULL"));
wxASSERT_MSG(row >= 0 && row < GetNumberRows(), _("Invalid row parameter"));
for (int col = 0; col < GetNumberCols(); col++)
{
LGridColEditor * gce = GetColEditor(row, col);
if (gce == NULL) continue;
if (gce->GetColumnName().Lower() == colName.Lower())
{
InitEditor(row, col, keepRegistered);
return gce->GetBoundControl();
}
}
return NULL;
}
LGridColEditor* LBoundGrid::GetColEditor(const unsigned int row, const unsigned int col) const
{
wxASSERT_MSG(row >= 0 && row < GetNumberRows(), _("Invalid row parameter"));
wxASSERT_MSG(col >= 0 && col < GetNumberCols(), _("Invalid col parameter"));
wxObjectDataPtr<wxGridCellAttr> cellAttr;
cellAttr = m_stringTable->GetAttr(row, col, wxGridCellAttr::Col);
if (cellAttr.get() == NULL) return NULL;
wxObjectDataPtr<wxGridCellEditor> ed;
ed = cellAttr->GetEditor(this, row, col);
if (ed.get() == NULL) return NULL;
return dynamic_cast<LGridColEditor*> (ed.get());
}
wxControl* LBoundGrid::GetFormEditor(const unsigned int col) const
{
wxASSERT_MSG(m_rs != NULL, _("RS = NULL"));
wxASSERT_MSG(col >= 0 && col < GetNumberCols(), _("Invalid col parameter"));
int row = m_rs->GetRow();
if (m_rs->IsInserting()) row = m_rs->GetRowCount();
LGridColEditor* gce = GetColEditor(row, col);
if (!gce) return NULL;
return gce->GetFormEditor();
}
wxControl* LBoundGrid::GetFormEditor(const wxString& colName)
{
wxASSERT_MSG(m_rs != NULL, _("RS = NULL"));
int row = m_rs->GetRow();
if (m_rs->IsInserting()) row = m_rs->GetRowCount();
for (int col = 0; col < GetNumberCols(); col++)
{
LGridColEditor * gce = GetColEditor(row, col);
if (gce == NULL) continue;
if (gce->GetColumnName().Lower() == colName.Lower())
return gce->GetFormEditor();
}
return NULL;
}
bool LBoundGrid::InitEditor(const unsigned int row,
const unsigned int col,
bool keepRegistered)
{
wxASSERT_MSG(row >= 0 && row < GetNumberRows(), _("Invalid row parameter"));
wxASSERT_MSG(col >= 0 && col < GetNumberCols(), _("Invalid col parameter"));
wxObjectDataPtr<wxGridCellAttr> cellAttr;
cellAttr = m_stringTable->GetAttr(row, col, wxGridCellAttr::Col);
if (cellAttr.get() == NULL) return false;
wxObjectDataPtr<wxGridCellEditor> ed;
ed = cellAttr->GetEditor(this, row, col);
if (ed.get() == NULL) return false;
// That's what we want to do.
ed->BeginEdit(row, col, this);
ed->Show(false);
if (!keepRegistered)
{
wxASSERT_MSG(m_rs != NULL, _("RS = NULL"));
LGridColEditor* gce = dynamic_cast<LGridColEditor*> (ed.get());
if (!gce) return false;
m_rs->UnRegisterControl(gce->GetBoundControl());
}
return true;
}
void LBoundGrid::InitAllEditors(const unsigned int row, bool keepRegistered)
{
wxASSERT_MSG(row >= 0 && row < GetNumberRows(), _("Invalid row parameter"));
if (m_stringTable == NULL) return;
if (GetNumberCols() > 0)
{
for (int col = 0; col < GetNumberCols(); col++)
{
InitEditor(row, col, keepRegistered);
}
}
}
void LBoundGrid::AddMenuSeparator()
{
m_menu->AppendSeparator();
}
void LBoundGrid::AddMenuItem(wxMenuItem* newItem)
{
wxASSERT_MSG(newItem != NULL, _("Menu item is NULL"));
if (m_menu->FindItem(newItem->GetItemLabelText()) != wxNOT_FOUND) return;
m_menu->Append(newItem);
}
void LBoundGrid::AddSubMenu(wxMenu* newSubMenu, const wxString& label)
{
wxASSERT_MSG(newSubMenu != NULL, _("Submenu is NULL"));
if (m_menu->FindItem(newSubMenu->GetTitle()) != wxNOT_FOUND) return;
m_menu->AppendSubMenu(newSubMenu, label);
}
void LBoundGrid::RemoveMenuItem(const wxString& newItemLabelText)
{
if (m_menu->FindItem(newItemLabelText) == wxNOT_FOUND) return;
m_menu->Remove(m_menu->FindChildItem(m_menu->FindItem(newItemLabelText)));
}
void LBoundGrid::RemoveAllExternalMenuItems()
{
if (m_menu->GetMenuItemCount() < 8) return;
do
{
m_menu->Remove(m_menu->GetMenuItems()[7]);
}
while (m_menu->GetMenuItemCount() > 7);
}
void LBoundGrid::EnableMenuItem(int id, bool enable)
{
if (m_menu->FindChildItem(id)) m_menu->Enable(id, enable);
}
/*
* Only one single row must be selected at a time.
* Even if multiple selections do not affect the grid row and col cursor values,
* selecting only one row may avoid confusion.
* And the library is not designed to account for edits on multiple rows.
*/
void LBoundGrid::ForceSingleLineRange(wxGridRangeSelectEvent& evt)
{
if ((evt.Selecting()))
{
wxASSERT_MSG(GetSelectionMode() == wxGridSelectRows, "Selection mode is not wxGridSelectRows.");
if (evt.ControlDown() == true
|| evt.GetTopRow() != evt.GetBottomRow())
{
SelectRow(GetGridCursorRow());
evt.Veto();
}
}
evt.Skip();
}
void LBoundGrid::CellSelected(wxGridEvent& evt)
{
wxASSERT_MSG(m_rs != NULL, _("RS = NULL"));
// The insert row is somehow un-natural, it exists in the grid but not in the resultset, we manage it separately.
if (!m_rs->IsInserting())
{
// The user wants to change row.
if ((evt.GetRow() != m_rs->GetRow()))
{
// If there have been no edits in therow we are leaving, we must unregister all controls in the resultset.
if (!m_rs->IsDirty() && m_rs->HasData()) RestoreEditorControls();
// The user doesn't want to go on insert row.
if (evt.GetRow() < m_rs->GetRowCount())
{
// Absolute() will fail if there are edits
if (!m_rs->Absolute(evt.GetRow()))
{
evt.Veto(); // Doesn't seem to do anything
// Absolute() failed, get back to where we were.
GoToCell(m_rs->GetRow(), GetGridCursorCol());
SelectRow(m_rs->GetRow());
}
}
else
{
// The user wants to go on insert row, call AddNe(). Will fail if there are edits.
if (!m_rs->AddNew())
{
evt.Veto();
// AddNew() failed, get back to where we were.
GoToCell(m_rs->GetRow(), GetGridCursorCol());
SelectRow(m_rs->GetRow());
}
}
}
}
else
// We are inserting, on insert row.
{
// The user want to go above (if there is saved data).
if (evt.GetRow() < m_rs->GetRowCount())
{
// There are no edits on the insert row.
if (!m_rs->IsDirty())
{
RestoreEditorControls();
m_rs->Cancel();
// Synchronize the resultset with the grid.
m_rs->Absolute(evt.GetRow());
}
else
{
// There are edits on the insert row.
m_rs->InformInserting();
evt.Veto();
// Get back.
GoToCell(m_rs->GetRowCount(), GetGridCursorCol());
SelectRow(m_rs->GetRowCount());
}
}
}
evt.Skip();
}
void LBoundGrid::CreateMenu()
{
m_menu = new wxMenu(0);
wxMenuItem * item = new wxMenuItem(m_menu, ID_MNU_SAVE, _("Save"));
m_menu->Append(item);
item = new wxMenuItem(m_menu, ID_MNU_CANCEL, _("Cancel"));
m_menu->Append(item);
item = new wxMenuItem(m_menu, ID_MNU_DELETE, _("Delete"));
m_menu->Append(item);
item = new wxMenuItem(m_menu);
m_menu->Append(item);
item = new wxMenuItem(m_menu, ID_MNU_REFRESH, _("Refresh"));
m_menu->Append(item);
item = new wxMenuItem(m_menu);
m_menu->Append(item);
item = new wxMenuItem(m_menu, ID_MNU_FORMVIEW, _("Form view"));
m_menu->Append(item);
m_menu->Bind(wxEVT_COMMAND_MENU_SELECTED, &LBoundGrid::MenuAction, this);
}
void LBoundGrid::ShowMenu(wxGridEvent& evt)
{
GetGridWindow()->PopupMenu(m_menu);
}
void LBoundGrid::MenuAction(wxCommandEvent& evt)
{
switch (evt.GetId()) {
case ID_MNU_SAVE:
if (m_rs)
{
int row = m_rs->GetRow();
if (m_rs->IsInserting()) row = m_rs->GetRowCount();
InitPKEditor(row);
if (m_rs->Save())
{
RestoreEditorControls();
FillGrid();
}
}
break;
case ID_MNU_CANCEL:
if (m_rs)
{
HideCellEditControl();
const unsigned int nbCols = m_rs->GetColumnCount();
int row = m_rs->GetRow();
if (m_rs->IsInserting()) row = m_rs->GetRowCount();
for (int c = 0; c < nbCols; c++)
{
wxAny data = wxEmptyString;
if (!m_rs->IsInserting())
data = (m_rs->GetData(row, c));
m_stringTable->SetValue(row, c, data.As<wxString>());
}
m_rs->Cancel();
RestoreEditorControls();
row = m_rs->HasData() ? m_rs->GetRow() : 0;
GoToCell(row, GetGridCursorCol());
SelectRow(row);
ForceRefresh();
}
break;
case ID_MNU_REFRESH:
// If there's no data, the grid is on insert row and AddNew() has been called.
if (!m_rs->HasData()) m_rs->Cancel();
RestoreEditorControls();
m_rs->Refresh();
FillGrid();
break;
case ID_MNU_DELETE:
if (m_rs)
{
if (m_rs->GetRowCount() < 1) return;
InitPKEditor(m_rs->GetRow());
if (m_rs->Delete())
{
RestoreEditorControls();
FillGrid();
}
}
break;
case ID_MNU_FORMVIEW:
ShowFormView();
break;
}
GetGridWindow()->SetFocus();
}
bool LBoundGrid::InitPKEditor(const int row)
{
wxASSERT_MSG(m_rs != NULL, _("RS = NULL"));
for (int c = 0; c < GetNumberCols(); c++)
{
wxObjectDataPtr<wxGridCellAttr> cellAttr;
cellAttr = m_stringTable->GetAttr(row, c, wxGridCellAttr::Col);
if (cellAttr.get() == NULL) continue;
wxObjectDataPtr<wxGridCellEditor> ed;
ed = cellAttr->GetEditor(this, row, c);
if (ed.get() == NULL) continue;
LGridColEditor * gce = dynamic_cast<LGridColEditor*> (ed.get());
if (gce == NULL) continue;
if (gce->GetColumnName().Lower() == m_rs->GetPKColumnName().Lower())
{
ed->BeginEdit(row, c, this);
ed->Show(false);
return true;
}
}
return false;
}
void LBoundGrid::ShowFormView()
{
wxASSERT_MSG(m_rs != NULL, _("RS = NULL"));
wxDialog * dlg = new wxDialog(this, wxID_ANY, _("Form view"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxMAXIMIZE_BOX | wxRESIZE_BORDER);
unsigned int row = m_rs->GetRow();
if (m_rs->IsInserting()) row = m_rs->GetRowCount();
// We want to ignore hidden columns.
unsigned int visibleCol = 0;
// Multiline wxTextCtrl must be able to expand vertically.
bool hasMultiline = false;
// ScrolledWindow/VerticalSizer/Panel/VerticalSizer/FlexGridSizer
// /ClientSizer
wxScrolledWindow * swMain = new wxScrolledWindow(dlg, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER | wxHSCROLL | wxVSCROLL);
swMain->SetScrollbars(1, 1, 0, 0);
wxBoxSizer* vsz0 = new wxBoxSizer(wxVERTICAL);
swMain->SetSizer(vsz0);
wxPanel * pan0 = new wxPanel(swMain, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER | wxHSCROLL | wxVSCROLL | wxTAB_TRAVERSAL);
vsz0->Add(pan0, 1, wxEXPAND);
wxBoxSizer * vsz = new wxBoxSizer(wxVERTICAL);
wxFlexGridSizer * flxsz = new wxFlexGridSizer(0, 2, 0, 0);
pan0->SetSizer(vsz);
vsz->Add(flxsz, 1, wxGROW | wxGROW | wxALL);
flxsz->AddGrowableCol(1);
m_formClientSizer = new wxBoxSizer(wxHORIZONTAL);
vsz->Add(m_formClientSizer, 0, wxGROW, 1);
for (unsigned int col = 0; col < GetNumberCols(); col++)
{
if (GetColSize(col) == 0) continue;
InitEditor(row, col, true);
LGridColEditor * gce = GetColEditor(row, col);
if (gce == NULL) continue;
int type = gce->GetType();
// Receive the form editor from LGridColEditor::ProvideFormEditor
wxControl * fEditor = NULL;
// One more pointer to a text control
wxTextCtrl * txtCtrl = NULL;
switch (type) {
case LGridColEditor::TEXT:
fEditor = static_cast<wxTextCtrl*> (gce->ProvideFormEditor(pan0));
txtCtrl = static_cast<wxTextCtrl*> (fEditor);
break;
case LGridColEditor::CHECK:
fEditor = static_cast<wxCheckBox*> (gce->ProvideFormEditor(pan0));
break;
case LGridColEditor::COMBO:
fEditor = static_cast<wxComboBox*> (gce->ProvideFormEditor(pan0));
break;
case LGridColEditor::DATE:
fEditor = static_cast<wxDatePickerCtrl*> (gce->ProvideFormEditor(pan0));
break;
case LGridColEditor::SPIN:
fEditor = static_cast<wxSpinCtrl*> (gce->ProvideFormEditor(pan0));
break;
}
// A label corresponding to the grid column header
wxStaticText * lbl = new wxStaticText(pan0, wxID_ANY, m_stringTable->GetColLabelValue(col), wxDefaultPosition, wxDefaultSize, 0);
flxsz->Add(lbl, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 0);
if (txtCtrl && txtCtrl->IsMultiLine())
{
flxsz->Add(fEditor, 0, wxGROW | wxGROW | wxALL, 0);
txtCtrl = NULL;
// The multiline text control must expand.
flxsz->AddGrowableRow(visibleCol);
hasMultiline = true;
}
else
{
flxsz->Add(fEditor, 0, wxGROW | wxALIGN_CENTER_VERTICAL | wxALL, 0);
}
wxObjectDataPtr<wxGridCellAttr> cellAttr;
cellAttr = m_stringTable->GetAttr(row, col, wxGridCellAttr::Col);
if (cellAttr.get() != NULL)
{
// read only columns must not be edited
fEditor->Enable(!cellAttr->IsReadOnly());
}
fEditor->Show(true);
// visibleCol <> col
visibleCol++;
}
wxSize dSize = wxDefaultSize;
if (hasMultiline)
{
// Some arbitrary values
wxSize screen = wxGetDisplaySize();
dSize.SetWidth(screen.GetWidth() * 0.4);
dSize.SetHeight(screen.GetHeight() * 0.75);
}
// Let the application do something with the dialog before we show it
if (m_gridFormEVH) m_gridFormEVH->BeforeFormShown(this, m_formClientSizer);
vsz->SetSizeHints(pan0); // here
dlg->SetSize(dSize);
dlg->CentreOnScreen();
swMain->FitInside();
int res = dlg->ShowModal();
// Sync back any edits. Here we don't care about visible columns.
for (int col = 0; col < GetNumberCols(); col++)
{
LGridColEditor * dce = GetColEditor(row, col);
if (dce == NULL) continue;
dce->SyncBack(row, col, this);
}
// Let the application complete whatever.
if (m_gridFormEVH) m_gridFormEVH->AfterFormHidden(this, m_formClientSizer);
SetFocus();
dlg->Destroy();
wxDELETE(dlg); // ??
m_formClientSizer = NULL;
// Last information. But it's not idle time yet; this may be a source of unexpected trouble.
if (m_gridFormEVH) m_gridFormEVH->AfterFormDestroyed(this);
}
void LBoundGrid::RestoreEditorControls()
{
wxASSERT_MSG(m_rs != NULL, _("RS = NULL"));
while (m_rs->GetRegisteredControls().GetCount())
{
LBoundControl * ctrl = static_cast<LBoundControl*> (m_rs->GetRegisteredControls().Item(0));
m_rs->UnRegisterControl(ctrl);
ctrl->SetNull();
}
}
void LBoundGrid::ResetColEditor(const int col)
{
wxObjectDataPtr<wxGridCellAttr> cellAttr;
cellAttr = m_stringTable->GetAttr(GetGridCursorRow(), col, wxGridCellAttr::Col);
if (cellAttr == NULL) return;
wxObjectDataPtr<wxGridCellEditor> ed;
ed = cellAttr->GetEditor(this, GetGridCursorRow(), col);
// This deletes the editor (m_control).
if (ed.get()) ed->Reset();
}
void LBoundGrid::SetDefaultRowSize(int height, bool resizeExistingRows)
{
wxGrid::SetDefaultRowSize(((wxDouble) height) * m_scaleFactor, resizeExistingRows);
}
void LBoundGrid::SetColMinimalAcceptableWidth(int width)
{
wxGrid::SetColMinimalAcceptableWidth(((wxDouble) width) * m_scaleFactor);
}
void LBoundGrid::SetColMinimalWidth(int col, int width)
{
wxGrid::SetColMinimalWidth(col, ((wxDouble) width) * m_scaleFactor);
}
void LBoundGrid::SetColSize(int col, int width)
{
wxGrid::SetColSize(col, ((wxDouble) width) * m_scaleFactor);
}
void LBoundGrid::SetDefaultColSize(int width, bool resizeExistingCols)
{
wxGrid::SetDefaultColSize(((wxDouble) width) * m_scaleFactor, resizeExistingCols);
}
void LBoundGrid::SetRowLabelSize(int width)
{
wxGrid::SetRowLabelSize(((wxDouble) width) * m_scaleFactor);
}
void LBoundGrid::SetRowMinimalAcceptableHeight(int height)
{
wxGrid::SetRowMinimalAcceptableHeight(((wxDouble) height) * m_scaleFactor);
}
void LBoundGrid::SetRowMinimalHeight(int row, int height)
{
wxGrid::SetRowMinimalHeight(row, ((wxDouble) height) * m_scaleFactor);
}
void LBoundGrid::SetRowSize(int row, int height)
{
wxGrid::SetRowSize(row, ((wxDouble) height) * m_scaleFactor);
}
///////////////////////////////////////////////////////////////////////////
LBoundGridFormEvent::LBoundGridFormEvent()
{
}
LBoundGridFormEvent::~LBoundGridFormEvent()
{
}
void LBoundGridFormEvent::BeforeFormShown(const LBoundGrid * origin, wxBoxSizer* clientSizer)
{
}
void LBoundGridFormEvent::AfterFormHidden(const LBoundGrid * origin, wxBoxSizer* clientSizer)
{
}
void LBoundGridFormEvent::AfterFormDestroyed(const LBoundGrid * origin)
{
}

320
L7/LBoundGrid.h Normal file
View File

@@ -0,0 +1,320 @@
/*
* File: LBoundGrid.h
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, 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);
/**
*
* @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 */

60
L7/LBoundSpinCtrl.cpp Normal file
View File

@@ -0,0 +1,60 @@
/*
* File: LBoundSpinCtrl.cpp
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 22 septembre 2014, 14:38
*/
#include "LBoundSpinCtrl.h"
LBoundSpinCtrl::LBoundSpinCtrl(wxWindow* parent,
wxWindowID id,
const wxPoint& pos,
const wxSize& size,
long style,
int min,
int max,
int initial)
: wxSpinCtrl(parent, id, wxEmptyString, pos, size, style, min, max, initial)
{
m_initialValue = initial;
}
LBoundSpinCtrl::~LBoundSpinCtrl()
{
if (m_rs) m_rs->UnRegisterControl(this);
}
void LBoundSpinCtrl::SetResultSet(LResultSet* newResultSet)
{
m_rs = newResultSet;
if (m_rs == NULL) return;
m_rs->RegisterControl(this);
}
bool LBoundSpinCtrl::SetData(const wxAny& newData)
{
if (newData.IsNull() || newData.As<wxString>().IsEmpty() )
{
SetValue(m_initialValue);
}
else
{
int iData;
newData.GetAs<int>(&iData);
SetValue(iData);
}
return true;
}
bool LBoundSpinCtrl::IsDirty()
{
wxASSERT_MSG(m_rs != NULL, _("RS = NULL"));
wxAny BEData = m_rs->GetData(m_columnName);
if (BEData.IsNull() || BEData.As<wxString>().IsEmpty())
BEData = m_initialValue;
return (GetData().As<wxString>() != BEData.As<wxString>());
}

88
L7/LBoundSpinCtrl.h Normal file
View File

@@ -0,0 +1,88 @@
/*
* File: LBoundSpinCtrl.h
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 22 septembre 2014, 14:36
*/
#ifndef LBOUNDSPINCTRL_H
#define LBOUNDSPINCTRL_H
#include <wx/spinctrl.h>
#include "LBoundControl.h"
#include "LResultSet.h"
/**
This integer spin control always has a value. Hence, the associated table column must have the
* same default value as the initial value of the control.
*/
class LBoundSpinCtrl : public wxSpinCtrl, public LBoundControl
{
public:
LBoundSpinCtrl(wxWindow *parent,
wxWindowID id = wxID_ANY,
const wxPoint &pos = wxDefaultPosition,
const wxSize &size = wxDefaultSize,
long style = wxSP_ARROW_KEYS | wxALIGN_RIGHT,
int min = 0,
int max = 100,
int initial = 0);
virtual ~LBoundSpinCtrl();
/**
* Sets the resultset member and registers the control in the resultset.
* @param newResultSet
*/
void SetResultSet(LResultSet * newResultSet);
/**
*
* @return Alias for GetValue().
*/
const wxAny GetData()
{
return GetValue();
}
/**
* If newData is null or empty, sets the control to its initial value.
* @param newData
* @return
*/
bool SetData(const wxAny& newData);
/**
* This control is never empty.
* @return false, always
*/
bool IsNull()
{
return false;
}
/**
* Sets the control to its initial value.
* @return
*/
bool SetNull()
{
SetData(m_initialValue);
}
bool IsDirty();
/**
* Alias for GetData().
* @return
*/
const wxString GetDisplayedData()
{
return GetData().As<wxString>();
}
private:
int m_initialValue;
};
#endif /* LBOUNDSPINCTRL_H */

47
L7/LBoundTextCtrl.cpp Normal file
View File

@@ -0,0 +1,47 @@
/*
* File: LBoundTextCtrl.cpp
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 2 juin 2014, 14:53
*/
#include "LBoundTextCtrl.h"
LBoundTextCtrl::LBoundTextCtrl(wxWindow* parent, wxWindowID id, long style)
: wxTextCtrl(parent, id, wxEmptyString, wxDefaultPosition, wxDefaultSize, style)
{
m_sqlQuote = _T("'");
}
LBoundTextCtrl::~LBoundTextCtrl()
{
if (m_rs) m_rs->UnRegisterControl(this);
}
void LBoundTextCtrl::SetResultSet(LResultSet* newResultSet)
{
m_rs = newResultSet;
if (m_rs == NULL) return;
m_rs->RegisterControl(this);
}
const wxAny LBoundTextCtrl::GetData()
{
if (GetValue().IsEmpty()) return L_SQLNULL;
return GetValue();
}
bool LBoundTextCtrl::SetData(const wxAny& newData)
{
ChangeValue(newData.As<wxString>());
return true;
}
bool LBoundTextCtrl::IsDirty()
{
wxASSERT_MSG(m_rs != NULL, _("RS = NULL"));
wxAny BEData = m_rs->GetData(m_columnName);
return (GetValue() != BEData.As<wxString>());
}

68
L7/LBoundTextCtrl.h Normal file
View File

@@ -0,0 +1,68 @@
/*
* File: LBoundTextCtrl.h
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 2 juin 2014, 14:52
*/
#ifndef LBOUNDTEXTCTRL_H
#define LBOUNDTEXTCTRL_H
#include <wx/textctrl.h>
#include "LBoundControl.h"
#include "LResultSet.h"
class LBoundTextCtrl : public wxTextCtrl, public LBoundControl
{
public:
LBoundTextCtrl(wxWindow* parent, wxWindowID id = wxID_ANY, long style = 0);
virtual ~LBoundTextCtrl();
/**
* Sets the resultset member and registers the control in the resultset.
* @param newResultSet
*/
void SetResultSet(LResultSet * newResultSet);
/**
*
* @return If the control is empty, returns literal NULL. Else, returns GetValue().
*/
const wxAny GetData();
/**
* Calls ChangeValue().
* @param newData
* @return
*/
bool SetData(const wxAny& newData);
/**
* Alias for IsEmpty().
* @return
*/
bool IsNull()
{
return IsEmpty();
}
/**
* Alias for Clear().
* @return
*/
bool SetNull()
{
Clear();
}
bool IsDirty();
/**
* Alias for GetValue().
* @return
*/
const wxString GetDisplayedData()
{
return GetValue();
}
private:
};
#endif /* LBOUNDTEXTCTRL_H */

64
L7/LConnection.cpp Normal file
View File

@@ -0,0 +1,64 @@
/*
* File: LConnection.cpp
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 25 mai 2014, 10:49
*/
#include "LConnection.h"
LConnection::LConnection()
{
m_connInfo = wxEmptyString;
m_UserName = wxEmptyString;
m_DBName = wxEmptyString;
m_ServerName = wxEmptyString;
m_Port = wxEmptyString;
m_readOnly = false;
}
LConnection::LConnection(const wxString& newInfo)
{
m_connInfo = newInfo;
m_UserName = wxEmptyString;
m_DBName = wxEmptyString;
m_ServerName = wxEmptyString;
m_Port = wxEmptyString;
m_readOnly = false;
}
LConnection::~LConnection()
{
}
void LConnection::RegisterEventHandler(LConnectionEvent * evh)
{
if (evh == NULL || m_evtHandlers.Index(evh) != wxNOT_FOUND) return;
m_evtHandlers.Add(evh);
}
void LConnection::UnRegisterEventHandler(LConnectionEvent * evh)
{
if (evh == NULL || m_evtHandlers.Index(evh) == wxNOT_FOUND) return;
m_evtHandlers.Remove(evh);
}
///////////////////////////////////////////////////////////////////////////////
LConnectionEvent::LConnectionEvent()
{
}
LConnectionEvent::~LConnectionEvent()
{
}
void LConnectionEvent::BeforeExecute(const LConnection* caller)
{
}
void LConnectionEvent::AfterExecute(const LConnection* caller)
{
}
void LConnectionEvent::Inform(const LConnection* caller, const LInformation& msg) const
{
}

189
L7/LConnection.h Normal file
View File

@@ -0,0 +1,189 @@
/*
* File: LConnection.h
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 25 mai 2014, 10:48
*/
#ifndef LCONNECTION_H
#define LCONNECTION_H
#include <wx/wx.h>
#include "LInformation.h"
class LConnection;
class LConnectionEvent;
/**
* Abstract class for implementing a database connection.
*/
class LConnection : public wxTrackable
{
public:
LConnection();
/**
*
* @param newInfo database connection information.
*/
LConnection(const wxString& newInfo);
virtual ~LConnection();
virtual const char* GetLastLibMessage() const = 0;
/**
*
* @return the connection information.
*/
const wxString& GetInfo() const
{
return m_connInfo;
}
/**
*
* @param newInfo the connection information.
*/
void SetInfo(const wxString& newInfo)
{
m_connInfo = newInfo;
}
virtual bool Connect() = 0;
virtual void * Get() const = 0;
virtual bool IsValid() const = 0;
virtual void Close() = 0;
virtual void * ExecuteSQL(const wxString& newSql) = 0;
virtual bool ExecuteUpdateSQL(const wxString& newSql) = 0;
virtual const wxAny GetReturnedValue(const unsigned int col) const = 0;
/**
* After a change, the connection must be closed and re-established.
* @param newReadOnly
*/
void SetReadOnly(bool newReadOnly)
{
m_readOnly = newReadOnly;
}
/**
*
* @return
*/
bool IsReadOnly() const
{
return m_readOnly;
}
/**
* Concerns the PostgreSQL backend only.
* @return the backend user name.
*/
const wxString& GetUserName() const
{
return m_UserName;
}
/**
* Concerns the PostgreSQL backend only.
* @return the database name.
*/
const wxString& GetDBName() const
{
return m_DBName;
}
/**
* Concerns the PostgreSQL backend only.
* @return the server address, as specified in the connection string.
*/
const wxString& GetServerName() const
{
return m_ServerName;
}
/**
* Concerns the PostgreSQL backend only.
* @return the server port.
*/
const wxString& GetServerPort() const
{
return m_Port;
}
/**
* Concerns the PostgreSQL backend only.
* @return a result set of the returned keys after an insert.
*/
virtual void * GetReturnedKeys() const
{
};
/**
* Concerns the PostgreSQL backend only. Frees memory.
*/
virtual void ClearReturnedKeys()
{
};
/**
* Application can register derived classes of LConnectionEvent.
* @param evh : an LConnectionEvent derived class.
*/
void RegisterEventHandler(LConnectionEvent * evh);
/**
* Application can unregister derived classes of LConnectionEvent.
* @param evh : an LConnectionEvent derived class.
*/
void UnRegisterEventHandler(LConnectionEvent * evh);
/**
* Returns registered derived classes of LConnectionEvent.
* @return A reference to a wxArrayPtrVoid object.
*/
wxArrayPtrVoid& GetEventHandlers()
{
return m_evtHandlers;
}
protected:
wxString m_connInfo;
wxString m_UserName;
wxString m_DBName;
wxString m_ServerName;
wxString m_Port;
wxArrayPtrVoid m_evtHandlers;
bool m_readOnly;
private:
};
/**
This class can be derived by an application to implement its methods.
* The application should register its derived classes with an LConnection object.
*/
class LConnectionEvent
{
public:
LConnectionEvent();
virtual ~LConnectionEvent();
/**
* Concerns the PostgreSQL backend only.
* @param caller the LConnection object having registered the derived class.
*/
virtual void BeforeExecute(const LConnection * caller);
/**
* Concerns the PostgreSQL backend only.
* @param caller the LConnection object having registered the derived class.
*/
virtual void AfterExecute(const LConnection * caller);
/**
*
* @param caller the LConnection object having registered the derived class.
* @param msg messages from the LConnection object.
*/
virtual void Inform(const LConnection * caller,
const LInformation& msg) const;
private:
};
#endif /* LCONNECTION_H */

101
L7/LGridCheckEditor.cpp Normal file
View File

@@ -0,0 +1,101 @@
/*
* File: LGridCheckEditor.cpp
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 9 juin 2014, 20:04
*/
#include "LGridCheckEditor.h"
#include "LBoundGrid.h"
LGridCheckEditor::LGridCheckEditor(const wxString& newColName, bool isDualstate, const wxString& newNullLabel)
{
m_triState = !isDualstate;
m_style = wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER;
if (!m_triState) m_style = wxCHK_2STATE;
m_colName = newColName;
if (newNullLabel.IsEmpty()) {
m_nullLabel = _T("?");
} else {
m_nullLabel = newNullLabel;
}
m_type = LGridColEditor::CHECK;
m_formEditor = NULL;
m_BoundControl = NULL;
m_BoundCheckBox = NULL;
}
LGridCheckEditor::~LGridCheckEditor()
{
wxDELETE(m_control);
}
void LGridCheckEditor::Create (wxWindow *parent, wxWindowID id, wxEvtHandler *evtHandler) {
m_control = new LBoundCheckBox(parent, id, m_style);
m_BoundCheckBox = static_cast<LBoundCheckBox*> (m_control);
m_BoundCheckBox->SetColumnName(m_colName);
m_BoundCheckBox->SetLabel(wxEmptyString);
m_BoundControl = m_BoundCheckBox;
m_control->Show(false);
}
void LGridCheckEditor::BeginEdit (int row, int col, wxGrid *grid) {
if (m_control == NULL) {
Create(grid->GetGridWindow(), wxID_ANY, NULL);
}
m_BoundCheckBox->SetResultSet(((LBoundGrid *) grid)->GetResultSet());
const wxAny val = grid->GetTable()->GetValue(row, col);
if (m_triState && val.As<wxString>() == m_nullLabel) {
m_BoundCheckBox->SetNull();
} else {
m_BoundCheckBox->SetData(val);
}
m_control->Show(true);
}
wxGridCellEditor* LGridCheckEditor::Clone () const {
return new LGridCheckEditor(m_colName, !m_triState, m_nullLabel);
}
bool LGridCheckEditor::EndEdit (int row, int col, const wxGrid *grid, const wxString &oldval, wxString *newval) {
// What do we do here ?
return true;
}
void LGridCheckEditor::ApplyEdit (int row, int col, wxGrid *grid) {
const wxAny val = m_BoundCheckBox->GetData();
if (m_triState && val.As<wxString>() == L_SQLNULL) {
grid->GetTable()->SetValue(row, col, m_nullLabel);
} else {
grid->GetTable()->SetValue(row, col, val.As<wxString>());
}
}
void LGridCheckEditor::Reset () {
wxDELETE(m_control);
m_BoundControl = NULL;
m_BoundCheckBox = NULL;
}
wxString LGridCheckEditor::GetValue() const {
return m_control == NULL ? wxString(wxEmptyString) : m_BoundControl->GetData().As<wxString>();
}
wxControl* LGridCheckEditor::ProvideFormEditor(wxWindow * parent) {
if (!m_formEditor) m_formEditor = new wxCheckBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, m_style);
if (m_triState) {
m_formEditor->Set3StateValue(m_BoundCheckBox->Get3StateValue());
} else {
m_formEditor->SetValue(m_BoundCheckBox->GetValue());
}
m_formEditor->SetName(m_BoundCheckBox->GetName());
if (m_BoundCheckBox->GetValidator()) m_formEditor->SetValidator(*(m_BoundCheckBox->GetValidator()));
return m_formEditor;
}
void LGridCheckEditor::SyncBack(const int row, const int col, wxGrid * grid) {
if (!m_formEditor) return;
if (m_triState) {
m_BoundCheckBox->Set3StateValue(m_formEditor->Get3StateValue());
} else {
m_BoundCheckBox->SetValue(m_formEditor->GetValue());
}
ApplyEdit(row, col, grid);
wxDELETE(m_formEditor);
}

97
L7/LGridCheckEditor.h Normal file
View File

@@ -0,0 +1,97 @@
/*
* File: LGridCheckEditor.h
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 9 juin 2014, 20:04
*/
#ifndef LGRIDCHECKEDITOR_H
#define LGRIDCHECKEDITOR_H
#include "LBoundCheckBox.h"
#include "LGridColEditor.h"
/**
* Edits table data using an LBoundCheckBox.
*/
class LGridCheckEditor : public wxGridCellEditor, public LGridColEditor
{
public:
/**
* N.B. newNullLabel must be the same in LGridCheckEditor and LGridCheckRenderer
* @param newColName database column name
* @param isDualState use a dual or triple state checkbox.
* @param newNullLabel cell value to interprete as undetermined for a tristate checkbox..
*/
LGridCheckEditor(const wxString& newColName,
bool isDualState = false,
const wxString& newNullLabel = _T("?"));
/**
* The editor gets deleted.
*/
virtual ~LGridCheckEditor();
/**
* Creates m_control as LBoundCheckBox.
* @param parent
* @param id
* @param evtHandler
*/
void Create(wxWindow *parent, wxWindowID id, wxEvtHandler *evtHandler);
/**
* Creates m_control if necessary. Registers the editor in the grid's resultset.
*
* @param row
* @param col
* @param grid
*/
void BeginEdit(int row, int col, wxGrid *grid);
wxGridCellEditor* Clone() const;
bool EndEdit(int row, int col, const wxGrid *grid, const wxString &oldval, wxString *newval);
/**
* Applies the editor value as returned by GetData() to the grid cell.
* @param row
* @param col
* @param grid
*/
void ApplyEdit(int row, int col, wxGrid *grid);
/**
* Deletes the editor, all pointers to the editor are set to NULL.
*/
void Reset();
/**
*
* @return GetData(), or wxEmptyString if the editor control has not been created.
*/
wxString GetValue() const;
/**
* Creates a wxCheckBox to be used as editor in form view.
*/
wxControl* ProvideFormEditor(wxWindow * parent);
wxControl* GetFormEditor() const
{
return m_formEditor;
}
/**
* Updates the grid cell and the editor. m_formEditor is deleted and set to NULL.
* @param row
* @param col
* @param grid
*/
void SyncBack(const int row, const int col, wxGrid * grid);
private:
bool m_triState;
unsigned long m_style;
wxCheckBox * m_formEditor;
wxString m_nullLabel;
/**
* Fully typed alias to m_control.
*/
LBoundCheckBox * m_BoundCheckBox;
};
#endif /* LGRIDCHECKEDITOR_H */

81
L7/LGridCheckRenderer.cpp Normal file
View File

@@ -0,0 +1,81 @@
/*
* File: LGridCheckRenderer.cpp
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 9 juin 2014, 21:33
*/
#include "LGridCheckRenderer.h"
LGridCheckRenderer::LGridCheckRenderer(bool isDualState, const wxString& newNullLabel)
: wxGridCellStringRenderer()
{
m_triState = !isDualState;
if (newNullLabel.IsEmpty())
{
m_nullLabel = _T("?");
}
else
{
m_nullLabel = newNullLabel;
}
}
LGridCheckRenderer::~LGridCheckRenderer()
{
}
void LGridCheckRenderer::Draw(wxGrid & grid,
wxGridCellAttr & attr,
wxDC & dc,
const wxRect & rect,
int row,
int col,
bool isSelected)
{
/* The interpretation of literal non/oui is not documented
* as it's for internal use.
*/
wxString val = grid.GetCellValue(row, col);
if (m_triState)
{
if (val.IsEmpty()
|| val == m_nullLabel)
{
grid.GetTable()->SetValue(row, col, m_nullLabel);
wxGridCellStringRenderer::Draw(grid, attr, dc, rect, row, col, isSelected);
return;
}
if (val == _T("0")
|| val.Lower() == _("no"))
{
grid.GetTable()->SetValue(row, col, _T("No"));
}
else
{
grid.GetTable()->SetValue(row, col, _T("Yes"));
}
}
else
{
if (val == _T("0")
|| val.IsEmpty()
|| val.Lower() == _("no"))
{
grid.GetTable()->SetValue(row, col, _T("No"));
}
else
{
grid.GetTable()->SetValue(row, col, _T("Yes"));
}
}
wxGridCellStringRenderer::Draw(grid, attr, dc, rect, row, col, isSelected);
}
wxGridCellRenderer* LGridCheckRenderer::Clone() const
{
return new LGridCheckRenderer(!m_triState, m_nullLabel);
}

56
L7/LGridCheckRenderer.h Normal file
View File

@@ -0,0 +1,56 @@
/*
* File: LGridCheckRenderer.h
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 9 juin 2014, 21:32
*/
#ifndef LGRIDCHECKRENDERER_H
#define LGRIDCHECKRENDERER_H
#include "wx/grid.h"
class LGridCheckRenderer : public wxGridCellStringRenderer
{
public:
/**
* N.B. newNullLabel must be the same in LGridCheckEditor and LGridCheckRenderer
* @param isDualState : is the cell edited with a dual or tristate checkbox ?
* @param newNullLabel : what to show if tristate with undetermined state.
*/
LGridCheckRenderer(bool isDualState = false, const wxString& newNullLabel = _T("?"));
virtual ~LGridCheckRenderer();
/**
* What is rendered per cell value.
*
* If tristate : empty cell maps to nullLabel,
* 0 maps to literal Non,
* anything else is shown as literal Oui.
*
* If dualstate : empty cell or 0 map to literal Non,
* Anything else is shown as literal Oui.
* @param grid
* @param attr
* @param dc
* @param rect
* @param row
* @param col
* @param isSelected
*/
void Draw(wxGrid & grid,
wxGridCellAttr & attr,
wxDC & dc,
const wxRect & rect,
int row,
int col,
bool isSelected);
wxGridCellRenderer* Clone() const;
private:
wxString m_nullLabel;
bool m_triState;
};
#endif /* LGRIDCHECKRENDERER_H */

20
L7/LGridColEditor.cpp Normal file
View File

@@ -0,0 +1,20 @@
/*
* File: LGridColEditor.cpp
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 9 juin 2014, 15:46
*/
#include "LGridColEditor.h"
#include "LBoundGrid.h"
LGridColEditor::LGridColEditor()
{
}
LGridColEditor::~LGridColEditor()
{
}

78
L7/LGridColEditor.h Normal file
View File

@@ -0,0 +1,78 @@
/*
* File: LGridColEditor.h
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 9 juin 2014, 15:45
*/
#include <wx/wx.h>
#include <wx/grid.h>
#include "LBoundControl.h"
#ifndef LGRIDCOLEDITOR_H
#define LGRIDCOLEDITOR_H
/**
* Abstract class defining methods data bound grid cell editors must implement.
*/
class LGridColEditor
{
public:
LGridColEditor();
virtual ~LGridColEditor();
enum COL_TYPE
{
TEXT, COMBO, DATE, CHECK, SPIN
};
/**
*
* @return the database table column name.
*/
const wxString& GetColumnName() const
{
return m_colName;
}
int GetType() const
{
return m_type;
}
/**
*
* @param parent : the parent of the returned wxControl.
* @return
*/
virtual wxControl* ProvideFormEditor(wxWindow * parent) = 0;
/**
* Applies values of controls in form view of the row to their respective cells.
* @param row
* @param col
* @param grid
*/
virtual void SyncBack(const int row, const int col, wxGrid * grid) = 0;
/**
*
* @return the wxControl on the form. May be NULL if grid row is not in form view.
*/
virtual wxControl* GetFormEditor() const = 0;
LBoundControl * GetBoundControl() const
{
return m_BoundControl;
}
protected:
int m_type;
wxString m_colName;
/**
* m_control of the wxGridCellEditor, typed as generic LBoundControl.
*/
LBoundControl * m_BoundControl;
private:
};
#endif /* LGRIDCOLEDITOR_H */

108
L7/LGridComboEditor.cpp Normal file
View File

@@ -0,0 +1,108 @@
/*
* File: LGridComboEditor.cpp
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 12 juin 2014, 18:34
*/
#include "LGridComboEditor.h"
#include "LBoundGrid.h"
LGridComboEditor::LGridComboEditor(const wxString& newColName)
{
m_colName = newColName;
m_type = LGridColEditor::COMBO;
m_formEditor = NULL;
m_BoundControl = NULL;
m_BoundComboBox = NULL;
}
LGridComboEditor::~LGridComboEditor()
{
wxDELETE(m_control);
}
void LGridComboEditor::Create(wxWindow* parent, wxWindowID id, wxEvtHandler* evtHandler)
{
m_control = new LBoundComboBox(parent, id);
m_BoundComboBox = static_cast<LBoundComboBox*> (m_control);
m_BoundComboBox->SetColumnName(m_colName);
m_BoundControl = m_BoundComboBox;
m_control->Show(false);
}
void LGridComboEditor::BeginEdit(int row, int col, wxGrid* grid)
{
if (m_control == NULL)
{
Create(grid->GetGridWindow(), wxID_ANY, NULL);
}
m_BoundComboBox->SetResultSet(((LBoundGrid *) grid)->GetResultSet());
const wxString cellVal = grid->GetTable()->GetValue(row, col);
if (cellVal.IsEmpty())
{
m_BoundComboBox->SetNull();
}
else
{
m_BoundComboBox->SetStringSelection(cellVal);
}
m_BoundComboBox->Show(true);
}
wxGridCellEditor* LGridComboEditor::Clone() const
{
return new LGridComboEditor(m_colName);
}
bool LGridComboEditor::EndEdit(int row, int col, const wxGrid* grid, const wxString& oldval, wxString* newval)
{
// What do we do here ?
return true;
}
void LGridComboEditor::ApplyEdit(int row, int col, wxGrid* grid)
{
grid->GetTable()->SetValue(row, col, m_BoundComboBox->GetStringSelection());
}
void LGridComboEditor::Reset()
{
wxDELETE(m_control);
m_BoundControl = NULL;
m_BoundComboBox = NULL;
}
wxString LGridComboEditor::GetValue() const
{
return m_control == NULL ? wxString(wxEmptyString) : m_BoundControl->GetData().As<wxString>();
}
wxControl* LGridComboEditor::ProvideFormEditor(wxWindow* parent)
{
if (!m_formEditor)
{
m_formEditor = new wxComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxArrayString(), m_BoundComboBox->GetWindowStyleFlag());
for (unsigned int i = 0; i < m_BoundComboBox->GetCount(); i++)
{
m_formEditor->Append(m_BoundComboBox->GetString(i));
}
m_formEditor->Select(m_BoundComboBox->GetSelection());
m_formEditor->SetName(m_BoundComboBox->GetName());
if (m_BoundComboBox->GetValidator()) m_formEditor->SetValidator(*(m_BoundComboBox->GetValidator()));
}
return m_formEditor;
}
void LGridComboEditor::SyncBack(const int row, const int col, wxGrid* grid)
{
if (!m_formEditor) return;
m_BoundComboBox->Select(m_formEditor->GetSelection());
ApplyEdit(row, col, grid);
grid->ForceRefresh();
grid->GetGridWindow()->SetFocus();
delete m_formEditor;
m_formEditor = NULL;
}

89
L7/LGridComboEditor.h Normal file
View File

@@ -0,0 +1,89 @@
/*
* File: LGridComboEditor.h
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 12 juin 2014, 18:33
*/
#ifndef LGRIDCOMBOEDITOR_H
#define LGRIDCOMBOEDITOR_H
#include "LGridColEditor.h"
#include "LBoundComboBox.h"
/**
* Edits table data using an LBoundComboBox.
*/
class LGridComboEditor : public wxGridCellEditor, public LGridColEditor
{
public:
/**
*
* @param newColName database column name
*/
LGridComboEditor(const wxString& newColName);
/**
* The editor gets deleted.
*/
virtual ~LGridComboEditor();
/**
* Creates m_control as LBoundComboBox.
* @param parent
* @param id
* @param evtHandler
*/
void Create(wxWindow *parent, wxWindowID id, wxEvtHandler *evtHandler);
/**
* Creates m_control if necessary. Registers the editor in the grid's resultset.
* @param row
* @param col
* @param grid
*/
void BeginEdit(int row, int col, wxGrid *grid);
wxGridCellEditor* Clone() const;
bool EndEdit(int row, int col, const wxGrid *grid, const wxString &oldval, wxString *newval);
/**
* Applies the editor value as returned by GetStringSelection() to the grid cell.
* @param row
* @param col
* @param grid
*/
void ApplyEdit(int row, int col, wxGrid *grid);
/**
* Deletes the editor, all pointers to the editor are set to NULL.
*/
void Reset();
/**
*
* @return GetData(), or wxEmptyString if the editor control has not been created.
*/
wxString GetValue() const;
/**
* Creates a wxComboBox to be used as editor in form view.
*/
wxControl* ProvideFormEditor(wxWindow * parent);
wxControl* GetFormEditor() const
{
return m_formEditor;
}
/**
* Updates the grid cell and the editor. m_formEditor is deleted and set to NULL.
* @param row
* @param col
* @param grid
*/
void SyncBack(const int row, const int col, wxGrid * grid);
private:
wxComboBox * m_formEditor;
/**
* Fully typed alias to m_control.
*/
LBoundComboBox * m_BoundComboBox;
};
#endif /* LGRIDCOMBOEDITOR_H */

20
L7/LGridComboRenderer.cpp Normal file
View File

@@ -0,0 +1,20 @@
/*
* File: LGridComboRenderer.cpp
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 13 juin 2014, 18:03
*/
#include "LGridComboRenderer.h"
LGridComboRenderer::LGridComboRenderer()
: wxGridCellAutoWrapStringRenderer()
{
}
LGridComboRenderer::~LGridComboRenderer()
{
}

25
L7/LGridComboRenderer.h Normal file
View File

@@ -0,0 +1,25 @@
/*
* File: LGridComboRenderer.h
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 13 juin 2014, 18:03
*/
#ifndef LGRIDCOMBORENDERER_H
#define LGRIDCOMBORENDERER_H
#include "wx/grid.h"
class LGridComboRenderer : public wxGridCellAutoWrapStringRenderer
{
public:
LGridComboRenderer();
virtual ~LGridComboRenderer();
private:
};
#endif /* LGRIDCOMBORENDERER_H */

96
L7/LGridDateEditor.cpp Normal file
View File

@@ -0,0 +1,96 @@
/*
* File: LGridDateEditor.cpp
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 12 juin 2014, 17:27
*/
#include "LGridDateEditor.h"
#include "LBoundGrid.h"
LGridDateEditor::LGridDateEditor(const wxString& newColName)
{
m_colName = newColName;
m_type = LGridColEditor::DATE;
m_formEditor = NULL;
m_BoundControl = NULL;
m_BoundDatePicker = NULL;
}
LGridDateEditor::~LGridDateEditor()
{
wxDELETE(m_control);
}
void LGridDateEditor::Create(wxWindow* parent, wxWindowID id, wxEvtHandler* evtHandler)
{
m_control = new LBoundDatePickerCtrl(parent, id);
m_BoundDatePicker = static_cast<LBoundDatePickerCtrl*> (m_control);
m_BoundDatePicker->SetColumnName(m_colName);
m_BoundControl = m_BoundDatePicker;
m_control->Show(false);
}
void LGridDateEditor::BeginEdit(int row, int col, wxGrid* grid)
{
if (m_control == NULL) {
Create(grid->GetGridWindow(), wxID_ANY, NULL);
}
m_BoundDatePicker->SetResultSet(((LBoundGrid *) grid)->GetResultSet());
const wxAny str_date = grid->GetTable()->GetValue(row, col);
m_BoundDatePicker->SetData(str_date);
m_BoundDatePicker->Show(true);
}
wxGridCellEditor* LGridDateEditor::Clone() const
{
return new LGridDateEditor(m_colName);
}
bool LGridDateEditor::EndEdit(int row, int col, const wxGrid* grid, const wxString& oldval, wxString* newval)
{
// What do we do here ?
return true;
}
void LGridDateEditor::ApplyEdit(int row, int col, wxGrid* grid)
{
const wxString sText = m_BoundDatePicker->IsNull()
? _T("")
: m_BoundDatePicker->GetData().As<wxString>();
grid->GetTable()->SetValue(row, col, sText);
}
void LGridDateEditor::Reset()
{
wxDELETE(m_control);
m_BoundControl = NULL;
m_BoundDatePicker = NULL;
}
wxString LGridDateEditor::GetValue() const
{
return m_control == NULL ? wxString(wxEmptyString) : m_BoundControl->GetData().As<wxString>();
}
wxControl* LGridDateEditor::ProvideFormEditor(wxWindow* parent)
{
if (!m_formEditor) m_formEditor = new wxDatePickerCtrl(parent, wxID_ANY, wxInvalidDateTime, wxDefaultPosition, wxDefaultSize, m_BoundDatePicker->GetWindowStyleFlag());
m_formEditor->SetValue(m_BoundDatePicker->GetValue());
//formEditor->SetValue(formEditor->GetValue()); // BUG SINCE 2.9.x Still ?
m_formEditor->SetName(m_BoundDatePicker->GetName());
if (m_BoundDatePicker->GetValidator()) m_formEditor->SetValidator(*(m_BoundDatePicker->GetValidator()));
return m_formEditor;
}
void LGridDateEditor::SyncBack(const int row, const int col, wxGrid* grid)
{
if (!m_formEditor) return;
m_BoundDatePicker->SetValue(m_formEditor->GetValue());
//m_BoundDatePicker->SetValue(m_BoundControl->GetValue()); // BUG SINCE 2.9.x . Still ?
ApplyEdit(row, col, grid);
wxDELETE(m_formEditor);
}

84
L7/LGridDateEditor.h Normal file
View File

@@ -0,0 +1,84 @@
/*
* File: LGridDateEditor.h
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 12 juin 2014, 17:27
*/
#ifndef LGRIDDATEEDITOR_H
#define LGRIDDATEEDITOR_H
#include "LGridColEditor.h"
#include "LBoundDatePickerCtrl.h"
/**
* Edits table data using an LBoundDatePickerCtrl.
*/
class LGridDateEditor : public wxGridCellEditor, public LGridColEditor {
public:
/**
*
* @param newColName database column name
*/
LGridDateEditor(const wxString& newColName);
/**
* The editor gets deleted.
*/
virtual ~LGridDateEditor();
/**
* Creates m_control as LBoundDatePickerCtrl.
* @param parent
* @param id
* @param evtHandler
*/
void Create (wxWindow *parent, wxWindowID id, wxEvtHandler *evtHandler);
/**
* Creates m_control if necessary. Registers the editor in the grid's resultset.
* @param row
* @param col
* @param grid
*/
void BeginEdit (int row, int col, wxGrid *grid);
wxGridCellEditor* Clone () const;
bool EndEdit (int row, int col, const wxGrid *grid, const wxString &oldval, wxString *newval);
/**
* Applies the editor value as returned by GetData() to the grid cell.
* If the editor contains wxInvalidDateTime, the grid cell is set to an empty string.
* @param row
* @param col
* @param grid
*/
void ApplyEdit (int row, int col, wxGrid *grid);
/**
* Deletes the editor, all pointers to the editor are set to NULL.
*/
void Reset ();
/**
*
* @return GetData(), or wxEmptyString if the editor control has not been created.
*/
wxString GetValue() const;
/**
* Creates a wxDatePickerCtrl to be used as editor in form view.
*/
wxControl* ProvideFormEditor(wxWindow * parent);
wxControl* GetFormEditor() const {return m_formEditor;}
/**
* Updates the grid cell and the editor. m_formEditor is deleted and set to NULL.
* @param row
* @param col
* @param grid
*/
void SyncBack(const int row, const int col, wxGrid * grid);
private:
wxDatePickerCtrl * m_formEditor;
/**
* Fully typed alias to m_control.
*/
LBoundDatePickerCtrl * m_BoundDatePicker;
};
#endif /* LGRIDDATEEDITOR_H */

20
L7/LGridDateRenderer.cpp Normal file
View File

@@ -0,0 +1,20 @@
/*
* File: LGridDateRenderer.cpp
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 12 juin 2014, 18:02
*/
#include "LGridDateRenderer.h"
LGridDateRenderer::LGridDateRenderer(const wxString& outFormat, const wxString& inFormat)
: wxGridCellDateTimeRenderer(outFormat, inFormat)
{
}
LGridDateRenderer::~LGridDateRenderer()
{
}

25
L7/LGridDateRenderer.h Normal file
View File

@@ -0,0 +1,25 @@
/*
* File: LGridDateRenderer.h
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 12 juin 2014, 18:01
*/
#ifndef LGRIDDATERENDERER_H
#define LGRIDDATERENDERER_H
#include <wx/grid.h>
class LGridDateRenderer : public wxGridCellDateTimeRenderer
{
public:
LGridDateRenderer(const wxString& outFormat = _T("%a %d %b %Y"), const wxString& inFormat = _T("%Y-%m-%d"));
virtual ~LGridDateRenderer();
private:
};
#endif /* LGRIDDATERENDERER_H */

100
L7/LGridSpinEditor.cpp Normal file
View File

@@ -0,0 +1,100 @@
/*
* File: LGridSpinEditor.cpp
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 23 septembre 2014, 18:02
*/
#include "LGridSpinEditor.h"
#include "LBoundGrid.h"
LGridSpinEditor::LGridSpinEditor(const wxString& newColName,
int newMin,
int newMax,
int newInitial)
{
m_min = newMin;
m_max = newMax;
m_initial = newInitial;
m_colName = newColName;
m_type = LGridColEditor::SPIN;
m_formEditor = NULL;
m_BoundControl = NULL;
m_BoundSpinCtrl = NULL;
}
LGridSpinEditor::~LGridSpinEditor()
{
wxDELETE(m_control);
}
void LGridSpinEditor::Create(wxWindow* parent, wxWindowID id, wxEvtHandler* evtHandler)
{
m_control = new LBoundSpinCtrl(parent, id, wxDefaultPosition,
wxDefaultSize, wxSP_ARROW_KEYS | wxALIGN_RIGHT,
m_min, m_max, m_initial);
m_BoundSpinCtrl = (static_cast<LBoundSpinCtrl*> (m_control));
m_BoundSpinCtrl->SetColumnName(m_colName);
m_BoundControl = m_BoundSpinCtrl;
m_control->Show(false);
}
void LGridSpinEditor::BeginEdit(int row, int col, wxGrid* grid)
{
if (m_control == NULL)
{
Create(grid->GetGridWindow(), wxID_ANY, NULL);
}
m_BoundSpinCtrl->SetResultSet(((LBoundGrid *) grid)->GetResultSet());
const wxAny sText = grid->GetTable()->GetValue(row, col);
m_BoundSpinCtrl->SetData(sText);
m_control->Show(true);
}
wxGridCellEditor* LGridSpinEditor::Clone() const
{
return new LGridSpinEditor(m_colName, m_min, m_max, m_initial);
}
bool LGridSpinEditor::EndEdit(int row, int col, const wxGrid* grid, const wxString& oldval, wxString* newval)
{
// What do we do here ?
return true;
}
void LGridSpinEditor::ApplyEdit(int row, int col, wxGrid* grid)
{
grid->GetTable()->SetValue(row, col, m_BoundSpinCtrl->GetData().As<wxString>());
}
void LGridSpinEditor::Reset()
{
wxDELETE(m_control);
m_BoundControl = NULL;
m_BoundSpinCtrl = NULL;
}
wxString LGridSpinEditor::GetValue() const
{
if (m_control == NULL) return wxAny(m_initial).As<wxString>();
return m_BoundSpinCtrl->GetData().As<wxString>();
}
wxControl* LGridSpinEditor::ProvideFormEditor(wxWindow* parent)
{
if (!m_formEditor) m_formEditor = new wxSpinCtrl(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS | wxALIGN_RIGHT, m_min, m_max, m_initial);
m_formEditor->SetValue(GetValue());
m_formEditor->SetName(m_BoundSpinCtrl->GetName());
if (m_BoundSpinCtrl->GetValidator()) m_formEditor->SetValidator(*(m_BoundSpinCtrl->GetValidator()));
return m_formEditor;
}
void LGridSpinEditor::SyncBack(const int row, const int col, wxGrid* grid)
{
if (!m_formEditor) return;
m_BoundSpinCtrl->SetValue(m_formEditor->GetValue());
ApplyEdit(row, col, grid);
wxDELETE(m_formEditor);
}

97
L7/LGridSpinEditor.h Normal file
View File

@@ -0,0 +1,97 @@
/*
* File: LGridSpinEditor.h
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 23 septembre 2014, 18:01
*/
#ifndef LGRIDSPINEDITOR_H
#define LGRIDSPINEDITOR_H
#include "LGridColEditor.h"
#include "LBoundSpinCtrl.h"
/**
* Edits table data using an LBoundSpinCtrl.
*/
class LGridSpinEditor : public wxGridCellEditor, public LGridColEditor
{
public:
/**
*
* @param newColName
* @param newMin
* @param newMax
* @param newInitial
*/
LGridSpinEditor(const wxString& newColName,
int newMin = 0,
int newMax = 100,
int newInitial = 0);
/**
* The editor gets deleted.
*/
virtual ~LGridSpinEditor();
/**
* Creates m_control as LBoundSpinCtrl.
* @param parent
* @param id
* @param evtHandler
*/
void Create(wxWindow *parent, wxWindowID id, wxEvtHandler *evtHandler);
/**
* Creates m_control if necessary. Registers the editor in the grid's resultset.
* @param row
* @param col
* @param grid
*/
void BeginEdit(int row, int col, wxGrid *grid);
wxGridCellEditor* Clone() const;
bool EndEdit(int row, int col, const wxGrid *grid, const wxString &oldval, wxString *newval);
/**
* Applies the editor value to the grid cell.
* @param row
* @param col
* @param grid
*/
void ApplyEdit(int row, int col, wxGrid *grid);
/**
* Deletes the editor, all pointers to the editor are set to NULL.
*/
void Reset();
/**
*
* @return GetData(), or the initial value if the editor control has not been created.
*/
wxString GetValue() const;
/**
* Creates a wxSpinCtrl to be used as editor in form view.
*/
wxControl* ProvideFormEditor(wxWindow * parent);
wxControl* GetFormEditor() const
{
return m_formEditor;
}
/**
* Updates the grid cell and the editor. m_formEditor is deleted and set to NULL.
* @param row
* @param col
* @param grid
*/
void SyncBack(const int row, const int col, wxGrid * grid);
private:
wxSpinCtrl * m_formEditor;
/**
* Fully typed alias to m_control.
*/
LBoundSpinCtrl * m_BoundSpinCtrl;
int m_min, m_max, m_initial;
};
#endif /* LGRIDSPINEDITOR_H */

20
L7/LGridSpinRenderer.cpp Normal file
View File

@@ -0,0 +1,20 @@
/*
* File: LGridSpinRenderer.cpp
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 25 septembre 2014, 21:20
*/
#include "LGridSpinRenderer.h"
LGridSpinRenderer::LGridSpinRenderer()
: wxGridCellNumberRenderer()
{
}
LGridSpinRenderer::~LGridSpinRenderer()
{
}

24
L7/LGridSpinRenderer.h Normal file
View File

@@ -0,0 +1,24 @@
/*
* File: LGridSpinRenderer.h
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 25 septembre 2014, 21:19
*/
#ifndef LGRIDSPINRENDERER_H
#define LGRIDSPINRENDERER_H
#include <wx/grid.h>
class LGridSpinRenderer : public wxGridCellNumberRenderer {
public:
LGridSpinRenderer();
virtual ~LGridSpinRenderer();
private:
};
#endif /* LGRIDSPINRENDERER_H */

77
L7/LGridTextEditor.cpp Normal file
View File

@@ -0,0 +1,77 @@
/*
* File: LGridTextEditor.cpp
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 9 juin 2014, 16:09
*/
#include "LGridTextEditor.h"
#include "LBoundGrid.h"
LGridTextEditor::LGridTextEditor(const wxString& newColName, bool newMultiline)
: wxGridCellAutoWrapStringEditor()
{
m_multiline = newMultiline;
m_style = 0;
if (m_multiline) m_style = wxTE_MULTILINE;
m_colName = newColName;
m_type = LGridColEditor::TEXT;
m_formEditor = NULL;
m_BoundControl = NULL;
m_BoundTextCtrl = NULL;
}
LGridTextEditor::~LGridTextEditor()
{
wxDELETE(m_control);
}
void LGridTextEditor::Create (wxWindow *parent, wxWindowID id, wxEvtHandler *evtHandler) {
m_control = new LBoundTextCtrl( parent, id, m_style);
m_BoundTextCtrl = (static_cast<LBoundTextCtrl*> (m_control));
m_BoundTextCtrl->SetColumnName(m_colName);
m_BoundControl = m_BoundTextCtrl;
m_control->Show(false);
}
void LGridTextEditor::BeginEdit (int row, int col, wxGrid *grid) {
if (m_control == NULL) {
Create(grid->GetGridWindow(), wxID_ANY, NULL);
}
m_BoundTextCtrl->SetResultSet(((LBoundGrid *) grid)->GetResultSet());
const wxAny sText = grid->GetTable()->GetValue(row, col);
m_BoundTextCtrl->SetData(sText);
m_control->Show(true);
}
wxGridCellEditor* LGridTextEditor::Clone () const {
return new LGridTextEditor(m_colName, m_multiline);
}
bool LGridTextEditor::EndEdit (int row, int col, const wxGrid *grid, const wxString &oldval, wxString *newval) {
// What do we do here ?
return true;
}
void LGridTextEditor::ApplyEdit (int row, int col, wxGrid *grid) {
grid->GetTable()->SetValue(row, col, m_BoundTextCtrl->GetValue());
}
void LGridTextEditor::Reset () {
wxDELETE(m_control);
m_BoundControl = NULL;
m_BoundTextCtrl = NULL;
}
wxString LGridTextEditor::GetValue() const {
return m_control == NULL ? wxString(wxEmptyString) : m_BoundControl->GetData().As<wxString>();
}
wxControl* LGridTextEditor::ProvideFormEditor(wxWindow * parent) {
if (!m_formEditor) m_formEditor = new wxTextCtrl(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, m_style);
m_formEditor->SetValue(GetValue());
m_formEditor->SetName(m_BoundTextCtrl->GetName());
if (m_BoundTextCtrl->GetValidator()) m_formEditor->SetValidator(*(m_BoundTextCtrl->GetValidator()));
return m_formEditor;
}
void LGridTextEditor::SyncBack(const int row, const int col, wxGrid * grid) {
if (!m_formEditor) return;
m_BoundTextCtrl->SetValue(m_formEditor->GetValue());
ApplyEdit(row, col, grid);
wxDELETE(m_formEditor);
}

92
L7/LGridTextEditor.h Normal file
View File

@@ -0,0 +1,92 @@
/*
* File: LGridTextEditor.h
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 9 juin 2014, 16:08
*/
#ifndef LGRIDTEXTEDITOR_H
#define LGRIDTEXTEDITOR_H
#include "LGridColEditor.h"
#include "LBoundTextCtrl.h"
/**
* Edits table data using an LBoundTextCtrl.
*/
class LGridTextEditor : public wxGridCellAutoWrapStringEditor, public LGridColEditor
{
public:
/**
*
* @param newColName database column name
* @param newMultiline if true, use wxTE_MULTILINE
*/
LGridTextEditor(const wxString& newColName, bool newMultiline = false);
/**
* The editor gets deleted.
*/
virtual ~LGridTextEditor();
/**
* Creates m_control as LBoundTextCtrl.
* @param parent
* @param id
* @param evtHandler
*/
void Create(wxWindow *parent, wxWindowID id, wxEvtHandler *evtHandler);
/**
* Creates m_control if necessary. Registers the editor in the grid's resultset.
* @param row
* @param col
* @param grid
*/
void BeginEdit(int row, int col, wxGrid *grid);
wxGridCellEditor* Clone() const;
bool EndEdit(int row, int col, const wxGrid *grid, const wxString &oldval, wxString *newval);
/**
* Applies the editor value as returned by GetValue() to the grid cell.
* @param row
* @param col
* @param grid
*/
void ApplyEdit(int row, int col, wxGrid *grid);
/**
* Deletes the editor, all pointers to the editor are set to NULL.
*/
void Reset();
/**
*
* @return GetData(), or wxEmptyString if the editor control has not been created.
*/
wxString GetValue() const;
/**
* Creates a wxTextCtrl to be used as editor in form view.
*/
wxControl* ProvideFormEditor(wxWindow * parent);
wxControl* GetFormEditor() const
{
return m_formEditor;
}
/**
* Updates the grid cell and the editor. m_formEditor is deleted and set to NULL.
* @param row
* @param col
* @param grid
*/
void SyncBack(const int row, const int col, wxGrid * grid);
private:
bool m_multiline;
unsigned long m_style;
wxTextCtrl * m_formEditor;
/**
* Fully typed alias to m_control.
*/
LBoundTextCtrl * m_BoundTextCtrl;
};
#endif /* LGRIDTEXTEDITOR_H */

20
L7/LGridTextRenderer.cpp Normal file
View File

@@ -0,0 +1,20 @@
/*
* File: LGridTextRenderer.cpp
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 9 juin 2014, 19:00
*/
#include "LGridTextRenderer.h"
LGridTextRenderer::LGridTextRenderer()
: wxGridCellAutoWrapStringRenderer()
{
}
LGridTextRenderer::~LGridTextRenderer()
{
}

25
L7/LGridTextRenderer.h Normal file
View File

@@ -0,0 +1,25 @@
/*
* File: LGridTextRenderer.h
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 9 juin 2014, 19:00
*/
#ifndef LGRIDTEXTRENDERER_H
#define LGRIDTEXTRENDERER_H
#include "wx/grid.h"
class LGridTextRenderer : public wxGridCellAutoWrapStringRenderer
{
public:
LGridTextRenderer();
virtual ~LGridTextRenderer();
private:
};
#endif /* LGRIDTEXTRENDERER_H */

22
L7/LInformation.cpp Normal file
View File

@@ -0,0 +1,22 @@
/*
* File: LInformation.cpp
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 24 mai 2014, 21:23
*/
#include "LInformation.h"
LInformation::LInformation(const wxString& newCode,
const wxString& newMsg)
{
m_code = newCode;
m_msg = newMsg;
}
LInformation::~LInformation()
{
}

50
L7/LInformation.h Normal file
View File

@@ -0,0 +1,50 @@
/*
* File: LInformation.h
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 24 mai 2014, 21:23
*/
#ifndef LINFORMATION_H
#define LINFORMATION_H
#include <wx/wx.h>
/**
* Holds messages from LConnection and LResultSet objects.
* @param newCode
* @param newMsg
*/
class LInformation
{
public:
LInformation(const wxString& newCode,
const wxString& newMsg);
virtual ~LInformation();
wxString GetCode() const
{
return m_code;
}
wxString GetMessage() const
{
return m_msg;
}
/**
*
* @return Both the code and the message concatenated.
*/
wxString GetFullInformation() const
{
return m_code + _T(" : ") + m_msg;
};
private:
wxString m_code;
wxString m_msg;
};
#endif /* LINFORMATION_H */

43
L7/LItemData.cpp Normal file
View File

@@ -0,0 +1,43 @@
/*
* File: ltItemData.cpp
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 24 mai 2014, 20:26
*/
#include "LItemData.h"
LItemData::LItemData(const long newData)
{
m_data = newData;
}
LItemData::LItemData(const wxString newData)
{
m_data = newData;
}
LItemData::LItemData(const wxAny newData)
{
m_data = newData;
}
LItemData::~LItemData()
{
}
long LItemData::GetLong()
{
long lVal;
m_data.GetAs(&lVal);
return lVal;
}
wxString LItemData::GetString()
{
wxString sVal;
m_data.GetAs(&sVal);
return sVal;
}

43
L7/LItemData.h Normal file
View File

@@ -0,0 +1,43 @@
/*
* File: ltItemData.h
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 24 mai 2014, 20:26
*/
#ifndef LITEMDATA_H
#define LITEMDATA_H
#include <wx/wx.h>
/**
Holds translated values for LComboBox items as wxClientData.
*
*/
class LItemData : public wxClientData
{
public:
LItemData(const long newData);
LItemData(const wxString newData);
LItemData(const wxAny newData);
virtual ~LItemData();
wxAny GetData()
{
return m_data;
}
long GetLong();
wxString GetString();
void SetValue(wxAny newData)
{
m_data = newData;
}
private:
wxAny m_data;
};
#endif /* LITEMDATA_H */

166
L7/LLightPQResultSet.cpp Normal file
View File

@@ -0,0 +1,166 @@
/*
* File: LLightPQResultSet.cpp
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 29 mai 2014, 13:29
*/
#ifdef USE_LIBPQ
#include "LLightPQResultSet.h"
using namespace PQ;
LLightPQResultSet::LLightPQResultSet() : LLightResultSet()
{
}
LLightPQResultSet::LLightPQResultSet(LConnection * newConnection) : LLightResultSet(newConnection)
{
}
LLightPQResultSet::~LLightPQResultSet()
{
if (m_rs)
{
PGresult * prs = static_cast<PGresult*> (m_rs);
PQclear(prs);
m_rs = NULL;
}
}
bool LLightPQResultSet::SetSQL(const wxString& newSql)
{
UpdateSQL(newSql);
if (RunSQL()) First();
return (m_rs != NULL);
}
bool LLightPQResultSet::RunSQL()
{
if (m_curSql.IsEmpty()) return false;
wxASSERT_MSG(m_conn != NULL, _T("m_conn est NULL."));
if (m_rs)
{
PGresult * prs = static_cast<PGresult*> (m_rs);
PQclear(prs);
m_rs = NULL;
}
void * vrs = m_conn->ExecuteSQL(m_curSql);
m_rs = static_cast<PGresult*> (vrs);
if (m_rs != NULL)
{
m_cursor = (HasData()) ? 0 : -1;
if (!m_initialised) m_initialised = true;
return true;
}
else
{
m_cursor = -1;
return false;
}
}
bool LLightPQResultSet::HasData() const
{
wxASSERT_MSG(m_rs != NULL, _T("m_rs est NULL."));
PGresult * prs = static_cast<PGresult*> (m_rs);
return (PQntuples(prs) > 0);
}
bool LLightPQResultSet::Absolute(const unsigned int newRowIndex)
{
if (!HasData())
{
m_cursor = -1;
return false;
}
wxASSERT_MSG(newRowIndex < GetRowCount(), _T("Paramètre newRowIndex invalide."));
m_cursor = newRowIndex;
return true;
}
bool LLightPQResultSet::IsFirst() const
{
if (!(HasData())) return false;
return (m_cursor == 0);
}
bool LLightPQResultSet::IsLast() const
{
if (!(HasData())) return false;
PGresult * prs = static_cast<PGresult*> (m_rs);
return (m_cursor == (PQntuples(prs) - 1));
}
bool LLightPQResultSet::First()
{
if (IsFirst()) return false;
return Absolute(0);
}
bool LLightPQResultSet::Next()
{
if (IsLast()) return false;
return Absolute(m_cursor + 1);
}
bool LLightPQResultSet::Previous()
{
if (IsFirst()) return false;
return Absolute(m_cursor - 1);
}
bool LLightPQResultSet::Last()
{
if (IsLast()) return false;
PGresult * prs = static_cast<PGresult*> (m_rs);
return Absolute(PQntuples(prs) - 1);
}
const unsigned int LLightPQResultSet::GetRowCount() const
{
wxASSERT_MSG(m_rs != NULL, _T("m_rs est NULL."));
PGresult * prs = static_cast<PGresult*> (m_rs);
return PQntuples(prs);
}
const unsigned int LLightPQResultSet::GetColumnCount() const
{
wxASSERT_MSG(m_rs != NULL, _T("m_rs est NULL."));
PGresult * prs = static_cast<PGresult*> (m_rs);
return PQnfields(prs);
}
const wxString LLightPQResultSet::GetColumnName(const unsigned int colIndex) const
{
wxASSERT_MSG(m_rs != NULL, _T("m_rs est NULL."));
PGresult * prs = static_cast<PGresult*> (m_rs);
return wxString(PQfname(prs, colIndex));
}
const int LLightPQResultSet::GetColumnIndex(const wxString& colName) const
{
wxASSERT_MSG(m_rs != NULL, _T("m_rs est NULL."));
PGresult * prs = static_cast<PGresult*> (m_rs);
return PQfnumber(prs, colName.c_str());
}
const wxAny LLightPQResultSet::GetData(const unsigned int rowIdx, const unsigned int colIdx) const
{
PGresult * prs = static_cast<PGresult*> (m_rs);
const char * data = PQgetvalue(prs, rowIdx, colIdx);
return wxString(data, wxConvUTF8);
}
const wxAny LLightPQResultSet::GetData(const wxString &columnName) const
{
if (m_cursor < 0) return wxEmptyString;
const char* colName = columnName.c_str();
PGresult * prs = static_cast<PGresult*> (m_rs);
int colIdx = PQfnumber(prs, colName);
if (colIdx < 0 || colIdx >= PQnfields(prs)) return wxEmptyString;
return GetData(m_cursor, colIdx);
}
#endif

69
L7/LLightPQResultSet.h Normal file
View File

@@ -0,0 +1,69 @@
/*
* File: LLightPQResultSet.h
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 29 mai 2014, 13:28
*/
#ifdef USE_LIBPQ
#ifndef LLIGHTPQRESULTSET_H
#define LLIGHTPQRESULTSET_H
#include <wx/wx.h>
#include <libpq-fe.h>
#include "LLightResultSet.h"
/**
* PostgreSQL namespace.
*
* Please note USE_LIBPQ pre-processor directive must be defined to include the PostgreSQL backend.
*/
namespace PQ
{
/**
* Scrollable minimal resultset for the PostgreSQL backend.
*
* This class does not allow data modification and does not output any messages.
* The underlying SQL query may contain table and/or column aliases.
*/
class LLightPQResultSet : public LLightResultSet
{
public:
LLightPQResultSet();
LLightPQResultSet(LConnection * newConnection);
virtual ~LLightPQResultSet();
/**
* Updates and runs the SQL string.
* @param newSql
* @return
*/
bool SetSQL(const wxString& newSql);
bool HasData() const;
bool Absolute(const unsigned int newRowIndex);
bool IsFirst() const;
bool IsLast() const;
bool First();
bool Next();
bool Previous();
bool Last();
const unsigned int GetRowCount() const;
const unsigned int GetColumnCount() const;
const wxString GetColumnName(const unsigned int colIndex) const;
const int GetColumnIndex(const wxString& colName) const;
const wxAny GetData(const int unsigned rowIdx, const unsigned int colIdx) const;
/**
* At current row.
* @param colName
* @return database table value or wxEmptyString.
*/
const wxAny GetData(const wxString& colName) const;
private:
bool RunSQL();
};
}
#endif /* LLIGHTPQRESULTSET_H */
#endif

32
L7/LLightResultSet.cpp Normal file
View File

@@ -0,0 +1,32 @@
/*
* File: LLightResultSet.cpp
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 28 mai 2014, 14:41
*/
#include "LLightResultSet.h"
LLightResultSet::LLightResultSet()
{
m_initialised = false;
m_curSql = wxEmptyString;
m_cursor = -1;
m_rs = NULL;
m_conn = NULL;
}
LLightResultSet::~LLightResultSet()
{
}
LLightResultSet::LLightResultSet(LConnection* newConnection)
{
m_initialised = false;
m_curSql = wxEmptyString;
m_cursor = -1;
m_rs = NULL;
m_conn = newConnection;
}

93
L7/LLightResultSet.h Normal file
View File

@@ -0,0 +1,93 @@
/*
* File: LLightResultSet.h
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 28 mai 2014, 14:40
*/
#ifndef LLIGHTRESULTSET_H
#define LLIGHTRESULTSET_H
/* Added to be able to use derived classes independantly
* If xConnection and xResultSet classes are included in some project,
* the compiler would complain ofan undeclared wxWeakRef.
*/
#include <wx/wx.h>
#include <wx/weakref.h>
#include "LConnection.h"
/**
* An abstract class to scroll through data obtained after running an SQL query.
* Does not interact with GUI controls.
*
* Does not output any messages.
*
* Does not modify data.
*/
class LLightResultSet : public wxTrackable {
public:
LLightResultSet();
LLightResultSet(LConnection * newConnection);
virtual ~LLightResultSet();
virtual bool SetSQL(const wxString& newSql) = 0;
/**
* Updates the SQL statement without running it.
* @param newSql
*/
void UpdateSQL(const wxString& newSql) {
m_curSql = newSql;
}
const wxString& GetSQL() const {
return m_curSql;
}
void SetConnection(LConnection * newConnection) {
m_conn = newConnection;
}
const LConnection * GetConnection() const {
return m_conn;
}
virtual bool HasData() const = 0;
virtual bool Absolute(const unsigned int newRowIndex) = 0;
virtual bool IsFirst() const = 0;
virtual bool IsLast() const = 0;
virtual bool First() = 0;
virtual bool Next() = 0;
virtual bool Previous() = 0;
virtual bool Last() = 0;
/**
* Returns the cursor position from 0 to (GetRowCount() - 1).
*
* Returns -1 if there's no data.
*/
const int GetRow() const {
return m_cursor;
}
virtual const unsigned int GetRowCount() const = 0;
virtual const unsigned int GetColumnCount() const = 0;
virtual const wxString GetColumnName(const unsigned int colIndex) const = 0;
virtual const int GetColumnIndex(const wxString& colName) const = 0;
virtual const wxAny GetData(const wxString& colName) const = 0;
virtual const wxAny GetData(const unsigned int rowIdx, const unsigned int colIdx) const = 0;
protected:
bool m_initialised;
wxString m_curSql;
void * m_rs;
wxWeakRef<LConnection> m_conn;
int m_cursor;
virtual bool RunSQL() = 0;
private:
};
#endif /* LLIGHTRESULTSET_H */

215
L7/LLightSQResultSet.cpp Normal file
View File

@@ -0,0 +1,215 @@
/*
* File: LLightSQResultSet.cpp
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 31 mai 2014, 18:34
*/
#ifdef USE_LIBSQ
#include "LLightSQResultSet.h"
#include "LSQConnection.h"
using namespace SQ;
LLightSQResultSet::LLightSQResultSet() : LLightResultSet()
{
}
LLightSQResultSet::LLightSQResultSet(LConnection * newConnection) : LLightResultSet(newConnection)
{
}
LLightSQResultSet::~LLightSQResultSet()
{
if (m_rs)
{
SQresult * srs = static_cast<SQresult*> (m_rs);
sqlite3_free_table(srs->m_data);
delete srs; m_rs = NULL;
}
}
bool LLightSQResultSet::SetSQL(const wxString& newSql)
{
UpdateSQL(newSql);
if (RunSQL()) First();
return (m_rs != NULL);
}
bool LLightSQResultSet::RunSQL()
{
if (m_curSql.IsEmpty()) return false;
wxASSERT_MSG(m_conn != NULL, _T("m_conn est NULL."));
if (m_rs)
{
SQresult * srs = static_cast<SQresult*> (m_rs);
sqlite3_free_table(srs->m_data);
wxDELETE(srs);;
m_rs = NULL;
}
m_rs = m_conn->ExecuteSQL(m_curSql);
SQresult * srs = static_cast<SQresult*> (m_rs);
if (!RetrieveColNames(srs)) { // No columns returned if no data !
m_rs = NULL;
return false;
}
if (m_rs)
{
m_cursor = (HasData()) ? 0 : -1;
if (!m_initialised) m_initialised = true;
return true;
}
else
{
m_cursor = -1;
return false;
}
}
bool LLightSQResultSet::HasData() const
{
wxASSERT_MSG(m_rs != NULL, _T("m_rs est NULL."));
SQresult * srs = static_cast<SQresult*> (m_rs);
return (srs->m_nbRows > 0);
}
bool LLightSQResultSet::Absolute(const unsigned int newRowIndex)
{
if (!HasData())
{
m_cursor = -1;
return false;
}
wxASSERT_MSG(newRowIndex < GetRowCount(), _T("Paramètre newRowIndex invalide."));
m_cursor = newRowIndex;
return true;
}
bool LLightSQResultSet::IsFirst() const
{
if (!(HasData())) return false;
return (m_cursor == 0);
}
bool LLightSQResultSet::IsLast() const
{
if (!(HasData())) return false;
SQresult * srs = static_cast<SQresult*> (m_rs);
return (m_cursor == (srs->m_nbRows - 1));
}
bool LLightSQResultSet::First()
{
if (IsFirst()) return false;
return Absolute(0);
}
bool LLightSQResultSet::Next()
{
if (IsLast()) return false;
return Absolute(m_cursor + 1);
}
bool LLightSQResultSet::Previous()
{
if (IsFirst()) return false;
return Absolute(m_cursor - 1);
}
bool LLightSQResultSet::Last()
{
if (IsLast()) return false;
SQresult * srs = static_cast<SQresult*> (m_rs);
return Absolute(srs->m_nbRows - 1);
}
const unsigned int LLightSQResultSet::GetRowCount() const
{
wxASSERT_MSG(m_rs != NULL, _T("m_rs est NULL."));
SQresult * srs = static_cast<SQresult*> (m_rs);
return srs->m_nbRows;
}
const unsigned int LLightSQResultSet::GetColumnCount() const
{
wxASSERT_MSG(m_rs != NULL, _T("m_rs est NULL."));
SQresult * srs = static_cast<SQresult*> (m_rs);
return srs->m_nbCols;
}
const wxString LLightSQResultSet::GetColumnName(const unsigned int colIndex) const
{
wxASSERT_MSG(m_rs != NULL, _T("m_rs est NULL."));
if (!HasData()) return m_colNames.Item(colIndex);
SQresult * srs = static_cast<SQresult*> (m_rs);
return wxString(srs->m_data[colIndex]);
}
const int LLightSQResultSet::GetColumnIndex(const wxString& colName) const
{
wxASSERT_MSG(m_rs != NULL, _T("m_rs est NULL."));
if (!HasData()) return m_colNames.Index(colName, false);
SQresult * srs = static_cast<SQresult*> (m_rs);
for (unsigned int c = 0; c < srs->m_nbCols; c++)
{
const wxString sName(srs->m_data[c]);
if (sName.Lower() == colName.Lower()) return c;
}
return -1;
}
const wxAny LLightSQResultSet::GetData(const unsigned int rowIdx, const unsigned int colIdx) const
{
if (!HasData()) return wxEmptyString;
SQresult * srs = static_cast<SQresult*> (m_rs);
const char * data = srs->m_data[((rowIdx + 1) * (srs->m_nbCols)) + colIdx];
return wxString(data, wxConvUTF8);
}
const wxAny LLightSQResultSet::GetData(const wxString &columnName) const
{
if (m_cursor < 0) return wxEmptyString;
if (!HasData()) return wxEmptyString;
SQresult * srs = static_cast<SQresult*> (m_rs);
for (int c = 0; c < srs->m_nbCols; c++)
{
const wxString sColName(srs->m_data[c]);
if (sColName.Lower() == columnName.Lower()) return GetData(m_cursor, c);
}
return wxEmptyString;
}
bool LLightSQResultSet::RetrieveColNames(SQresult * emptyResult)
{
wxASSERT_MSG(m_conn != NULL, _T("m_conn est NULL."));
sqlite3 * db = static_cast<sqlite3*> (m_conn->Get());
if (db)
{
sqlite3_stmt * ppStmt;
int res = sqlite3_prepare_v2(db, m_curSql, -1, &ppStmt, NULL);
if (res == SQLITE_OK)
{
m_colNames.Clear();
int colCount = sqlite3_column_count(ppStmt);
for (unsigned int i = 0; i < colCount; i++)
{
const char * constName = sqlite3_column_name(ppStmt, i);
m_colNames.Add(wxString(constName));
}
emptyResult->m_nbCols = m_colNames.GetCount();
sqlite3_finalize(ppStmt);
return true;
} else {
int errCode = sqlite3_errcode(db);
const char * errMsg = sqlite3_errmsg(db);
const char * errStr = sqlite3_errstr(errCode);
const wxString msg(wxAny(errCode).As<wxString>() + _T(" ") +
wxString(errMsg) + _T("\n") + wxString(errStr));
wxPrintf("%s\n", msg);
wxFAIL_MSG(msg);
}
}
return false;
}
#endif

71
L7/LLightSQResultSet.h Normal file
View File

@@ -0,0 +1,71 @@
/*
* File: LLightSQResultSet.h
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 31 mai 2014, 18:34
*/
#ifdef USE_LIBSQ
#ifndef LLIGHTSQRESULTSET_H
#define LLIGHTSQRESULTSET_H
#include <wx/wx.h>
#include <sqlite3.h>
#include "LLightResultSet.h"
#include "LSQresult.h"
/**
* SQLite namespace.
*
* Please note USE_LIBSQ pre-processor directive must be defined to include the SQLite backend.
*/
namespace SQ
{
/**
* Scrollable minimal resultset for the SQLite backend.
*
* This object does not allow data modification and does not output any messages.
* The underlying SQL query may contain table and/or column aliases
*/
class LLightSQResultSet : public LLightResultSet
{
public:
LLightSQResultSet();
LLightSQResultSet(LConnection * newConnection);
virtual ~LLightSQResultSet();
/**
* Updates and runs the SQL string.
* @param newSql
* @return
*/
bool SetSQL(const wxString& newSql);
bool HasData() const;
bool Absolute(const unsigned int newRowIndex);
bool IsFirst() const;
bool IsLast() const;
bool First();
bool Next();
bool Previous();
bool Last();
const unsigned int GetRowCount() const;
const unsigned int GetColumnCount() const;
const wxString GetColumnName(const unsigned int colIndex) const;
const int GetColumnIndex(const wxString& colName) const;
const wxAny GetData(const int unsigned rowIdx, const unsigned int colIdx) const;
/**
* At current row.
* @param colName
* @return database table value or wxEmptyString.
*/
const wxAny GetData(const wxString& colName) const;
private:
bool RunSQL();
wxArrayString m_colNames;
bool RetrieveColNames(SQresult * emptyResult);
};
}
#endif /* LLIGHTSQRESULTSET_H */
#endif

234
L7/LNavigator.cpp Normal file
View File

@@ -0,0 +1,234 @@
/*
* File: LNavigator.cpp
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 4 juin 2014, 14:57
*/
#include "LNavigator.h"
LNavigator::LNavigator(wxWindow* parent, wxWindowID id)
: wxPanel(parent, id, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER | wxTAB_TRAVERSAL)
{
m_vsz = new wxBoxSizer(wxVERTICAL);
SetSizer(m_vsz);
m_hsz1 = new wxBoxSizer(wxHORIZONTAL);
m_vsz->Add(m_hsz1, 1, wxGROW, 0);
m_hsz1->Add(5, 5, 0, wxGROW | wxTOP | wxBOTTOM, 8);
m_btnNew = new wxButton(this, wxID_ANY, _("New"), wxDefaultPosition, wxSize(-1, 15), wxNO_BORDER);
m_hsz1->Add(m_btnNew, 1, wxGROW, 0);
m_btnSave = new wxButton(this, wxID_ANY, _("Save"), wxDefaultPosition, wxSize(-1, 15), wxNO_BORDER);
m_hsz1->Add(m_btnSave, 1, wxGROW, 0);
m_btnCancel = new wxButton(this, wxID_ANY, _("Cancel"), wxDefaultPosition, wxSize(-1, 15), wxNO_BORDER);
m_hsz1->Add(m_btnCancel, 1, wxGROW, 0);
m_btnRefresh = new wxButton(this, wxID_ANY, _("Refresh"), wxDefaultPosition, wxSize(-1, 15), wxNO_BORDER);
m_hsz1->Add(m_btnRefresh, 1, wxGROW | wxTOP | wxBOTTOM, 0);
m_btnDelete = new wxButton(this, wxID_ANY, _("Delete"), wxDefaultPosition, wxSize(-1, 15), wxNO_BORDER);
m_hsz1->Add(m_btnDelete, 1, wxGROW, 0);
m_hsz2 = new wxBoxSizer(wxHORIZONTAL);
m_vsz->Add(m_hsz2, 1, wxGROW, 0);
m_btnFirst = new wxButton(this, wxID_ANY, _T("<<"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER);
m_hsz2->Add(m_btnFirst, 0, wxGROW, 0);
m_btnPrevious = new wxButton(this, wxID_ANY, _T("<"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER);
m_hsz2->Add(m_btnPrevious, 0, wxGROW, 0);
m_lbl = new wxStaticText(this, wxID_STATIC, _("Rec : "), wxDefaultPosition, wxDefaultSize, wxNO_BORDER);
m_hsz2->Add(m_lbl, 1, wxALIGN_CENTER_VERTICAL, 0);
m_btnNext = new wxButton(this, wxID_ANY, _T(">"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER);
m_hsz2->Add(m_btnNext, 0, wxGROW, 0);
btnLast = new wxButton(this, wxID_ANY, _T(">>"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER);
m_hsz2->Add(btnLast, 0, wxGROW, 0);
m_btnNew->Bind(wxEVT_BUTTON, &LNavigator::OnButtonNew, this);
m_btnSave->Bind(wxEVT_BUTTON, &LNavigator::OnButtonSave, this);
m_btnCancel->Bind(wxEVT_BUTTON, &LNavigator::OnButtonCancel, this);
m_btnRefresh->Bind(wxEVT_BUTTON, &LNavigator::OnButtonRefresh, this);
m_btnDelete->Bind(wxEVT_BUTTON, &LNavigator::OnButtonDelete, this);
m_btnFirst->Bind(wxEVT_BUTTON, &LNavigator::OnBtnFirst, this);
m_btnPrevious->Bind(wxEVT_BUTTON, &LNavigator::OnBtnPrevious, this);
m_btnNext->Bind(wxEVT_BUTTON, &LNavigator::OnBtnNext, this);
btnLast->Bind(wxEVT_BUTTON, &LNavigator::OnBtnLast, this);
m_vsz->Fit(this);
m_rs = NULL;
m_evh = NULL;
}
LNavigator::~LNavigator()
{
delete m_btnNew;
delete m_btnSave;
delete m_btnCancel;
delete m_btnRefresh;
delete m_btnDelete;
delete m_btnFirst;
delete m_btnPrevious;
delete m_lbl;
delete m_btnNext;
delete btnLast;
m_rs->UnRegisterEventHandler(m_evh);
delete m_evh;
}
void LNavigator::OnBtnNext(wxCommandEvent& evt)
{
if (m_rs) m_rs->Next();
evt.Skip(false);
}
void LNavigator::OnBtnFirst(wxCommandEvent& evt)
{
if (m_rs) m_rs->First();
evt.Skip(false);
}
void LNavigator::OnBtnLast(wxCommandEvent& evt)
{
if (m_rs) m_rs->Last();
evt.Skip(false);
}
void LNavigator::OnBtnPrevious(wxCommandEvent& evt)
{
if (m_rs) m_rs->Previous();
evt.Skip(false);
}
void LNavigator::OnButtonSave(wxCommandEvent& evt)
{
if (m_rs) m_rs->Save();
evt.Skip(false);
}
void LNavigator::OnButtonRefresh(wxCommandEvent& evt)
{
if (m_rs) m_rs->Refresh();
evt.Skip(false);
}
void LNavigator::OnButtonCancel(wxCommandEvent& evt)
{
if (m_rs) m_rs->Cancel();
evt.Skip(false);
}
void LNavigator::OnButtonNew(wxCommandEvent& evt)
{
if (m_rs) m_rs->AddNew();
evt.Skip(false);
}
void LNavigator::OnButtonDelete(wxCommandEvent& evt)
{
if (m_rs) m_rs->Delete();
evt.Skip(false);
}
void LNavigator::SetResultSet(LResultSet * newResultSet)
{
m_rs = newResultSet;
if (!m_rs) return;
wxASSERT_MSG(m_rs->GetConnection() != NULL, _T("GetConnection() = NULL."));
m_evh = new NavigatorRsEVH(m_lbl);
m_rs->RegisterEventHandler(m_evh);
ShowActionBar(!(m_rs->IsReadOnly()));
if (m_vsz->IsShown(m_hsz1))
{
if (m_rs->GetConnection()) ShowActionBar(!(m_rs->GetConnection()->IsReadOnly()));
}
}
LResultSet* LNavigator::GetResultSet() const
{
return m_rs;
}
void LNavigator::ShowActionBar(bool show) const
{
m_vsz->Show(m_hsz1, show, true);
m_vsz->Layout();
}
void LNavigator::ShowNavigationBar(bool show) const
{
m_vsz->Show(m_hsz2, show, true);
m_vsz->Layout();
}
void LNavigator::ShowButtonAddNew(bool show) const
{
m_hsz1->Show(m_btnNew, show, false);
m_vsz->Layout();
}
void LNavigator::ShowButtonSave(bool show) const
{
m_hsz1->Show(m_btnSave, show, false);
m_vsz->Layout();
}
void LNavigator::ShowButtonCancel(bool show) const
{
m_hsz1->Show(m_btnCancel, show, false);
m_vsz->Layout();
}
void LNavigator::ShowButtonRefresh(bool show) const
{
m_hsz1->Show(m_btnRefresh, show, false);
m_vsz->Layout();
}
void LNavigator::ShowButtonDelete(bool show) const
{
m_hsz1->Show(m_btnDelete, show, false);
m_vsz->Layout();
}
////////////////////////////////////////////////////////////////////////////
NavigatorRsEVH::NavigatorRsEVH(wxStaticText * newLbl)
{
m_lbl = newLbl;
}
NavigatorRsEVH::~NavigatorRsEVH()
{
}
void NavigatorRsEVH::Initialised(LResultSet* caller)
{
UpdateLocation(caller);
}
void NavigatorRsEVH::AfterChangeRow(LResultSet* caller)
{
UpdateLocation(caller);
}
void NavigatorRsEVH::AfterAction(LResultSet* caller, ACTIONS action)
{
UpdateLocation(caller);
}
void NavigatorRsEVH::UpdateLocation(const LResultSet* caller)
{
if (!caller) return;
if (caller->IsInserting())
{
m_lbl->SetLabel(_("Insert"));
}
else
{
const wxAny row = (caller->GetRow() + 1);
const wxAny count = caller->GetRowCount();
const wxString loc = _("Rec : ")
+ row.As<wxString>()
+ _T("/")
+ count.As<wxString>();
m_lbl->SetLabel(loc);
}
}

95
L7/LNavigator.h Normal file
View File

@@ -0,0 +1,95 @@
/*
* File: LNavigator.h
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 4 juin 2014, 14:56
*/
#ifndef LNAVIGATOR_H
#define LNAVIGATOR_H
#include <wx/wx.h>
#include "LResultSet.h"
class NavigatorRsEVH;
/**
* This combined control displays an action bar and a navigation bar.
* These contains standard buttons to interact with a resultset.
*
* The action bar can
* move the resultset to the insert row,
* save any edits,
* cancel any edits,
* refresh the resultset,
* delete the current record.
*
* The navigation bar is used to move the resultset's cursor
* and displays the current position.
*/
class LNavigator : public wxPanel
{
public:
LNavigator(wxWindow* parent, wxWindowID id = wxID_ANY);
virtual ~LNavigator();
void SetResultSet(LResultSet * newResultSet);
LResultSet* GetResultSet() const;
void ShowActionBar(bool show) const;
void ShowNavigationBar(bool show) const;
void ShowButtonAddNew(bool show) const;
void ShowButtonSave(bool show) const;
void ShowButtonCancel(bool show) const;
void ShowButtonRefresh(bool show) const;
void ShowButtonDelete(bool show) const;
private:
wxBoxSizer* m_vsz;
wxBoxSizer* m_hsz1;
wxButton* m_btnNew;
wxButton* m_btnSave;
wxButton* m_btnCancel;
wxButton* m_btnRefresh;
wxButton* m_btnDelete;
wxBoxSizer* m_hsz2;
wxButton* m_btnFirst;
wxButton* m_btnPrevious;
wxStaticText* m_lbl;
wxButton* m_btnNext;
wxButton* btnLast;
wxWeakRef<LResultSet> m_rs;
NavigatorRsEVH * m_evh;
void OnButtonNew(wxCommandEvent& evt);
void OnButtonSave(wxCommandEvent& evt);
void OnButtonCancel(wxCommandEvent& evt);
void OnButtonRefresh(wxCommandEvent& evt);
void OnButtonDelete(wxCommandEvent& evt);
void OnBtnFirst(wxCommandEvent& evt);
void OnBtnPrevious(wxCommandEvent& evt);
void OnBtnNext(wxCommandEvent& evt);
void OnBtnLast(wxCommandEvent& evt);
};
//////////////////////////////////////////////////////////////////////////////
/**
* A private resultset event handler for LNavigator. All functions are declared private.
* Don't use it.
*/
class NavigatorRsEVH : public LResultSetEvent
{
friend class LNavigator;
private:
NavigatorRsEVH(wxStaticText * newLbl);
virtual ~NavigatorRsEVH();
void Initialised(LResultSet* caller);
void AfterChangeRow(LResultSet* caller);
void AfterAction(LResultSet * caller, ACTIONS action);
wxStaticText * m_lbl;
void UpdateLocation(const LResultSet* caller);
};
#endif /* LNAVIGATOR_H */

193
L7/LPQConnection.cpp Normal file
View File

@@ -0,0 +1,193 @@
/*
* File: LPQConnection.cpp
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 25 mai 2014, 11:44
*/
#ifdef USE_LIBPQ
#include "LPQConnection.h"
using namespace PQ;
LPQConnection::LPQConnection() : LConnection()
{
m_conn = NULL;
m_retKeys = NULL;
}
LPQConnection::LPQConnection(const wxString& newInfo) : LConnection(newInfo)
{
m_conn = NULL;
m_retKeys = NULL;
}
LPQConnection::~LPQConnection()
{
PQclear(m_retKeys);
Close();
}
const char* LPQConnection::GetLastLibMessage() const
{
return PQerrorMessage(m_conn);
}
bool LPQConnection::Connect()
{
wxCHECK_MSG(!m_connInfo.IsEmpty(), false, _("Connection string is undefined"));
if (m_conn != NULL)
{
if (PQstatus(m_conn) == CONNECTION_OK) return true;
}
const char* cinfo = m_connInfo.utf8_str();
m_conn = PQconnectdb(cinfo);
bool res = IsValid();
if (res)
{
ApplyReadWriteStatus();
m_UserName = wxString(PQuser(m_conn));
m_DBName = wxString(PQdb(m_conn));
m_ServerName = wxString(PQhost(m_conn));
m_Port = wxString(PQport(m_conn));
}
else
{
Close();
}
return res;
}
void* LPQConnection::Get() const
{
return (void*) m_conn;
}
bool LPQConnection::IsValid() const
{
if (PQstatus(m_conn) != CONNECTION_OK)
{
InformPQMessage(PQerrorMessage(m_conn));
return false;
}
return true;
}
void LPQConnection::Close()
{
if (m_conn != NULL)
{
PQfinish(m_conn);
m_conn = NULL;
}
}
void* LPQConnection::ExecuteSQL(const wxString& newSql)
{
InformBeforeExecute();
wxCHECK_MSG(IsValid() == true, NULL, _("Invalid connection"));
const char* cSQL = newSql.utf8_str();
PGresult * res = PQexec(m_conn, cSQL);
if (PQresultStatus(res) != PGRES_TUPLES_OK)
{
PQclear(res);
InformPQMessage(PQerrorMessage(m_conn));
InformAfterExecute();
return NULL;
}
InformAfterExecute();
return (void*) res;
}
bool LPQConnection::ExecuteUpdateSQL(const wxString& newSql)
{
InformBeforeExecute();
wxCHECK_MSG(IsValid() == true, false, _("Invalid connection"));
const char* cSQL = newSql.utf8_str();
m_retKeys = PQexec(m_conn, cSQL);
if ((PQresultStatus(m_retKeys) != PGRES_TUPLES_OK) && (PQresultStatus(m_retKeys) != PGRES_COMMAND_OK))
{
PQclear(m_retKeys);
m_retKeys = NULL;
InformPQMessage(PQerrorMessage(m_conn));
InformAfterExecute();
return false;
}
InformAfterExecute();
return true;
}
const wxAny LPQConnection::GetReturnedValue(const unsigned int col) const
{
if (!m_retKeys)
{
const wxAny k;
return k;
}
const char * data = PQgetvalue(m_retKeys, 0, col);
const wxAny k(data);
return k;
}
void* LPQConnection::GetReturnedKeys() const
{
return (void*) m_retKeys;
}
void LPQConnection::ClearReturnedKeys()
{
if (m_retKeys != NULL)
{
PQclear(m_retKeys);
m_retKeys = NULL;
}
}
bool LPQConnection::ApplyReadWriteStatus()
{
wxString sql = (m_readOnly)
? _T("SET SESSION CHARACTERISTICS AS TRANSACTION READ ONLY")
: _T("SET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE");
return ExecuteUpdateSQL(sql);
}
void LPQConnection::InformPQMessage(const char* PQmsg) const
{
if (!PQmsg) return;
wxString msg(PQmsg);
if (msg.IsEmpty()) return;
const LInformation inf(CNPQMC, msg);
InformLibMessage(inf);
}
void LPQConnection::InformBeforeExecute()
{
for (int i = 0; i < m_evtHandlers.GetCount(); i++)
{
void * p = m_evtHandlers.Item(i);
LConnectionEvent * evh = static_cast<LConnectionEvent*> (p);
if (evh != NULL) evh->BeforeExecute(this);
}
}
void LPQConnection::InformAfterExecute()
{
for (int i = 0; i < m_evtHandlers.GetCount(); i++)
{
void * p = m_evtHandlers.Item(i);
LConnectionEvent * evh = static_cast<LConnectionEvent*> (p);
if (evh != NULL) evh->AfterExecute(this);
}
}
void LPQConnection::InformLibMessage(const LInformation& msg) const
{
for (int i = 0; i < m_evtHandlers.GetCount(); i++)
{
void * p = m_evtHandlers.Item(i);
LConnectionEvent * evh = static_cast<LConnectionEvent*> (p);
if (evh != NULL) evh->Inform(this, msg);
}
}
#endif

134
L7/LPQConnection.h Normal file
View File

@@ -0,0 +1,134 @@
/*
* File: LPQConnection.h
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 25 mai 2014, 11:43
*/
#ifdef USE_LIBPQ
#ifndef LPQCONNECTION_H
#define LPQCONNECTION_H
#include <wx/wx.h>
#include <libpq-fe.h>
#include "LConnection.h"
/**
* PostgreSQL namespace.
*
* Please note USE_LIBPQ pre-processor directive must be defined to include the PostgreSQL backend.
*/
namespace PQ
{
#define CNPQMC wxString(_T("CNPQM"))
/**
Minimalist class managing a PostgreSQL connection.
*/
class LPQConnection : public LConnection
{
public:
LPQConnection();
/**
* Ex : host=localhost port=5432 dbname=postgres user=postgres password=secret
* @param newInfo connection information.
*/
LPQConnection(const wxString& newInfo);
/**
* The connection is closed in the destructor. Clears any returned keys.
* But any fetched resultset persists. The caller is responsible to clear this.
*/
virtual ~LPQConnection();
/**
*
* @return the last backend error message, may be NULL.
*/
const char* GetLastLibMessage() const;
/**
* Establishes a new connection calling PQconnectdb
*
* Does nothing if a connection already exists.
* Updates the username, dbname, servername and port variables.
* @return true if a new connection is established, or if a connection already esists. False on error.
*/
bool Connect();
/**
*
* @return a pointer to the PGconn real database pointer.
*/
void* Get() const;
/**
* Evaluates PQstatus(PGconn*).
* @return true if the database connection is valid, false otherwise.
*/
bool IsValid() const;
/**
* Closes the connection.
*
* The data referenced in a PGresult object is not cleared.
* It is the responsibility of the caller to free this object.
*/
void Close();
/**
* Performs synchronous PQexec query and returns rows from a SELECT query.
*
* @param newSql : a valid single SELECT SQL statement.
* @return an untyped pointer to a PGresult containing the data, or NULL on error.
*/
void* ExecuteSQL(const wxString& newSql);
/**
* Intended for database actions that do not fetch table rows. Performs synchronous PQexec query.
*
* @param newSql a valid single SQL statement.
* @return true on success, false otherwise.
*/
bool ExecuteUpdateSQL(const wxString& newSql);
/**
* The value of an auto-generated primary key after executing an INSERT SQL statement.
*
* The SQL statement should have a RETURNING clause that includes a serial column, whose
* index is specified by the col parameter. The column value of the first row is returned.
* @param col index of an auto-increment serial column in a RETURNING SQL clause.
* @return the value of the first row for that column.
*/
const wxAny GetReturnedValue(const unsigned int col) const;
/**
* PGresult object containing a primary key value
* resulting from a successful execution of an INSERT SQL statement.
* @return an untyped pointer to the PGresult object containing the key.
*/
void* GetReturnedKeys() const;
/**
* Clears the PGresult object to free memory.
*/
void ClearReturnedKeys();
private:
PGconn * m_conn;
PGresult * m_retKeys;
bool ApplyReadWriteStatus();
/**
* Forwards libpq messages to InformLibMessage
* @param
*/
void InformPQMessage(const char * PQmsg) const;
/**
* Informs application an SQL statement is about to be processed regardless of connection status..
*/
void InformBeforeExecute();
/**
* Informs application an SQL statement has been processed, regardless of errors.
*/
void InformAfterExecute();
/**
* Informs application that registers LConnectionEvent handlers here.
* @param msg
*/
void InformLibMessage(const LInformation& msg) const;
};
}
#endif /* LPQCONNECTION_H */
#endif

446
L7/LPQResultSet.cpp Normal file
View File

@@ -0,0 +1,446 @@
/*
* File: LPQResultSet.cpp
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 29 mai 2014, 16:19
*/
#ifdef USE_LIBPQ
#include "LPQResultSet.h"
#include "LLightPQResultSet.h"
using namespace PQ;
LPQResultSet::LPQResultSet() : LResultSet()
{
}
LPQResultSet::LPQResultSet(LConnection* newConnection) : LResultSet(newConnection)
{
}
LPQResultSet::~LPQResultSet()
{
if (m_rs)
{
PGresult * prs = static_cast<PGresult*> (m_rs);
PQclear(prs);
m_rs = NULL;
}
}
bool LPQResultSet::SetSQL(const wxString& newSql)
{
UpdateSQL(newSql);
if (RunSQL()) First();
return (m_rs != NULL);
}
bool LPQResultSet::RunSQL()
{
if (m_curSql.IsEmpty())
{
return false;
}
wxASSERT_MSG(m_conn != NULL, _T("m_conn est NULL."));
if (m_rs)
{
PGresult * prs = static_cast<PGresult*> (m_rs);
PQclear(prs);
m_rs = NULL;
}
void * vrs = m_conn->ExecuteSQL(m_curSql);
m_rs = static_cast<PGresult*> (vrs);
if (m_rs != NULL)
{
m_cursor = (HasData()) ? 0 : -1;
Display();
m_inserting = false;
if (!m_initialised)
{
m_initialised = true;
InformInitialised();
}
return true;
}
else
{
m_cursor = -1;
Display();
m_inserting = false;
const LInformation inf(RS000C, RS000M);
InformLibMessage(inf);
return false;
}
}
bool LPQResultSet::HasData() const
{
if (m_rs == NULL) return false;
PGresult * prs = static_cast<PGresult*> (m_rs);
if (PQntuples(prs) == 0) return false;
return true;
}
bool LPQResultSet::Absolute(const unsigned int newRowIndex)
{
if (!m_readOnly)
{
if (m_inserting)
{
InformInserting();
return false;
}
if (IsDirty())
{
InformDirty();
return false;
}
}
if (!HasData())
{
m_cursor = -1;
Display();
return false;
}
wxASSERT_MSG(newRowIndex < GetRowCount(), _T("Paramètre newRowIndex invalide."));
InformBeforeChangeRow();
if (!m_canMove) return false;
m_cursor = newRowIndex;
Display();
m_inserting = false;
InformAfterChangeRow();
return true;
}
bool LPQResultSet::IsFirst() const
{
if (m_inserting) return false;
if (!(HasData())) return false;
return (m_cursor == 0);
}
bool LPQResultSet::IsLast() const
{
if (m_inserting) return false;
if (!(HasData())) return false;
PGresult * prs = static_cast<PGresult*> (m_rs);
return (m_cursor == (PQntuples(prs) - 1));
}
bool LPQResultSet::First()
{
if (IsFirst()) return false;
return Absolute(0);
}
bool LPQResultSet::Last()
{
if (IsLast()) return false;
PGresult * prs = static_cast<PGresult*> (m_rs);
return Absolute(PQntuples(prs) - 1);
}
bool LPQResultSet::Next()
{
if (IsLast()) return false;
return Absolute(m_cursor + 1);
}
bool LPQResultSet::Previous()
{
if (IsFirst()) return false;
return Absolute(m_cursor - 1);
}
const unsigned int LPQResultSet::GetRowCount() const
{
wxASSERT_MSG(m_rs != NULL, _T("m_rs est NULL."));
PGresult * prs = static_cast<PGresult*> (m_rs);
return PQntuples(prs);
}
const unsigned int LPQResultSet::GetColumnCount() const
{
wxASSERT_MSG(m_rs != NULL, _T("m_rs est NULL."));
PGresult * prs = static_cast<PGresult*> (m_rs);
return PQnfields(prs);
}
const wxString LPQResultSet::GetColumnName(const unsigned int colIndex) const
{
wxASSERT_MSG(m_rs != NULL, _T("m_rs est NULL."));
PGresult * prs = static_cast<PGresult*> (m_rs);
const char * name = PQfname(prs, colIndex);
if (name) return wxString(name);
return wxEmptyString;
}
const int LPQResultSet::GetColumnIndex(const wxString& colName) const
{
wxASSERT_MSG(m_rs != NULL, _T("m_rs est NULL."));
PGresult * prs = static_cast<PGresult*> (m_rs);
return PQfnumber(prs, colName.c_str());
}
const wxAny LPQResultSet::GetData(const unsigned int rowIdx, const unsigned int colIdx) const
{
PGresult * prs = static_cast<PGresult*> (m_rs);
const char * data = PQgetvalue(prs, rowIdx, colIdx);
return wxString(data, wxConvUTF8);
}
const wxAny LPQResultSet::GetData(const wxString& columnName) const
{
PGresult * prs = static_cast<PGresult*> (m_rs);
if (m_cursor < 0
|| IsInserting()
|| !HasData()
|| m_cursor > PQntuples(prs) - 1)
return wxEmptyString;
const char* colName = columnName.c_str();
int colIdx = PQfnumber(prs, colName);
if (colIdx < 0 || colIdx >= PQnfields(prs))
{
const wxString msg = RS004M + columnName;
const LInformation inf(RS004C, msg);
InformLibMessage(inf);
return wxEmptyString;
}
return GetData(m_cursor, colIdx);
}
void LPQResultSet::Display()
{
for (unsigned int i = 0; i < m_BoundControls.GetCount(); i++)
{
LBoundControl * control = static_cast<LBoundControl*> (m_BoundControls.Item(i));
if (!control) continue;
wxAny aData = GetData(control->GetColumnName());
control->SetData(aData);
}
}
bool LPQResultSet::Save()
{
wxASSERT_MSG(m_conn != NULL, _T("m_conn est NULL."));
if (m_readOnly || m_conn->IsReadOnly()) return false;
if (!m_inserting && !HasData()) return false;
InformBeforeSave();
if (!m_canSave) return false;
LBoundControl* pkControl = GetControl(m_pkColName);
if (!pkControl) return false;
if (pkControl->IsNull())
{
InformBeforeInsert();
if (!m_canInsert) return false;
}
else
{
InformBeforeUpdate();
if (!m_canUpdate) return false;
}
const wxString sql = MakeUpdateSQL();
if (sql.IsEmpty()) return false;
bool updating = (sql.Mid(0, 7) == _T("UPDATE "));
wxAny pkValue;
bool res;
if (updating) pkValue = GetData(m_pkColName);
if (m_conn->ExecuteUpdateSQL(sql))
{
const int oldCursor = m_cursor;
if (updating)
{
InformAfterUpdate(pkValue, sql);
res = RunSQL();
if (res)
{
m_cursor = GetRowByPKValue(pkValue);
Display();
if (oldCursor != m_cursor) InformAfterChangeRow();
}
}
else
{
void * vretKeys = m_conn->GetReturnedKeys();
PGresult * retKeys = static_cast<PGresult*> (vretKeys);
if (retKeys != NULL)
{
const char * data = PQgetvalue(retKeys, 0, 0); // RETURNING pkColName from MakeUpdateSQL
wxAny newPK = wxString(data);
InformAfterInsert(newPK, sql); // Before RunSQL so as UpdateSQL can be called by client app
res = RunSQL();
if (res)
{
m_cursor = GetRowByPKValue(newPK);
Display();
m_inserting = false;
if (oldCursor != m_cursor) InformAfterChangeRow();
}
//m_conn->ClearReturnedKeys(); // Not here
}
else
{
const LInformation inf(RS002C, RS002M);
InformLibMessage(inf);
}
}
InformAfterSave();
}
else
{
const LInformation inf(RSPQMC, wxString(m_conn->GetLastLibMessage()));
InformLibMessage(inf);
}
m_conn->ClearReturnedKeys(); // Always clear, even if update.
if (res) InformAfterAction(LResultSetEvent::ACTION_SAVE);
return res;
}
const wxString LPQResultSet::MakeUpdateSQL() const
{
if (m_readOnly || !m_canSave || !m_canInsert || !m_canUpdate) return wxEmptyString;
if (!m_inserting && !HasData()) return wxEmptyString;
LBoundControl* pkControl = GetControl(m_pkColName);
if (pkControl == NULL) return wxEmptyString;
wxString sql = _T("UPDATE");
bool updating = true;
if (pkControl->IsNull())
{
sql = _T("INSERT INTO");
updating = false;
}
wxString columns = wxEmptyString;
wxString values = wxEmptyString;
wxString singleValue = wxEmptyString;
for (unsigned int i = 0; i < m_BoundControls.GetCount(); i++)
{
LBoundControl * control = static_cast<LBoundControl*> (m_BoundControls.Item(i));
if (!control) continue;
const wxString colName = control->GetColumnName();
if (updating)
{
if (colName.Lower() != m_pkColName.Lower())
{
if (control->IsDirty())
{
// Build "col = value, " string
singleValue = wxEmptyString;
control->GetData().GetAs<wxString> (&singleValue);
EscapeChar(singleValue);
const wxString quote = control->IsNull() ? wxString(wxEmptyString) : control->GetSQLQuote();
values += colName + _T(" = ") + quote
+ singleValue
+ quote + _T(", ");
}
}
}
else
{
if (colName.Lower() != m_pkColName.Lower())
{
if (control->IsDirty())
{
// Construct "col1, col2,..." string
columns += colName + _T(", ");
singleValue = wxEmptyString;
control->GetData().GetAs<wxString> (&singleValue);
EscapeChar(singleValue);
// Construct "value1, value2,..." string
const wxString quote = control->IsNull() ? wxString(wxEmptyString) : control->GetSQLQuote();
values += quote
+ singleValue
+ quote + _T(", ");
}
}
}
}
if (updating)
{
if (values.IsEmpty())
{
sql = wxEmptyString;
}
else
{
// Append "WHERE pkColName = value"
values = values.Mid(0, (values.Len() - 2));
singleValue = wxEmptyString;
pkControl->GetData().GetAs<wxString> (&singleValue);
values += _T(" WHERE ") + m_pkColName + _T(" = ")
+ pkControl->GetSQLQuote() + singleValue
+ pkControl->GetSQLQuote();
// Build final string
sql += _T(" ") + m_tblName + _T(" SET ") + values;
}
}
else
{
if (values.IsEmpty() || columns.IsEmpty())
{
sql = wxEmptyString;
}
else
{
// Manage master/child columns
wxString childColList = wxEmptyString;
wxString masterValueList = wxEmptyString;
if (IsChild())
{
childColList = MakeChildInsertColList();
masterValueList = MakeMasterValueList();
}
columns = childColList + columns;
columns = columns.Mid(0, (columns.Len() - 2));
columns = _T(" (") + columns + _T(") ");
values = masterValueList + values;
values = values.Mid(0, (values.Len() - 2));
values = _T(" (") + values + _T(") ");
// Near final string
sql = sql + _T(" ") + m_tblName + columns + _T("VALUES") + values;
// Add returning primary key clause
if (!m_pkColName.IsEmpty())
{
sql += _T(" RETURNING ") + m_pkColName;
}
}
}
return sql;
}
const wxString LPQResultSet::MakeDeleteSQL() const
{
if (m_readOnly || !m_canDelete) return wxEmptyString;
if (!HasData()) return wxEmptyString;
if (m_inserting) return wxEmptyString;
LBoundControl* pkControl = GetControl(m_pkColName);
if (pkControl == NULL) return wxEmptyString;
wxString pkValue = wxEmptyString;
pkControl->GetData().GetAs<wxString>(&pkValue);
EscapeChar(pkValue); // ???
wxString sql = _T("DELETE FROM ") + m_tblName
+ _T(" WHERE ") + m_pkColName + _T(" = ")
+ pkControl->GetSQLQuote()
+ pkValue
+ pkControl->GetSQLQuote();
return sql;
}
const int LPQResultSet::GetRowByPKValue(const wxAny& pkValue) const
{
if (!HasData()) return -1;
PGresult * prs = static_cast<PGresult*> (m_rs);
int colIdx = PQfnumber(prs, m_pkColName.c_str());
if (colIdx < 0) return -1;
for (unsigned int i = 0; i < GetRowCount(); i++)
{
const wxAny beData = GetData(i, colIdx);
if (pkValue.As<wxString>() == beData.As<wxString>()) return i;
}
return -1;
}
#endif

118
L7/LPQResultSet.h Normal file
View File

@@ -0,0 +1,118 @@
/*
* File: LPQResultSet.h
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 29 mai 2014, 16:16
*/
#ifdef USE_LIBPQ
#ifndef LPQRESULTSET_H
#define LPQRESULTSET_H
#include "LResultSet.h"
#include <libpq-fe.h>
/**
* PostgreSQL namespace.
*
* Please note USE_LIBPQ pre-processor directive must be defined to include the PostgreSQL backend.
*/
namespace PQ
{
#define RSPQMC wxString(_T("RSPQM"))
#define RS000C wxString(_T("RS000"))
#define RS000M wxString(_("Result set is NULL."))
#define RS001C wxString(_T("RS001"))
#define RS001M wxString(_("Insert started\nPlease SAVE or CANCEL first"))
#define RS002C wxString(_T("RS002"))
#define RS002M wxString(_("Unknown error"))
#define RS003C wxString(_T("RS003"))
#define RS003M wxString(_("Data altered\nPlease SAVE or CANCEL first"))
#define RS004C wxString(_T("RS004"))
#define RS004M wxString(_("Invalid column name :\n"))
/**
* Scrollable resultset for the PostgreSQL backend.
*
* This class allows data modification through GUI elements.
* The underlying SQL query must not contain table aliases.
*
* A column alias must still be a real column name of the table specified in SetTableName.
*
* Ex : SELECT tbl1.pk1, tbl1.text1, list2.text2 AS num1 FROM tbl1 LEFT JOIN list2 ON tbl1.num1 = list2.pk2
*/
class LPQResultSet : public LResultSet
{
public:
LPQResultSet();
LPQResultSet(LConnection * newConnection);
virtual ~LPQResultSet();
/**
* Updates and runs the SQL string.
* @param newSql
* @return
*/
bool SetSQL(const wxString& newSql);
bool HasData() const;
bool Absolute(const unsigned int newRowIndex);
bool IsFirst() const;
bool IsLast() const;
bool First();
bool Next();
bool Previous();
bool Last();
const unsigned int GetRowCount() const;
const unsigned int GetColumnCount() const;
const wxString GetColumnName(const unsigned int colIndex) const;
const int GetColumnIndex(const wxString& colName) const;
const wxAny GetData(const unsigned int rowIdx, const unsigned int colIdx) const;
/**
* At current row.
* @param colName
* @return database table value or wxEmptyString.
*/
const wxAny GetData(const wxString& colName) const;
/**
* Updates registered controls on screen.
*/
void Display();
bool Save();
inline void InformInserting() const
{
InformLibMessage(LInformation(RS001C, RS001M));
}
inline void InformDirty() const
{
InformLibMessage(LInformation(RS003C, RS003M));
};
/**
* Replaces a single quote ' by two single quotes '' .
* @param literal
* @return the number of single quotes replaced
*/
static int EscapeChar(wxString& literal)
{
return literal.Replace(_T("'"), _T("''"));
}
private:
bool RunSQL();
const wxString MakeUpdateSQL() const;
const wxString MakeDeleteSQL() const;
/**
* Locates a row by the primary key value and returns its index.
* @param pkValue
* @return row index or -1 if not found.
*/
const int GetRowByPKValue(const wxAny& pkValue) const;
};
}
#endif /* LPQRESULTSET_H */
#endif

439
L7/LResultSet.cpp Normal file
View File

@@ -0,0 +1,439 @@
/*
* File: LResultSet.cpp
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 28 mai 2014, 21:13
*/
#include "LResultSet.h"
#include <wx/tokenzr.h>
LResultSet::LResultSet() : LLightResultSet()
{
m_tblName = wxEmptyString;
m_pkColName = wxEmptyString;
m_inserting = false;
m_canDelete = true;
m_canSave = true;
m_canInsert = true;
m_canUpdate = true;
m_readOnly = false;
m_canMove = true;
m_masterResultSet = NULL;
m_masterColumnNames = wxEmptyString;
m_childColumnNames = wxEmptyString;
}
LResultSet::LResultSet(LConnection* newConnection) : LLightResultSet(newConnection)
{
m_tblName = wxEmptyString;
m_pkColName = wxEmptyString;
m_inserting = false;
m_canDelete = true;
m_canSave = true;
m_canInsert = true;
m_canUpdate = true;
m_readOnly = false;
m_canMove = true;
m_masterResultSet = NULL;
m_masterColumnNames = wxEmptyString;
m_childColumnNames = wxEmptyString;
}
LResultSet::~LResultSet()
{
UnRegisterAllControls();
m_evtHandlers.Clear();
}
void LResultSet::RegisterEventHandler(LResultSetEvent * evh)
{
if (evh == NULL || m_evtHandlers.Index(evh) != wxNOT_FOUND) return;
m_evtHandlers.Add(evh);
}
void LResultSet::UnRegisterEventHandler(LResultSetEvent * evh)
{
if (evh == NULL || m_evtHandlers.Index(evh) == wxNOT_FOUND) return;
m_evtHandlers.Remove(evh);
}
void LResultSet::RegisterControl(LBoundControl * comp)
{
if (comp == NULL || m_BoundControls.Index(comp) != wxNOT_FOUND) return;
m_BoundControls.Add(comp);
}
void LResultSet::UnRegisterControl(LBoundControl * comp)
{
if (comp == NULL || m_BoundControls.Index(comp) == wxNOT_FOUND) return;
m_BoundControls.Remove(comp);
comp->SetResultSet(NULL);
}
void LResultSet::UnRegisterAllControls()
{
while (m_BoundControls.Count() > 0)
{
LBoundControl * ctrl = static_cast<LBoundControl*> (m_BoundControls.Item(0));
if (ctrl) UnRegisterControl(ctrl);
}
}
bool LResultSet::IsDirty() const
{
for (unsigned int i = 0; i < m_BoundControls.GetCount(); i++)
{
LBoundControl * control = static_cast<LBoundControl*> (m_BoundControls.Item(i));
if (!control) continue;
if (control->IsDirty()) return true;
}
return false;
}
bool LResultSet::Refresh()
{
if (!m_readOnly)
{
if (m_inserting)
{
InformInserting();
return false;
}
if (IsDirty())
{
InformDirty();
return false;
}
}
bool res = RunSQL();
if (res) InformAfterAction(LResultSetEvent::ACTION_REFRESH);
return res;
}
bool LResultSet::Cancel()
{
if (!m_inserting && !IsDirty()) return false;
bool wasInserting = m_inserting;
m_inserting = false;
Display();
if (wasInserting)
{
if (m_cursor > -1) InformAfterChangeRow();
}
InformAfterAction(LResultSetEvent::ACTION_CANCEL);
return true;
}
bool LResultSet::AddNew()
{
wxASSERT_MSG(m_conn != NULL, _T("m_conn est NULL."));
if (m_readOnly || m_conn->IsReadOnly()) return false;
if (m_inserting)
{
InformInserting();
return false;
}
if (IsDirty())
{
InformDirty();
return false;
}
m_inserting = true;
Display();
if (m_cursor > -1) InformAfterChangeRow();
InformAfterAction(LResultSetEvent::ACTION_ADDNEW);
return true;
}
bool LResultSet::Delete()
{
wxASSERT_MSG(m_conn != NULL, _T("m_conn est NULL."));
if (m_readOnly || m_conn->IsReadOnly()) return false;
if (!HasData()) return false;
if (m_inserting)
{
InformInserting();
return false;
}
if (IsDirty())
{
InformDirty();
return false;
}
InformBeforeDelete();
if (!m_canDelete) return false;
const wxString sql = MakeDeleteSQL();
if (sql.IsEmpty()) return false;
wxVariant oldPkValue = GetData(m_pkColName);
bool res = m_conn->ExecuteUpdateSQL(sql);
if (res)
{
const int oldCursor = m_cursor;
RunSQL(); // m_cursor gets 0 or -1
m_cursor = oldCursor - 1;
Display();
InformAfterDelete(oldPkValue, sql);
InformAfterChangeRow();
InformAfterAction(LResultSetEvent::ACTION_DELETE);
}
return res;
}
LBoundControl* LResultSet::GetControl(const wxString& colName) const
{
for (unsigned int i = 0; i < m_BoundControls.GetCount(); i++)
{
LBoundControl * control = static_cast<LBoundControl*> (m_BoundControls.Item(i));
if (!control) continue;
if (control->GetColumnName().Lower() == colName.Lower()) return control;
}
return NULL;
}
void LResultSet::InformInitialised()
{
for (int i = 0; i < m_evtHandlers.GetCount(); i++)
{
void * p = m_evtHandlers.Item(i);
LResultSetEvent * evh = static_cast<LResultSetEvent*> (p);
if (evh != NULL) evh->Initialised(this);
}
}
void LResultSet::InformBeforeSave()
{
for (int i = 0; i < m_evtHandlers.GetCount(); i++)
{
void * p = m_evtHandlers.Item(i);
LResultSetEvent * evh = static_cast<LResultSetEvent*> (p);
if (evh != NULL) evh->BeforeSave(this);
}
}
void LResultSet::InformBeforeInsert()
{
for (int i = 0; i < m_evtHandlers.GetCount(); i++)
{
void * p = m_evtHandlers.Item(i);
LResultSetEvent * evh = static_cast<LResultSetEvent*> (p);
if (evh != NULL) evh->BeforeInsert(this);
}
}
void LResultSet::InformBeforeUpdate()
{
for (int i = 0; i < m_evtHandlers.GetCount(); i++)
{
void * p = m_evtHandlers.Item(i);
LResultSetEvent * evh = static_cast<LResultSetEvent*> (p);
if (evh != NULL) evh->BeforeUpdate(this);
}
}
void LResultSet::InformBeforeDelete()
{
for (int i = 0; i < m_evtHandlers.GetCount(); i++)
{
void * p = m_evtHandlers.Item(i);
LResultSetEvent * evh = static_cast<LResultSetEvent*> (p);
if (evh != NULL) evh->BeforeDelete(this);
}
}
void LResultSet::InformBeforeChangeRow()
{
for (int i = 0; i < m_evtHandlers.GetCount(); i++)
{
void * p = m_evtHandlers.Item(i);
LResultSetEvent * evh = static_cast<LResultSetEvent*> (p);
if (evh != NULL) evh->BeforeChangeRow(this);
}
}
void LResultSet::InformAfterSave()
{
for (int i = 0; i < m_evtHandlers.GetCount(); i++)
{
void * p = m_evtHandlers.Item(i);
LResultSetEvent * evh = static_cast<LResultSetEvent*> (p);
if (evh != NULL) evh->AfterSave(this);
}
}
void LResultSet::InformAfterInsert(const wxAny& newPK, const wxString& sql)
{
for (int i = 0; i < m_evtHandlers.GetCount(); i++)
{
void * p = m_evtHandlers.Item(i);
LResultSetEvent * evh = static_cast<LResultSetEvent*> (p);
if (evh != NULL) evh->AfterInsert(this, newPK, sql);
}
}
void LResultSet::InformAfterUpdate(const wxAny& curPK, const wxString& sql)
{
for (int i = 0; i < m_evtHandlers.GetCount(); i++)
{
void * p = m_evtHandlers.Item(i);
LResultSetEvent * evh = static_cast<LResultSetEvent*> (p);
if (evh != NULL) evh->AfterUpdate(this, curPK, sql);
}
}
void LResultSet::InformAfterDelete(const wxAny& oldPK, const wxString& sql)
{
for (int i = 0; i < m_evtHandlers.GetCount(); i++)
{
void * p = m_evtHandlers.Item(i);
LResultSetEvent * evh = static_cast<LResultSetEvent*> (p);
if (evh != NULL) evh->AfterDelete(this, oldPK, sql);
}
}
void LResultSet::InformAfterChangeRow()
{
for (int i = 0; i < m_evtHandlers.GetCount(); i++)
{
void * p = m_evtHandlers.Item(i);
LResultSetEvent * evh = static_cast<LResultSetEvent*> (p);
if (evh != NULL) evh->AfterChangeRow(this);
}
}
void LResultSet::InformLibMessage(const LInformation& msg) const
{
for (int i = 0; i < m_evtHandlers.GetCount(); i++)
{
void * p = m_evtHandlers.Item(i);
LResultSetEvent * evh = static_cast<LResultSetEvent*> (p);
if (evh != NULL) evh->Inform(this, msg);
}
}
void LResultSet::InformAfterAction(const int action)
{
LResultSetEvent::ACTIONS a = static_cast<LResultSetEvent::ACTIONS> (action);
for (int i = 0; i < m_evtHandlers.GetCount(); i++)
{
void * p = m_evtHandlers.Item(i);
LResultSetEvent * evh = static_cast<LResultSetEvent*> (p);
if (evh != NULL) evh->AfterAction(this, a);
}
}
bool LResultSet::IsChild() const
{
if (m_masterResultSet == NULL) return false;
if ((m_masterColumnNames.IsEmpty()) || (m_childColumnNames.IsEmpty()))
return false;
wxStringTokenizer zMaster(m_masterColumnNames, _T(";"));
wxStringTokenizer zChild(m_childColumnNames, _T(";"));
return ((zMaster.CountTokens()) == (zChild.CountTokens()));
}
wxString LResultSet::MakeChildInsertColList() const
{
wxStringTokenizer zChild(m_childColumnNames, _T(";"));
wxString token = wxEmptyString;
wxString colList = wxEmptyString;
while (zChild.HasMoreTokens())
{
token = zChild.GetNextToken();
colList += token + _T(", ");
}
return colList; // with a trailing ", " if not empty.
}
wxString LResultSet::MakeMasterValueList() const
{
wxStringTokenizer zMaster(m_masterColumnNames, _T(";"));
wxString token = wxEmptyString;
wxString val = wxEmptyString;
wxString valList = wxEmptyString;
LBoundControl * control = NULL;
while (zMaster.HasMoreTokens())
{
wxASSERT_MSG(m_masterResultSet != NULL, "m_masterResultSet est NULL.");
token = zMaster.GetNextToken();
control = m_masterResultSet->GetControl(token);
wxString sData = wxEmptyString;
if (control)
{
m_masterResultSet->GetData(token).GetAs<wxString>(&sData);
val = control->GetSQLQuote() + sData + control->GetSQLQuote();
}
else
{
// The master resultset may not have GUI controls.
m_masterResultSet->GetData(m_masterResultSet->GetRow(), m_masterResultSet->GetColumnIndex(token)).GetAs<wxString>(&sData);
val = _T("'") + sData + _T("'");
}
valList += val + _T(", ");
}
return valList; // with a trailing ", " if not empty.
}
/////////////////////////////////////////////////////////////////////////////
LResultSetEvent::LResultSetEvent()
{
}
LResultSetEvent::~LResultSetEvent()
{
}
void LResultSetEvent::Initialised(LResultSet* caller)
{
}
void LResultSetEvent::BeforeSave(LResultSet * caller)
{
}
void LResultSetEvent::BeforeInsert(LResultSet * caller)
{
}
void LResultSetEvent::BeforeUpdate(LResultSet * caller)
{
}
void LResultSetEvent::BeforeDelete(LResultSet * caller)
{
}
void LResultSetEvent::BeforeChangeRow(LResultSet * caller)
{
}
void LResultSetEvent::AfterSave(LResultSet * caller)
{
}
void LResultSetEvent::AfterInsert(LResultSet * caller, const wxAny& newPK, const wxString& sql)
{
}
void LResultSetEvent::AfterUpdate(LResultSet * caller, const wxAny& curPK, const wxString& sql)
{
}
void LResultSetEvent::AfterDelete(LResultSet * caller, const wxAny& oldPK, const wxString& sql)
{
}
void LResultSetEvent::AfterChangeRow(LResultSet * caller)
{
}
void LResultSetEvent::AfterAction(LResultSet * caller, ACTIONS action)
{
}
void LResultSetEvent::Inform(const LResultSet * caller, const LInformation& msg) const
{
}

275
L7/LResultSet.h Normal file
View File

@@ -0,0 +1,275 @@
/*
* File: LResultSet.h
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 28 mai 2014, 21:11
*/
#ifndef LRESULTSET_H
#define LRESULTSET_H
#include "LInformation.h"
#include "LBoundControl.h"
#include "LLightResultSet.h"
class LBoundControl;
class LResultSetEvent;
/**
* An abstract class that allows data modification using GUI elements.
*
* Don't use aliases for table names.
*
* A column alias must still be a real column name of the table specified in SetTableName.
*
* Ex : SELECT tbl1.pk1, tbl1.text1, list2.text2 AS num1 FROM tbl1 LEFT JOIN list2 ON tbl1.num1 = list2.pk2
*
*/
class LResultSet : public LLightResultSet
{
public:
LResultSet();
LResultSet(LConnection * newConnection);
/**
* All controls are unregistered in the destructor.
*/
virtual ~LResultSet();
/**
*
* @param newTableName : the database table to update.
*/
void SetTableName(const wxString& newTableName)
{
m_tblName = newTableName;
}
const wxString& GetTableName() const
{
return m_tblName;
}
/**
* May not necessarily be the real primary key of the table.
*
* @param newPKColumnName : an auto-increment column.
*/
void SetPKColumnName(const wxString& newPKColumnName)
{
m_pkColName = newPKColumnName;
}
const wxString& GetPKColumnName() const
{
return m_pkColName;
}
void RegisterControl(LBoundControl * comp);
/**
* Unregisters a control and set its internal resultset member to NULL.
* @param comp
*/
void UnRegisterControl(LBoundControl * comp);
virtual void UnRegisterAllControls();
const wxArrayPtrVoid GetRegisteredControls() const
{
return m_BoundControls;
}
bool IsControlRegistered(LBoundControl * comp) const
{
return (m_BoundControls.Index(comp) != wxNOT_FOUND);
}
virtual void Display() = 0;
/**
*
* @return true if any registered control is dirty, false otherwise.
*/
bool IsDirty() const;
virtual bool Save() = 0;
bool Refresh();
bool Cancel();
bool AddNew();
bool Delete();
LBoundControl* GetControl(const wxString& colName) const;
void SetCanSave(bool newCanSave)
{
m_canSave = newCanSave;
}
bool GetCanSave() const
{
return m_canSave;
}
void SetCanInsert(bool newCanInsert)
{
m_canInsert = newCanInsert;
}
bool GetCanInsert() const
{
return m_canInsert;
}
void SetCanUpdate(bool newCanUpdate)
{
m_canUpdate = newCanUpdate;
}
bool GetCanUpdate() const
{
return m_canUpdate;
}
void SetCanDelete(bool newCanDelete)
{
m_canDelete = newCanDelete;
}
bool GetCanDelete() const
{
return m_canDelete;
}
void SetReadOnly(bool newReadOnly)
{
m_readOnly = newReadOnly;
}
bool IsReadOnly() const
{
return m_readOnly;
}
void SetCanMove(bool newCanMove)
{
m_canMove = newCanMove;
}
bool GetCanMove() const
{
return m_canMove;
}
bool IsInserting() const
{
return m_inserting;
}
void SetMasterResultSet(LResultSet * newResultSet)
{
m_masterResultSet = newResultSet;
}
const LResultSet* GetMasterResultSet() const
{
return m_masterResultSet;
}
void SetMasterColumnNames(const wxString& newColumnNames)
{
m_masterColumnNames = newColumnNames;
}
const wxString& GetMasterColumnNames() const
{
return m_masterColumnNames;
}
void SetChildColumnNames(const wxString& newColumnNames)
{
m_childColumnNames = newColumnNames;
}
const wxString& GetChildColumnNames() const
{
return m_childColumnNames;
}
virtual void InformInserting() const = 0;
virtual void InformDirty() const = 0;
void RegisterEventHandler(LResultSetEvent * evh);
void UnRegisterEventHandler(LResultSetEvent * evh);
wxArrayPtrVoid& GetEventHandlers()
{
return m_evtHandlers;
}
protected:
wxString m_tblName;
wxString m_pkColName;
wxArrayPtrVoid m_BoundControls;
virtual const wxString MakeUpdateSQL() const = 0;
virtual const wxString MakeDeleteSQL() const = 0;
virtual const int GetRowByPKValue(const wxAny& pkValue) const = 0;
bool m_inserting;
bool m_canSave;
bool m_canInsert;
bool m_canUpdate;
bool m_canDelete;
bool m_readOnly;
bool m_canMove;
wxArrayPtrVoid m_evtHandlers;
void InformInitialised();
void InformBeforeSave();
void InformBeforeInsert();
void InformBeforeUpdate();
void InformBeforeDelete();
void InformBeforeChangeRow();
void InformAfterSave();
void InformAfterChangeRow();
void InformAfterAction(const int action);
void InformAfterInsert(const wxAny& newPK, const wxString& sql);
void InformAfterUpdate(const wxAny& curPK, const wxString& sql);
void InformAfterDelete(const wxAny& oldPK, const wxString& sql);
void InformLibMessage(const LInformation& msg) const;
wxWeakRef<LResultSet> m_masterResultSet;
wxString m_masterColumnNames;
wxString m_childColumnNames;
bool IsChild() const;
wxString MakeChildInsertColList() const;
wxString MakeMasterValueList() const;
private:
};
////////////////////////////////////////////////////////////////////////
class LResultSetEvent
{
public:
LResultSetEvent();
virtual ~LResultSetEvent();
enum ACTIONS
{
ACTION_ADDNEW = 0, ACTION_SAVE, ACTION_CANCEL, ACTION_REFRESH, ACTION_DELETE
};
virtual void Initialised(LResultSet * caller);
virtual void BeforeSave(LResultSet * caller);
virtual void BeforeInsert(LResultSet * caller);
virtual void BeforeUpdate(LResultSet * caller);
virtual void BeforeDelete(LResultSet * caller);
virtual void BeforeChangeRow(LResultSet * caller);
virtual void AfterSave(LResultSet * caller);
virtual void AfterInsert(LResultSet * caller, const wxAny& newPK, const wxString& sql);
virtual void AfterUpdate(LResultSet * caller, const wxAny& curPK, const wxString& sql);
virtual void AfterDelete(LResultSet * caller, const wxAny& oldPK, const wxString& sql);
virtual void AfterChangeRow(LResultSet * caller);
virtual void AfterAction(LResultSet * caller, ACTIONS action);
virtual void Inform(const LResultSet * caller, const LInformation& msg) const;
private:
};
#endif /* LRESULTSET_H */

135
L7/LSQConnection.cpp Normal file
View File

@@ -0,0 +1,135 @@
/*
* File: LSQConnection.cpp
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 25 mai 2014, 16:08
*/
#ifdef USE_LIBSQ
#include "LSQConnection.h"
#include "LSQresult.h"
using namespace SQ;
LSQConnection::LSQConnection() : LConnection()
{
m_conn = NULL;
m_errMsg = NULL;
}
LSQConnection::LSQConnection(const wxString& newInfo) : LConnection(newInfo)
{
m_conn = NULL;
m_errMsg = NULL;
}
LSQConnection::~LSQConnection()
{
Close();
}
const char *LSQConnection::GetLastLibMessage() const
{
return m_errMsg;
}
bool LSQConnection::Connect()
{
if (m_conn != NULL)
{
return true;
}
const char* cinfo = m_connInfo.c_str();
int flag = (m_readOnly ? SQLITE_OPEN_READONLY | SQLITE_OPEN_CREATE : SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
int res = sqlite3_open_v2(cinfo, &m_conn, flag, NULL);
if (res != 0) Close();
return (res == 0);
}
void * LSQConnection::Get() const
{
return (void*) m_conn;
}
bool LSQConnection::IsValid() const
{
/*
Is there a better way to really check the status of the sqlite3 connection object ?
* Something like PQstatus(PGconn*) ?
* Quote from the documentation :
*
* The application must insure that the 1st parameter to sqlite3_exec()
* is a valid and open [database connection]
*
* How to ?
*/
return (m_conn != NULL);
}
void LSQConnection::Close()
{
if (m_conn != NULL)
{
sqlite3_close(m_conn);
m_conn = NULL;
m_errMsg = NULL;
}
}
void * LSQConnection::ExecuteSQL(const wxString& newSql)
{
wxCHECK_MSG(IsValid() == true, NULL, _("Invalid connection"));
SQresult * res = new SQresult();
const char* cSQL = newSql.c_str();
m_errMsg = NULL;
int rc = sqlite3_get_table(m_conn, cSQL, &res->m_data, &res->m_nbRows, &res->m_nbCols, &m_errMsg);
if (m_errMsg)
{
InformSQMessage(m_errMsg);
sqlite3_free(m_errMsg);
sqlite3_free_table(res->m_data);
res = NULL;
}
return (void*) res;
}
bool LSQConnection::ExecuteUpdateSQL(const wxString& newSql)
{
wxCHECK_MSG(IsValid() == true, false, _("Invalid connection"));
const char* cSQL = newSql.c_str();
m_errMsg = NULL;
int rc = sqlite3_exec(m_conn, cSQL, NULL, NULL, &m_errMsg);
if (m_errMsg)
{
InformSQMessage(m_errMsg);
sqlite3_free(m_errMsg);
}
return (rc == SQLITE_OK);
}
const wxAny LSQConnection::GetReturnedValue(const unsigned int unused) const
{
sqlite3_int64 r = sqlite3_last_insert_rowid(m_conn);
return wxAny((long) r);
}
void LSQConnection::InformSQMessage(const char * SQmsg) const
{
if (!SQmsg) return;
wxString msg(SQmsg);
if (msg.IsEmpty()) return;
const LInformation inf(CNSQMC, msg);
InformLibMessage(inf);
}
void LSQConnection::InformLibMessage(const LInformation& msg) const
{
for (int i = 0; i < evtHandlers.GetCount(); i++)
{
void * p = evtHandlers.Item(i);
LConnectionEvent * evh = static_cast<LConnectionEvent*> (p);
if (evh != NULL) evh->Inform(this, msg);
}
}
#endif

108
L7/LSQConnection.h Normal file
View File

@@ -0,0 +1,108 @@
/*
* File: LSQConnection.h
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 25 mai 2014, 16:07
*/
#ifdef USE_LIBSQ
#ifndef LSQCONNECTION_H
#define LSQCONNECTION_H
#include <sqlite3.h>
#include <vector>
#include <wx/wx.h>
#include "LConnection.h"
/**
* SQLite namespace.
*
* Please note USE_LIBSQ pre-processor directive must be defined to include the SQLite backend.
*/
namespace SQ
{
#define CNSQMC wxString(_T("CNSQM"))
class SQresult;
/**
Minimalist class managing an SQLite3 connection; derives from LConnection.
*/
class LSQConnection : public LConnection
{
public:
LSQConnection();
/**
*
* @param newInfo : connection information. A file path, or memory/temporary database string instructions.
*/
LSQConnection(const wxString& newInfo);
/**
* The connection is closed in the destructor.
*/
virtual ~LSQConnection();
/**
*
* @return the last backend error message, may be NULL.
*/
const char* GetLastLibMessage() const;
/**
* Establishes a new connection, creating the SQLIte database if necessary.
* Does nothing if a connection already exists.
* @return true if a new connection is established, or if a connection already esists. False on error.
*/
bool Connect();
/**
*
* @return a pointer to the sqlite3 real database pointer.
*/
void * Get() const;
/**
* Checks if the sqlite3 pointer is not NULL.
* @return true if the sqlite3 pointer is not NULL.
*/
bool IsValid() const;
/**
* Closes the connection. Error message pointer is set to NULL.
*/
void Close();
/**
* Calls sqlite3_get_table and returns rows from a SELECT query.
* @param newSql a valid SQL statement.
* @return an untyped pointer to an SQresult referencing the data, or NULL if error.
*/
void * ExecuteSQL (const wxString& newSql);
/**
* Intended for database actions that do not fetch table rows. Calls sqlite3_exec.
* @param newSql : : a valid SQL statement.
* @return true on success, false otherwise.
*/
bool ExecuteUpdateSQL(const wxString& newSql);
/**
*
* @param col : unused
* @return an insert row identifier is always returned, even if the table does not have an autoincrement column.
*/
const wxAny GetReturnedValue(const unsigned int unused) const;
private:
sqlite3 * m_conn;
char * m_errMsg;
/**
* Forwards SQLite messages to InformLibMessage
* @param
*/
void InformSQMessage(const char * SQmsg) const;
wxArrayPtrVoid evtHandlers;
/**
* Informs application that registers LConnectionEvent handlers here.
* @param msg
*/
void InformLibMessage(const LInformation& msg) const;
};
}
#endif /* LSQCONNECTION_H */
#endif

492
L7/LSQResultSet.cpp Normal file
View File

@@ -0,0 +1,492 @@
/*
* File: LSQResultSet.cpp
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 1 juin 2014, 11:43
*/
#ifdef USE_LIBSQ
#include "LSQResultSet.h"
using namespace SQ;
LSQResultSet::LSQResultSet() : LResultSet()
{
}
LSQResultSet::LSQResultSet(LConnection* newConnection) : LResultSet(newConnection)
{
}
LSQResultSet::~LSQResultSet()
{
if (m_rs)
{
SQresult * srs = static_cast<SQresult*> (m_rs);
sqlite3_free_table(srs->m_data);
delete srs;
m_rs = NULL;
}
}
bool LSQResultSet::SetSQL(const wxString& newSql)
{
UpdateSQL(newSql);
if (RunSQL()) First();
return (m_rs != NULL);
}
bool LSQResultSet::RunSQL()
{
if (m_curSql == wxEmptyString)
{
return false;
}
wxASSERT_MSG(m_conn != NULL, _T("m_conn est NULL."));
if (m_rs != NULL)
{
SQresult * srs = static_cast<SQresult*> (m_rs);
sqlite3_free_table(srs->m_data);
wxDELETE(srs);
m_rs = NULL;
}
m_rs = m_conn->ExecuteSQL(m_curSql);
SQresult * srs = static_cast<SQresult*> (m_rs);
if (!RetrieveColNames(srs))
{ // ON EMPTY TABLES, EXECUTESQL RETURNS NO COLUMNS AS WELL
m_rs = NULL;
return false;
}
if (m_rs != NULL)
{
m_cursor = (HasData()) ? 0 : -1;
Display();
m_inserting = false;
if (!m_initialised)
{
m_initialised = true;
InformInitialised();
}
return true;
}
else
{
m_cursor = -1;
Display();
m_inserting = false;
const LInformation inf(RSSQ000C, RSSQ000M);
InformLibMessage(inf);
return false;
}
}
bool LSQResultSet::HasData() const
{
if (m_rs == NULL) return false;
SQresult * srs = static_cast<SQresult*> (m_rs);
if (srs->m_nbRows == 0) return false;
return true;
}
bool LSQResultSet::Absolute(const unsigned int newRowIndex)
{
if (!m_readOnly)
{
if (m_inserting)
{
InformInserting();
return false;
}
if (IsDirty())
{
InformDirty();
return false;
}
}
if (!HasData())
{
m_cursor = -1;
Display();
return false;
}
if (newRowIndex > (GetRowCount() - 1)) return false;
InformBeforeChangeRow();
if (!m_canMove) return false;
m_cursor = newRowIndex;
Display();
m_inserting = false;
InformAfterChangeRow();
return true;
}
bool LSQResultSet::IsFirst() const
{
if (!(HasData())) return false;
return (m_cursor == 0);
}
bool LSQResultSet::IsLast() const
{
if (!(HasData())) return false;
SQresult * srs = static_cast<SQresult*> (m_rs);
return (m_cursor == (srs->m_nbRows - 1));
}
bool LSQResultSet::First()
{
if (IsFirst()) return false;
return Absolute(0);
}
bool LSQResultSet::Next()
{
if (IsLast()) return false;
return Absolute(m_cursor + 1);
}
bool LSQResultSet::Previous()
{
if (IsFirst()) return false;
return Absolute(m_cursor - 1);
}
bool LSQResultSet::Last()
{
if (IsLast()) return false;
SQresult * srs = static_cast<SQresult*> (m_rs);
return Absolute(srs->m_nbRows - 1);
}
const unsigned int LSQResultSet::GetRowCount() const
{
if (m_rs == NULL) return -1;
SQresult * srs = static_cast<SQresult*> (m_rs);
return srs->m_nbRows;
}
const unsigned int LSQResultSet::GetColumnCount() const
{
if (m_rs == NULL) return -1;
SQresult * srs = static_cast<SQresult*> (m_rs);
return srs->m_nbCols;
}
const wxString LSQResultSet::GetColumnName(const unsigned int colIndex) const
{
if (m_rs == NULL) return wxEmptyString;
if (!HasData()) return m_colNames.Item(colIndex);
SQresult * srs = static_cast<SQresult*> (m_rs);
const char* name = srs->m_data[colIndex];
if (name) return wxString(name);
return wxEmptyString;
}
const int LSQResultSet::GetColumnIndex(const wxString& colName) const
{
if (m_rs == NULL) return -1;
if (!HasData()) return m_colNames.Index(colName, false);
SQresult * srs = static_cast<SQresult*> (m_rs);
for (unsigned int c = 0; c < srs->m_nbCols; c++)
{
const char* name = srs->m_data[c];
const wxString sName(name);
if (sName.Lower() == colName.Lower()) return c;
}
return -1;
}
const wxAny LSQResultSet::GetData(const unsigned int rowIdx, const unsigned int colIdx) const
{
if (!HasData()) return wxEmptyString;
SQresult * srs = static_cast<SQresult*> (m_rs);
const char * data = srs->m_data[((rowIdx + 1) * (srs->m_nbCols)) + colIdx];
if (data == NULL) return wxEmptyString;
return wxString(data, wxConvUTF8);
}
const wxAny LSQResultSet::GetData(const wxString &columnName) const
{
SQresult * srs = static_cast<SQresult*> (m_rs);
if (m_cursor < 0
|| IsInserting()
|| !HasData()
|| m_cursor > srs->m_nbRows - 1)
return wxEmptyString;
for (unsigned int c = 0; c < srs->m_nbCols; c++)
{
const char * colName = srs->m_data[c];
const wxString sColName(colName);
if (sColName.Lower() == columnName.Lower()) return GetData(m_cursor, c);
}
return wxEmptyString;
}
void LSQResultSet::Display()
{
for (unsigned int i = 0; i < m_BoundControls.GetCount(); i++)
{
LBoundControl * control = static_cast<LBoundControl*> (m_BoundControls.Item(i));
if (!control) continue;
if (control)
{
wxAny aData = GetData(control->GetColumnName());
control->SetData(aData);
}
}
}
bool LSQResultSet::Save()
{
wxASSERT_MSG(m_conn != NULL, _T("m_conn est NULL."));
if (m_readOnly || m_conn->IsReadOnly()) return false;
if (!m_inserting && !HasData()) return false;
InformBeforeSave();
if (!m_canSave) return false;
LBoundControl* pkControl = GetControl(m_pkColName);
if (!pkControl) return false;
if (pkControl->IsNull())
{
InformBeforeInsert();
if (!m_canInsert) return false;
}
else
{
InformBeforeUpdate();
if (!m_canUpdate) return false;
}
const wxString sql = MakeUpdateSQL();
if (sql.IsEmpty()) return false;
bool updating = (sql.Mid(0, 7) == _T("UPDATE "));
wxAny pkValue;
bool res;
if (updating) pkValue = GetData(m_pkColName);
if (m_conn->ExecuteUpdateSQL(sql))
{
const int oldCursor = m_cursor;
if (updating)
{
InformAfterUpdate(pkValue, sql);
res = RunSQL();
if (res)
{
m_cursor = GetRowByPKValue(pkValue);
Display();
if (oldCursor != m_cursor) InformAfterChangeRow();
}
}
else
{
wxAny newPK = m_conn->GetReturnedValue(0);
int inewPK;
newPK.GetAs<int> (&inewPK);
if (inewPK != 0)
{
InformAfterInsert(newPK, sql); // Before RunSQL so that UpdateSQL can be called by client app
res = RunSQL();
if (res)
{
m_cursor = GetRowByPKValue(newPK);
Display();
m_inserting = false;
if (oldCursor != m_cursor) InformAfterChangeRow();
}
m_conn->ClearReturnedKeys();
}
else
{
const LInformation inf(RSSQ002C, RSSQ002M);
InformLibMessage(inf);
}
}
InformAfterSave();
}
else
{
const LInformation inf(RSSQMC, wxString(m_conn->GetLastLibMessage()));
InformLibMessage(inf);
}
if (res) InformAfterAction(LResultSetEvent::ACTION_SAVE);
return res;
}
const wxString LSQResultSet::MakeUpdateSQL() const
{
if (m_readOnly || !m_canSave) return wxEmptyString;
if (!m_inserting && !HasData()) return wxEmptyString;
LBoundControl* pkControl = GetControl(m_pkColName);
if (pkControl == NULL) return wxEmptyString;
wxString sql = _T("UPDATE");
bool updating = true;
if (pkControl->IsNull())
{
sql = _T("INSERT INTO");
updating = false;
}
wxString columns = wxEmptyString;
wxString values = wxEmptyString;
wxString singleValue = wxEmptyString;
for (unsigned int i = 0; i < m_BoundControls.GetCount(); i++)
{
LBoundControl * control = static_cast<LBoundControl*> (m_BoundControls.Item(i));
if (!control) continue;
if (!control) continue;
wxString colName = control->GetColumnName();
if (updating)
{
if (colName.Lower() != m_pkColName.Lower())
{
if (control->IsDirty())
{
// Build "col = value, " string
singleValue = wxEmptyString;
control->GetData().GetAs<wxString> (&singleValue);
EscapeChar(singleValue);
const wxString quote = control->IsNull() ? wxString(wxEmptyString) : control->GetSQLQuote();
values += colName + _T(" = ") + quote
+ singleValue
+ quote + _T(", ");
}
}
}
else
{
if (colName.Lower() != m_pkColName.Lower())
{
if (control->IsDirty())
{
// Construct "col1, col2,..." string
columns += colName + _T(", ");
singleValue = wxEmptyString;
control->GetData().GetAs<wxString> (&singleValue);
EscapeChar(singleValue);
// Construct "value1, value2,..." string
const wxString quote = control->IsNull() ? wxString(wxEmptyString) : control->GetSQLQuote();
values += quote
+ singleValue
+ quote + _T(", ");
}
}
}
}
if (updating)
{
if (values.IsEmpty())
{
sql = wxEmptyString;
}
else
{
// Append "WHERE pkColName = value"
values = values.Mid(0, (values.Len() - 2));
singleValue = wxEmptyString;
pkControl->GetData().GetAs<wxString> (&singleValue);
values += _T(" WHERE ") + m_pkColName + _T(" = ")
+ pkControl->GetSQLQuote() + singleValue
+ pkControl->GetSQLQuote();
// Build final string
sql += _T(" ") + m_tblName + _T(" SET ") + values;
}
}
else
{
if (values.IsEmpty() || columns.IsEmpty())
{
sql = wxEmptyString;
}
else
{
// Manage master/child columns
wxString childColList = wxEmptyString;
wxString masterValueList = wxEmptyString;
if (IsChild())
{
childColList = MakeChildInsertColList();
masterValueList = MakeMasterValueList();
}
columns = childColList + columns;
columns = columns.Mid(0, (columns.Len() - 2));
columns = _T(" (") + columns + _T(") ");
values = masterValueList + values;
values = values.Mid(0, (values.Len() - 2));
values = _T(" (") + values + _T(") ");
// Final string
sql = sql + _T(" ") + m_tblName + columns + _T("VALUES") + values;
}
}
return sql;
}
const wxString LSQResultSet::MakeDeleteSQL() const
{
if (m_readOnly || !m_canDelete) return wxEmptyString;
if (!HasData()) return wxEmptyString;
if (m_inserting) return wxEmptyString;
LBoundControl* pkControl = GetControl(m_pkColName);
if (pkControl == NULL) return wxEmptyString;
wxString pkValue = wxEmptyString;
pkControl->GetData().GetAs<wxString>(&pkValue);
EscapeChar(pkValue); // ???
wxString sql = _T("DELETE FROM ") + m_tblName
+ _T(" WHERE ") + m_pkColName + _T(" = ")
+ pkControl->GetSQLQuote()
+ pkValue
+ pkControl->GetSQLQuote();
return sql;
}
const int LSQResultSet::GetRowByPKValue(const wxAny& pkValue) const
{
if (!HasData()) return -1;
int colIdx = GetColumnIndex(m_pkColName);
if (colIdx < 0) return -1;
for (unsigned int i = 0; i < GetRowCount(); i++)
{
wxAny beData = GetData(i, colIdx);
if (pkValue.As<wxString>() == beData.As<wxString>()) return i;
}
return -1;
}
bool LSQResultSet::RetrieveColNames(SQresult * emptyResult)
{
/*
* PRAGMA table_info(tbl1)
* gives table metadata
* but columns ordering in m_curSql is obviously app dependant
*
*/
wxASSERT_MSG(m_conn != NULL, _T("m_conn est NULL."));
sqlite3 * db = static_cast<sqlite3*> (m_conn->Get());
if (db)
{
sqlite3_stmt * ppStmt;
int res = sqlite3_prepare(db, m_curSql, -1, &ppStmt, NULL);
if (res == SQLITE_OK)
{
m_colNames.Clear();
int colCount = sqlite3_column_count(ppStmt);
for (unsigned int i = 0; i < colCount; i++)
{
const char * name = sqlite3_column_name(ppStmt, i);
m_colNames.Add(wxString(name));
}
emptyResult->m_nbCols = m_colNames.GetCount();
sqlite3_finalize(ppStmt);
return true;
}
else
{
int errCode = sqlite3_errcode(db);
const char * errMsg = sqlite3_errmsg(db);
const char * errStr = sqlite3_errstr(errCode);
const wxString msg(wxAny(errCode).As<wxString>() + _T(" ") +
wxString(errMsg) + _T("\n") + wxString(errStr));
wxPrintf("%s\n", msg);
wxFAIL_MSG(msg);
}
}
return false;
}
#endif

119
L7/LSQResultSet.h Normal file
View File

@@ -0,0 +1,119 @@
/*
* File: LSQResultSet.h
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 1 juin 2014, 11:42
*/
#ifdef USE_LIBSQ
#ifndef LSQRESULTSET_H
#define LSQRESULTSET_H
#include "LResultSet.h"
#include <sqlite3.h>
#include "LSQresult.h"
/**
* SQLite namespace.
*
* Please note USE_LIBSQ pre-processor directive must be defined to include the SQLite backend.
*/
namespace SQ
{
#define RSSQMC wxString(_T("RSSQM"))
#define RSSQ000C wxString(_T("RS000"))
#define RSSQ000M wxString(_("Result set is NULL."))
#define RSSQ001C wxString(_T("RS001"))
#define RSSQ001M wxString(_("Insert started\nPlease SAVE or CANCEL first"))
#define RSSQ002C wxString(_T("RS002"))
#define RSSQ002M wxString(_("Unknown error"))
#define RSSQ003C wxString(_T("RS003"))
#define RSSQ003M wxString(_("Data altered\nPlease SAVE or CANCEL first"))
#define RSSQ004C wxString(_T("RS004"))
#define RSSQ004M wxString(_("Invalid column name :\n"))
/**
* Scrollable resultset for the SQLite backend.
*
* This class allows data modification through GUI elements.
* The underlying SQL query must not contain table aliases.
*
* A column alias must still be a real column name of the table specified in SetTableName.
*
* Ex : SELECT tbl1.pk1, tbl1.text1, list2.text2 AS num1 FROM tbl1 LEFT JOIN list2 ON tbl1.num1 = list2.pk2
*/
class LSQResultSet : public LResultSet
{
public:
LSQResultSet();
LSQResultSet(LConnection * newConnection);
virtual ~LSQResultSet();
/**
* Updates and runs the SQL string.
* @param newSql
* @return
*/
bool SetSQL(const wxString& newSql);
bool HasData() const;
bool Absolute(const unsigned int newRowIndex);
bool IsFirst() const;
bool IsLast() const;
bool First();
bool Next();
bool Previous();
bool Last();
const unsigned int GetRowCount() const;
const unsigned int GetColumnCount() const;
const wxString GetColumnName(const unsigned int colIndex) const;
const int GetColumnIndex(const wxString& colName) const;
const wxAny GetData(const unsigned int rowIdx, const unsigned int colIdx) const;
/**
* At current row.
* @param colName
* @return database table value or wxEmptyString.
*/
const wxAny GetData(const wxString& colName) const;
/**
* Updates registered controls on screen.
*/
void Display();
bool Save();
inline void InformInserting() const
{
InformLibMessage(LInformation(RSSQ001C, RSSQ001M));
}
inline void InformDirty() const
{
InformLibMessage(LInformation(RSSQ003C, RSSQ003M));
};
/**
* Replaces a single quote ' by two single quotes '' .
* @param literal
* @return the number of single quotes replaced
*/
static int EscapeChar(wxString& literal)
{
return literal.Replace(_T("'"), _T("''"));
}
private:
bool RunSQL();
const wxString MakeUpdateSQL() const;
const wxString MakeDeleteSQL() const;
/**
* Locates a row by the primary key value and returns its index.
* @param pkValue
* @return row index or -1 if not found.
*/
const int GetRowByPKValue(const wxAny& pkValue) const;
wxArrayString m_colNames;
bool RetrieveColNames(SQresult * emptyResult);
};
}
#endif /* LSQRESULTSET_H */
#endif

26
L7/LSQresult.cpp Normal file
View File

@@ -0,0 +1,26 @@
/*
* File: LSQresult.cpp
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 31 mai 2014, 18:57
*/
#ifdef USE_LIBSQ
#include "stddef.h"
#include "LSQresult.h"
using namespace SQ;
SQresult::SQresult()
{
m_nbRows = 0;
m_nbCols = 0;
m_data = NULL;
}
SQresult::~SQresult()
{
}
#endif

49
L7/LSQresult.h Normal file
View File

@@ -0,0 +1,49 @@
/*
* File: LSQresult.h
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 31 mai 2014, 18:56
*/
#ifdef USE_LIBSQ
#ifndef LSQRESULT_H
#define LSQRESULT_H
/**
* SQLite namespace.
*
* Please note USE_LIBSQ pre-processor directive must be defined to include the SQLite backend.
*/
namespace SQ
{
class SQresult
{
/**
* This class is used to reference the data obtained by LSQConnection::ExecuteSQL.
*
* If no rows are returned, m_data is NULL and does not even provide the column names.
*/
public:
SQresult();
virtual ~SQresult();
/**
* Pointer to the array of column names and data.
*/
char ** m_data;
/**
* Number of rows.
*/
int m_nbRows;
/**
* Number of columns
*/
int m_nbCols;
private:
};
}
#endif /* LSQRESULT_H */
#endif

16
L7/LVersion.h Normal file
View File

@@ -0,0 +1,16 @@
/*
* File: LVersion.h
* Author: SET - nmset@netcourrier.com
* License : LGPL version 2.1
* Copyright SET, M. D. - © 2014
*
* Created on 28 juillet 2014, 19:47
*/
#ifndef LVERSION_H
#define LVERSION_H
#define L7_VERSION_STR "4"
#endif /* LVERSION_H */

128
L7/Makefile Normal file
View File

@@ -0,0 +1,128 @@
#
# There exist several targets which are by default empty and which can be
# used for execution of your targets. These targets are usually executed
# before and after some main targets. They are:
#
# .build-pre: called before 'build' target
# .build-post: called after 'build' target
# .clean-pre: called before 'clean' target
# .clean-post: called after 'clean' target
# .clobber-pre: called before 'clobber' target
# .clobber-post: called after 'clobber' target
# .all-pre: called before 'all' target
# .all-post: called after 'all' target
# .help-pre: called before 'help' target
# .help-post: called after 'help' target
#
# Targets beginning with '.' are not intended to be called on their own.
#
# Main targets can be executed directly, and they are:
#
# build build a specific configuration
# clean remove built files from a configuration
# clobber remove all built files
# all build all configurations
# help print help mesage
#
# Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and
# .help-impl are implemented in nbproject/makefile-impl.mk.
#
# Available make variables:
#
# CND_BASEDIR base directory for relative paths
# CND_DISTDIR default top distribution directory (build artifacts)
# CND_BUILDDIR default top build directory (object files, ...)
# CONF name of current configuration
# CND_PLATFORM_${CONF} platform name (current configuration)
# CND_ARTIFACT_DIR_${CONF} directory of build artifact (current configuration)
# CND_ARTIFACT_NAME_${CONF} name of build artifact (current configuration)
# CND_ARTIFACT_PATH_${CONF} path to build artifact (current configuration)
# CND_PACKAGE_DIR_${CONF} directory of package (current configuration)
# CND_PACKAGE_NAME_${CONF} name of package (current configuration)
# CND_PACKAGE_PATH_${CONF} path to package (current configuration)
#
# NOCDDL
# Environment
MKDIR=mkdir
CP=cp
CCADMIN=CCadmin
# build
build: .build-post
.build-pre:
# Add your pre 'build' code here...
.build-post: .build-impl
# Add your post 'build' code here...
# clean
clean: .clean-post
.clean-pre:
# Add your pre 'clean' code here...
.clean-post: .clean-impl
# Add your post 'clean' code here...
# clobber
clobber: .clobber-post
.clobber-pre:
# Add your pre 'clobber' code here...
.clobber-post: .clobber-impl
# Add your post 'clobber' code here...
# all
all: .all-post
.all-pre:
# Add your pre 'all' code here...
.all-post: .all-impl
# Add your post 'all' code here...
# build tests
build-tests: .build-tests-post
.build-tests-pre:
# Add your pre 'build-tests' code here...
.build-tests-post: .build-tests-impl
# Add your post 'build-tests' code here...
# run tests
test: .test-post
.test-pre: build-tests
# Add your pre 'test' code here...
.test-post: .test-impl
# Add your post 'test' code here...
# help
help: .help-post
.help-pre:
# Add your pre 'help' code here...
.help-post: .help-impl
# Add your post 'help' code here...
# include project implementation makefile
include nbproject/Makefile-impl.mk
# include project make variables
include nbproject/Makefile-variables.mk

30
L7/changelog.txt Normal file
View File

@@ -0,0 +1,30 @@
2018-04-25
1. Controls in 'Form View' inherit the grid cell's editor validator.
2. Corrected a bug in LGridSpinEditor::ProvideFormEditor, where the form editor was created without the style parameter.
3. Rename the project to L7.
4. Change versioning pattern to running integers.
5. Moved to github.com.
2015-10-19
version 0.9.3
1. LPQConnection and LSQConnection must free memory by calling Close() if
connection fails.
2015-09-27
version 0.9.2
1. Added a weakref.h include in LLightResultset.h, so as to be able to use
resultset and connection classes independantly.
2. LConnection::ClearReturnedKeys() is always called in LPQResultSet::Save()
to prevent memory leak.
2014-09-27
version 0.9.1
1. Added bound spin control with relevant grid editor and renderer.
2. Added a 'Refresh' menu item in a bound grid's context menu.
3. The bound grid FillGrid() function must call RestoreEditorControls().
4. Minor documentation changes.
2014-08-09
version 0.9.0
Initial release

View File

@@ -0,0 +1,263 @@
#
# Generated Makefile - do not edit!
#
# Edit the Makefile in the project folder instead (../Makefile). Each target
# has a -pre and a -post target defined where you can add customized code.
#
# This makefile implements configuration specific macros and targets.
# Environment
MKDIR=mkdir
CP=cp
GREP=grep
NM=nm
CCADMIN=CCadmin
RANLIB=ranlib
CC=gcc
CCC=g++
CXX=g++
FC=gfortran
AS=as
# Macros
CND_PLATFORM=GNU-Linux
CND_DLIB_EXT=so
CND_CONF=Debug
CND_DISTDIR=dist
CND_BUILDDIR=build
# Include project Makefile
include Makefile
# Object Directory
OBJECTDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}
# Object Files
OBJECTFILES= \
${OBJECTDIR}/LBoundCheckBox.o \
${OBJECTDIR}/LBoundComboBox.o \
${OBJECTDIR}/LBoundControl.o \
${OBJECTDIR}/LBoundDatePickerCtrl.o \
${OBJECTDIR}/LBoundGrid.o \
${OBJECTDIR}/LBoundSpinCtrl.o \
${OBJECTDIR}/LBoundTextCtrl.o \
${OBJECTDIR}/LConnection.o \
${OBJECTDIR}/LGridCheckEditor.o \
${OBJECTDIR}/LGridCheckRenderer.o \
${OBJECTDIR}/LGridColEditor.o \
${OBJECTDIR}/LGridComboEditor.o \
${OBJECTDIR}/LGridComboRenderer.o \
${OBJECTDIR}/LGridDateEditor.o \
${OBJECTDIR}/LGridDateRenderer.o \
${OBJECTDIR}/LGridSpinEditor.o \
${OBJECTDIR}/LGridSpinRenderer.o \
${OBJECTDIR}/LGridTextEditor.o \
${OBJECTDIR}/LGridTextRenderer.o \
${OBJECTDIR}/LInformation.o \
${OBJECTDIR}/LItemData.o \
${OBJECTDIR}/LLightPQResultSet.o \
${OBJECTDIR}/LLightResultSet.o \
${OBJECTDIR}/LLightSQResultSet.o \
${OBJECTDIR}/LNavigator.o \
${OBJECTDIR}/LPQConnection.o \
${OBJECTDIR}/LPQResultSet.o \
${OBJECTDIR}/LResultSet.o \
${OBJECTDIR}/LSQConnection.o \
${OBJECTDIR}/LSQResultSet.o \
${OBJECTDIR}/LSQresult.o
# C Compiler Flags
CFLAGS=
# CC Compiler Flags
CCFLAGS=
CXXFLAGS=
# Fortran Compiler Flags
FFLAGS=
# Assembler Flags
ASFLAGS=
# Link Libraries and Options
LDLIBSOPTIONS=-L/usr/local/wxWidgets/lib -lwx_baseu-3.1 -lwx_gtk2u_core-3.1
# Build Targets
.build-conf: ${BUILD_SUBPROJECTS}
"${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libL7.${CND_DLIB_EXT}
${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libL7.${CND_DLIB_EXT}: ${OBJECTFILES}
${MKDIR} -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}
g++ -o ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libL7.${CND_DLIB_EXT} ${OBJECTFILES} ${LDLIBSOPTIONS} -shared -fPIC
${OBJECTDIR}/LBoundCheckBox.o: LBoundCheckBox.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -g -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -I/usr/local/wxWidgets/lib/wx/include/gtk2-unicode-3.1 -I/usr/local/wxWidgets/include/wx-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LBoundCheckBox.o LBoundCheckBox.cpp
${OBJECTDIR}/LBoundComboBox.o: LBoundComboBox.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -g -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -I/usr/local/wxWidgets/lib/wx/include/gtk2-unicode-3.1 -I/usr/local/wxWidgets/include/wx-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LBoundComboBox.o LBoundComboBox.cpp
${OBJECTDIR}/LBoundControl.o: LBoundControl.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -g -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -I/usr/local/wxWidgets/lib/wx/include/gtk2-unicode-3.1 -I/usr/local/wxWidgets/include/wx-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LBoundControl.o LBoundControl.cpp
${OBJECTDIR}/LBoundDatePickerCtrl.o: LBoundDatePickerCtrl.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -g -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -I/usr/local/wxWidgets/lib/wx/include/gtk2-unicode-3.1 -I/usr/local/wxWidgets/include/wx-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LBoundDatePickerCtrl.o LBoundDatePickerCtrl.cpp
${OBJECTDIR}/LBoundGrid.o: LBoundGrid.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -g -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -I/usr/local/wxWidgets/lib/wx/include/gtk2-unicode-3.1 -I/usr/local/wxWidgets/include/wx-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LBoundGrid.o LBoundGrid.cpp
${OBJECTDIR}/LBoundSpinCtrl.o: LBoundSpinCtrl.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -g -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -I/usr/local/wxWidgets/lib/wx/include/gtk2-unicode-3.1 -I/usr/local/wxWidgets/include/wx-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LBoundSpinCtrl.o LBoundSpinCtrl.cpp
${OBJECTDIR}/LBoundTextCtrl.o: LBoundTextCtrl.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -g -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -I/usr/local/wxWidgets/lib/wx/include/gtk2-unicode-3.1 -I/usr/local/wxWidgets/include/wx-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LBoundTextCtrl.o LBoundTextCtrl.cpp
${OBJECTDIR}/LConnection.o: LConnection.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -g -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -I/usr/local/wxWidgets/lib/wx/include/gtk2-unicode-3.1 -I/usr/local/wxWidgets/include/wx-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LConnection.o LConnection.cpp
${OBJECTDIR}/LGridCheckEditor.o: LGridCheckEditor.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -g -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -I/usr/local/wxWidgets/lib/wx/include/gtk2-unicode-3.1 -I/usr/local/wxWidgets/include/wx-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LGridCheckEditor.o LGridCheckEditor.cpp
${OBJECTDIR}/LGridCheckRenderer.o: LGridCheckRenderer.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -g -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -I/usr/local/wxWidgets/lib/wx/include/gtk2-unicode-3.1 -I/usr/local/wxWidgets/include/wx-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LGridCheckRenderer.o LGridCheckRenderer.cpp
${OBJECTDIR}/LGridColEditor.o: LGridColEditor.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -g -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -I/usr/local/wxWidgets/lib/wx/include/gtk2-unicode-3.1 -I/usr/local/wxWidgets/include/wx-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LGridColEditor.o LGridColEditor.cpp
${OBJECTDIR}/LGridComboEditor.o: LGridComboEditor.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -g -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -I/usr/local/wxWidgets/lib/wx/include/gtk2-unicode-3.1 -I/usr/local/wxWidgets/include/wx-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LGridComboEditor.o LGridComboEditor.cpp
${OBJECTDIR}/LGridComboRenderer.o: LGridComboRenderer.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -g -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -I/usr/local/wxWidgets/lib/wx/include/gtk2-unicode-3.1 -I/usr/local/wxWidgets/include/wx-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LGridComboRenderer.o LGridComboRenderer.cpp
${OBJECTDIR}/LGridDateEditor.o: LGridDateEditor.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -g -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -I/usr/local/wxWidgets/lib/wx/include/gtk2-unicode-3.1 -I/usr/local/wxWidgets/include/wx-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LGridDateEditor.o LGridDateEditor.cpp
${OBJECTDIR}/LGridDateRenderer.o: LGridDateRenderer.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -g -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -I/usr/local/wxWidgets/lib/wx/include/gtk2-unicode-3.1 -I/usr/local/wxWidgets/include/wx-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LGridDateRenderer.o LGridDateRenderer.cpp
${OBJECTDIR}/LGridSpinEditor.o: LGridSpinEditor.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -g -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -I/usr/local/wxWidgets/lib/wx/include/gtk2-unicode-3.1 -I/usr/local/wxWidgets/include/wx-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LGridSpinEditor.o LGridSpinEditor.cpp
${OBJECTDIR}/LGridSpinRenderer.o: LGridSpinRenderer.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -g -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -I/usr/local/wxWidgets/lib/wx/include/gtk2-unicode-3.1 -I/usr/local/wxWidgets/include/wx-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LGridSpinRenderer.o LGridSpinRenderer.cpp
${OBJECTDIR}/LGridTextEditor.o: LGridTextEditor.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -g -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -I/usr/local/wxWidgets/lib/wx/include/gtk2-unicode-3.1 -I/usr/local/wxWidgets/include/wx-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LGridTextEditor.o LGridTextEditor.cpp
${OBJECTDIR}/LGridTextRenderer.o: LGridTextRenderer.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -g -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -I/usr/local/wxWidgets/lib/wx/include/gtk2-unicode-3.1 -I/usr/local/wxWidgets/include/wx-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LGridTextRenderer.o LGridTextRenderer.cpp
${OBJECTDIR}/LInformation.o: LInformation.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -g -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -I/usr/local/wxWidgets/lib/wx/include/gtk2-unicode-3.1 -I/usr/local/wxWidgets/include/wx-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LInformation.o LInformation.cpp
${OBJECTDIR}/LItemData.o: LItemData.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -g -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -I/usr/local/wxWidgets/lib/wx/include/gtk2-unicode-3.1 -I/usr/local/wxWidgets/include/wx-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LItemData.o LItemData.cpp
${OBJECTDIR}/LLightPQResultSet.o: LLightPQResultSet.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -g -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -I/usr/local/wxWidgets/lib/wx/include/gtk2-unicode-3.1 -I/usr/local/wxWidgets/include/wx-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LLightPQResultSet.o LLightPQResultSet.cpp
${OBJECTDIR}/LLightResultSet.o: LLightResultSet.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -g -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -I/usr/local/wxWidgets/lib/wx/include/gtk2-unicode-3.1 -I/usr/local/wxWidgets/include/wx-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LLightResultSet.o LLightResultSet.cpp
${OBJECTDIR}/LLightSQResultSet.o: LLightSQResultSet.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -g -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -I/usr/local/wxWidgets/lib/wx/include/gtk2-unicode-3.1 -I/usr/local/wxWidgets/include/wx-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LLightSQResultSet.o LLightSQResultSet.cpp
${OBJECTDIR}/LNavigator.o: LNavigator.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -g -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -I/usr/local/wxWidgets/lib/wx/include/gtk2-unicode-3.1 -I/usr/local/wxWidgets/include/wx-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LNavigator.o LNavigator.cpp
${OBJECTDIR}/LPQConnection.o: LPQConnection.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -g -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -I/usr/local/wxWidgets/lib/wx/include/gtk2-unicode-3.1 -I/usr/local/wxWidgets/include/wx-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LPQConnection.o LPQConnection.cpp
${OBJECTDIR}/LPQResultSet.o: LPQResultSet.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -g -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -I/usr/local/wxWidgets/lib/wx/include/gtk2-unicode-3.1 -I/usr/local/wxWidgets/include/wx-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LPQResultSet.o LPQResultSet.cpp
${OBJECTDIR}/LResultSet.o: LResultSet.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -g -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -I/usr/local/wxWidgets/lib/wx/include/gtk2-unicode-3.1 -I/usr/local/wxWidgets/include/wx-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LResultSet.o LResultSet.cpp
${OBJECTDIR}/LSQConnection.o: LSQConnection.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -g -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -I/usr/local/wxWidgets/lib/wx/include/gtk2-unicode-3.1 -I/usr/local/wxWidgets/include/wx-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LSQConnection.o LSQConnection.cpp
${OBJECTDIR}/LSQResultSet.o: LSQResultSet.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -g -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -I/usr/local/wxWidgets/lib/wx/include/gtk2-unicode-3.1 -I/usr/local/wxWidgets/include/wx-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LSQResultSet.o LSQResultSet.cpp
${OBJECTDIR}/LSQresult.o: LSQresult.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -g -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -I/usr/local/wxWidgets/lib/wx/include/gtk2-unicode-3.1 -I/usr/local/wxWidgets/include/wx-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LSQresult.o LSQresult.cpp
# Subprojects
.build-subprojects:
# Clean Targets
.clean-conf: ${CLEAN_SUBPROJECTS}
${RM} -r ${CND_BUILDDIR}/${CND_CONF}
# Subprojects
.clean-subprojects:
# Enable dependency checking
.dep.inc: .depcheck-impl
include .dep.inc

View File

@@ -0,0 +1,263 @@
#
# Generated Makefile - do not edit!
#
# Edit the Makefile in the project folder instead (../Makefile). Each target
# has a -pre and a -post target defined where you can add customized code.
#
# This makefile implements configuration specific macros and targets.
# Environment
MKDIR=mkdir
CP=cp
GREP=grep
NM=nm
CCADMIN=CCadmin
RANLIB=ranlib
CC=gcc
CCC=g++
CXX=g++
FC=gfortran
AS=as
# Macros
CND_PLATFORM=GNU-Linux
CND_DLIB_EXT=so
CND_CONF=Release
CND_DISTDIR=dist
CND_BUILDDIR=build
# Include project Makefile
include Makefile
# Object Directory
OBJECTDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}
# Object Files
OBJECTFILES= \
${OBJECTDIR}/LBoundCheckBox.o \
${OBJECTDIR}/LBoundComboBox.o \
${OBJECTDIR}/LBoundControl.o \
${OBJECTDIR}/LBoundDatePickerCtrl.o \
${OBJECTDIR}/LBoundGrid.o \
${OBJECTDIR}/LBoundSpinCtrl.o \
${OBJECTDIR}/LBoundTextCtrl.o \
${OBJECTDIR}/LConnection.o \
${OBJECTDIR}/LGridCheckEditor.o \
${OBJECTDIR}/LGridCheckRenderer.o \
${OBJECTDIR}/LGridColEditor.o \
${OBJECTDIR}/LGridComboEditor.o \
${OBJECTDIR}/LGridComboRenderer.o \
${OBJECTDIR}/LGridDateEditor.o \
${OBJECTDIR}/LGridDateRenderer.o \
${OBJECTDIR}/LGridSpinEditor.o \
${OBJECTDIR}/LGridSpinRenderer.o \
${OBJECTDIR}/LGridTextEditor.o \
${OBJECTDIR}/LGridTextRenderer.o \
${OBJECTDIR}/LInformation.o \
${OBJECTDIR}/LItemData.o \
${OBJECTDIR}/LLightPQResultSet.o \
${OBJECTDIR}/LLightResultSet.o \
${OBJECTDIR}/LLightSQResultSet.o \
${OBJECTDIR}/LNavigator.o \
${OBJECTDIR}/LPQConnection.o \
${OBJECTDIR}/LPQResultSet.o \
${OBJECTDIR}/LResultSet.o \
${OBJECTDIR}/LSQConnection.o \
${OBJECTDIR}/LSQResultSet.o \
${OBJECTDIR}/LSQresult.o
# C Compiler Flags
CFLAGS=
# CC Compiler Flags
CCFLAGS=
CXXFLAGS=
# Fortran Compiler Flags
FFLAGS=
# Assembler Flags
ASFLAGS=
# Link Libraries and Options
LDLIBSOPTIONS=-L/usr/local/wxWidgets-Release/lib -lwx_baseu-3.1 -lwx_gtk2u_core-3.1
# Build Targets
.build-conf: ${BUILD_SUBPROJECTS}
"${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libL7.${CND_DLIB_EXT}
${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libL7.${CND_DLIB_EXT}: ${OBJECTFILES}
${MKDIR} -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}
${LINK.cc} -o ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libL7.${CND_DLIB_EXT} ${OBJECTFILES} ${LDLIBSOPTIONS} -shared -s -fPIC
${OBJECTDIR}/LBoundCheckBox.o: LBoundCheckBox.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -O2 -s -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -DwxDEBUG_LEVEL=0 -I/usr/local/wxWidgets-Release/include/wx-3.1 -I/usr/local/wxWidgets-Release/lib/wx/include/gtk2-unicode-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LBoundCheckBox.o LBoundCheckBox.cpp
${OBJECTDIR}/LBoundComboBox.o: LBoundComboBox.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -O2 -s -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -DwxDEBUG_LEVEL=0 -I/usr/local/wxWidgets-Release/include/wx-3.1 -I/usr/local/wxWidgets-Release/lib/wx/include/gtk2-unicode-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LBoundComboBox.o LBoundComboBox.cpp
${OBJECTDIR}/LBoundControl.o: LBoundControl.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -O2 -s -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -DwxDEBUG_LEVEL=0 -I/usr/local/wxWidgets-Release/include/wx-3.1 -I/usr/local/wxWidgets-Release/lib/wx/include/gtk2-unicode-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LBoundControl.o LBoundControl.cpp
${OBJECTDIR}/LBoundDatePickerCtrl.o: LBoundDatePickerCtrl.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -O2 -s -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -DwxDEBUG_LEVEL=0 -I/usr/local/wxWidgets-Release/include/wx-3.1 -I/usr/local/wxWidgets-Release/lib/wx/include/gtk2-unicode-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LBoundDatePickerCtrl.o LBoundDatePickerCtrl.cpp
${OBJECTDIR}/LBoundGrid.o: LBoundGrid.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -O2 -s -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -DwxDEBUG_LEVEL=0 -I/usr/local/wxWidgets-Release/include/wx-3.1 -I/usr/local/wxWidgets-Release/lib/wx/include/gtk2-unicode-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LBoundGrid.o LBoundGrid.cpp
${OBJECTDIR}/LBoundSpinCtrl.o: LBoundSpinCtrl.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -O2 -s -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -DwxDEBUG_LEVEL=0 -I/usr/local/wxWidgets-Release/include/wx-3.1 -I/usr/local/wxWidgets-Release/lib/wx/include/gtk2-unicode-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LBoundSpinCtrl.o LBoundSpinCtrl.cpp
${OBJECTDIR}/LBoundTextCtrl.o: LBoundTextCtrl.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -O2 -s -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -DwxDEBUG_LEVEL=0 -I/usr/local/wxWidgets-Release/include/wx-3.1 -I/usr/local/wxWidgets-Release/lib/wx/include/gtk2-unicode-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LBoundTextCtrl.o LBoundTextCtrl.cpp
${OBJECTDIR}/LConnection.o: LConnection.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -O2 -s -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -DwxDEBUG_LEVEL=0 -I/usr/local/wxWidgets-Release/include/wx-3.1 -I/usr/local/wxWidgets-Release/lib/wx/include/gtk2-unicode-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LConnection.o LConnection.cpp
${OBJECTDIR}/LGridCheckEditor.o: LGridCheckEditor.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -O2 -s -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -DwxDEBUG_LEVEL=0 -I/usr/local/wxWidgets-Release/include/wx-3.1 -I/usr/local/wxWidgets-Release/lib/wx/include/gtk2-unicode-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LGridCheckEditor.o LGridCheckEditor.cpp
${OBJECTDIR}/LGridCheckRenderer.o: LGridCheckRenderer.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -O2 -s -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -DwxDEBUG_LEVEL=0 -I/usr/local/wxWidgets-Release/include/wx-3.1 -I/usr/local/wxWidgets-Release/lib/wx/include/gtk2-unicode-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LGridCheckRenderer.o LGridCheckRenderer.cpp
${OBJECTDIR}/LGridColEditor.o: LGridColEditor.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -O2 -s -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -DwxDEBUG_LEVEL=0 -I/usr/local/wxWidgets-Release/include/wx-3.1 -I/usr/local/wxWidgets-Release/lib/wx/include/gtk2-unicode-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LGridColEditor.o LGridColEditor.cpp
${OBJECTDIR}/LGridComboEditor.o: LGridComboEditor.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -O2 -s -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -DwxDEBUG_LEVEL=0 -I/usr/local/wxWidgets-Release/include/wx-3.1 -I/usr/local/wxWidgets-Release/lib/wx/include/gtk2-unicode-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LGridComboEditor.o LGridComboEditor.cpp
${OBJECTDIR}/LGridComboRenderer.o: LGridComboRenderer.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -O2 -s -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -DwxDEBUG_LEVEL=0 -I/usr/local/wxWidgets-Release/include/wx-3.1 -I/usr/local/wxWidgets-Release/lib/wx/include/gtk2-unicode-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LGridComboRenderer.o LGridComboRenderer.cpp
${OBJECTDIR}/LGridDateEditor.o: LGridDateEditor.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -O2 -s -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -DwxDEBUG_LEVEL=0 -I/usr/local/wxWidgets-Release/include/wx-3.1 -I/usr/local/wxWidgets-Release/lib/wx/include/gtk2-unicode-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LGridDateEditor.o LGridDateEditor.cpp
${OBJECTDIR}/LGridDateRenderer.o: LGridDateRenderer.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -O2 -s -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -DwxDEBUG_LEVEL=0 -I/usr/local/wxWidgets-Release/include/wx-3.1 -I/usr/local/wxWidgets-Release/lib/wx/include/gtk2-unicode-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LGridDateRenderer.o LGridDateRenderer.cpp
${OBJECTDIR}/LGridSpinEditor.o: LGridSpinEditor.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -O2 -s -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -DwxDEBUG_LEVEL=0 -I/usr/local/wxWidgets-Release/include/wx-3.1 -I/usr/local/wxWidgets-Release/lib/wx/include/gtk2-unicode-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LGridSpinEditor.o LGridSpinEditor.cpp
${OBJECTDIR}/LGridSpinRenderer.o: LGridSpinRenderer.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -O2 -s -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -DwxDEBUG_LEVEL=0 -I/usr/local/wxWidgets-Release/include/wx-3.1 -I/usr/local/wxWidgets-Release/lib/wx/include/gtk2-unicode-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LGridSpinRenderer.o LGridSpinRenderer.cpp
${OBJECTDIR}/LGridTextEditor.o: LGridTextEditor.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -O2 -s -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -DwxDEBUG_LEVEL=0 -I/usr/local/wxWidgets-Release/include/wx-3.1 -I/usr/local/wxWidgets-Release/lib/wx/include/gtk2-unicode-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LGridTextEditor.o LGridTextEditor.cpp
${OBJECTDIR}/LGridTextRenderer.o: LGridTextRenderer.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -O2 -s -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -DwxDEBUG_LEVEL=0 -I/usr/local/wxWidgets-Release/include/wx-3.1 -I/usr/local/wxWidgets-Release/lib/wx/include/gtk2-unicode-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LGridTextRenderer.o LGridTextRenderer.cpp
${OBJECTDIR}/LInformation.o: LInformation.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -O2 -s -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -DwxDEBUG_LEVEL=0 -I/usr/local/wxWidgets-Release/include/wx-3.1 -I/usr/local/wxWidgets-Release/lib/wx/include/gtk2-unicode-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LInformation.o LInformation.cpp
${OBJECTDIR}/LItemData.o: LItemData.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -O2 -s -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -DwxDEBUG_LEVEL=0 -I/usr/local/wxWidgets-Release/include/wx-3.1 -I/usr/local/wxWidgets-Release/lib/wx/include/gtk2-unicode-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LItemData.o LItemData.cpp
${OBJECTDIR}/LLightPQResultSet.o: LLightPQResultSet.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -O2 -s -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -DwxDEBUG_LEVEL=0 -I/usr/local/wxWidgets-Release/include/wx-3.1 -I/usr/local/wxWidgets-Release/lib/wx/include/gtk2-unicode-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LLightPQResultSet.o LLightPQResultSet.cpp
${OBJECTDIR}/LLightResultSet.o: LLightResultSet.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -O2 -s -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -DwxDEBUG_LEVEL=0 -I/usr/local/wxWidgets-Release/include/wx-3.1 -I/usr/local/wxWidgets-Release/lib/wx/include/gtk2-unicode-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LLightResultSet.o LLightResultSet.cpp
${OBJECTDIR}/LLightSQResultSet.o: LLightSQResultSet.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -O2 -s -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -DwxDEBUG_LEVEL=0 -I/usr/local/wxWidgets-Release/include/wx-3.1 -I/usr/local/wxWidgets-Release/lib/wx/include/gtk2-unicode-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LLightSQResultSet.o LLightSQResultSet.cpp
${OBJECTDIR}/LNavigator.o: LNavigator.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -O2 -s -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -DwxDEBUG_LEVEL=0 -I/usr/local/wxWidgets-Release/include/wx-3.1 -I/usr/local/wxWidgets-Release/lib/wx/include/gtk2-unicode-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LNavigator.o LNavigator.cpp
${OBJECTDIR}/LPQConnection.o: LPQConnection.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -O2 -s -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -DwxDEBUG_LEVEL=0 -I/usr/local/wxWidgets-Release/include/wx-3.1 -I/usr/local/wxWidgets-Release/lib/wx/include/gtk2-unicode-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LPQConnection.o LPQConnection.cpp
${OBJECTDIR}/LPQResultSet.o: LPQResultSet.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -O2 -s -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -DwxDEBUG_LEVEL=0 -I/usr/local/wxWidgets-Release/include/wx-3.1 -I/usr/local/wxWidgets-Release/lib/wx/include/gtk2-unicode-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LPQResultSet.o LPQResultSet.cpp
${OBJECTDIR}/LResultSet.o: LResultSet.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -O2 -s -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -DwxDEBUG_LEVEL=0 -I/usr/local/wxWidgets-Release/include/wx-3.1 -I/usr/local/wxWidgets-Release/lib/wx/include/gtk2-unicode-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LResultSet.o LResultSet.cpp
${OBJECTDIR}/LSQConnection.o: LSQConnection.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -O2 -s -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -DwxDEBUG_LEVEL=0 -I/usr/local/wxWidgets-Release/include/wx-3.1 -I/usr/local/wxWidgets-Release/lib/wx/include/gtk2-unicode-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LSQConnection.o LSQConnection.cpp
${OBJECTDIR}/LSQResultSet.o: LSQResultSet.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -O2 -s -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -DwxDEBUG_LEVEL=0 -I/usr/local/wxWidgets-Release/include/wx-3.1 -I/usr/local/wxWidgets-Release/lib/wx/include/gtk2-unicode-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LSQResultSet.o LSQResultSet.cpp
${OBJECTDIR}/LSQresult.o: LSQresult.cpp
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.cc) -O2 -s -DUSE_LIBPQ -DUSE_LIBSQ -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXGTK__ -DwxDEBUG_LEVEL=0 -I/usr/local/wxWidgets-Release/include/wx-3.1 -I/usr/local/wxWidgets-Release/lib/wx/include/gtk2-unicode-3.1 -fPIC -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LSQresult.o LSQresult.cpp
# Subprojects
.build-subprojects:
# Clean Targets
.clean-conf: ${CLEAN_SUBPROJECTS}
${RM} -r ${CND_BUILDDIR}/${CND_CONF}
# Subprojects
.clean-subprojects:
# Enable dependency checking
.dep.inc: .depcheck-impl
include .dep.inc

View File

@@ -0,0 +1,133 @@
#
# Generated Makefile - do not edit!
#
# Edit the Makefile in the project folder instead (../Makefile). Each target
# has a pre- and a post- target defined where you can add customization code.
#
# This makefile implements macros and targets common to all configurations.
#
# NOCDDL
# Building and Cleaning subprojects are done by default, but can be controlled with the SUB
# macro. If SUB=no, subprojects will not be built or cleaned. The following macro
# statements set BUILD_SUB-CONF and CLEAN_SUB-CONF to .build-reqprojects-conf
# and .clean-reqprojects-conf unless SUB has the value 'no'
SUB_no=NO
SUBPROJECTS=${SUB_${SUB}}
BUILD_SUBPROJECTS_=.build-subprojects
BUILD_SUBPROJECTS_NO=
BUILD_SUBPROJECTS=${BUILD_SUBPROJECTS_${SUBPROJECTS}}
CLEAN_SUBPROJECTS_=.clean-subprojects
CLEAN_SUBPROJECTS_NO=
CLEAN_SUBPROJECTS=${CLEAN_SUBPROJECTS_${SUBPROJECTS}}
# Project Name
PROJECTNAME=L7
# Active Configuration
DEFAULTCONF=Debug
CONF=${DEFAULTCONF}
# All Configurations
ALLCONFS=Debug Release
# build
.build-impl: .build-pre .validate-impl .depcheck-impl
@#echo "=> Running $@... Configuration=$(CONF)"
"${MAKE}" -f nbproject/Makefile-${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .build-conf
# clean
.clean-impl: .clean-pre .validate-impl .depcheck-impl
@#echo "=> Running $@... Configuration=$(CONF)"
"${MAKE}" -f nbproject/Makefile-${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .clean-conf
# clobber
.clobber-impl: .clobber-pre .depcheck-impl
@#echo "=> Running $@..."
for CONF in ${ALLCONFS}; \
do \
"${MAKE}" -f nbproject/Makefile-$${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .clean-conf; \
done
# all
.all-impl: .all-pre .depcheck-impl
@#echo "=> Running $@..."
for CONF in ${ALLCONFS}; \
do \
"${MAKE}" -f nbproject/Makefile-$${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .build-conf; \
done
# build tests
.build-tests-impl: .build-impl .build-tests-pre
@#echo "=> Running $@... Configuration=$(CONF)"
"${MAKE}" -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .build-tests-conf
# run tests
.test-impl: .build-tests-impl .test-pre
@#echo "=> Running $@... Configuration=$(CONF)"
"${MAKE}" -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .test-conf
# dependency checking support
.depcheck-impl:
@echo "# This code depends on make tool being used" >.dep.inc
@if [ -n "${MAKE_VERSION}" ]; then \
echo "DEPFILES=\$$(wildcard \$$(addsuffix .d, \$${OBJECTFILES} \$${TESTOBJECTFILES}))" >>.dep.inc; \
echo "ifneq (\$${DEPFILES},)" >>.dep.inc; \
echo "include \$${DEPFILES}" >>.dep.inc; \
echo "endif" >>.dep.inc; \
else \
echo ".KEEP_STATE:" >>.dep.inc; \
echo ".KEEP_STATE_FILE:.make.state.\$${CONF}" >>.dep.inc; \
fi
# configuration validation
.validate-impl:
@if [ ! -f nbproject/Makefile-${CONF}.mk ]; \
then \
echo ""; \
echo "Error: can not find the makefile for configuration '${CONF}' in project ${PROJECTNAME}"; \
echo "See 'make help' for details."; \
echo "Current directory: " `pwd`; \
echo ""; \
fi
@if [ ! -f nbproject/Makefile-${CONF}.mk ]; \
then \
exit 1; \
fi
# help
.help-impl: .help-pre
@echo "This makefile supports the following configurations:"
@echo " ${ALLCONFS}"
@echo ""
@echo "and the following targets:"
@echo " build (default target)"
@echo " clean"
@echo " clobber"
@echo " all"
@echo " help"
@echo ""
@echo "Makefile Usage:"
@echo " make [CONF=<CONFIGURATION>] [SUB=no] build"
@echo " make [CONF=<CONFIGURATION>] [SUB=no] clean"
@echo " make [SUB=no] clobber"
@echo " make [SUB=no] all"
@echo " make help"
@echo ""
@echo "Target 'build' will build a specific configuration and, unless 'SUB=no',"
@echo " also build subprojects."
@echo "Target 'clean' will clean a specific configuration and, unless 'SUB=no',"
@echo " also clean subprojects."
@echo "Target 'clobber' will remove all built files from all configurations and,"
@echo " unless 'SUB=no', also from subprojects."
@echo "Target 'all' will will build all configurations and, unless 'SUB=no',"
@echo " also build subprojects."
@echo "Target 'help' prints this message."
@echo ""

View File

@@ -0,0 +1,35 @@
#
# Generated - do not edit!
#
# NOCDDL
#
CND_BASEDIR=`pwd`
CND_BUILDDIR=build
CND_DISTDIR=dist
# Debug configuration
CND_PLATFORM_Debug=GNU-Linux
CND_ARTIFACT_DIR_Debug=dist/Debug/GNU-Linux
CND_ARTIFACT_NAME_Debug=libL7.so
CND_ARTIFACT_PATH_Debug=dist/Debug/GNU-Linux/libL7.so
CND_PACKAGE_DIR_Debug=dist/Debug/GNU-Linux/package
CND_PACKAGE_NAME_Debug=libL7.so.tar
CND_PACKAGE_PATH_Debug=dist/Debug/GNU-Linux/package/libL7.so.tar
# Release configuration
CND_PLATFORM_Release=GNU-Linux
CND_ARTIFACT_DIR_Release=dist/Release/GNU-Linux
CND_ARTIFACT_NAME_Release=libL7.so
CND_ARTIFACT_PATH_Release=dist/Release/GNU-Linux/libL7.so
CND_PACKAGE_DIR_Release=dist/Release/GNU-Linux/package
CND_PACKAGE_NAME_Release=libL7.so.tar
CND_PACKAGE_PATH_Release=dist/Release/GNU-Linux/package/libL7.so.tar
#
# include compiler specific variables
#
# dmake command
ROOT:sh = test -f nbproject/private/Makefile-variables.mk || \
(mkdir -p nbproject/private && touch nbproject/private/Makefile-variables.mk)
#
# gmake command
.PHONY: $(shell test -f nbproject/private/Makefile-variables.mk || (mkdir -p nbproject/private && touch nbproject/private/Makefile-variables.mk))
#
include nbproject/private/Makefile-variables.mk

View File

@@ -0,0 +1,76 @@
#!/bin/bash -x
#
# Generated - do not edit!
#
# Macros
TOP=`pwd`
CND_PLATFORM=GNU-Linux
CND_CONF=Debug
CND_DISTDIR=dist
CND_BUILDDIR=build
CND_DLIB_EXT=so
NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging
TMPDIRNAME=tmp-packaging
OUTPUT_PATH=${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libL7.${CND_DLIB_EXT}
OUTPUT_BASENAME=libL7.${CND_DLIB_EXT}
PACKAGE_TOP_DIR=libL7.so/
# Functions
function checkReturnCode
{
rc=$?
if [ $rc != 0 ]
then
exit $rc
fi
}
function makeDirectory
# $1 directory path
# $2 permission (optional)
{
mkdir -p "$1"
checkReturnCode
if [ "$2" != "" ]
then
chmod $2 "$1"
checkReturnCode
fi
}
function copyFileToTmpDir
# $1 from-file path
# $2 to-file path
# $3 permission
{
cp "$1" "$2"
checkReturnCode
if [ "$3" != "" ]
then
chmod $3 "$2"
checkReturnCode
fi
}
# Setup
cd "${TOP}"
mkdir -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package
rm -rf ${NBTMPDIR}
mkdir -p ${NBTMPDIR}
# Copy files and create directories and links
cd "${TOP}"
makeDirectory "${NBTMPDIR}/libL7.so/lib"
copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}lib/${OUTPUT_BASENAME}" 0644
# Generate tar file
cd "${TOP}"
rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/libL7.so.tar
cd ${NBTMPDIR}
tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/libL7.so.tar *
checkReturnCode
# Cleanup
cd "${TOP}"
rm -rf ${NBTMPDIR}

View File

@@ -0,0 +1,76 @@
#!/bin/bash -x
#
# Generated - do not edit!
#
# Macros
TOP=`pwd`
CND_PLATFORM=GNU-Linux
CND_CONF=Release
CND_DISTDIR=dist
CND_BUILDDIR=build
CND_DLIB_EXT=so
NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging
TMPDIRNAME=tmp-packaging
OUTPUT_PATH=${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libL7.${CND_DLIB_EXT}
OUTPUT_BASENAME=libL7.${CND_DLIB_EXT}
PACKAGE_TOP_DIR=libL7.so/
# Functions
function checkReturnCode
{
rc=$?
if [ $rc != 0 ]
then
exit $rc
fi
}
function makeDirectory
# $1 directory path
# $2 permission (optional)
{
mkdir -p "$1"
checkReturnCode
if [ "$2" != "" ]
then
chmod $2 "$1"
checkReturnCode
fi
}
function copyFileToTmpDir
# $1 from-file path
# $2 to-file path
# $3 permission
{
cp "$1" "$2"
checkReturnCode
if [ "$3" != "" ]
then
chmod $3 "$2"
checkReturnCode
fi
}
# Setup
cd "${TOP}"
mkdir -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package
rm -rf ${NBTMPDIR}
mkdir -p ${NBTMPDIR}
# Copy files and create directories and links
cd "${TOP}"
makeDirectory "${NBTMPDIR}/libL7.so/lib"
copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}lib/${OUTPUT_BASENAME}" 0644
# Generate tar file
cd "${TOP}"
rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/libL7.so.tar
cd ${NBTMPDIR}
tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/libL7.so.tar *
checkReturnCode
# Cleanup
cd "${TOP}"
rm -rf ${NBTMPDIR}

View File

@@ -0,0 +1,422 @@
<?xml version="1.0" encoding="UTF-8"?>
<configurationDescriptor version="100">
<logicalFolder name="root" displayName="root" projectFiles="true" kind="ROOT">
<logicalFolder name="HeaderFiles"
displayName="Header Files"
projectFiles="true">
<itemPath>LBoundCheckBox.h</itemPath>
<itemPath>LBoundComboBox.h</itemPath>
<itemPath>LBoundControl.h</itemPath>
<itemPath>LBoundDatePickerCtrl.h</itemPath>
<itemPath>LBoundGrid.h</itemPath>
<itemPath>LBoundSpinCtrl.h</itemPath>
<itemPath>LBoundTextCtrl.h</itemPath>
<itemPath>LConnection.h</itemPath>
<itemPath>LGridCheckEditor.h</itemPath>
<itemPath>LGridCheckRenderer.h</itemPath>
<itemPath>LGridColEditor.h</itemPath>
<itemPath>LGridComboEditor.h</itemPath>
<itemPath>LGridComboRenderer.h</itemPath>
<itemPath>LGridDateEditor.h</itemPath>
<itemPath>LGridDateRenderer.h</itemPath>
<itemPath>LGridSpinEditor.h</itemPath>
<itemPath>LGridSpinRenderer.h</itemPath>
<itemPath>LGridTextEditor.h</itemPath>
<itemPath>LGridTextRenderer.h</itemPath>
<itemPath>LInformation.h</itemPath>
<itemPath>LItemData.h</itemPath>
<itemPath>LLightPQResultSet.h</itemPath>
<itemPath>LLightResultSet.h</itemPath>
<itemPath>LLightSQResultSet.h</itemPath>
<itemPath>LNavigator.h</itemPath>
<itemPath>LPQConnection.h</itemPath>
<itemPath>LPQResultSet.h</itemPath>
<itemPath>LResultSet.h</itemPath>
<itemPath>LSQConnection.h</itemPath>
<itemPath>LSQResultSet.h</itemPath>
<itemPath>LSQresult.h</itemPath>
<itemPath>LVersion.h</itemPath>
</logicalFolder>
<logicalFolder name="ResourceFiles"
displayName="Resource Files"
projectFiles="true">
</logicalFolder>
<logicalFolder name="SourceFiles"
displayName="Source Files"
projectFiles="true">
<itemPath>LBoundCheckBox.cpp</itemPath>
<itemPath>LBoundComboBox.cpp</itemPath>
<itemPath>LBoundControl.cpp</itemPath>
<itemPath>LBoundDatePickerCtrl.cpp</itemPath>
<itemPath>LBoundGrid.cpp</itemPath>
<itemPath>LBoundSpinCtrl.cpp</itemPath>
<itemPath>LBoundTextCtrl.cpp</itemPath>
<itemPath>LConnection.cpp</itemPath>
<itemPath>LGridCheckEditor.cpp</itemPath>
<itemPath>LGridCheckRenderer.cpp</itemPath>
<itemPath>LGridColEditor.cpp</itemPath>
<itemPath>LGridComboEditor.cpp</itemPath>
<itemPath>LGridComboRenderer.cpp</itemPath>
<itemPath>LGridDateEditor.cpp</itemPath>
<itemPath>LGridDateRenderer.cpp</itemPath>
<itemPath>LGridSpinEditor.cpp</itemPath>
<itemPath>LGridSpinRenderer.cpp</itemPath>
<itemPath>LGridTextEditor.cpp</itemPath>
<itemPath>LGridTextRenderer.cpp</itemPath>
<itemPath>LInformation.cpp</itemPath>
<itemPath>LItemData.cpp</itemPath>
<itemPath>LLightPQResultSet.cpp</itemPath>
<itemPath>LLightResultSet.cpp</itemPath>
<itemPath>LLightSQResultSet.cpp</itemPath>
<itemPath>LNavigator.cpp</itemPath>
<itemPath>LPQConnection.cpp</itemPath>
<itemPath>LPQResultSet.cpp</itemPath>
<itemPath>LResultSet.cpp</itemPath>
<itemPath>LSQConnection.cpp</itemPath>
<itemPath>LSQResultSet.cpp</itemPath>
<itemPath>LSQresult.cpp</itemPath>
</logicalFolder>
<logicalFolder name="TestFiles"
displayName="Test Files"
projectFiles="false"
kind="TEST_LOGICAL_FOLDER">
</logicalFolder>
<logicalFolder name="ExternalFiles"
displayName="Important Files"
projectFiles="false"
kind="IMPORTANT_FILES_FOLDER">
<itemPath>Makefile</itemPath>
</logicalFolder>
</logicalFolder>
<projectmakefile>Makefile</projectmakefile>
<confs>
<conf name="Debug" type="2">
<toolsSet>
<compilerSet>default</compilerSet>
<dependencyChecking>true</dependencyChecking>
<rebuildPropChanged>false</rebuildPropChanged>
</toolsSet>
<compileType>
<ccTool>
<incDir>
<pElem>/usr/local/wxWidgets/lib/wx/include/gtk2-unicode-3.1</pElem>
<pElem>/usr/local/wxWidgets/include/wx-3.1</pElem>
</incDir>
<preprocessorList>
<Elem>USE_LIBPQ</Elem>
<Elem>USE_LIBSQ</Elem>
<Elem>WXUSINGDLL</Elem>
<Elem>_FILE_OFFSET_BITS=64</Elem>
<Elem>__WXGTK__</Elem>
</preprocessorList>
</ccTool>
<linkerTool>
<linkerAddLib>
<pElem>/usr/local/wxWidgets/lib</pElem>
</linkerAddLib>
<commandlineTool>g++</commandlineTool>
<linkerLibItems>
<linkerLibLibItem>wx_baseu-3.1</linkerLibLibItem>
<linkerLibLibItem>wx_gtk2u_core-3.1</linkerLibLibItem>
</linkerLibItems>
</linkerTool>
</compileType>
<item path="LBoundCheckBox.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LBoundCheckBox.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LBoundComboBox.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LBoundComboBox.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LBoundControl.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LBoundControl.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LBoundDatePickerCtrl.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LBoundDatePickerCtrl.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LBoundGrid.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LBoundGrid.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LBoundSpinCtrl.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LBoundSpinCtrl.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LBoundTextCtrl.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LBoundTextCtrl.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LConnection.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LConnection.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LGridCheckEditor.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LGridCheckEditor.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LGridCheckRenderer.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LGridCheckRenderer.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LGridColEditor.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LGridColEditor.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LGridComboEditor.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LGridComboEditor.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LGridComboRenderer.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LGridComboRenderer.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LGridDateEditor.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LGridDateEditor.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LGridDateRenderer.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LGridDateRenderer.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LGridSpinEditor.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LGridSpinEditor.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LGridSpinRenderer.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LGridSpinRenderer.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LGridTextEditor.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LGridTextEditor.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LGridTextRenderer.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LGridTextRenderer.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LInformation.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LInformation.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LItemData.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LItemData.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LLightPQResultSet.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LLightPQResultSet.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LLightResultSet.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LLightResultSet.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LLightSQResultSet.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LLightSQResultSet.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LNavigator.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LNavigator.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LPQConnection.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LPQConnection.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LPQResultSet.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LPQResultSet.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LResultSet.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LResultSet.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LSQConnection.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LSQConnection.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LSQResultSet.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LSQResultSet.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LSQresult.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LSQresult.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LVersion.h" ex="false" tool="3" flavor2="0">
</item>
</conf>
<conf name="Release" type="2">
<toolsSet>
<compilerSet>default</compilerSet>
<dependencyChecking>true</dependencyChecking>
<rebuildPropChanged>false</rebuildPropChanged>
</toolsSet>
<compileType>
<cTool>
<developmentMode>5</developmentMode>
</cTool>
<ccTool>
<developmentMode>5</developmentMode>
<stripSymbols>true</stripSymbols>
<incDir>
<pElem>/usr/local/wxWidgets-Release/include/wx-3.1</pElem>
<pElem>/usr/local/wxWidgets-Release/lib/wx/include/gtk2-unicode-3.1</pElem>
</incDir>
<preprocessorList>
<Elem>USE_LIBPQ</Elem>
<Elem>USE_LIBSQ</Elem>
<Elem>WXUSINGDLL</Elem>
<Elem>_FILE_OFFSET_BITS=64</Elem>
<Elem>__WXGTK__</Elem>
<Elem>wxDEBUG_LEVEL=0</Elem>
</preprocessorList>
</ccTool>
<fortranCompilerTool>
<developmentMode>5</developmentMode>
</fortranCompilerTool>
<asmTool>
<developmentMode>5</developmentMode>
</asmTool>
<linkerTool>
<linkerAddLib>
<pElem>/usr/local/wxWidgets-Release/lib</pElem>
</linkerAddLib>
<stripSymbols>true</stripSymbols>
<linkerLibItems>
<linkerLibLibItem>wx_baseu-3.1</linkerLibLibItem>
<linkerLibLibItem>wx_gtk2u_core-3.1</linkerLibLibItem>
</linkerLibItems>
</linkerTool>
</compileType>
<item path="LBoundCheckBox.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LBoundCheckBox.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LBoundComboBox.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LBoundComboBox.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LBoundControl.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LBoundControl.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LBoundDatePickerCtrl.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LBoundDatePickerCtrl.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LBoundGrid.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LBoundGrid.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LBoundSpinCtrl.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LBoundSpinCtrl.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LBoundTextCtrl.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LBoundTextCtrl.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LConnection.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LConnection.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LGridCheckEditor.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LGridCheckEditor.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LGridCheckRenderer.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LGridCheckRenderer.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LGridColEditor.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LGridColEditor.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LGridComboEditor.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LGridComboEditor.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LGridComboRenderer.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LGridComboRenderer.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LGridDateEditor.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LGridDateEditor.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LGridDateRenderer.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LGridDateRenderer.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LGridSpinEditor.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LGridSpinEditor.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LGridSpinRenderer.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LGridSpinRenderer.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LGridTextEditor.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LGridTextEditor.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LGridTextRenderer.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LGridTextRenderer.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LInformation.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LInformation.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LItemData.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LItemData.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LLightPQResultSet.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LLightPQResultSet.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LLightResultSet.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LLightResultSet.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LLightSQResultSet.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LLightSQResultSet.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LNavigator.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LNavigator.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LPQConnection.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LPQConnection.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LPQResultSet.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LPQResultSet.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LResultSet.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LResultSet.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LSQConnection.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LSQConnection.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LSQResultSet.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LSQResultSet.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LSQresult.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="LSQresult.h" ex="false" tool="3" flavor2="0">
</item>
<item path="LVersion.h" ex="false" tool="3" flavor2="0">
</item>
</conf>
</confs>
</configurationDescriptor>

View File

@@ -0,0 +1,7 @@
#
# Generated - do not edit!
#
# NOCDDL
#
# Debug configuration
# Release configuration

View File

@@ -0,0 +1,75 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved.
*
* Oracle and Java are registered trademarks of Oracle and/or its affiliates.
* Other names may be trademarks of their respective owners.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common
* Development and Distribution License("CDDL") (collectively, the
* "License"). You may not use this file except in compliance with the
* License. You can obtain a copy of the License at
* http://www.netbeans.org/cddl-gplv2.html
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
* specific language governing permissions and limitations under the
* License. When distributing the software, include this License Header
* Notice in each file and include the License file at
* nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the GPL Version 2 section of the License file that
* accompanied this code. If applicable, add the following below the
* License Header, with the fields enclosed by brackets [] replaced by
* your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* If you wish your version of this file to be governed by only the CDDL
* or only the GPL Version 2, indicate your decision by adding
* "[Contributor] elects to include this software in this distribution
* under the [CDDL or GPL Version 2] license." If you do not indicate a
* single choice of license, a recipient has the option to distribute
* your version of this file under either the CDDL, the GPL Version 2 or
* to extend the choice of license to its licensees as provided above.
* However, if you add GPL Version 2 code and therefore, elected the GPL
* Version 2 license, then the option applies only if the new code is
* made subject to such option by the copyright holder.
*
* Contributor(s):
*/
// List of standard headers was taken in http://en.cppreference.com/w/c/header
#include <assert.h> // Conditionally compiled macro that compares its argument to zero
#include <ctype.h> // Functions to determine the type contained in character data
#include <errno.h> // Macros reporting error conditions
#include <float.h> // Limits of float types
#include <limits.h> // Sizes of basic types
#include <locale.h> // Localization utilities
#include <math.h> // Common mathematics functions
#include <setjmp.h> // Nonlocal jumps
#include <signal.h> // Signal handling
#include <stdarg.h> // Variable arguments
#include <stddef.h> // Common macro definitions
#include <stdio.h> // Input/output
#include <string.h> // String handling
#include <stdlib.h> // General utilities: memory management, program utilities, string conversions, random numbers
#include <time.h> // Time/date utilities
#include <iso646.h> // (since C95) Alternative operator spellings
#include <wchar.h> // (since C95) Extended multibyte and wide character utilities
#include <wctype.h> // (since C95) Wide character classification and mapping utilities
#ifdef _STDC_C99
#include <complex.h> // (since C99) Complex number arithmetic
#include <fenv.h> // (since C99) Floating-point environment
#include <inttypes.h> // (since C99) Format conversion of integer types
#include <stdbool.h> // (since C99) Boolean type
#include <stdint.h> // (since C99) Fixed-width integer types
#include <tgmath.h> // (since C99) Type-generic math (macros wrapping math.h and complex.h)
#endif
#ifdef _STDC_C11
#include <stdalign.h> // (since C11) alignas and alignof convenience macros
#include <stdatomic.h> // (since C11) Atomic types
#include <stdnoreturn.h> // (since C11) noreturn convenience macros
#include <threads.h> // (since C11) Thread library
#include <uchar.h> // (since C11) UTF-16 and UTF-32 character utilities
#endif

View File

@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8"?>
<configurationDescriptor version="100">
<projectmakefile>Makefile</projectmakefile>
<confs>
<conf name="Debug" type="2">
<toolsSet>
<developmentServer>localhost</developmentServer>
<platform>2</platform>
</toolsSet>
<dbx_gdbdebugger version="1">
<gdb_pathmaps>
</gdb_pathmaps>
<gdb_interceptlist>
<gdbinterceptoptions gdb_all="false" gdb_unhandled="true" gdb_unexpected="true"/>
</gdb_interceptlist>
<gdb_options>
<DebugOptions>
</DebugOptions>
</gdb_options>
<gdb_buildfirst gdb_buildfirst_overriden="false" gdb_buildfirst_old="false"/>
</dbx_gdbdebugger>
<nativedebugger version="1">
<engine>gdb</engine>
</nativedebugger>
<runprofile version="9">
<runcommandpicklist>
<runcommandpicklistitem>"${OUTPUT_PATH}"</runcommandpicklistitem>
</runcommandpicklist>
<runcommand>"${OUTPUT_PATH}"</runcommand>
<rundir></rundir>
<buildfirst>true</buildfirst>
<terminal-type>0</terminal-type>
<remove-instrumentation>0</remove-instrumentation>
<environment>
</environment>
</runprofile>
</conf>
<conf name="Release" type="2">
<toolsSet>
<developmentServer>localhost</developmentServer>
<platform>2</platform>
</toolsSet>
<dbx_gdbdebugger version="1">
<gdb_pathmaps>
</gdb_pathmaps>
<gdb_interceptlist>
<gdbinterceptoptions gdb_all="false" gdb_unhandled="true" gdb_unexpected="true"/>
</gdb_interceptlist>
<gdb_options>
<DebugOptions>
</DebugOptions>
</gdb_options>
<gdb_buildfirst gdb_buildfirst_overriden="false" gdb_buildfirst_old="false"/>
</dbx_gdbdebugger>
<nativedebugger version="1">
<engine>gdb</engine>
</nativedebugger>
<runprofile version="9">
<runcommandpicklist>
<runcommandpicklistitem>"${OUTPUT_PATH}"</runcommandpicklistitem>
</runcommandpicklist>
<runcommand>"${OUTPUT_PATH}"</runcommand>
<rundir></rundir>
<buildfirst>true</buildfirst>
<terminal-type>0</terminal-type>
<remove-instrumentation>0</remove-instrumentation>
<environment>
<variable name="LD_LIBRARY_PATH" value="/usr/local/wxWidgets-Release/lib"/>
</environment>
</runprofile>
</conf>
</confs>
</configurationDescriptor>

View File

@@ -0,0 +1,135 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved.
*
* Oracle and Java are registered trademarks of Oracle and/or its affiliates.
* Other names may be trademarks of their respective owners.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common
* Development and Distribution License("CDDL") (collectively, the
* "License"). You may not use this file except in compliance with the
* License. You can obtain a copy of the License at
* http://www.netbeans.org/cddl-gplv2.html
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
* specific language governing permissions and limitations under the
* License. When distributing the software, include this License Header
* Notice in each file and include the License file at
* nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the GPL Version 2 section of the License file that
* accompanied this code. If applicable, add the following below the
* License Header, with the fields enclosed by brackets [] replaced by
* your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* If you wish your version of this file to be governed by only the CDDL
* or only the GPL Version 2, indicate your decision by adding
* "[Contributor] elects to include this software in this distribution
* under the [CDDL or GPL Version 2] license." If you do not indicate a
* single choice of license, a recipient has the option to distribute
* your version of this file under either the CDDL, the GPL Version 2 or
* to extend the choice of license to its licensees as provided above.
* However, if you add GPL Version 2 code and therefore, elected the GPL
* Version 2 license, then the option applies only if the new code is
* made subject to such option by the copyright holder.
*
* Contributor(s):
*/
// List of standard headers was taken in http://en.cppreference.com/w/cpp/header
#include <cstdlib> // General purpose utilities: program control, dynamic memory allocation, random numbers, sort and search
#include <csignal> // Functions and macro constants for signal management
#include <csetjmp> // Macro (and function) that saves (and jumps) to an execution context
#include <cstdarg> // Handling of variable length argument lists
#include <typeinfo> // Runtime type information utilities
#include <bitset> // std::bitset class template
#include <functional> // Function objects, designed for use with the standard algorithms
#include <utility> // Various utility components
#include <ctime> // C-style time/date utilites
#include <cstddef> // typedefs for types such as size_t, NULL and others
#include <new> // Low-level memory management utilities
#include <memory> // Higher level memory management utilities
#include <climits> // limits of integral types
#include <cfloat> // limits of float types
#include <limits> // standardized way to query properties of arithmetic types
#include <exception> // Exception handling utilities
#include <stdexcept> // Standard exception objects
#include <cassert> // Conditionally compiled macro that compares its argument to zero
#include <cerrno> // Macro containing the last error number
#include <cctype> // functions to determine the type contained in character data
#include <cwctype> // functions for determining the type of wide character data
#include <cstring> // various narrow character string handling functions
#include <cwchar> // various wide and multibyte string handling functions
#include <string> // std::basic_string class template
#include <vector> // std::vector container
#include <deque> // std::deque container
#include <list> // std::list container
#include <set> // std::set and std::multiset associative containers
#include <map> // std::map and std::multimap associative containers
#include <stack> // std::stack container adaptor
#include <queue> // std::queue and std::priority_queue container adaptors
#include <algorithm> // Algorithms that operate on containers
#include <iterator> // Container iterators
#include <cmath> // Common mathematics functions
#include <complex> // Complex number type
#include <valarray> // Class for representing and manipulating arrays of values
#include <numeric> // Numeric operations on values in containers
#include <iosfwd> // forward declarations of all classes in the input/output library
#include <ios> // std::ios_base class, std::basic_ios class template and several typedefs
#include <istream> // std::basic_istream class template and several typedefs
#include <ostream> // std::basic_ostream, std::basic_iostream class templates and several typedefs
#include <iostream> // several standard stream objects
#include <fstream> // std::basic_fstream, std::basic_ifstream, std::basic_ofstream class templates and several typedefs
#include <sstream> // std::basic_stringstream, std::basic_istringstream, std::basic_ostringstream class templates and several typedefs
#include <strstream> // std::strstream, std::istrstream, std::ostrstream(deprecated)
#include <iomanip> // Helper functions to control the format or input and output
#include <streambuf> // std::basic_streambuf class template
#include <cstdio> // C-style input-output functions
#include <locale> // Localization utilities
#include <clocale> // C localization utilities
#include <ciso646> // empty header. The macros that appear in iso646.h in C are keywords in C++
#if __cplusplus >= 201103L
#include <typeindex> // (since C++11) std::type_index
#include <type_traits> // (since C++11) Compile-time type information
#include <chrono> // (since C++11) C++ time utilites
#include <initializer_list> // (since C++11) std::initializer_list class template
#include <tuple> // (since C++11) std::tuple class template
#include <scoped_allocator> // (since C++11) Nested allocator class
#include <cstdint> // (since C++11) fixed-size types and limits of other types
#include <cinttypes> // (since C++11) formatting macros , intmax_t and uintmax_t math and conversions
#include <system_error> // (since C++11) defines std::error_code, a platform-dependent error code
#include <cuchar> // (since C++11) C-style Unicode character conversion functions
#include <array> // (since C++11) std::array container
#include <forward_list> // (since C++11) std::forward_list container
#include <unordered_set> // (since C++11) std::unordered_set and std::unordered_multiset unordered associative containers
#include <unordered_map> // (since C++11) std::unordered_map and std::unordered_multimap unordered associative containers
#include <random> // (since C++11) Random number generators and distributions
#include <ratio> // (since C++11) Compile-time rational arithmetic
#include <cfenv> // (since C++11) Floating-point environment access functions
#include <codecvt> // (since C++11) Unicode conversion facilities
#include <regex> // (since C++11) Classes, algorithms and iterators to support regular expression processing
#include <atomic> // (since C++11) Atomic operations library
#include <ccomplex> // (since C++11)(deprecated in C++17) simply includes the header <complex>
#include <ctgmath> // (since C++11)(deprecated in C++17) simply includes the headers <ccomplex> (until C++17)<complex> (since C++17) and <cmath>: the overloads equivalent to the contents of the C header tgmath.h are already provided by those headers
#include <cstdalign> // (since C++11)(deprecated in C++17) defines one compatibility macro constant
#include <cstdbool> // (since C++11)(deprecated in C++17) defines one compatibility macro constant
#include <thread> // (since C++11) std::thread class and supporting functions
#include <mutex> // (since C++11) mutual exclusion primitives
#include <future> // (since C++11) primitives for asynchronous computations
#include <condition_variable> // (since C++11) thread waiting conditions
#endif
#if __cplusplus >= 201300L
#include <shared_mutex> // (since C++14) shared mutual exclusion primitives
#endif
#if __cplusplus >= 201500L
#include <any> // (since C++17) std::any class template
#include <optional> // (since C++17) std::optional class template
#include <variant> // (since C++17) std::variant class template
#include <memory_resource> // (since C++17) Polymorphic allocators and memory resources
#include <string_view> // (since C++17) std::basic_string_view class template
#include <execution> // (since C++17) Predefined execution policies for parallel versions of the algorithms
#include <filesystem> // (since C++17) std::path class and supporting functions
#endif

View File

@@ -0,0 +1,40 @@
# Launchers File syntax:
#
# [Must-have property line]
# launcher1.runCommand=<Run Command>
# [Optional extra properties]
# launcher1.displayName=<Display Name, runCommand by default>
# launcher1.buildCommand=<Build Command, Build Command specified in project properties by default>
# launcher1.runDir=<Run Directory, ${PROJECT_DIR} by default>
# launcher1.symbolFiles=<Symbol Files loaded by debugger, ${OUTPUT_PATH} by default>
# launcher1.env.<Environment variable KEY>=<Environment variable VALUE>
# (If this value is quoted with ` it is handled as a native command which execution result will become the value)
# [Common launcher properties]
# common.runDir=<Run Directory>
# (This value is overwritten by a launcher specific runDir value if the latter exists)
# common.env.<Environment variable KEY>=<Environment variable VALUE>
# (Environment variables from common launcher are merged with launcher specific variables)
# common.symbolFiles=<Symbol Files loaded by debugger>
# (This value is overwritten by a launcher specific symbolFiles value if the latter exists)
#
# In runDir, symbolFiles and env fields you can use these macroses:
# ${PROJECT_DIR} - project directory absolute path
# ${OUTPUT_PATH} - linker output path (relative to project directory path)
# ${OUTPUT_BASENAME}- linker output filename
# ${TESTDIR} - test files directory (relative to project directory path)
# ${OBJECTDIR} - object files directory (relative to project directory path)
# ${CND_DISTDIR} - distribution directory (relative to project directory path)
# ${CND_BUILDDIR} - build directory (relative to project directory path)
# ${CND_PLATFORM} - platform name
# ${CND_CONF} - configuration name
# ${CND_DLIB_EXT} - dynamic library extension
#
# All the project launchers must be listed in the file!
#
# launcher1.runCommand=...
# launcher2.runCommand=...
# ...
# common.runDir=...
# common.env.KEY=VALUE
# launcher1.runCommand=<type your run command here>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<project-private xmlns="http://www.netbeans.org/ns/project-private/1">
<data xmlns="http://www.netbeans.org/ns/make-project-private/1">
<activeConfTypeElem>2</activeConfTypeElem>
<activeConfIndexElem>0</activeConfIndexElem>
</data>
<editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/2" lastBookmarkId="0"/>
<open-files xmlns="http://www.netbeans.org/ns/projectui-open-files/2">
<group/>
</open-files>
</project-private>

31
L7/nbproject/project.xml Normal file
View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://www.netbeans.org/ns/project/1">
<type>org.netbeans.modules.cnd.makeproject</type>
<configuration>
<data xmlns="http://www.netbeans.org/ns/make-project/1">
<name>L7</name>
<c-extensions/>
<cpp-extensions>cpp</cpp-extensions>
<header-extensions>h</header-extensions>
<sourceEncoding>UTF-8</sourceEncoding>
<make-dep-projects/>
<sourceRootList/>
<confList>
<confElem>
<name>Debug</name>
<type>2</type>
</confElem>
<confElem>
<name>Release</name>
<type>2</type>
</confElem>
</confList>
<formatting>
<project-formatting-style>true</project-formatting-style>
<c-style>Apache|Apache</c-style>
<cpp-style>Apache|Apache</cpp-style>
<header-style>Apache|Apache</header-style>
</formatting>
</data>
</configuration>
</project>