// TSDisplayField.cpp: implementation of the TSDisplayField class. // ///////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include #include "TSDisplayField.h" #include "TSServer.h" #include TSDisplayField::TSDisplayField( TSServer& server, int nItemId /*=0*/ ) : m_bCanUpdate ( true ), m_bModifiedFlag ( false ), m_nAttribute ( 0 ), m_nProperty ( 0 ), m_nRequired ( 0 ), m_nSection ( 0 ), m_nType ( 0 ), m_bUseInternal ( false ), m_sInternalValue( "" ), m_sDisplayValue ( "" ), m_sPrefix ( "" ), m_sSuffix ( "" ), m_selections ( ), TSRecordRef ( server, TS_TBLID_FIELDS, nItemId ) { } TSDisplayField::TSDisplayField( const TSDisplayField& that ) : m_bCanUpdate ( that.m_bCanUpdate ), m_bModifiedFlag ( that.m_bModifiedFlag ), m_nAttribute ( that.m_nAttribute ), m_nProperty ( that.m_nProperty ), m_nRequired ( that.m_nRequired ), m_nSection ( that.m_nSection ), m_nType ( that.m_nType ), m_bUseInternal ( that.m_bUseInternal ), m_sInternalValue( that.m_sInternalValue ), m_sDisplayValue ( that.m_sDisplayValue ), m_sPrefix ( that.m_sPrefix ), m_sSuffix ( that.m_sSuffix ), TSRecordRef ( that ) { TSRecordRefList::const_iterator it = that.m_selections.begin(); for ( ; it != that.m_selections.end(); it++ ) { TSRecordRef* pRecordRef = new TSRecordRef( **it ); m_selections.push_back( pRecordRef ); } } TSDisplayField::~TSDisplayField() { TSRecordRefList::iterator it = m_selections.begin(); for ( ; it != m_selections.end(); it++ ) { delete *it; } } TSDisplayField& TSDisplayField::operator = ( const TSDisplayField& that ) { TSRecordRef::operator = ( that ); m_bCanUpdate = that.m_bCanUpdate; m_bModifiedFlag = that.m_bModifiedFlag; m_nAttribute = that.m_nAttribute; m_nProperty = that.m_nProperty; m_nRequired = that.m_nRequired; m_nSection = that.m_nSection; m_nType = that.m_nType; m_bUseInternal = that.m_bUseInternal; m_sInternalValue = that.m_sInternalValue; m_sDisplayValue = that.m_sDisplayValue; m_sPrefix = that.m_sPrefix; m_sSuffix = that.m_sSuffix; TSRecordRefList::const_iterator it = that.m_selections.begin(); for ( ; it != that.m_selections.end(); it++ ) { TSRecordRef* pRecordRef = new TSRecordRef( **it ); m_selections.push_back( pRecordRef ); } return *this; } namespace { class FindRecRefByItemName { public: FindRecRefByItemName( TSString itemName ) : m_itemName( itemName ) {} BOOL operator()( const TSRecordRef* pRecRef ) { return pRecRef->GetItemName() == m_itemName; } TSString m_itemName; }; } bool TSDisplayField::IsMultiSelect() const { return ( m_nType == TS_FLDTYPE_MULTIPLE_SELECTION || m_nType == TS_FLDTYPE_MULTIPLE_RELATIONAL ); } int TSDisplayField::Read() { TSSetLastError( TS_ERROR ); return TSGetLastError(); } int TSDisplayField::AddToDisplayValueForMultiSelect( const TSString& sAdditionalDisplayValue ) { if ( IsUpdateable() ) { if ( IsMultiSelect() ) { // Parse for multiple display values separated by tabs char* sCompleteString = strdup( sAdditionalDisplayValue ); char* sSingleValue = strtok( sCompleteString, "\t" ); int nError = TS_OK; while ( sSingleValue != NULL ) { FindRecRefByItemName finder( sSingleValue ); TSRecordRefList::iterator it = std::find_if( m_selections.begin(), m_selections.end(), finder ); if ( it != m_selections.end() ) { int nTempError; nTempError = AddToDisplayValueForMultiSelect( *it ); if ( nTempError != TS_OK ) { nError = nTempError; } } else { // Unable to find item nError = TS_INVALID_PARAMETERS; } sSingleValue = strtok( NULL, "\t" ); } free( sCompleteString ); TSSetLastError( nError ); return TSGetLastError(); } else { // This call should only be used with multi-select fields TSSetLastError( TS_INVALID_DATATYPE ); return TSGetLastError(); } } else { TSSetLastError( TS_NOT_UPDATEABLE ); return TSGetLastError(); } } int TSDisplayField::AddToDisplayValueForMultiSelect( const TSRecordRef* pAdditionalSelection ) { if ( IsUpdateable() ) { if ( IsMultiSelect() ) { if ( m_sDisplayValue.Length() ) { m_sDisplayValue += "\t"; } m_sDisplayValue += pAdditionalSelection->GetItemName(); m_bModifiedFlag = true; char str[16]; if ( m_sInternalValue.Length() <= 1 ) { // This is the first item in the string - surround by commas sprintf( str, ",%d,", pAdditionalSelection->GetItemId() ); m_sInternalValue = str; } else { // add to the existing string - still end with a comma sprintf( str, "%d,", pAdditionalSelection->GetItemId() ); m_sInternalValue += str; } return TS_OK; } else { // This call should only be used with multi-select fields TSSetLastError( TS_INVALID_DATATYPE ); return TSGetLastError(); } } else { TSSetLastError( TS_NOT_UPDATEABLE ); return TSGetLastError(); } } int TSDisplayField::ClearDisplayValue() { if ( IsUpdateable() ) { m_sDisplayValue = ""; m_bModifiedFlag = true; if ( IsMultiSelect() ) { // set to , if multi-select m_sInternalValue = ","; } else { m_sInternalValue = ""; } return TS_OK; } else { TSSetLastError( TS_NOT_UPDATEABLE ); return TSGetLastError(); } } int TSDisplayField::Receive( TSSocket* socket ) { if ( socket->ReceiveInt( &m_nItemId ) != TS_OK ) { return TSGetLastError(); } if ( socket->ReceiveInt( &m_nTableId ) != TS_OK ) { return TSGetLastError(); } if ( socket->ReceiveString( &m_sItemName ) != TS_OK ) { return TSGetLastError(); } // change the int to bool int nTemp; if ( socket->ReceiveInt( &nTemp ) != TS_OK ) { return TSGetLastError(); } m_bCanUpdate = nTemp != 0; if ( socket->ReceiveInt( &m_nAttribute ) != TS_OK ) { return TSGetLastError(); } if ( socket->ReceiveInt( &m_nLength ) != TS_OK ) { return TSGetLastError(); } if ( socket->ReceiveInt( &m_nProperty ) != TS_OK ) { return TSGetLastError(); } if ( socket->ReceiveInt( &m_nRequired ) != TS_OK ) { return TSGetLastError(); } if ( socket->ReceiveInt( &m_nSection ) != TS_OK ) { return TSGetLastError(); } if ( socket->ReceiveInt( &m_nType ) != TS_OK ) { return TSGetLastError(); } // change the int to bool nTemp; if ( socket->ReceiveInt( &nTemp ) != TS_OK ) { return TSGetLastError(); } m_bUseInternal = nTemp != 0; if ( socket->ReceiveString( &m_sInternalValue ) != TS_OK ) { return TSGetLastError(); } if ( socket->ReceiveString( &m_sDisplayValue ) != TS_OK ) { return TSGetLastError(); } if ( socket->ReceiveString( &m_sPrefix ) != TS_OK ) { return TSGetLastError(); } if ( socket->ReceiveString( &m_sSuffix ) != TS_OK ) { return TSGetLastError(); } int nErrCode = TS_OK; while ( nErrCode == TS_OK ) { TSRecordRef* pRecordRef = new TSRecordRef( *this ); nErrCode = pRecordRef->Receive( socket ); if ( nErrCode != TS_OK ) { delete pRecordRef; break; } m_selections.push_back( pRecordRef ); } // There's always a \r\n at the end of the list, but usually the \r has // already been read so read up till the next \n. char ch; while (( ch = socket->ReadChar()) != 0 ) { if ( ch == '\n' ) { break; } } return TS_OK; } int TSDisplayField::SetDisplayValue( const TSString& sNewDisplayValue ) {// check for tabs clear values call the add if ( IsUpdateable() ) { if ( m_bUseInternal ) { FindRecRefByItemName finder( sNewDisplayValue ); TSRecordRefList::iterator it = std::find_if( m_selections.begin(), m_selections.end(), finder ); if ( it != m_selections.end() ) { return SetDisplayValue( (*it) ); } TSSetLastError( TS_INVALID_PARAMETERS ); return TSGetLastError(); } else { m_bModifiedFlag = true; m_sDisplayValue = sNewDisplayValue; return TS_OK; } } else { TSSetLastError( TS_NOT_UPDATEABLE ); return TSGetLastError(); } } int TSDisplayField::SetDisplayValue( const TSRecordRef* pNewSelection ) { if ( IsUpdateable() ) { if ( IsMultiSelect() ) { ClearDisplayValue(); return AddToDisplayValueForMultiSelect( pNewSelection ); } else { m_bModifiedFlag = true; m_sDisplayValue = pNewSelection->GetItemName(); char str[16]; sprintf( str, "%d", pNewSelection->GetItemId() ); m_sInternalValue = str; return TS_OK; } } else { TSSetLastError( TS_NOT_UPDATEABLE ); return TSGetLastError(); } } int TSDisplayField::SetItemId( int nNewItemId ) { nNewItemId; TSSetLastError( TS_ERROR ); return TSGetLastError(); } int TSDisplayField::SetTableId( int nNewTableId ) { nNewTableId; TSSetLastError( TS_ERROR ); return TSGetLastError(); } TSString TSDisplayField::StringDump( TSString sIndentation ) { char tmpBuf[64]; TSString sSpacer = sIndentation + " "; TSString s = sIndentation + "Display Field:\n"; s += sSpacer + "Item Name = "; s += m_sItemName + "\n"; s += sSpacer + "Item Id = "; sprintf( tmpBuf, "%ld", m_nItemId ); s += tmpBuf; s += "\n"; s += sSpacer + "Table Id = "; sprintf( tmpBuf, "%ld", m_nTableId ); s += tmpBuf; s += "\n"; s += sSpacer + "Can Update = "; if ( m_bCanUpdate ) { s += "TRUE\n"; } else { s += "FALSE\n"; } s += sSpacer + "Modified Flag = "; if ( m_bModifiedFlag ) { s += "TRUE\n"; } else { s += "FALSE\n"; } s += sSpacer + "Attribute = "; sprintf( tmpBuf, "%ld", m_nAttribute ); s += tmpBuf; s += "\n"; s += sSpacer + "Property = "; sprintf( tmpBuf, "%ld", m_nProperty ); s += tmpBuf; s += "\n"; s += sSpacer + "Required = "; sprintf( tmpBuf, "%ld", m_nRequired ); s += tmpBuf; s += "\n"; s += sSpacer + "Section = "; sprintf( tmpBuf, "%ld", m_nSection ); s += tmpBuf; s += "\n"; s += sSpacer + "Type = "; sprintf( tmpBuf, "%ld", m_nType ); s += tmpBuf; s += "\n"; s += sSpacer + "Use Internal = "; if ( m_bUseInternal ) { s += "TRUE\n"; } else { s += "FALSE\n"; } s += sSpacer + "Internal Value = "; s += m_sInternalValue + "\n"; s += sSpacer + "Display Value = "; s += m_sDisplayValue + "\n"; s += sSpacer + "Prefix = "; s += m_sPrefix + "\n"; s += sSpacer + "Suffix = "; s += m_sSuffix + "\n\n"; TSRecordRefList::iterator itSelect = m_selections.begin(); for ( ; itSelect != m_selections.end(); itSelect++ ) { s += (*itSelect)->StringDump( sIndentation ); } return s; }