You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
361 lines
10 KiB
361 lines
10 KiB
//+-----------------------------------------------------------------------
|
|
//
|
|
// 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)(DBROWCOUNT *pcRows);
|
|
STDMETHOD(getColumnCount)(DB_LORDINAL *pcCols);
|
|
STDMETHOD(getRWStatus)(DBROWCOUNT iRow, DB_LORDINAL iCol, OSPRW *prwStatus);
|
|
STDMETHOD(getVariant)(DBROWCOUNT iRow, DB_LORDINAL iCol, OSPFORMAT format, VARIANT *pVar);
|
|
STDMETHOD(setVariant)(DBROWCOUNT iRow, DB_LORDINAL iCol, OSPFORMAT format, VARIANT Var);
|
|
STDMETHOD(getLocale)(BSTR *pbstrLocale);
|
|
STDMETHOD(deleteRows)(DBROWCOUNT iRow, DBROWCOUNT cRows, DBROWCOUNT *pcRowsDeleted);
|
|
STDMETHOD(insertRows)(DBROWCOUNT iRow, DBROWCOUNT cRows, DBROWCOUNT *pcRowsInserted);
|
|
STDMETHOD(find) (DBROWCOUNT iRowStart, DB_LORDINAL iCol, VARIANT val,
|
|
OSPFIND findFlags, OSPCOMP compType, DBROWCOUNT *piRowFound);
|
|
STDMETHOD(addOLEDBSimpleProviderListener)(OLEDBSimpleProviderListener *pospIListener);
|
|
STDMETHOD(removeOLEDBSimpleProviderListener)(OLEDBSimpleProviderListener *pospIListener);
|
|
STDMETHOD(getEstimatedRows)(DBROWCOUNT *pcRows);
|
|
STDMETHOD(isAsync)(BOOL *pbAsync);
|
|
STDMETHOD(stopTransfer)();
|
|
// ;begin_internal
|
|
STDMETHOD(DeleteColumns)(DB_LORDINAL iCol, DB_LORDINAL cCols, DB_LORDINAL *pcColsDeleted);
|
|
STDMETHOD(InsertColumns)(DB_LORDINAL iCol, DB_LORDINAL cCols, DB_LORDINAL *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
|