HexEdit/CalcDlg.cpp
void CCalcDlg::add_hist()
{
	// We get the expression that generated the result as a full string to be added
	// to the tape (history window) and the drop down (history list)
	CString strTape = CString(get_expr(true));   // string to be added to calc tape window
	CString strDrop;                             // string to be added to drop down history
	if (strTape.GetLength() <= 100)
		strDrop = strTape;
	else
		strDrop = strTape.Left(100) + "...";  // Don't add a really long string to the drop down

	// The first char of the string stores the radix as a char ('2'-'9', 'A'-'Z')
	char buf[64];
	if (state_ > CALCINTEXPR)
		buf[0] = ' ';               // space indicates we don't care about the radix because it's not an int
	else if (orig_radix_ < 10)
		buf[0] = orig_radix_ + '0';      // 0-9
	else
		buf[0] = orig_radix_ - 10 + 'A'; // A-Z
	buf[1] = '\0';

	CString * pResult = new CString(buf);   // Create the string to attach to the new drop-down hist list element

	// Put the result string on the heap so we can store it in the drop list item data
	edit_.get();   // Get the result string into current_str_
	int len = current_str_.GetLength();

	CString strAnswerOrigRadix;                        // result as string in original radix
	if (state_ >= CALCINTRES && state_ <= CALCINTEXPR)
	{
		// Short int result that needs conversion to original radix
		int numlen = mpz_sizeinbase(current_.get_mpz_t(), orig_radix_) + 3;
		char *numbuf = new char[numlen];
		numbuf[numlen-1] = '\xCD';

		// Get the number as a string
		mpz_get_str(numbuf, theApp.hex_ucase_? -orig_radix_ : orig_radix_, current_.get_mpz_t());
		ASSERT(numbuf[numlen-1] == '\xCD');

		strAnswerOrigRadix = numbuf;
		delete[] numbuf;

		// Add to the tape (history window)
		mm_->m_wndCalcHist.Add(strTape + " = " + 
							   strAnswerOrigRadix +
							   //CString(radix_ == orig_radix_ ? "" : radix_string(orig_radix_)) );
							   CString(radix_string(orig_radix_)) );
	}
	else
	{
		CString strType;
		switch (state_)
		{
		case CALCREALEXPR:
		case CALCREALRES:
			strType = " [REAL (dec)]";
			break;
		case CALCDATEEXPR:
		case CALCDATERES:
			strType = " [DATE]";
			break;
		case CALCSTREXPR:
		case CALCSTRRES:
			strType = " [STRING]";
			break;
		case CALCBOOLEXPR:
		case CALCBOOLRES:
			strType = " [BOOLEAN]";
			break;
		}
		mm_->m_wndCalcHist.Add(strTape + " = " + (CString)current_str_ + strType);
	}

	if (len < 2000 && state_ > CALCINTLIT)
	{
		// Short non-int result
		*pResult += current_str_;
	}
	else if (state_ > CALCINTLIT)      // not integer - probably a very long string
	{
		// Long non-int result
		*pResult += current_str_.Left(2000);
		*pResult += " ...";
	}
	else if (len < 2000 && radix_ != orig_radix_)
	{
		// Short int result in original radix
		*pResult += strAnswerOrigRadix;
	}
	else if (len < 2000 && radix_ == orig_radix_)
	{
		*pResult += current_str_;
	}
	else
	{
		// Large integer result (displayed in radix 10)
		const int extra = 2 + 1;  // Need room for possible sign, EOS, and dummy (\xCD) byte
		int numlen = mpz_sizeinbase(current_.get_mpz_t(), 10) + extra;
		char *numbuf = new char[numlen];
		numbuf[numlen-1] = '\xCD';

		// Get the number as a string
		mpz_get_str(numbuf, 10, current_.get_mpz_t());
		ASSERT(numbuf[numlen-1] == '\xCD');

		// Copy the most sig. digits copying sign if present, including decimal point after 1st digit
		const char * pin = numbuf;
		char * pout = buf;
		if (*pin == '-')
		{
			*pout = '-';
			++pin, ++pout;
			//numlen--;         // mpz_sizeinbase does not return room for sign
		}
		*pout++ = *pin++;
		*pout++ = theApp.dec_point_;
		for (int ii = 0; ii < 40; ++ii)
		{
			if (isdigit(*pin) || isalpha(*pin))
				*pout++ = *pin;
			++pin;
		}
		delete[] numbuf;

		// Add the exponent (decimal) and add initial 'A' to indicate that this number uses base 10
		sprintf(pout, " E %d", numlen - 1 - extra);
		*pResult = CString("A") + buf;
	}

	// Find any duplicate entry in the history (expression and result) and remove it
	for (int ii = 0; ii < ctl_edit_combo_.GetCount(); ++ii)
	{
		// Get expression and result for this item
		CString ss, * ps;
		ctl_edit_combo_.GetLBText(ii, ss);
		ps = (CString *)ctl_edit_combo_.GetItemDataPtr(ii);

		if (ss == strDrop && ps != NULL && *ps == *pResult)
		{
			// We also have to delete the string (here and when combo is destroyed)
			// It would have been easy just to handle WM_DELETEITEM but 
			// this is only sent for owner-draw combo boxes apparently.
			delete ps;

			ctl_edit_combo_.DeleteString(ii);       // remove this entry

			break;  // exit loop since the same value could not appear again
		}
	}

	// Add the new entry (at the top of the drop-down list)
	ctl_edit_combo_.InsertString(0, strDrop);
	ctl_edit_combo_.SetItemDataPtr(0, pResult);
}
// add_hist() adds to the history list of previous calculations by adding to the
// drop-down list (in which the main edit box resides) when a result is generated.
// The expression that created the result is added as a string to the drop-list, and
// the data-item associated with that contains the result (as a string).
// The result is displayed in atip window when the user holds the mouse over an
// expression in the history list.
// Duplicates are removed from the list but since the same expression can generate
// different result (eg if it use a variable name) then a duplicate is only one
// where both the expression and the result match.

