//+-----------------------------------------------------------------------
//
// TDC Array
// Copyright (C) Microsoft Corporation, 1996, 1997
//
// File: TDCArr.h
//
// Contents: Declaration of the CTDCArr class.
// This class forms the heart of the Tabular Data Control.
// It provides the core 2D array of variant values, plus
// a (possibly filtered/sorted) view of this data for
// presentation through an ISimpleTabularData interface.
//
//------------------------------------------------------------------------
// ;begin_internal
#ifndef TDC_SKEL
// ;end_internal
#include "tarray.h"
//------------------------------------------------------------------------
//
// CTDCCell
//
// This class represents a cell value within the 2D TDC control
//
//------------------------------------------------------------------------
class CTDCCell : public VARIANT
{
public:
CTDCCell()
{
VariantInit(this);
}
~CTDCCell()
{
clear();
}
void clear()
{
VariantClear(this);
}
};
//------------------------------------------------------------------------
//
// TDCDateFmt
//
// This enum represents the 6 meaningful ways to format dates
//
//------------------------------------------------------------------------
typedef enum
{
TDCDF_NULL,
TDCDF_DMY,
TDCDF_DYM,
TDCDF_MDY,
TDCDF_MYD,
TDCDF_YMD,
TDCDF_YDM,
}
TDCDateFmt;
//------------------------------------------------------------------------
//
// CTDCColInfo
//
// This class represents type/formatting information for a column
//
//------------------------------------------------------------------------
class CTDCColInfo
{
public:
VARTYPE vtType;
TDCDateFmt datefmt; // Format string for dates
CTDCColInfo()
{
vtType = VT_EMPTY;
}
};
// ;begin_internal
#endif // TDC_SKEL
// ;end_internal
//------------------------------------------------------------------------
//
// CTDCSortCriterion
//
// This class represents a sorting criterion (sort column and direction)
//
//------------------------------------------------------------------------
class CTDCSortCriterion
{
public:
LONG m_iSortCol;
boolean m_fSortAscending;
CTDCSortCriterion *m_pNext;
CTDCSortCriterion()
{
m_pNext = NULL;
}
~CTDCSortCriterion()
{
if (m_pNext != NULL)
delete m_pNext;
}
};
//------------------------------------------------------------------------
//
// CTDCFilterNode
//
// This class represents a tree node in a filter query.
//
//------------------------------------------------------------------------
class CTDCFilterNode
{
public:
enum NODE_OP
{
NT_AND,
NT_OR,
NT_EQ,
NT_NE,
NT_LT,
NT_GT,
NT_LE,
NT_GE,
NT_ATOM,
NT_NULL,
};
NODE_OP m_type;
CTDCFilterNode *m_pLeft; // NT_AND ... NT_GE
CTDCFilterNode *m_pRight; // NT_AND ... NT_GE
LONG m_iCol; // NT_ATOM, +ve column #, 0 means fixed value
VARIANT m_value; // NT_ATOM, m_iCol == 0: optional fixed value
VARTYPE m_vt; // NT_EQ ... NT_ATOM - type of comparison/atom
boolean m_fWildcard; // True for string literals with '*' wildcard
CTDCFilterNode()
{
m_type = NT_NULL;
m_pLeft = NULL;
m_pRight = NULL;
m_iCol = 0;
m_vt = VT_EMPTY;
VariantInit(&m_value);
}
~CTDCFilterNode()
{
if (m_pLeft != NULL)
delete m_pLeft;
if (m_pRight != NULL)
delete m_pRight;
VariantClear(&m_value);
}
};
class CEventBroker;
//------------------------------------------------------------------------
//
// CTDCArr
//
//------------------------------------------------------------------------
class CTDCArr : public OLEDBSimpleProvider,
public CTDCFieldSink
{
public:
STDMETHOD(QueryInterface) (REFIID, LPVOID FAR*);
STDMETHOD_(ULONG,AddRef) (THIS);
STDMETHOD_(ULONG,Release) (THIS);
CTDCArr();
STDMETHOD(Init)(CEventBroker *pEventBroker, IMultiLanguage *pML);
// CTDCFieldSink methods
//
STDMETHOD(AddField)(LPWCH pwch, DWORD dwSize);
STDMETHOD(EOLN)();
STDMETHOD(EOF)();
// TDC control methods
//
STDMETHOD(StartDataLoad)(boolean fUseHeader,
BSTR bstrSortExpr, BSTR bstrFilterExpr, LCID lcid,
CComObject<CMyBindStatusCallback<CTDCCtl> > *pBSC,
boolean fAppend, boolean fCaseSensitive);
STDMETHOD(SetSortFilterCriteria)(BSTR bstrSortExpr, BSTR bstrFilterExpr,
boolean fCaseSensitive);
// OLEDBSimpleProvider methods
//
STDMETHOD(getRowCount)(LONG *pcRows);
STDMETHOD(getColumnCount)(LONG *pcCols);
STDMETHOD(getRWStatus)(LONG iRow, LONG iCol, OSPRW *prwStatus);
STDMETHOD(getVariant)(LONG iRow, LONG iCol, OSPFORMAT format, VARIANT *pVar);
STDMETHOD(setVariant)(LONG iRow, LONG iCol, OSPFORMAT format, VARIANT Var);
STDMETHOD(getLocale)(BSTR *pbstrLocale);
STDMETHOD(deleteRows)(LONG iRow, LONG cRows, LONG *pcRowsDeleted);
STDMETHOD(insertRows)(LONG iRow, LONG cRows, LONG *pcRowsInserted);
STDMETHOD(find) (LONG iRowStart, LONG iCol, VARIANT val,
OSPFIND findFlags, OSPCOMP compType, LONG *piRowFound);
STDMETHOD(addOLEDBSimpleProviderListener)(OLEDBSimpleProviderListener *pospIListener);
STDMETHOD(removeOLEDBSimpleProviderListener)(OLEDBSimpleProviderListener *pospIListener);
STDMETHOD(getEstimatedRows)(LONG *pcRows);
STDMETHOD(isAsync)(BOOL *pbAsync);
STDMETHOD(stopTransfer)();
// ;begin_internal
STDMETHOD(DeleteColumns)(LONG iCol, LONG cCols, LONG *pcColsDeleted);
STDMETHOD(InsertColumns)(LONG iCol, LONG cCols, LONG *pcColsInserted);
// ;end_internal
// This member is used during a sort operation
//
int SortComp(LONG iRow1, LONG iRow2);
enum LOAD_STATE
{
LS_UNINITIALISED,
LS_LOADING_HEADER_UNAVAILABLE,
LS_LOADING_HEADER_AVAILABLE,
LS_LOADED,
};
LOAD_STATE GetLoadState() { return m_state; }
void SetIsAsync(BOOL fAsync) { m_fAsync = fAsync; }
CEventBroker *m_pEventBroker;
IMultiLanguage *m_pML;
private:
ULONG m_cRef; // interface reference count
LOAD_STATE m_state;
LCID m_lcid; // Default user LCID
LCID m_lcidRead; // User LCID corresponding to LANGUAGE property
~CTDCArr();
// ;begin_internal
#ifndef TDC_SKEL
// ;end_internal
boolean m_fSortFilterDisrupted;
STDMETHOD(ApplySortFilterCriteria)();
// These members are used during a sort operation
//
CTDCSortCriterion *m_pSortList;
BSTR m_bstrSortExpr;
HRESULT CreateSortList(BSTR bstrSortCols);
// These members are used during a filter operation
//
CTDCFilterNode *m_pFilterTree;
BSTR m_bstrFilterExpr;
boolean EvalDataRow(LONG iRow, CTDCFilterNode *pNode);
CTDCFilterNode *FilterParseComplex(LPWCH *ppwch, HRESULT *phr);
CTDCFilterNode *FilterParseSimple(LPWCH *ppwch, HRESULT *phr);
CTDCFilterNode *FilterParseAtom(LPWCH *ppwch, HRESULT *phr);
LONG m_fLastFilter;
// ;begin_internal
#endif // TDC_SKEL
// ;end_internal
// These members are used during a load
//
boolean m_fUseHeader;
boolean m_fSkipRow;
LONG m_iCurrRow;
LONG m_iCurrCol;
LONG m_iDataRows;
LONG m_iFilterRows;
LONG m_iCols;
boolean m_fCaseSensitive;
BOOL m_fAsync; // TRUE iff Async
// These methods and members form the internal array implementation
//
inline boolean fValidDataRow(LONG iRow);
inline boolean fValidFilterRow(LONG iRow);
inline boolean fValidCol(LONG iCol);
inline boolean fValidDataCell(LONG iRow, LONG iCol);
inline boolean fValidFilterCell(LONG iRow, LONG iCol);
inline CTDCCell *GetDataCell(LONG iRow, LONG iCol);
inline CTDCCell *GetFilterCell(LONG iRow, LONG iCol);
inline CTDCColInfo *GetColInfo(LONG iCol);
LONG CalcDataRows();
LONG CalcFilterRows();
LONG CalcCols();
TSTDArray<TSTDArray<CTDCCell> *> m_arrparrCells;
TSTDArray<TSTDArray<CTDCCell> *> m_arrparrFilter;
TSTDArray<CTDCColInfo> m_arrColInfo;
// Misc internal methods
//
LONG FindCol(BSTR bstrColName);
HRESULT GetVariantBSTR(VARIANT *pv, BSTR *pbstr, boolean *pfAllocated);
void RenumberColumnHeadings();
HRESULT CreateNumberedColumnHeadings();
HRESULT ParseColumnHeadings();
HRESULT VariantFromBSTR(VARIANT *pv, BSTR bstr, CTDCColInfo *pColInfo, LCID);
int VariantComp(VARIANT *pVar1, VARIANT *pVar2, VARTYPE type,
boolean fCaseSensitive);
int InsertionSortHelper(int iRow);
};
inline boolean CTDCArr::fValidDataRow(LONG iRow)
{
return iRow >= 0 && iRow <= m_iDataRows;
}
inline boolean CTDCArr::fValidFilterRow(LONG iRow)
{
return iRow >= 0 && iRow <= m_iFilterRows;
}
inline boolean CTDCArr::fValidCol(LONG iCol)
{
return iCol >= 1 && iCol <= m_iCols;
}
inline boolean CTDCArr::fValidDataCell(LONG iRow, LONG iCol)
{
return fValidDataRow(iRow) && fValidCol(iCol);
}
inline boolean CTDCArr::fValidFilterCell(LONG iRow, LONG iCol)
{
return fValidFilterRow(iRow) && fValidCol(iCol);
}
// ;begin_internal
#ifndef TDC_SKEL
// ;end_internal
inline CTDCCell *CTDCArr::GetDataCell(LONG iRow, LONG iCol)
{
return &((*m_arrparrCells[iRow])[iCol - 1]);
}
inline CTDCColInfo *CTDCArr::GetColInfo(LONG iCol)
{
return &m_arrColInfo[iCol - 1];
}
inline CTDCCell *CTDCArr::GetFilterCell(LONG iRow, LONG iCol)
{
return &((*m_arrparrFilter[iRow])[iCol - 1]);
}
// ;begin_internal
#endif // TDC_SKEL
// ;end_internal