//+----------------------------------------------------------------------- // // 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 > *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 *> m_arrparrCells; TSTDArray *> m_arrparrFilter; TSTDArray 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