extras/calcsoft/src/CalcDoc.cpp
branchRCL_3
changeset 21 10c6e6d6e4d9
--- /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 <e32cmn.h>
+#include <s32file.h>
+// 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<KCalcMaxNumberWidth> 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<KCalcMaxNumberWidth> 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