extras/calcsoft/src/CalcDoc.cpp
branchRCL_3
changeset 21 10c6e6d6e4d9
equal deleted inserted replaced
20:41b775cdc0c8 21:10c6e6d6e4d9
       
     1 /*
       
     2 * Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0""
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Document class, CCalcDocument
       
    15 *                Derived from CEikDocument
       
    16 *                The history of inputted data is held.
       
    17 *                The memory of four-arithmetical-operations operation 
       
    18 *                or a calculation result is held.
       
    19 *                The last result and memory are saved at a file and 
       
    20 *                it restores.
       
    21 *
       
    22 */
       
    23 
       
    24 
       
    25 
       
    26 // INCLUDE FILES  
       
    27 #include    "CalcDoc.h"
       
    28 #include    "CalcEditline.h"
       
    29 #include    "CalcAppUi.h"
       
    30 #include    "CalcApp.h"
       
    31 #include	"CalcEnv.h"
       
    32 #include    "CalcHistory.h"
       
    33 #include	"e32math.h"
       
    34 #include <e32cmn.h>
       
    35 #include <s32file.h>
       
    36 // CONSTANTS
       
    37 const TReal64 KCalcDefaultMemory(0.0);
       
    38 const TReal64 KCalcDefaultLastResult(0.0);
       
    39 const TReal64 KCalcDefaultZero(1E-12);
       
    40 
       
    41 _LIT( KCalculatorFilename,"Calcsoft.ini");
       
    42 _LIT(KDelimiter, ":");
       
    43 
       
    44 // ================= MEMBER FUNCTIONS =======================
       
    45 
       
    46 // Two-phased constructor.
       
    47 CCalcDocument* CCalcDocument::NewL
       
    48                 (CEikApplication& aApp) 
       
    49     {
       
    50     CCalcDocument* self = new (ELeave) CCalcDocument(aApp);
       
    51     CleanupStack::PushL(self);
       
    52     self->ConstructL();
       
    53     CleanupStack::Pop(self);
       
    54     return self;
       
    55     }
       
    56 
       
    57 // Destructor
       
    58 CCalcDocument::~CCalcDocument()
       
    59     {
       
    60     delete iHistory;
       
    61     }
       
    62 
       
    63 // ---------------------------------------------------------
       
    64 // CCalcDocument::CalculateAndAddHistoryL
       
    65 // This function is called when State is changed to State3 or State5. 
       
    66 // (other items were commented in a header).
       
    67 // ---------------------------------------------------------
       
    68 //
       
    69 TReal64 CCalcDocument::CalculateAndAddHistoryL
       
    70                    (TReal64 aOperand,
       
    71                     const TCalcEditLine& aLine)
       
    72     {
       
    73 	iProvisionalResult = CalculateL(aOperand, aLine.Operator()); 
       
    74 	iHistory->Add(aLine);       // Add a line to history.	
       
    75 	return iProvisionalResult;	
       
    76     }
       
    77 
       
    78 // ---------------------------------------------------------
       
    79 // CCalcDocument::CalculateAndNoHistoryL
       
    80 // This function is called when the calculations is not
       
    81 // written to the Outputsheet (sqrt and percent in some cases).
       
    82 // (other items were commented in a header).
       
    83 // ---------------------------------------------------------
       
    84 //
       
    85 TReal64 CCalcDocument::CalculateAndNoHistoryL
       
    86                    (TReal64 aOperand,
       
    87                     const TCalcEditLine& aLine)
       
    88 	{
       
    89 	TReal64 result = CalculateL(aOperand, aLine.Operator()); 
       
    90 	return result;
       
    91 	}
       
    92 
       
    93 // ---------------------------------------------------------
       
    94 // CCalcDocument::CalculateAndModifyHistoryL
       
    95 // This function is called when the output needs to be edited
       
    96 // before it is displayed in the Outputsheet. This function 
       
    97 // may call the CalculateL twice, because it may need to
       
    98 // calculate the percent first.
       
    99 // (other items were commented in a header).
       
   100 // ---------------------------------------------------------
       
   101 //
       
   102 TReal64 CCalcDocument::CalculateAndModifyHistoryL
       
   103                    (TReal64 aOperand,
       
   104                     TCalcEditLine& aLine,
       
   105 					TCalcEditLine::TCalcOperatorType aOperator)
       
   106 	{
       
   107 	if (aOperator == TCalcEditLine::ECalcMultiply)
       
   108 		iProvisionalResult = CalculateL(aOperand, aLine.Operator()); 
       
   109 	else
       
   110 		{
       
   111 		TReal64 iTempResult = CalculateL(aOperand, aLine.Operator()); 
       
   112 		iProvisionalResult = CalculateL(iTempResult, aOperator);
       
   113 		}
       
   114 
       
   115 	aLine.SetOperator(aOperator);
       
   116 	// Get the percent character from iCalcAppEnv (it uses the resource
       
   117 	// file to get the character).
       
   118 	TChar character((iCalcAppEnv->OutSheetOperator(TCalcEditLine::ECalcPercent))[0]);
       
   119 	aLine.AppendNumberStringL(character); // Add percent to the line
       
   120 	iHistory->Add(aLine);       // Add a line to history.	
       
   121 	return iProvisionalResult;
       
   122 	}
       
   123 
       
   124 // ---------------------------------------------------------
       
   125 // CCalcDocument::AddEqualLineAndUpdateLastResult
       
   126 // This is called when "Equal" command is selected. 
       
   127 // (other items were commented in a header).
       
   128 // ---------------------------------------------------------
       
   129 //
       
   130 void CCalcDocument::AddEqualLineAndUpdateLastResultL()
       
   131     {
       
   132     TCalcEditLine line;
       
   133     line.SetOperator(TCalcEditLine::ECalcEqual);
       
   134     line.SetNumber(iProvisionalResult);
       
   135     iHistory->Add(line);         // Add a line to history.
       
   136     iLastResult = iProvisionalResult;
       
   137     SaveStateL();
       
   138     }
       
   139 
       
   140 // ---------------------------------------------------------
       
   141 // CCalcDocument::AddEmptyLine
       
   142 // Add a empty line
       
   143 // (other items were commented in a header).
       
   144 // ---------------------------------------------------------
       
   145 //
       
   146 void CCalcDocument::AddEmptyLine()
       
   147     {
       
   148     TCalcEditLine line;
       
   149     iHistory->Add(line);       
       
   150     }
       
   151 
       
   152 // ---------------------------------------------------------
       
   153 // CCalcDocument::MemorySave
       
   154 // Save a memory from value of current editor.
       
   155 // (other items were commented in a header).
       
   156 // ---------------------------------------------------------
       
   157 //
       
   158 void CCalcDocument::MemorySaveL
       
   159                    (TReal64 aNewMemory)
       
   160     {
       
   161     iMemory = aNewMemory;
       
   162     SaveStateL();
       
   163     }
       
   164 
       
   165 
       
   166 // ---------------------------------------------------------
       
   167 // CCalcDocument::HasMemory
       
   168 // Check memory non-zero.
       
   169 // (other items were commented in a header).
       
   170 // ---------------------------------------------------------
       
   171 //
       
   172 TBool CCalcDocument::HasMemory() const
       
   173     {
       
   174     return (iMemory != 0.0);
       
   175     }
       
   176 
       
   177 // ---------------------------------------------------------
       
   178 // CCalcDocument::Memory
       
   179 // Return memory.
       
   180 // (other items were commented in a header).
       
   181 // ---------------------------------------------------------
       
   182 //
       
   183 TReal64 CCalcDocument::Memory() const
       
   184     {
       
   185     return (iMemory);
       
   186     }
       
   187 
       
   188 // ---------------------------------------------------------
       
   189 // CCalcDocument::MemoryClear
       
   190 // Clear memory.
       
   191 // (other items were commented in a header).
       
   192 // ---------------------------------------------------------
       
   193 //
       
   194 void CCalcDocument::MemoryClearL()
       
   195     {
       
   196     iMemory = 0.0;
       
   197     SaveStateL(); 	
       
   198     }
       
   199 
       
   200 // ----------------------------------------------------
       
   201 // CCalcDocument::LastResult
       
   202 // Return Last result.
       
   203 // (other items were commented in a header).
       
   204 // ----------------------------------------------------
       
   205 //
       
   206 TReal64 CCalcDocument::LastResult() const
       
   207     {
       
   208     return (iLastResult);
       
   209     }
       
   210 
       
   211 // ----------------------------------------------------
       
   212 // CCalcDocument::ProvisionalResult
       
   213 // Return provisional result
       
   214 // (other items were commented in a header).
       
   215 // ----------------------------------------------------
       
   216 //
       
   217 TReal64 CCalcDocument::ProvisionalResult() const
       
   218     {
       
   219     return iProvisionalResult;
       
   220     }
       
   221 
       
   222 
       
   223 // ----------------------------------------------------
       
   224 // CCalcDocument::History
       
   225 // Return CCalcHistory class.
       
   226 // (other items were commented in a header).
       
   227 // ----------------------------------------------------
       
   228 //
       
   229 CCalcHistory* CCalcDocument::History() const
       
   230     {
       
   231     return iHistory;
       
   232     }
       
   233 
       
   234 
       
   235 // C++ default constructor can NOT contain any code, that
       
   236 // might leave.
       
   237 //
       
   238 CCalcDocument::CCalcDocument
       
   239                (CEikApplication& aApp) 
       
   240               : CEikDocument(aApp)
       
   241     {
       
   242     }
       
   243 
       
   244 // Second phase constructor.
       
   245 void CCalcDocument::ConstructL()
       
   246     {
       
   247     iHistory = new (ELeave) CCalcHistory();
       
   248     }
       
   249 
       
   250 // ---------------------------------------------------------
       
   251 // CCalcDocument::CalculateL
       
   252 // Calculate result
       
   253 // Leave may occur, causes KErrOverflow or KErrDivideByZero.
       
   254 // (other items were commented in a header).
       
   255 // ---------------------------------------------------------
       
   256 //
       
   257 TReal64 CCalcDocument::CalculateL
       
   258         (TReal64 aOperand,
       
   259          TCalcEditLine::TCalcOperatorType aOperator) 
       
   260     {
       
   261     TReal64  result(iProvisionalResult);
       
   262 
       
   263     switch (aOperator)
       
   264         {
       
   265         case  TCalcEditLine::ECalcAdd:
       
   266             {
       
   267             result += aOperand;
       
   268             if( Abs(result)<= KCalcDefaultZero )
       
   269             	{
       
   270             	result = 0;
       
   271             	}
       
   272             break;
       
   273             }
       
   274         case  TCalcEditLine::ECalcSubtract:
       
   275             {
       
   276             result -= aOperand;
       
   277             if( Abs(result)<= KCalcDefaultZero )
       
   278             	{
       
   279             	result = 0;
       
   280             	}
       
   281             break;
       
   282             }
       
   283         case  TCalcEditLine::ECalcMultiply:
       
   284             {
       
   285             result *= aOperand;
       
   286             break;
       
   287             }
       
   288         case  TCalcEditLine::ECalcDivide:
       
   289             {
       
   290             if ( aOperand == 0 )
       
   291                 {
       
   292                 iCCalcView->UpdateState( CCalcView::EOperator );
       
   293                 User::Leave(KErrDivideByZero); //  Error causes
       
   294                 }
       
   295             else
       
   296                 {
       
   297                 result /= aOperand;
       
   298                 }
       
   299             break;
       
   300             }
       
   301 		case TCalcEditLine::ECalcSqrt:
       
   302 			{
       
   303 			if ( aOperand < 0 )
       
   304 				{
       
   305                 User::Leave(KErrNotSupported); //  Error causes
       
   306                 }
       
   307 			else
       
   308 				Math::Sqrt(result, aOperand);
       
   309 			break;
       
   310 			}
       
   311 		case TCalcEditLine::ECalcPercent:
       
   312 			{
       
   313 			result = (result * aOperand) / 100;
       
   314 			break;
       
   315 			}
       
   316         case  TCalcEditLine::ECalcOperatorNone:
       
   317             {
       
   318             result = aOperand;
       
   319             break;
       
   320             }
       
   321         default:
       
   322             {
       
   323             break;
       
   324             }
       
   325         }
       
   326     //  Check Result. If overflow, Leave occurs.
       
   327     CheckResultL(&result);
       
   328 
       
   329     // Overflow do not occur
       
   330     return  result;
       
   331     }
       
   332 
       
   333 
       
   334 // ---------------------------------------------------------
       
   335 // CCalcDocument::CheckResultL
       
   336 // Check overflow and underflow  
       
   337 // Leave may occur, causes KErrOverflow.
       
   338 // (other items were commented in a header).
       
   339 // ---------------------------------------------------------
       
   340 //
       
   341 void CCalcDocument::CheckResultL
       
   342                    (TReal64* aResult)    
       
   343     {
       
   344     // Set data format 
       
   345     TRealFormat realFormat(KCalcMaxNumberWidth, KCalcMaxDigits);  
       
   346     if ( *aResult >= 0 )
       
   347         {
       
   348         realFormat.iWidth--;
       
   349         }
       
   350     realFormat.iType = KRealFormatNoExponent;
       
   351     realFormat.iTriLen = 0;  //  Delimit character is nothing
       
   352     TLocale locale;
       
   353     TChar separator(locale.DecimalSeparator());
       
   354     
       
   355     realFormat.iPoint = separator;
       
   356 
       
   357     TBuf<KCalcMaxNumberWidth> buffer;  
       
   358     TInt code = buffer.Num(*aResult, realFormat);
       
   359     
       
   360     if(KErrOverflow == code || KErrUnderflow == code)
       
   361 	    {
       
   362 	    TRealFormat realFormat(KCalcMaxNumberWidth);  
       
   363 	    if ( *aResult >= 0 )
       
   364 	        {
       
   365 	        realFormat.iWidth--;
       
   366 	        }
       
   367 	    realFormat.iType = KRealFormatExponent;
       
   368 	    realFormat.iPlaces = 3;
       
   369 	    realFormat.iTriLen = 0;  //  Delimit character is nothing
       
   370 	    TLocale locale;
       
   371 	    TChar separator(locale.DecimalSeparator());
       
   372 	    
       
   373 	    realFormat.iPoint = separator;
       
   374 
       
   375 	    TBuf<KCalcMaxNumberWidth> buffer;  
       
   376 	    code = buffer.Num(*aResult, realFormat);
       
   377 	    }
       
   378 	
       
   379 	switch (code)
       
   380         {
       
   381         case KErrOverflow:
       
   382             {
       
   383             User::Leave(KErrOverflow);  
       
   384             break;
       
   385             }
       
   386         case KErrUnderflow:
       
   387             {
       
   388             *aResult = 0.0;
       
   389             break;
       
   390             }
       
   391         default:
       
   392             {
       
   393             break;
       
   394             }
       
   395         }
       
   396    
       
   397     }
       
   398 
       
   399 
       
   400 // ---------------------------------------------------------
       
   401 // CCalcDocument::ExternalizeL
       
   402 // Externalising of the last result and memory.
       
   403 // (other items were commented in a header).
       
   404 // ---------------------------------------------------------
       
   405 //
       
   406 void CCalcDocument::ExternalizeL
       
   407         (RWriteStream& aStream) const 
       
   408     {
       
   409     aStream.WriteReal64L(iLastResult);  // Write last result
       
   410     aStream.WriteReal64L(iMemory);      // Write memory
       
   411     }
       
   412 
       
   413 // ---------------------------------------------------------
       
   414 // CCalcDocument::InternalizeL
       
   415 // Internalising of the last result and memory.
       
   416 // (other items were commented in a header).
       
   417 // ---------------------------------------------------------
       
   418 //
       
   419 void CCalcDocument::InternalizeL
       
   420         (RReadStream& aStream) 
       
   421     {
       
   422     iLastResult = aStream.ReadReal64L();    // Read last result
       
   423     iMemory = aStream.ReadReal64L();        // Read memory
       
   424 
       
   425     // If read value is out of range, 
       
   426     // memory is replaced to default one.
       
   427     TRAPD(error, CheckResultL(&iMemory));
       
   428     if (error == KErrOverflow)
       
   429         {
       
   430         iMemory = KCalcDefaultMemory;
       
   431         }
       
   432 
       
   433     // If read value is out of range, 
       
   434     // last result is replaced to default one.
       
   435     TRAP(error, CheckResultL(&iLastResult));
       
   436     if (error == KErrOverflow)
       
   437         {
       
   438         iLastResult = KCalcDefaultLastResult;
       
   439         }
       
   440 
       
   441     }
       
   442 
       
   443 // ---------------------------------------------------------
       
   444 // CCalcDocument::CreateAppUiL
       
   445 // This function is called when Calculator application is opened. 
       
   446 // (other items were commented in a header).
       
   447 // ---------------------------------------------------------
       
   448 //
       
   449 CEikAppUi* CCalcDocument::CreateAppUiL()
       
   450     {
       
   451     return new (ELeave) CCalcAppUi;
       
   452     }
       
   453 
       
   454 // ---------------------------------------------------------
       
   455 // CCalcDocument::SaveStateL
       
   456 // Store memory and last result
       
   457 // (other items were commented in a header).
       
   458 // ---------------------------------------------------------
       
   459 //
       
   460 void CCalcDocument::SaveStateL()
       
   461 {
       
   462 		RFileWriteStream out;
       
   463 		RFs fileSession;
       
   464 			
       
   465 		User::LeaveIfError(fileSession.Connect());
       
   466     	CleanupClosePushL(fileSession);
       
   467     
       
   468     	TFileName filePath;
       
   469 		TBuf<1> tempDes;
       
   470 		TChar driveChar;
       
   471 	   	
       
   472     	User::LeaveIfError(fileSession.PrivatePath(filePath));
       
   473     	fileSession.DriveToChar(KDefaultDrive, driveChar);
       
   474     	tempDes.Append(driveChar);
       
   475     	filePath.Insert(0,KDelimiter);
       
   476     	filePath.Insert(0,tempDes);
       
   477     	filePath.Append(KCalculatorFilename);
       
   478     	
       
   479     	TInt err( out.Replace( fileSession, filePath,EFileWrite ) );
       
   480 	
       
   481 	if( !err )
       
   482 		{
       
   483 		TRAP( err, ExternalizeL( out ) );
       
   484 	
       
   485 		out.Close();
       
   486 		}
       
   487 		  
       
   488   	CleanupStack::PopAndDestroy();
       
   489   		
       
   490 }
       
   491 
       
   492  // ---------------------------------------------------------
       
   493 // CCalcDocument::LoadStateL
       
   494 // Restore memory and last result
       
   495 // This function is called when document file exists. 
       
   496 // (other items were commented in a header).
       
   497 // ---------------------------------------------------------
       
   498 //   
       
   499     void CCalcDocument::LoadStateL()
       
   500     {
       
   501     	RFileReadStream in;
       
   502     	RFs fileSession;
       
   503     		
       
   504     	User::LeaveIfError(fileSession.Connect());
       
   505     	CleanupClosePushL(fileSession);
       
   506 
       
   507 		TFileName filePath;
       
   508 		TBuf<1> tempDes;
       
   509 		TChar driveChar;
       
   510     	User::LeaveIfError(fileSession.PrivatePath(filePath));
       
   511     	fileSession.DriveToChar(KDefaultDrive, driveChar);
       
   512     	tempDes.Append(driveChar);
       
   513     	filePath.Insert(0,KDelimiter);
       
   514     	filePath.Insert(0,tempDes);
       
   515     	filePath.Append(KCalculatorFilename);
       
   516   		
       
   517 		TInt err( in.Open( fileSession, filePath,
       
   518 			EFileRead ) );
       
   519 
       
   520 	if( !err )
       
   521 		{
       
   522 		TRAPD(readErr,InternalizeL( in ) );
       
   523 		
       
   524 		if ( readErr )
       
   525         {
       
   526         // Internalizing fails.
       
   527         iMemory = KCalcDefaultMemory;         // Reset memoey
       
   528         iLastResult = KCalcDefaultLastResult; // Reset last result
       
   529         }
       
   530         
       
   531 		in.Close();
       
   532 		}
       
   533 			CleanupStack::PopAndDestroy();
       
   534 		
       
   535         SetChanged(EFalse);
       
   536 	
       
   537     }
       
   538 
       
   539 // ---------------------------------------------------------
       
   540 // CCalcDocument::SetAppEnv
       
   541 // This function is used to receive a pointer to the
       
   542 // CCalcAppEnv.
       
   543 // (other items were commented in a header).
       
   544 // ---------------------------------------------------------
       
   545 //
       
   546 void CCalcDocument::SetAppEnv(CCalcAppEnv* aCalcAppEnv)
       
   547 	{
       
   548 		iCalcAppEnv = aCalcAppEnv;
       
   549 	}
       
   550 
       
   551 // ---------------------------------------------------------
       
   552 // CCalcDocument::SetCalcView
       
   553 // This function is used to receive a pointer to the
       
   554 // SetCalcView.
       
   555 // (other items were commented in a header).
       
   556 // ---------------------------------------------------------
       
   557 //
       
   558 void CCalcDocument::SetCalcView( CCalcView* aCCalcView )
       
   559     {
       
   560     iCCalcView = aCCalcView;
       
   561     }
       
   562 //  End of File