diff -r 41b775cdc0c8 -r 10c6e6d6e4d9 extras/calcsoft/src/CalcDoc.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extras/calcsoft/src/CalcDoc.cpp Wed Sep 01 12:29:54 2010 +0100 @@ -0,0 +1,562 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0"" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Document class, CCalcDocument +* Derived from CEikDocument +* The history of inputted data is held. +* The memory of four-arithmetical-operations operation +* or a calculation result is held. +* The last result and memory are saved at a file and +* it restores. +* +*/ + + + +// INCLUDE FILES +#include "CalcDoc.h" +#include "CalcEditline.h" +#include "CalcAppUi.h" +#include "CalcApp.h" +#include "CalcEnv.h" +#include "CalcHistory.h" +#include "e32math.h" +#include +#include +// CONSTANTS +const TReal64 KCalcDefaultMemory(0.0); +const TReal64 KCalcDefaultLastResult(0.0); +const TReal64 KCalcDefaultZero(1E-12); + +_LIT( KCalculatorFilename,"Calcsoft.ini"); +_LIT(KDelimiter, ":"); + +// ================= MEMBER FUNCTIONS ======================= + +// Two-phased constructor. +CCalcDocument* CCalcDocument::NewL + (CEikApplication& aApp) + { + CCalcDocument* self = new (ELeave) CCalcDocument(aApp); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +// Destructor +CCalcDocument::~CCalcDocument() + { + delete iHistory; + } + +// --------------------------------------------------------- +// CCalcDocument::CalculateAndAddHistoryL +// This function is called when State is changed to State3 or State5. +// (other items were commented in a header). +// --------------------------------------------------------- +// +TReal64 CCalcDocument::CalculateAndAddHistoryL + (TReal64 aOperand, + const TCalcEditLine& aLine) + { + iProvisionalResult = CalculateL(aOperand, aLine.Operator()); + iHistory->Add(aLine); // Add a line to history. + return iProvisionalResult; + } + +// --------------------------------------------------------- +// CCalcDocument::CalculateAndNoHistoryL +// This function is called when the calculations is not +// written to the Outputsheet (sqrt and percent in some cases). +// (other items were commented in a header). +// --------------------------------------------------------- +// +TReal64 CCalcDocument::CalculateAndNoHistoryL + (TReal64 aOperand, + const TCalcEditLine& aLine) + { + TReal64 result = CalculateL(aOperand, aLine.Operator()); + return result; + } + +// --------------------------------------------------------- +// CCalcDocument::CalculateAndModifyHistoryL +// This function is called when the output needs to be edited +// before it is displayed in the Outputsheet. This function +// may call the CalculateL twice, because it may need to +// calculate the percent first. +// (other items were commented in a header). +// --------------------------------------------------------- +// +TReal64 CCalcDocument::CalculateAndModifyHistoryL + (TReal64 aOperand, + TCalcEditLine& aLine, + TCalcEditLine::TCalcOperatorType aOperator) + { + if (aOperator == TCalcEditLine::ECalcMultiply) + iProvisionalResult = CalculateL(aOperand, aLine.Operator()); + else + { + TReal64 iTempResult = CalculateL(aOperand, aLine.Operator()); + iProvisionalResult = CalculateL(iTempResult, aOperator); + } + + aLine.SetOperator(aOperator); + // Get the percent character from iCalcAppEnv (it uses the resource + // file to get the character). + TChar character((iCalcAppEnv->OutSheetOperator(TCalcEditLine::ECalcPercent))[0]); + aLine.AppendNumberStringL(character); // Add percent to the line + iHistory->Add(aLine); // Add a line to history. + return iProvisionalResult; + } + +// --------------------------------------------------------- +// CCalcDocument::AddEqualLineAndUpdateLastResult +// This is called when "Equal" command is selected. +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CCalcDocument::AddEqualLineAndUpdateLastResultL() + { + TCalcEditLine line; + line.SetOperator(TCalcEditLine::ECalcEqual); + line.SetNumber(iProvisionalResult); + iHistory->Add(line); // Add a line to history. + iLastResult = iProvisionalResult; + SaveStateL(); + } + +// --------------------------------------------------------- +// CCalcDocument::AddEmptyLine +// Add a empty line +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CCalcDocument::AddEmptyLine() + { + TCalcEditLine line; + iHistory->Add(line); + } + +// --------------------------------------------------------- +// CCalcDocument::MemorySave +// Save a memory from value of current editor. +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CCalcDocument::MemorySaveL + (TReal64 aNewMemory) + { + iMemory = aNewMemory; + SaveStateL(); + } + + +// --------------------------------------------------------- +// CCalcDocument::HasMemory +// Check memory non-zero. +// (other items were commented in a header). +// --------------------------------------------------------- +// +TBool CCalcDocument::HasMemory() const + { + return (iMemory != 0.0); + } + +// --------------------------------------------------------- +// CCalcDocument::Memory +// Return memory. +// (other items were commented in a header). +// --------------------------------------------------------- +// +TReal64 CCalcDocument::Memory() const + { + return (iMemory); + } + +// --------------------------------------------------------- +// CCalcDocument::MemoryClear +// Clear memory. +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CCalcDocument::MemoryClearL() + { + iMemory = 0.0; + SaveStateL(); + } + +// ---------------------------------------------------- +// CCalcDocument::LastResult +// Return Last result. +// (other items were commented in a header). +// ---------------------------------------------------- +// +TReal64 CCalcDocument::LastResult() const + { + return (iLastResult); + } + +// ---------------------------------------------------- +// CCalcDocument::ProvisionalResult +// Return provisional result +// (other items were commented in a header). +// ---------------------------------------------------- +// +TReal64 CCalcDocument::ProvisionalResult() const + { + return iProvisionalResult; + } + + +// ---------------------------------------------------- +// CCalcDocument::History +// Return CCalcHistory class. +// (other items were commented in a header). +// ---------------------------------------------------- +// +CCalcHistory* CCalcDocument::History() const + { + return iHistory; + } + + +// C++ default constructor can NOT contain any code, that +// might leave. +// +CCalcDocument::CCalcDocument + (CEikApplication& aApp) + : CEikDocument(aApp) + { + } + +// Second phase constructor. +void CCalcDocument::ConstructL() + { + iHistory = new (ELeave) CCalcHistory(); + } + +// --------------------------------------------------------- +// CCalcDocument::CalculateL +// Calculate result +// Leave may occur, causes KErrOverflow or KErrDivideByZero. +// (other items were commented in a header). +// --------------------------------------------------------- +// +TReal64 CCalcDocument::CalculateL + (TReal64 aOperand, + TCalcEditLine::TCalcOperatorType aOperator) + { + TReal64 result(iProvisionalResult); + + switch (aOperator) + { + case TCalcEditLine::ECalcAdd: + { + result += aOperand; + if( Abs(result)<= KCalcDefaultZero ) + { + result = 0; + } + break; + } + case TCalcEditLine::ECalcSubtract: + { + result -= aOperand; + if( Abs(result)<= KCalcDefaultZero ) + { + result = 0; + } + break; + } + case TCalcEditLine::ECalcMultiply: + { + result *= aOperand; + break; + } + case TCalcEditLine::ECalcDivide: + { + if ( aOperand == 0 ) + { + iCCalcView->UpdateState( CCalcView::EOperator ); + User::Leave(KErrDivideByZero); // Error causes + } + else + { + result /= aOperand; + } + break; + } + case TCalcEditLine::ECalcSqrt: + { + if ( aOperand < 0 ) + { + User::Leave(KErrNotSupported); // Error causes + } + else + Math::Sqrt(result, aOperand); + break; + } + case TCalcEditLine::ECalcPercent: + { + result = (result * aOperand) / 100; + break; + } + case TCalcEditLine::ECalcOperatorNone: + { + result = aOperand; + break; + } + default: + { + break; + } + } + // Check Result. If overflow, Leave occurs. + CheckResultL(&result); + + // Overflow do not occur + return result; + } + + +// --------------------------------------------------------- +// CCalcDocument::CheckResultL +// Check overflow and underflow +// Leave may occur, causes KErrOverflow. +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CCalcDocument::CheckResultL + (TReal64* aResult) + { + // Set data format + TRealFormat realFormat(KCalcMaxNumberWidth, KCalcMaxDigits); + if ( *aResult >= 0 ) + { + realFormat.iWidth--; + } + realFormat.iType = KRealFormatNoExponent; + realFormat.iTriLen = 0; // Delimit character is nothing + TLocale locale; + TChar separator(locale.DecimalSeparator()); + + realFormat.iPoint = separator; + + TBuf buffer; + TInt code = buffer.Num(*aResult, realFormat); + + if(KErrOverflow == code || KErrUnderflow == code) + { + TRealFormat realFormat(KCalcMaxNumberWidth); + if ( *aResult >= 0 ) + { + realFormat.iWidth--; + } + realFormat.iType = KRealFormatExponent; + realFormat.iPlaces = 3; + realFormat.iTriLen = 0; // Delimit character is nothing + TLocale locale; + TChar separator(locale.DecimalSeparator()); + + realFormat.iPoint = separator; + + TBuf buffer; + code = buffer.Num(*aResult, realFormat); + } + + switch (code) + { + case KErrOverflow: + { + User::Leave(KErrOverflow); + break; + } + case KErrUnderflow: + { + *aResult = 0.0; + break; + } + default: + { + break; + } + } + + } + + +// --------------------------------------------------------- +// CCalcDocument::ExternalizeL +// Externalising of the last result and memory. +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CCalcDocument::ExternalizeL + (RWriteStream& aStream) const + { + aStream.WriteReal64L(iLastResult); // Write last result + aStream.WriteReal64L(iMemory); // Write memory + } + +// --------------------------------------------------------- +// CCalcDocument::InternalizeL +// Internalising of the last result and memory. +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CCalcDocument::InternalizeL + (RReadStream& aStream) + { + iLastResult = aStream.ReadReal64L(); // Read last result + iMemory = aStream.ReadReal64L(); // Read memory + + // If read value is out of range, + // memory is replaced to default one. + TRAPD(error, CheckResultL(&iMemory)); + if (error == KErrOverflow) + { + iMemory = KCalcDefaultMemory; + } + + // If read value is out of range, + // last result is replaced to default one. + TRAP(error, CheckResultL(&iLastResult)); + if (error == KErrOverflow) + { + iLastResult = KCalcDefaultLastResult; + } + + } + +// --------------------------------------------------------- +// CCalcDocument::CreateAppUiL +// This function is called when Calculator application is opened. +// (other items were commented in a header). +// --------------------------------------------------------- +// +CEikAppUi* CCalcDocument::CreateAppUiL() + { + return new (ELeave) CCalcAppUi; + } + +// --------------------------------------------------------- +// CCalcDocument::SaveStateL +// Store memory and last result +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CCalcDocument::SaveStateL() +{ + RFileWriteStream out; + RFs fileSession; + + User::LeaveIfError(fileSession.Connect()); + CleanupClosePushL(fileSession); + + TFileName filePath; + TBuf<1> tempDes; + TChar driveChar; + + User::LeaveIfError(fileSession.PrivatePath(filePath)); + fileSession.DriveToChar(KDefaultDrive, driveChar); + tempDes.Append(driveChar); + filePath.Insert(0,KDelimiter); + filePath.Insert(0,tempDes); + filePath.Append(KCalculatorFilename); + + TInt err( out.Replace( fileSession, filePath,EFileWrite ) ); + + if( !err ) + { + TRAP( err, ExternalizeL( out ) ); + + out.Close(); + } + + CleanupStack::PopAndDestroy(); + +} + + // --------------------------------------------------------- +// CCalcDocument::LoadStateL +// Restore memory and last result +// This function is called when document file exists. +// (other items were commented in a header). +// --------------------------------------------------------- +// + void CCalcDocument::LoadStateL() + { + RFileReadStream in; + RFs fileSession; + + User::LeaveIfError(fileSession.Connect()); + CleanupClosePushL(fileSession); + + TFileName filePath; + TBuf<1> tempDes; + TChar driveChar; + User::LeaveIfError(fileSession.PrivatePath(filePath)); + fileSession.DriveToChar(KDefaultDrive, driveChar); + tempDes.Append(driveChar); + filePath.Insert(0,KDelimiter); + filePath.Insert(0,tempDes); + filePath.Append(KCalculatorFilename); + + TInt err( in.Open( fileSession, filePath, + EFileRead ) ); + + if( !err ) + { + TRAPD(readErr,InternalizeL( in ) ); + + if ( readErr ) + { + // Internalizing fails. + iMemory = KCalcDefaultMemory; // Reset memoey + iLastResult = KCalcDefaultLastResult; // Reset last result + } + + in.Close(); + } + CleanupStack::PopAndDestroy(); + + SetChanged(EFalse); + + } + +// --------------------------------------------------------- +// CCalcDocument::SetAppEnv +// This function is used to receive a pointer to the +// CCalcAppEnv. +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CCalcDocument::SetAppEnv(CCalcAppEnv* aCalcAppEnv) + { + iCalcAppEnv = aCalcAppEnv; + } + +// --------------------------------------------------------- +// CCalcDocument::SetCalcView +// This function is used to receive a pointer to the +// SetCalcView. +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CCalcDocument::SetCalcView( CCalcView* aCCalcView ) + { + iCCalcView = aCCalcView; + } +// End of File