mirror of https://github.com/PCSX2/pcsx2.git
728 lines
20 KiB
C++
728 lines
20 KiB
C++
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
// Name: src/common/dbgrid.cpp
|
||
|
// Purpose: Displays a wxDbTable in a wxGrid.
|
||
|
// Author: Roger Gammans, Paul Gammans
|
||
|
// Modified by:
|
||
|
// Created:
|
||
|
// RCS-ID: $Id: dbgrid.cpp 43769 2006-12-03 18:20:28Z VZ $
|
||
|
// Copyright: (c) 1999 The Computer Surgery (roger@computer-surgery.co.uk)
|
||
|
// Licence: wxWindows licence
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
// Branched From : dbgrid.cpp,v 1.18 2000/12/19 13:00:58
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
#include "wx/wxprec.h"
|
||
|
|
||
|
#ifdef __BORLANDC__
|
||
|
#pragma hdrstop
|
||
|
#endif
|
||
|
|
||
|
#if wxUSE_ODBC && wxUSE_GRID
|
||
|
|
||
|
#ifndef WX_PRECOMP
|
||
|
#include "wx/textctrl.h"
|
||
|
#include "wx/dc.h"
|
||
|
#include "wx/app.h"
|
||
|
#endif // WX_PRECOMP
|
||
|
|
||
|
#include "wx/generic/gridctrl.h"
|
||
|
#include "wx/dbgrid.h"
|
||
|
|
||
|
// DLL options compatibility check:
|
||
|
WX_CHECK_BUILD_OPTIONS("wxDbGrid")
|
||
|
|
||
|
|
||
|
wxDbGridCellAttrProvider::wxDbGridCellAttrProvider()
|
||
|
{
|
||
|
m_data=NULL;
|
||
|
m_ColInfo=NULL;
|
||
|
}
|
||
|
|
||
|
wxDbGridCellAttrProvider::wxDbGridCellAttrProvider(wxDbTable *tab, wxDbGridColInfoBase* ColInfo)
|
||
|
{
|
||
|
m_data=tab;
|
||
|
m_ColInfo=ColInfo;
|
||
|
}
|
||
|
|
||
|
wxDbGridCellAttrProvider::~wxDbGridCellAttrProvider()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
wxGridCellAttr *wxDbGridCellAttrProvider::GetAttr(int row, int col,
|
||
|
wxGridCellAttr::wxAttrKind kind) const
|
||
|
{
|
||
|
wxGridCellAttr *attr = wxGridCellAttrProvider::GetAttr(row,col,kind);
|
||
|
|
||
|
if (m_data && m_ColInfo && (m_data->GetNumberOfColumns() > m_ColInfo[col].DbCol))
|
||
|
{
|
||
|
//FIXME: this test could.
|
||
|
// ??::InsertPending == m_data->get_ModifiedStatus()
|
||
|
// and if InsertPending use colDef[].InsertAllowed
|
||
|
if (!(m_data->GetColDefs()[(m_ColInfo[col].DbCol)].Updateable))
|
||
|
{
|
||
|
switch(kind)
|
||
|
{
|
||
|
case (wxGridCellAttr::Any):
|
||
|
if (!attr)
|
||
|
{
|
||
|
attr = new wxGridCellAttr;
|
||
|
// Store so we don't keep creating / deleting this...
|
||
|
wxDbGridCellAttrProvider * self = wxConstCast(this, wxDbGridCellAttrProvider) ;
|
||
|
attr->IncRef();
|
||
|
self->SetColAttr(attr, col);
|
||
|
attr->SetReadOnly();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//We now must check what we were returned. and do the right thing (tm)
|
||
|
wxGridCellAttr::wxAttrKind attrkind = attr->GetKind();
|
||
|
if ((attrkind == (wxGridCellAttr::Default)) || (attrkind == (wxGridCellAttr::Cell)) ||
|
||
|
(attrkind == (wxGridCellAttr::Col)))
|
||
|
{
|
||
|
wxGridCellAttr *attrtomerge = attr;
|
||
|
attr = new wxGridCellAttr;
|
||
|
attr->SetKind(wxGridCellAttr::Merged);
|
||
|
attr->MergeWith(attrtomerge);
|
||
|
attr->SetReadOnly();
|
||
|
attrtomerge->DecRef();
|
||
|
}
|
||
|
attr->SetReadOnly();
|
||
|
}
|
||
|
break;
|
||
|
case (wxGridCellAttr::Col):
|
||
|
//As we must have a Coll, and were setting Coll attributes
|
||
|
// we can based on wxdbTable's so just set RO if attr valid
|
||
|
if (!attr)
|
||
|
{
|
||
|
attr = new wxGridCellAttr;
|
||
|
wxDbGridCellAttrProvider * self = wxConstCast(this, wxDbGridCellAttrProvider) ;
|
||
|
attr->IncRef();
|
||
|
self->SetColAttr(attr, col);
|
||
|
}
|
||
|
attr->SetReadOnly();
|
||
|
break;
|
||
|
default:
|
||
|
//Dont add RO for...
|
||
|
// wxGridCellAttr::Cell - Not required, will inherit on merge from row.
|
||
|
// wxGridCellAttr::Row - If wxDbtable ever supports row locking could add
|
||
|
// support to make RO on a row basis also.
|
||
|
// wxGridCellAttr::Default - Don't edit this ! or all cell with a attr will become readonly
|
||
|
// wxGridCellAttr::Merged - This should never be asked for.
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
return attr;
|
||
|
}
|
||
|
|
||
|
void wxDbGridCellAttrProvider::AssignDbTable(wxDbTable *tab)
|
||
|
{
|
||
|
m_data = tab;
|
||
|
}
|
||
|
|
||
|
wxDbGridTableBase::wxDbGridTableBase(wxDbTable *tab, wxDbGridColInfo* ColInfo,
|
||
|
int count, bool takeOwnership) :
|
||
|
m_keys(),
|
||
|
m_data(tab),
|
||
|
m_dbowner(takeOwnership),
|
||
|
m_rowmodified(false)
|
||
|
{
|
||
|
|
||
|
if (count == wxUSE_QUERY)
|
||
|
{
|
||
|
m_rowtotal = m_data ? m_data->Count() : 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_rowtotal = count;
|
||
|
}
|
||
|
// m_keys.Size(m_rowtotal);
|
||
|
m_row = -1;
|
||
|
if (ColInfo)
|
||
|
{
|
||
|
m_nocols = ColInfo->Length();
|
||
|
m_ColInfo = new wxDbGridColInfoBase[m_nocols];
|
||
|
//Do Copy.
|
||
|
wxDbGridColInfo *ptr = ColInfo;
|
||
|
int i =0;
|
||
|
while (ptr && i < m_nocols)
|
||
|
{
|
||
|
m_ColInfo[i] = ptr->m_data;
|
||
|
ptr = ptr->m_next;
|
||
|
i++;
|
||
|
}
|
||
|
#ifdef __WXDEBUG__
|
||
|
if (ptr)
|
||
|
{
|
||
|
wxLogDebug(wxT("NoCols over length after traversing %i items"),i);
|
||
|
}
|
||
|
if (i < m_nocols)
|
||
|
{
|
||
|
wxLogDebug(wxT("NoCols under length after traversing %i items"),i);
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
}
|
||
|
|
||
|
wxDbGridTableBase::~wxDbGridTableBase()
|
||
|
{
|
||
|
wxDbGridCellAttrProvider *provider;
|
||
|
|
||
|
//Can't check for update here as
|
||
|
|
||
|
//FIXME: should i remove m_ColInfo and m_data from m_attrProvider if a wxDbGridAttrProvider
|
||
|
// if ((provider = dynamic_cast<wxDbGridCellAttrProvider *>(GetAttrProvider())))
|
||
|
// Using C casting for now until we can support dynamic_cast with wxWidgets
|
||
|
provider = (wxDbGridCellAttrProvider *)(GetAttrProvider());
|
||
|
if (provider)
|
||
|
{
|
||
|
provider->AssignDbTable(NULL);
|
||
|
}
|
||
|
delete [] m_ColInfo;
|
||
|
|
||
|
Writeback();
|
||
|
if (m_dbowner)
|
||
|
{
|
||
|
delete m_data;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool wxDbGridTableBase::CanHaveAttributes()
|
||
|
{
|
||
|
if (!GetAttrProvider())
|
||
|
{
|
||
|
// use the default attr provider by default
|
||
|
SetAttrProvider(new wxDbGridCellAttrProvider(m_data, m_ColInfo));
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
bool wxDbGridTableBase::AssignDbTable(wxDbTable *tab, int count, bool takeOwnership)
|
||
|
{
|
||
|
wxDbGridCellAttrProvider *provider;
|
||
|
|
||
|
//Remove Information from grid about old data
|
||
|
if (GetView())
|
||
|
{
|
||
|
wxGrid *grid = GetView();
|
||
|
grid->BeginBatch();
|
||
|
grid->ClearSelection();
|
||
|
if (grid->IsCellEditControlEnabled())
|
||
|
{
|
||
|
grid->DisableCellEditControl();
|
||
|
}
|
||
|
wxGridTableMessage msg(this, wxGRIDTABLE_NOTIFY_ROWS_DELETED,0,m_rowtotal);
|
||
|
grid->ProcessTableMessage(msg);
|
||
|
}
|
||
|
|
||
|
//reset our internals...
|
||
|
Writeback();
|
||
|
if (m_dbowner)
|
||
|
{
|
||
|
delete m_data;
|
||
|
}
|
||
|
m_keys.Empty();
|
||
|
m_data = tab;
|
||
|
//FIXME: Remove dynamic_cast before sumision to wxwin
|
||
|
// if ((provider = dynamic_cast<wxDbGridCellAttrProvider *> (GetAttrProvider())))
|
||
|
// Using C casting for now until we can support dynamic_cast with wxWidgets
|
||
|
provider = (wxDbGridCellAttrProvider *)(GetAttrProvider());
|
||
|
if (provider)
|
||
|
{
|
||
|
provider->AssignDbTable(m_data);
|
||
|
}
|
||
|
|
||
|
if (count == wxUSE_QUERY)
|
||
|
{
|
||
|
m_rowtotal = m_data ? m_data->Count() : 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_rowtotal = count;
|
||
|
}
|
||
|
m_row = -1;
|
||
|
|
||
|
//Add Information to grid about new data
|
||
|
if (GetView())
|
||
|
{
|
||
|
wxGrid * grid = GetView();
|
||
|
wxGridTableMessage msg(this, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, m_rowtotal);
|
||
|
grid->ProcessTableMessage(msg);
|
||
|
grid->EndBatch();
|
||
|
}
|
||
|
m_dbowner = takeOwnership;
|
||
|
m_rowmodified = false;
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
wxString wxDbGridTableBase::GetTypeName(int WXUNUSED(row), int col)
|
||
|
{
|
||
|
if (GetNumberCols() > col)
|
||
|
{
|
||
|
if (m_ColInfo[col].wxtypename == wxGRID_VALUE_DBAUTO)
|
||
|
{
|
||
|
if (m_data->GetNumberOfColumns() <= m_ColInfo[col].DbCol)
|
||
|
{
|
||
|
wxFAIL_MSG (_T("You can not use wxGRID_VALUE_DBAUTO for virtual columns"));
|
||
|
}
|
||
|
switch(m_data->GetColDefs()[(m_ColInfo[col].DbCol)].SqlCtype)
|
||
|
{
|
||
|
case SQL_C_CHAR:
|
||
|
#ifdef SQL_C_WCHAR
|
||
|
case SQL_C_WCHAR:
|
||
|
#endif
|
||
|
return wxGRID_VALUE_STRING;
|
||
|
case SQL_C_SHORT:
|
||
|
case SQL_C_SSHORT:
|
||
|
return wxGRID_VALUE_NUMBER;
|
||
|
case SQL_C_USHORT:
|
||
|
return wxGRID_VALUE_NUMBER;
|
||
|
case SQL_C_LONG:
|
||
|
case SQL_C_SLONG:
|
||
|
return wxGRID_VALUE_NUMBER;
|
||
|
case SQL_C_ULONG:
|
||
|
return wxGRID_VALUE_NUMBER;
|
||
|
case SQL_C_FLOAT:
|
||
|
return wxGRID_VALUE_FLOAT;
|
||
|
case SQL_C_DOUBLE:
|
||
|
return wxGRID_VALUE_FLOAT;
|
||
|
case SQL_C_DATE:
|
||
|
return wxGRID_VALUE_DATETIME;
|
||
|
case SQL_C_TIME:
|
||
|
return wxGRID_VALUE_DATETIME;
|
||
|
case SQL_C_TIMESTAMP:
|
||
|
return wxGRID_VALUE_DATETIME;
|
||
|
default:
|
||
|
return wxGRID_VALUE_STRING;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return m_ColInfo[col].wxtypename;
|
||
|
}
|
||
|
}
|
||
|
wxFAIL_MSG (_T("unknown column"));
|
||
|
return wxString();
|
||
|
}
|
||
|
|
||
|
bool wxDbGridTableBase::CanGetValueAs(int row, int col, const wxString& typeName)
|
||
|
{
|
||
|
wxLogDebug(wxT("CanGetValueAs() on %i,%i"),row,col);
|
||
|
//Is this needed? As it will be validated on GetValueAsXXXX
|
||
|
ValidateRow(row);
|
||
|
|
||
|
if (typeName == wxGRID_VALUE_STRING)
|
||
|
{
|
||
|
//FIXME ummm What about blob field etc.
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
if (m_data->IsColNull((UWORD)m_ColInfo[col].DbCol))
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if (m_data->GetNumberOfColumns() <= m_ColInfo[col].DbCol)
|
||
|
{
|
||
|
//If a virtual column then we can't find it's type. we have to
|
||
|
// return false to get using wxVariant.
|
||
|
return false;
|
||
|
}
|
||
|
int sqltype = m_data->GetColDefs()[(m_ColInfo[col].DbCol)].SqlCtype;
|
||
|
|
||
|
if (typeName == wxGRID_VALUE_DATETIME)
|
||
|
{
|
||
|
if ((sqltype == SQL_C_DATE) ||
|
||
|
(sqltype == SQL_C_TIME) ||
|
||
|
(sqltype == SQL_C_TIMESTAMP))
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
if (typeName == wxGRID_VALUE_NUMBER)
|
||
|
{
|
||
|
if ((sqltype == SQL_C_SSHORT) ||
|
||
|
(sqltype == SQL_C_USHORT) ||
|
||
|
(sqltype == SQL_C_SLONG) ||
|
||
|
(sqltype == SQL_C_ULONG))
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
if (typeName == wxGRID_VALUE_FLOAT)
|
||
|
{
|
||
|
if ((sqltype == SQL_C_SSHORT) ||
|
||
|
(sqltype == SQL_C_USHORT) ||
|
||
|
(sqltype == SQL_C_SLONG) ||
|
||
|
(sqltype == SQL_C_ULONG) ||
|
||
|
(sqltype == SQL_C_FLOAT) ||
|
||
|
(sqltype == SQL_C_DOUBLE))
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
bool wxDbGridTableBase::CanSetValueAs(int WXUNUSED(row), int col, const wxString& typeName)
|
||
|
{
|
||
|
if (typeName == wxGRID_VALUE_STRING)
|
||
|
{
|
||
|
//FIXME ummm What about blob field etc.
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
if (!(m_data->GetColDefs()[(m_ColInfo[col].DbCol)].Updateable))
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if (m_data->GetNumberOfColumns() <= m_ColInfo[col].DbCol)
|
||
|
{
|
||
|
//If a virtual column then we can't find it's type. we have to faulse to
|
||
|
//get using wxVairent.
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
int sqltype = m_data->GetColDefs()[(m_ColInfo[col].DbCol)].SqlCtype;
|
||
|
if (typeName == wxGRID_VALUE_DATETIME)
|
||
|
{
|
||
|
if ((sqltype == SQL_C_DATE) ||
|
||
|
(sqltype == SQL_C_TIME) ||
|
||
|
(sqltype == SQL_C_TIMESTAMP))
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
if (typeName == wxGRID_VALUE_NUMBER)
|
||
|
{
|
||
|
if ((sqltype == SQL_C_SSHORT) ||
|
||
|
(sqltype == SQL_C_USHORT) ||
|
||
|
(sqltype == SQL_C_SLONG) ||
|
||
|
(sqltype == SQL_C_ULONG))
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
if (typeName == wxGRID_VALUE_FLOAT)
|
||
|
{
|
||
|
if ((sqltype == SQL_C_SSHORT) ||
|
||
|
(sqltype == SQL_C_USHORT) ||
|
||
|
(sqltype == SQL_C_SLONG) ||
|
||
|
(sqltype == SQL_C_ULONG) ||
|
||
|
(sqltype == SQL_C_FLOAT) ||
|
||
|
(sqltype == SQL_C_DOUBLE))
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
long wxDbGridTableBase::GetValueAsLong(int row, int col)
|
||
|
{
|
||
|
ValidateRow(row);
|
||
|
|
||
|
if (m_data->GetNumberOfColumns() <= m_ColInfo[col].DbCol)
|
||
|
{
|
||
|
wxFAIL_MSG (_T("You can not use GetValueAsLong for virtual columns"));
|
||
|
return 0;
|
||
|
}
|
||
|
int sqltype = m_data->GetColDefs()[(m_ColInfo[col].DbCol)].SqlCtype;
|
||
|
if ((sqltype == SQL_C_SSHORT) ||
|
||
|
(sqltype == SQL_C_USHORT) ||
|
||
|
(sqltype == SQL_C_SLONG) ||
|
||
|
(sqltype == SQL_C_ULONG))
|
||
|
{
|
||
|
wxVariant val = m_data->GetColumn(m_ColInfo[col].DbCol);
|
||
|
return val.GetLong();
|
||
|
}
|
||
|
wxFAIL_MSG (_T("unknown column, "));
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
double wxDbGridTableBase::GetValueAsDouble(int row, int col)
|
||
|
{
|
||
|
wxLogDebug(wxT("GetValueAsDouble() on %i,%i"),row,col);
|
||
|
ValidateRow(row);
|
||
|
|
||
|
if (m_data->GetNumberOfColumns() <= m_ColInfo[col].DbCol)
|
||
|
{
|
||
|
wxFAIL_MSG (_T("You can not use GetValueAsDouble for virtual columns"));
|
||
|
return 0.0;
|
||
|
}
|
||
|
int sqltype = m_data->GetColDefs()[(m_ColInfo[col].DbCol)].SqlCtype;
|
||
|
if ((sqltype == SQL_C_SSHORT) ||
|
||
|
(sqltype == SQL_C_USHORT) ||
|
||
|
(sqltype == SQL_C_SLONG) ||
|
||
|
(sqltype == SQL_C_ULONG) ||
|
||
|
(sqltype == SQL_C_FLOAT) ||
|
||
|
(sqltype == SQL_C_DOUBLE))
|
||
|
{
|
||
|
wxVariant val = m_data->GetColumn(m_ColInfo[col].DbCol);
|
||
|
return val.GetDouble();
|
||
|
}
|
||
|
wxFAIL_MSG (_T("unknown column"));
|
||
|
return 0.0;
|
||
|
}
|
||
|
|
||
|
bool wxDbGridTableBase::GetValueAsBool(int row, int col)
|
||
|
{
|
||
|
wxLogDebug(wxT("GetValueAsBool() on %i,%i"),row,col);
|
||
|
ValidateRow(row);
|
||
|
|
||
|
if (m_data->GetNumberOfColumns() <= m_ColInfo[col].DbCol)
|
||
|
{
|
||
|
wxFAIL_MSG (_T("You can not use GetValueAsBool for virtual columns"));
|
||
|
return 0;
|
||
|
}
|
||
|
int sqltype = m_data->GetColDefs()[(m_ColInfo[col].DbCol)].SqlCtype;
|
||
|
if ((sqltype == SQL_C_SSHORT) ||
|
||
|
(sqltype == SQL_C_USHORT) ||
|
||
|
(sqltype == SQL_C_SLONG) ||
|
||
|
(sqltype == SQL_C_ULONG))
|
||
|
{
|
||
|
wxVariant val = m_data->GetColumn(m_ColInfo[col].DbCol);
|
||
|
return val.GetBool();
|
||
|
}
|
||
|
wxFAIL_MSG (_T("unknown column, "));
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
void* wxDbGridTableBase::GetValueAsCustom(int row, int col, const wxString& typeName)
|
||
|
{
|
||
|
wxLogDebug(wxT("GetValueAsCustom() on %i,%i"),row,col);
|
||
|
ValidateRow(row);
|
||
|
|
||
|
if (m_data->GetNumberOfColumns() <= m_ColInfo[col].DbCol)
|
||
|
{
|
||
|
wxFAIL_MSG (_T("You can not use GetValueAsCustom for virtual columns"));
|
||
|
return NULL;
|
||
|
}
|
||
|
if (m_data->IsColNull((UWORD)m_ColInfo[col].DbCol))
|
||
|
return NULL;
|
||
|
|
||
|
if (typeName == wxGRID_VALUE_DATETIME)
|
||
|
{
|
||
|
wxDbColDef *pColDefs = m_data->GetColDefs();
|
||
|
int sqltype = pColDefs[(m_ColInfo[col].DbCol)].SqlCtype;
|
||
|
|
||
|
if ((sqltype == SQL_C_DATE) ||
|
||
|
(sqltype == SQL_C_TIME) ||
|
||
|
(sqltype == SQL_C_TIMESTAMP))
|
||
|
{
|
||
|
wxVariant val = m_data->GetColumn(m_ColInfo[col].DbCol);
|
||
|
return new wxDateTime(val.GetDateTime());
|
||
|
}
|
||
|
}
|
||
|
wxFAIL_MSG (_T("unknown column data type "));
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
void wxDbGridTableBase::SetValueAsCustom(int row, int col, const wxString& typeName, void* value)
|
||
|
{
|
||
|
wxLogDebug(wxT("SetValueAsCustom() on %i,%i"),row,col);
|
||
|
ValidateRow(row);
|
||
|
|
||
|
if (m_data->GetNumberOfColumns() <= m_ColInfo[col].DbCol)
|
||
|
{
|
||
|
wxFAIL_MSG (_T("You can not use SetValueAsCustom for virtual columns"));
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (typeName == wxGRID_VALUE_DATETIME)
|
||
|
{
|
||
|
int sqltype = m_data->GetColDefs()[(m_ColInfo[col].DbCol)].SqlCtype;
|
||
|
if ((sqltype == SQL_C_DATE) ||
|
||
|
(sqltype == SQL_C_TIME) ||
|
||
|
(sqltype == SQL_C_TIMESTAMP))
|
||
|
{
|
||
|
//FIXME: you can't dynamic_cast from (void *)
|
||
|
//wxDateTime *date = wxDynamicCast(value, wxDateTime);
|
||
|
wxDateTime *date = (wxDateTime *)value;
|
||
|
if (!date)
|
||
|
{
|
||
|
wxFAIL_MSG (_T("Failed to convert data"));
|
||
|
return;
|
||
|
}
|
||
|
wxVariant val(date);
|
||
|
m_rowmodified = true;
|
||
|
m_data->SetColumn(m_ColInfo[col].DbCol,val);
|
||
|
}
|
||
|
}
|
||
|
wxFAIL_MSG (_T("unknown column data type"));
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
|
||
|
wxString wxDbGridTableBase::GetColLabelValue(int col)
|
||
|
{
|
||
|
if (GetNumberCols() > col)
|
||
|
{
|
||
|
return m_ColInfo[col].Title;
|
||
|
}
|
||
|
wxFAIL_MSG (_T("unknown column"));
|
||
|
return wxString();
|
||
|
}
|
||
|
|
||
|
bool wxDbGridTableBase::IsEmptyCell(int row, int col)
|
||
|
{
|
||
|
wxLogDebug(wxT("IsEmtpyCell on %i,%i"),row,col);
|
||
|
|
||
|
ValidateRow(row);
|
||
|
return m_data->IsColNull((UWORD)m_ColInfo[col].DbCol);
|
||
|
}
|
||
|
|
||
|
|
||
|
wxString wxDbGridTableBase::GetValue(int row, int col)
|
||
|
{
|
||
|
wxLogDebug(wxT("GetValue() on %i,%i"),row,col);
|
||
|
|
||
|
ValidateRow(row);
|
||
|
wxVariant val = m_data->GetColumn(m_ColInfo[col].DbCol);
|
||
|
wxLogDebug(wxT("\tReturning \"%s\"\n"),val.GetString().c_str());
|
||
|
|
||
|
return val.GetString();
|
||
|
}
|
||
|
|
||
|
|
||
|
void wxDbGridTableBase::SetValue(int row, int col,const wxString& value)
|
||
|
{
|
||
|
wxLogDebug(wxT("SetValue() on %i,%i"),row,col);
|
||
|
|
||
|
ValidateRow(row);
|
||
|
wxVariant val(value);
|
||
|
|
||
|
m_rowmodified = true;
|
||
|
m_data->SetColumn(m_ColInfo[col].DbCol,val);
|
||
|
}
|
||
|
|
||
|
|
||
|
void wxDbGridTableBase::SetValueAsLong(int row, int col, long value)
|
||
|
{
|
||
|
wxLogDebug(wxT("SetValueAsLong() on %i,%i"),row,col);
|
||
|
|
||
|
ValidateRow(row);
|
||
|
wxVariant val(value);
|
||
|
|
||
|
m_rowmodified = true;
|
||
|
m_data->SetColumn(m_ColInfo[col].DbCol,val);
|
||
|
}
|
||
|
|
||
|
|
||
|
void wxDbGridTableBase::SetValueAsDouble(int row, int col, double value)
|
||
|
{
|
||
|
wxLogDebug(wxT("SetValueAsDouble() on %i,%i"),row,col);
|
||
|
|
||
|
ValidateRow(row);
|
||
|
wxVariant val(value);
|
||
|
|
||
|
m_rowmodified = true;
|
||
|
m_data->SetColumn(m_ColInfo[col].DbCol,val);
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
void wxDbGridTableBase::SetValueAsBool(int row, int col, bool value)
|
||
|
{
|
||
|
wxLogDebug(wxT("SetValueAsBool() on %i,%i"),row,col);
|
||
|
|
||
|
ValidateRow(row);
|
||
|
wxVariant val(value);
|
||
|
|
||
|
m_rowmodified = true;
|
||
|
m_data->SetColumn(m_ColInfo[col].DbCol,val);
|
||
|
}
|
||
|
|
||
|
|
||
|
void wxDbGridTableBase::ValidateRow(int row)
|
||
|
{
|
||
|
wxLogDebug(wxT("ValidateRow(%i) currently on row (%i). Array count = %lu"),
|
||
|
row, m_row, (unsigned long)m_keys.GetCount());
|
||
|
|
||
|
if (row == m_row)
|
||
|
return;
|
||
|
Writeback();
|
||
|
|
||
|
//We add to row as Count is unsigned!
|
||
|
if ((unsigned)(row+1) > m_keys.GetCount())
|
||
|
{
|
||
|
wxLogDebug(wxT("\trow key unknown"));
|
||
|
// Extend Array, iterate through data filling with keys
|
||
|
m_data->SetRowMode(wxDbTable::WX_ROW_MODE_QUERY);
|
||
|
int trow;
|
||
|
for (trow = m_keys.GetCount(); trow <= row; trow++)
|
||
|
{
|
||
|
wxLogDebug(wxT("Fetching row %i.."), trow);
|
||
|
bool ret = m_data->GetNext();
|
||
|
|
||
|
wxLogDebug(wxT(" ...success=(%i)"),ret);
|
||
|
GenericKey k = m_data->GetKey();
|
||
|
m_keys.Add(k);
|
||
|
}
|
||
|
m_row = row;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
wxLogDebug(wxT("\trow key known centering data"));
|
||
|
GenericKey k = m_keys.Item(row);
|
||
|
m_data->SetRowMode(wxDbTable::WX_ROW_MODE_INDIVIDUAL);
|
||
|
m_data->ClearMemberVars();
|
||
|
m_data->SetKey(k);
|
||
|
if (!m_data->QueryOnKeyFields())
|
||
|
{
|
||
|
wxDbLogExtendedErrorMsg(_T("ODBC error during Query()\n\n"), m_data->GetDb(),__TFILE__,__LINE__);
|
||
|
}
|
||
|
|
||
|
m_data->GetNext();
|
||
|
|
||
|
m_row = row;
|
||
|
}
|
||
|
m_rowmodified = false;
|
||
|
}
|
||
|
|
||
|
bool wxDbGridTableBase::Writeback() const
|
||
|
{
|
||
|
if (!m_rowmodified)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool result=true;
|
||
|
wxLogDebug(wxT("\trow key unknown"));
|
||
|
|
||
|
// FIXME: this code requires dbtable support for record status
|
||
|
#if 0
|
||
|
switch (m_data->get_ModifiedStatus())
|
||
|
{
|
||
|
case wxDbTable::UpdatePending:
|
||
|
result = m_data->Update();
|
||
|
break;
|
||
|
case wxDbTable::InsertPending:
|
||
|
result = (m_data->Insert() == SQL_SUCCESS);
|
||
|
break;
|
||
|
default:
|
||
|
//Nothing
|
||
|
break;
|
||
|
}
|
||
|
#else
|
||
|
wxLogDebug(wxT("WARNING : Row writeback not implemented "));
|
||
|
#endif
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
#include "wx/arrimpl.cpp"
|
||
|
|
||
|
WX_DEFINE_EXPORTED_OBJARRAY(keyarray)
|
||
|
|
||
|
#endif // wxUSE_GRID && wxUSE_ODBC
|