add_hist() adds to the history list of previous calculations by adding to the
drop-down list (in which the main edit box resides) when a result is generated.
The expression that created the result is added as a string to the drop-list, and
the data-item associated with that contains the result (as a string).
The result is displayed in atip window when the user holds the mouse over an
expression in the history list.
Duplicates are removed from the list but since the same expression can generate
different result  then a duplicate is only one
where both the expression and the result match.
add_hist () adds to the history list of previous calculations by adding to the drop - down list ( in which the main edit box resides ) when a result is generated . The expression that created the result is added as a string to the drop - list and the data - item associated with that contains the result ( as a string ) . The result is displayed in atip window when the user holds the mouse over an expression in the history list . Duplicates are removed from the list but since the same expression can generate different result then a duplicate is only one where both the expression and the result match .
void CCalcDlg::add_hist()
{
	CString strTape = CString(get_expr(true));   
	CString strDrop;                             
	if (strTape.GetLength() <= 100)
		strDrop = strTape;
	else
		strDrop = strTape.Left(100) + "...";  
	char buf[64];
	if (state_ > CALCINTEXPR)
		buf[0] = ' ';               
	else if (orig_radix_ < 10)
		buf[0] = orig_radix_ + '0';      
	else
		buf[0] = orig_radix_ - 10 + 'A'; 
	buf[1] = '\0';
	CString * pResult = new CString(buf);   
	edit_.get();   
	int len = current_str_.GetLength();
	CString strAnswerOrigRadix;                        
	if (state_ >= CALCINTRES && state_ <= CALCINTEXPR)
	{
		int numlen = mpz_sizeinbase(current_.get_mpz_t(), orig_radix_) + 3;
		char *numbuf = new char[numlen];
		numbuf[numlen-1] = '\xCD';
		mpz_get_str(numbuf, theApp.hex_ucase_? -orig_radix_ : orig_radix_, current_.get_mpz_t());
		ASSERT(numbuf[numlen-1] == '\xCD');
		strAnswerOrigRadix = numbuf;
		delete[] numbuf;
		mm_->m_wndCalcHist.Add(strTape + " = " + 
							   strAnswerOrigRadix +
							   CString(radix_string(orig_radix_)) );
	}
	else
	{
		CString strType;
		switch (state_)
		{
		case CALCREALEXPR:
		case CALCREALRES:
			strType = " [REAL (dec)]";
			break;
		case CALCDATEEXPR:
		case CALCDATERES:
			strType = " [DATE]";
			break;
		case CALCSTREXPR:
		case CALCSTRRES:
			strType = " [STRING]";
			break;
		case CALCBOOLEXPR:
		case CALCBOOLRES:
			strType = " [BOOLEAN]";
			break;
		}
		mm_->m_wndCalcHist.Add(strTape + " = " + (CString)current_str_ + strType);
	}
	if (len < 2000 && state_ > CALCINTLIT)
	{
		*pResult += current_str_;
	}
	else if (state_ > CALCINTLIT)      
	{
		*pResult += current_str_.Left(2000);
		*pResult += " ...";
	}
	else if (len < 2000 && radix_ != orig_radix_)
	{
		*pResult += strAnswerOrigRadix;
	}
	else if (len < 2000 && radix_ == orig_radix_)
	{
		*pResult += current_str_;
	}
	else
	{
		const int extra = 2 + 1;  
		int numlen = mpz_sizeinbase(current_.get_mpz_t(), 10) + extra;
		char *numbuf = new char[numlen];
		numbuf[numlen-1] = '\xCD';
		mpz_get_str(numbuf, 10, current_.get_mpz_t());
		ASSERT(numbuf[numlen-1] == '\xCD');
		const char * pin = numbuf;
		char * pout = buf;
		if (*pin == '-')
		{
			*pout = '-';
			++pin, ++pout;
		}
		*pout++ = *pin++;
		*pout++ = theApp.dec_point_;
		for (int ii = 0; ii < 40; ++ii)
		{
			if (isdigit(*pin) || isalpha(*pin))
				*pout++ = *pin;
			++pin;
		}
		delete[] numbuf;
		sprintf(pout, " E %d", numlen - 1 - extra);
		*pResult = CString("A") + buf;
	}
	for (int ii = 0; ii < ctl_edit_combo_.GetCount(); ++ii)
	{
		CString ss, * ps;
		ctl_edit_combo_.GetLBText(ii, ss);
		ps = (CString *)ctl_edit_combo_.GetItemDataPtr(ii);
		if (ss == strDrop && ps != NULL && *ps == *pResult)
		{
			delete ps;
			ctl_edit_combo_.DeleteString(ii);       
			break;  
		}
	}
	ctl_edit_combo_.InsertString(0, strDrop);
	ctl_edit_combo_.SetItemDataPtr(0, pResult);
}
void CCalcDlg :: add_hist ( ) { CString strTape = CString ( get_expr ( true ) ) ; CString strDrop ; if ( strTape . GetLength ( ) <= 100 ) strDrop = strTape ; else strDrop = strTape . Left ( 100 ) + " " ; char buf [ 64 ] ; if ( state_ > CALCINTEXPR ) buf [ 0 ] = ' ' ; else if ( orig_radix_ < 10 ) buf [ 0 ] = orig_radix_ + ' ' ; else buf [ 0 ] = orig_radix_ - 10 + ' ' ; buf [ 1 ] = ' \0 ' ; CString * pResult = new CString ( buf ) ; edit_ . get ( ) ; int len = current_str_ . GetLength ( ) ; CString strAnswerOrigRadix ; if ( state_ >= CALCINTRES && state_ <= CALCINTEXPR ) { int numlen = mpz_sizeinbase ( current_ . get_mpz_t ( ) , orig_radix_ ) + 3 ; char * numbuf = new char [ numlen ] ; numbuf [ numlen - 1 ] = ' \xCD ' ; mpz_get_str ( numbuf , theApp . hex_ucase_ ? - orig_radix_ : orig_radix_ , current_ . get_mpz_t ( ) ) ; ASSERT ( numbuf [ numlen - 1 ] == ' \xCD ' ) ; strAnswerOrigRadix = numbuf ; delete [ ] numbuf ; mm_ -> m_wndCalcHist . Add ( strTape + " " + strAnswerOrigRadix + CString ( radix_string ( orig_radix_ ) ) ) ; } else { CString strType ; switch ( state_ ) { case CALCREALEXPR : case CALCREALRES : strType = " " ; break ; case CALCDATEEXPR : case CALCDATERES : strType = " " ; break ; case CALCSTREXPR : case CALCSTRRES : strType = " " ; break ; case CALCBOOLEXPR : case CALCBOOLRES : strType = " " ; break ; } mm_ -> m_wndCalcHist . Add ( strTape + " " + ( CString ) current_str_ + strType ) ; } if ( len < 2000 && state_ > CALCINTLIT ) { * pResult += current_str_ ; } else if ( state_ > CALCINTLIT ) { * pResult += current_str_ . Left ( 2000 ) ; * pResult += " " ; } else if ( len < 2000 && radix_ != orig_radix_ ) { * pResult += strAnswerOrigRadix ; } else if ( len < 2000 && radix_ == orig_radix_ ) { * pResult += current_str_ ; } else { const int extra = 2 + 1 ; int numlen = mpz_sizeinbase ( current_ . get_mpz_t ( ) , 10 ) + extra ; char * numbuf = new char [ numlen ] ; numbuf [ numlen - 1 ] = ' \xCD ' ; mpz_get_str ( numbuf , 10 , current_ . get_mpz_t ( ) ) ; ASSERT ( numbuf [ numlen - 1 ] == ' \xCD ' ) ; const char * pin = numbuf ; char * pout = buf ; if ( * pin == ' ' ) { * pout = ' ' ; ++ pin , ++ pout ; } * pout ++ = * pin ++ ; * pout ++ = theApp . dec_point_ ; for ( int ii = 0 ; ii < 40 ; ++ ii ) { if ( isdigit ( * pin ) || isalpha ( * pin ) ) * pout ++ = * pin ; ++ pin ; } delete [ ] numbuf ; sprintf ( pout , " " , numlen - 1 - extra ) ; * pResult = CString ( " " ) + buf ; } for ( int ii = 0 ; ii < ctl_edit_combo_ . GetCount ( ) ; ++ ii ) { CString ss , * ps ; ctl_edit_combo_ . GetLBText ( ii , ss ) ; ps = ( CString * ) ctl_edit_combo_ . GetItemDataPtr ( ii ) ; if ( ss == strDrop && ps != NULL && * ps == * pResult ) { delete ps ; ctl_edit_combo_ . DeleteString ( ii ) ; break ; } } ctl_edit_combo_ . InsertString ( 0 , strDrop ) ; ctl_edit_combo_ . SetItemDataPtr ( 0 , pResult ) ; }
add_hist() adds to the history list of previous calculations by adding to the
drop-down list (in which the main edit box resides) when a result is generated.
add_hist () adds to the history list of previous calculations by adding to the drop - down list ( in which the main edit box resides ) when a result is generated .
// We get the expression that generated the result as a full string to be added
 // to the tape (history window) and the drop down (history list)
 // string to be added to calc tape window
 // string to be added to drop down history
 // Don't add a really long string to the drop down
 // The first char of the string stores the radix as a char ('2'-'9', 'A'-'Z')
 // space indicates we don't care about the radix because it's not an int
 // 0-9
 // A-Z
 // Create the string to attach to the new drop-down hist list element
 // Put the result string on the heap so we can store it in the drop list item data
 // Get the result string into current_str_
 // result as string in original radix
 // Short int result that needs conversion to original radix
 // Get the number as a string
 // Add to the tape (history window)
 //CString(radix_ == orig_radix_ ? "" : radix_string(orig_radix_)) );
 // Short non-int result
 // not integer - probably a very long string
 // Long non-int result
 // Short int result in original radix
 // Large integer result (displayed in radix 10)
 // Need room for possible sign, EOS, and dummy (\xCD) byte
 // Get the number as a string
 // Copy the most sig. digits copying sign if present, including decimal point after 1st digit
 //numlen--;         // mpz_sizeinbase does not return room for sign
 // Add the exponent (decimal) and add initial 'A' to indicate that this number uses base 10
 // Find any duplicate entry in the history (expression and result) and remove it
 // Get expression and result for this item
 // We also have to delete the string (here and when combo is destroyed)
 // It would have been easy just to handle WM_DELETEITEM but 
 // this is only sent for owner-draw combo boxes apparently.
 // remove this entry
 // exit loop since the same value could not appear again
 // Add the new entry (at the top of the drop-down list)
