lafagnosticuifoundation/clockanim/src/TIMEDEV.CPP
changeset 0 2f259fa3e83a
equal deleted inserted replaced
-1:000000000000 0:2f259fa3e83a
       
     1 // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // source code for the time-device class and derived classes
       
    15 // $Workfile:   TIMEDEV.CPP  $
       
    16 // $Revision:   1.5  $
       
    17 // $Author:   DougF  $
       
    18 // $Date:   07 Jul 1999 16:16:18  $
       
    19 // 
       
    20 //
       
    21 
       
    22 #include "CL_STD.H"
       
    23 
       
    24 _LIT(KFormat1,"%A");
       
    25 _LIT(KFormat2,"%B");
       
    26 _LIT(KFormat3,"%H");
       
    27 _LIT(KFormat4,"%I");
       
    28 _LIT(KFormat5,"%J");
       
    29 _LIT(KFormat6,"%T");
       
    30 _LIT(KFormat7,"%C");
       
    31 _LIT(KFormat8,"%S");
       
    32 
       
    33 //  CMinuteTick
       
    34 CMinuteTick* CMinuteTick::NewL(MObserver& aObserver)
       
    35 	{
       
    36 	CMinuteTick* self = new(ELeave)CMinuteTick(aObserver);
       
    37 	CleanupStack::PushL(self);
       
    38 	self->ConstructL();
       
    39 	CleanupStack::Pop(self);
       
    40 	return self;
       
    41 	}
       
    42 
       
    43 CMinuteTick::CMinuteTick(MObserver& aObserver) : CTimer(CActive::EPriorityStandard), iObserver(aObserver)
       
    44 	{
       
    45 	CActiveScheduler::Add(this);
       
    46 	}
       
    47 
       
    48 CMinuteTick::~CMinuteTick()
       
    49 	{
       
    50 	}
       
    51 
       
    52 void CMinuteTick::CalculateTimeAtNextMinute()
       
    53 	{
       
    54 	iHomeTimeAtNextMinute.HomeTime();
       
    55 	// Add a second to make sure we definitely round up
       
    56 	iHomeTimeAtNextMinute+=TTimeIntervalSeconds(1);
       
    57 	iHomeTimeAtNextMinute.RoundUpToNextMinute();
       
    58 	}
       
    59 
       
    60 void CMinuteTick::ReQueueTimer()
       
    61 	{
       
    62 	CalculateTimeAtNextMinute();
       
    63 	At(iHomeTimeAtNextMinute);
       
    64 	}
       
    65 
       
    66 void CMinuteTick::Start()
       
    67 	{
       
    68 	// Only start if not already started
       
    69 	if(!IsActive())
       
    70 		{
       
    71 		ReQueueTimer();
       
    72 		}
       
    73 	}
       
    74 
       
    75 void CMinuteTick::Stop()
       
    76 	{
       
    77 	Cancel();
       
    78 	}
       
    79 
       
    80 void CMinuteTick::RunL()
       
    81 	{
       
    82 	if(iStatus.Int() == KErrNone)
       
    83 		{
       
    84 		// The observer expects universal time not home time
       
    85 		// so pass that back
       
    86 		TTime universalTimeNow;
       
    87 		universalTimeNow.UniversalTime();
       
    88 		iObserver.MinuteTickCompleteL(universalTimeNow);
       
    89 		}
       
    90 	else if(iStatus.Int() != KErrAbort)
       
    91 		{
       
    92 		// Another error has occured assert here to catch it in debug builds
       
    93 		__ASSERT_DEBUG(EFalse,Panic(EClockServerPanicUnexpectedError));
       
    94 		return;
       
    95 		}
       
    96 	// If the At timer has been aborted - this happens when the system
       
    97 	// time is changed then we just need to requeue the timer for the 
       
    98 	// new time
       
    99 	ReQueueTimer();
       
   100 	}
       
   101 
       
   102 
       
   103 // DTimeDevice
       
   104 
       
   105 DTimeDevice::DTimeDevice() : iFocusChangeCallback(CActive::EPriorityStandard)
       
   106 	{
       
   107 	__ASSERT_DEBUG(iDisplay==NULL, Panic(EClockServerPanicNotInitializedToNULL6));
       
   108 	TCallBack focusChangeCallback(FocusChangeCb,this);
       
   109 	iFocusChangeCallback.Set(focusChangeCallback);
       
   110 	}
       
   111 
       
   112 DTimeDevice::~DTimeDevice()
       
   113 	{
       
   114 	TRect rectToInvalidate;
       
   115 	TBool rectToInvalidateExists=EFalse;
       
   116 
       
   117 	if (iDisplay!=NULL)
       
   118 		{
       
   119 		rectToInvalidate=iDisplay->RectToInvalidate();
       
   120 		rectToInvalidateExists=ETrue;
       
   121 		}
       
   122 
       
   123 	delete iDisplay;
       
   124 
       
   125 	if (rectToInvalidateExists)
       
   126 		iWindowFunctions->Invalidate(rectToInvalidate);
       
   127 	//  Delete CMinuteTick object here
       
   128 	delete iMinuteTick;
       
   129 
       
   130 	// Remove ourselves as an event observer
       
   131 	iFunctions->RegisterForNotifications(0);
       
   132 
       
   133 	iFocusChangeCallback.Cancel();
       
   134 	}
       
   135 
       
   136 void DTimeDevice::ConstructLP(const TUint8* aBytePtr, TBool)
       
   137 	{
       
   138 	DoConstructL(aBytePtr);
       
   139 
       
   140 	MAnimGeneralFunctions::TAnimSync sync=MAnimGeneralFunctions::ESyncNone;
       
   141 	TDisplayType* displayType=(TDisplayType*)aBytePtr;
       
   142 	aBytePtr+=sizeof(TDisplayType);
       
   143 	switch (*displayType)
       
   144 		{
       
   145 	case EDisplayDigital:
       
   146 		{
       
   147 		SDigitalDisplayConstructorArgs* digitalArgs=(SDigitalDisplayConstructorArgs*)aBytePtr;
       
   148 		aBytePtr+=sizeof(SDigitalDisplayConstructorArgs);
       
   149 		TInt numTextSections=digitalArgs->iNumTextSections;
       
   150 		DDigitalDisplay* digitalDisplay=new(ELeave) DDigitalDisplay(digitalArgs->iPosition, digitalArgs->iSize, digitalArgs->iMargins, digitalArgs->iShadow, digitalArgs->iBackgroundColor, numTextSections);
       
   151 		CleanupStack::PushL(digitalDisplay);
       
   152 		iDisplayIsAnalogue = EFalse;
       
   153 		sync=MAnimGeneralFunctions::ESyncMinute;
       
   154 		for (TInt i=0; i<numTextSections; ++i)
       
   155 			{
       
   156 			SDigitalDisplayTextSectionConstructorArgs* textSectionArgs=(SDigitalDisplayTextSectionConstructorArgs*)aBytePtr;
       
   157 			aBytePtr+=sizeof(SDigitalDisplayTextSectionConstructorArgs);
       
   158 			DDigitalDisplayTextSection* textSection=new(ELeave) DDigitalDisplayTextSection(*iFunctions, textSectionArgs->iTextColor,
       
   159 																textSectionArgs->iHorizontalAlignment, textSectionArgs->iVerticalAlignment,
       
   160 																textSectionArgs->iHorizontalMargin, textSectionArgs->iVerticalMargin);
       
   161 			CleanupStack::PushL(textSection);
       
   162 			TPtrC format=ReadText(aBytePtr, textSectionArgs->iFormatLength);
       
   163 			HBufC* formatStrippedOfModifiers=format.AllocLC();
       
   164 			TPtr ptrToformatStrippedOfModifiers=formatStrippedOfModifiers->Des();
       
   165 			StripOutCharacter(ptrToformatStrippedOfModifiers, '*');
       
   166 			StripOutCharacter(ptrToformatStrippedOfModifiers, '-');
       
   167 			StripOutCharacter(ptrToformatStrippedOfModifiers, '+');
       
   168 			switch (sync)
       
   169 				{
       
   170 			case MAnimGeneralFunctions::ESyncNone:
       
   171 			case MAnimGeneralFunctions::ESyncDay:
       
   172 				if ((formatStrippedOfModifiers->FindF(KFormat1)!=KErrNotFound) ||
       
   173 					(formatStrippedOfModifiers->FindF(KFormat2)!=KErrNotFound) ||
       
   174 					(formatStrippedOfModifiers->FindF(KFormat3)!=KErrNotFound) ||
       
   175 					(formatStrippedOfModifiers->FindF(KFormat4)!=KErrNotFound) ||
       
   176 					(formatStrippedOfModifiers->FindF(KFormat5)!=KErrNotFound) ||
       
   177 					(formatStrippedOfModifiers->FindF(KFormat6)!=KErrNotFound))
       
   178 					{
       
   179 					sync=MAnimGeneralFunctions::ESyncMinute;
       
   180 					}
       
   181 				// N.B. fall through
       
   182 			case MAnimGeneralFunctions::ESyncMinute:
       
   183 				if ((formatStrippedOfModifiers->FindF(KFormat7)!=KErrNotFound) ||
       
   184 					(formatStrippedOfModifiers->FindF(KFormat8)!=KErrNotFound))
       
   185 					{
       
   186 					sync=MAnimGeneralFunctions::ESyncSecond;
       
   187 					}
       
   188 				// N.B. fall through
       
   189 			case MAnimGeneralFunctions::ESyncSecond:
       
   190 				if (formatStrippedOfModifiers->Locate(TChar(EDigitalDisplayLayoutCharFlashingBlockDelimiter))!=KErrNotFound)
       
   191 					{
       
   192 					sync=MAnimGeneralFunctions::ESyncFlash;
       
   193 					}
       
   194 				// N.B. fall through
       
   195 			case MAnimGeneralFunctions::ESyncFlash:
       
   196 				break;
       
   197 			default:
       
   198 				Panic(EClockServerPanicBadSync1);
       
   199 				break;
       
   200 				}
       
   201 			CleanupStack::PopAndDestroy(); // pop and destroy formatStrippedOfModifiers
       
   202 			textSection->ConstructL(format, textSectionArgs->iFontHandle);
       
   203 			digitalDisplay->AddTextSectionLP(textSection);
       
   204 			CleanupStack::Pop(); // pop off textSection
       
   205 			}
       
   206 
       
   207 		iDisplay=digitalDisplay;
       
   208 		CleanupStack::Pop(); // pop off digitalDisplay
       
   209 		}
       
   210 		break;
       
   211 	case EDisplayAnalog:
       
   212 		{
       
   213 		SAnalogDisplayConstructorArgs* analogArgs=(SAnalogDisplayConstructorArgs*)aBytePtr;
       
   214 		aBytePtr+=sizeof(SAnalogDisplayConstructorArgs);
       
   215 		TInt numHands=analogArgs->iNumHands;
       
   216 		DAnalogDisplay* analogDisplay=new(ELeave) DAnalogDisplay(analogArgs->iPosition, analogArgs->iSize, analogArgs->iMargins, analogArgs->iShadow, numHands);
       
   217 		CleanupStack::PushL(analogDisplay);
       
   218 		analogDisplay->ConstructL(*iFunctions, analogArgs->iFaceHandle, analogArgs->iFaceMaskHandle);
       
   219 		iDisplayIsAnalogue = ETrue;
       
   220 
       
   221 		if (analogArgs->iHasAmPm)
       
   222 			{
       
   223 			SAnalogDisplayAmPm* dateArgs=(SAnalogDisplayAmPm*)aBytePtr;
       
   224 			aBytePtr+=sizeof(SAnalogDisplayAmPm);
       
   225 			analogDisplay->AddAmPmLP(*iFunctions, dateArgs->iPositionRelativeToFace, dateArgs->iSize,
       
   226 										dateArgs->iShadow, dateArgs->iBackgroundColor, dateArgs->iFontHandle, dateArgs->iTextColor);
       
   227 			}
       
   228 
       
   229 		sync=MAnimGeneralFunctions::ESyncMinute;
       
   230 		for (TInt i=0; i<numHands; ++i)
       
   231 			{
       
   232 			SAnalogDisplayHandConstructorArgs* handArgs=(SAnalogDisplayHandConstructorArgs*)aBytePtr;
       
   233 			aBytePtr+=sizeof(SAnalogDisplayHandConstructorArgs);
       
   234 			TInt numHandFeatures=handArgs->iNumFeatures;
       
   235 			TAnalogDisplayHandType handType=handArgs->iType;
       
   236 			switch (sync)
       
   237 				{
       
   238 			case MAnimGeneralFunctions::ESyncNone:
       
   239 			case MAnimGeneralFunctions::ESyncDay:
       
   240 			case MAnimGeneralFunctions::ESyncMinute:
       
   241 				if (handType==EAnalogDisplayHandOneRevPerMinute)
       
   242 					sync=MAnimGeneralFunctions::ESyncSecond;
       
   243 				// N.B. fall through
       
   244 			case MAnimGeneralFunctions::ESyncSecond:
       
   245 				break;
       
   246 			case MAnimGeneralFunctions::ESyncFlash:
       
   247 			default:
       
   248 				Panic(EClockServerPanicBadSync2);
       
   249 				break;
       
   250 				}
       
   251 			DAnalogDisplayHand* hand=new(ELeave) DAnalogDisplayHand(handType, numHandFeatures);
       
   252 			CleanupStack::PushL(hand);
       
   253 			for (TInt j=0; j<numHandFeatures; ++j)
       
   254 				{
       
   255 				TAnalogDisplayHandFeatureType* featureType=(TAnalogDisplayHandFeatureType*)aBytePtr;
       
   256 				aBytePtr+=sizeof(TAnalogDisplayHandFeatureType);
       
   257 				DAnalogDisplayHandFeature* feature=NULL; // dummy initialization to prevent compiler warning
       
   258 				switch (*featureType)
       
   259 					{
       
   260 				case EAnalogDisplayHandFeatureLine:
       
   261 					{
       
   262 					SAnalogDisplayHandLineConstructorArgs* lineArgs=(SAnalogDisplayHandLineConstructorArgs*)aBytePtr;
       
   263 					aBytePtr+=sizeof(SAnalogDisplayHandLineConstructorArgs);
       
   264 					DAnalogDisplayHandLine* line=new(ELeave) DAnalogDisplayHandLine(lineArgs->iPenStyle, lineArgs->iPenColor,
       
   265 																lineArgs->iPenSize, lineArgs->iStartPoint, lineArgs->iEndPoint);
       
   266 					feature=line;
       
   267 					}
       
   268 					break;
       
   269 				case EAnalogDisplayHandFeaturePolyLine:
       
   270 					{
       
   271 					SAnalogDisplayHandPolyLineConstructorArgs* polyLineArgs=(SAnalogDisplayHandPolyLineConstructorArgs*)aBytePtr;
       
   272 					aBytePtr+=sizeof(SAnalogDisplayHandPolyLineConstructorArgs);
       
   273 					TInt numPoints=polyLineArgs->iNumPoints;
       
   274 					DAnalogDisplayHandPolyLine* polyLine=new(ELeave) DAnalogDisplayHandPolyLine(polyLineArgs->iPenStyle,
       
   275 																polyLineArgs->iPenColor, polyLineArgs->iPenSize, polyLineArgs->iBrushStyle,
       
   276 																polyLineArgs->iBrushColor, polyLineArgs->iClosed, numPoints);
       
   277 					CleanupStack::PushL(polyLine);
       
   278 					for (TInt k=0; k<numPoints; ++k)
       
   279 						{
       
   280 						TPoint* point=(TPoint*)aBytePtr;
       
   281 						aBytePtr+=sizeof(TPoint);
       
   282 						polyLine->AddPointLP(*point);
       
   283 						}
       
   284 					feature=polyLine;
       
   285 					CleanupStack::Pop(); // pop off polyLine
       
   286 					}
       
   287 					break;
       
   288 				case EAnalogDisplayHandFeatureCircle:
       
   289 					{
       
   290 					SAnalogDisplayHandCircleConstructorArgs* circleArgs=(SAnalogDisplayHandCircleConstructorArgs*)aBytePtr;
       
   291 					aBytePtr+=sizeof(SAnalogDisplayHandCircleConstructorArgs);
       
   292 					DAnalogDisplayHandCircle* circle=new(ELeave) DAnalogDisplayHandCircle(circleArgs->iPenStyle, circleArgs->iPenColor,
       
   293 																circleArgs->iPenSize, circleArgs->iBrushStyle, circleArgs->iBrushColor,
       
   294 																circleArgs->iCircleCenter, circleArgs->iRadius);
       
   295 					feature=circle;
       
   296 					}
       
   297 					break;
       
   298 				default:
       
   299 					PanicClientFromServer();
       
   300 					break;
       
   301 					}
       
   302 
       
   303 				CleanupStack::PushL(feature);
       
   304 				hand->AddFeatureLP(feature);
       
   305 				CleanupStack::Pop(); // pop off feature
       
   306 				}
       
   307 
       
   308 			analogDisplay->AddHandLP(hand);
       
   309 			CleanupStack::Pop(); // pop off hand
       
   310 			}
       
   311 
       
   312 		iDisplay=analogDisplay;
       
   313 		CleanupStack::Pop(); // pop off analogDisplay
       
   314 		}
       
   315 		break;
       
   316 	default:
       
   317 		PanicClientFromServer();
       
   318 		break;
       
   319 		}
       
   320 
       
   321 	switch (sync)
       
   322 		{
       
   323 	case MAnimGeneralFunctions::ESyncFlash:
       
   324 	case MAnimGeneralFunctions::ESyncSecond:
       
   325 		iSecondsPerUpdate=1;
       
   326 		break;
       
   327 	case MAnimGeneralFunctions::ESyncMinute:
       
   328 		iSecondsPerUpdate=60;
       
   329 		break;
       
   330 	case MAnimGeneralFunctions::ESyncDay:
       
   331 		iSecondsPerUpdate=60*60*24;
       
   332 		break;
       
   333 	case MAnimGeneralFunctions::ESyncNone:
       
   334 	default:
       
   335 		Panic(EClockServerPanicBadSync3);
       
   336 		}
       
   337 	iFunctions->SetSync(sync);
       
   338 	iWindowFunctions->SetRect(iDisplay->RectToInvalidate());
       
   339 	iUniversalTime=TTime(iFunctions->SystemTime());
       
   340 	iDisplay->SetInitialTimeP(Time());
       
   341 
       
   342 	//  Create CMinuteTick object here
       
   343 	iMinuteTick = CMinuteTick::NewL(*this);
       
   344 	
       
   345 	// Add ourselves as an event observer
       
   346 	iFunctions->RegisterForNotifications(EHeartbeatTimer);
       
   347 	// Assume that initially the wserv tick is not enabled. This will be corrected later in AnimateP if incorrect
       
   348 	iAnimatingOnMinTick = ETrue;
       
   349 	// Start the minute tick if conditions are correct
       
   350 	SwitchToMinuteTickIfNecessaryL();
       
   351 	
       
   352 
       
   353 	__ASSERT_ALWAYS(*(TInt*)aBytePtr==KCheckValueForEndOfTimeDeviceConstructionBuf, Panic(EClockServerPanicBadEndOfConstructionBuf));
       
   354 	}
       
   355 
       
   356 TInt DTimeDevice::CommandReplyLP(TInt aOpcode, TAny* aArgs)
       
   357 	{
       
   358 	if (aOpcode&EDisplayCommand)
       
   359 		{
       
   360 		if(aOpcode==EDisplayCommandSetVisible)
       
   361 			{
       
   362 			SDisplayCommandSetVisibleArgs* displayArgs=static_cast<SDisplayCommandSetVisibleArgs*>(aArgs);
       
   363 			if (iVisible!=displayArgs->iVisible)
       
   364 				{
       
   365 				iVisible=displayArgs->iVisible;
       
   366 				// The visibility of the clock has changed make sure the minute tick is in the
       
   367 				// appropriate state for the current visibility
       
   368 				SwitchToMinuteTickIfNecessaryL();
       
   369 				}
       
   370 			}
       
   371 		TFunctions functions(*iFunctions,*iWindowFunctions);
       
   372 		iDisplay->HandleCommandLP(functions, *iGc, Time(), aOpcode, aArgs);
       
   373 		}
       
   374 	else
       
   375 		return DAnimWithUtils::CommandReplyLP(aOpcode, aArgs);
       
   376 	return KErrNone;
       
   377 	}
       
   378 
       
   379 void DTimeDevice::CommandP(TInt aOpcode, TAny* aArgs)
       
   380 	{
       
   381 	DAnimWithUtils::CommandP(aOpcode, aArgs);
       
   382 	}
       
   383 
       
   384 void DTimeDevice::AnimateP(TDateTime* aDateTime)
       
   385 	{
       
   386 	// The wserv heartbeat is operational
       
   387 	if(iAnimatingOnMinTick)
       
   388 		{
       
   389 		// Stop animating on the minute tick	
       
   390 		iAnimatingOnMinTick = EFalse;
       
   391 		// Stop the minute tick
       
   392 		iMinuteTick->Stop();
       
   393 		if(iDisplayIsAnalogue) // Only for analogue display
       
   394 			{
       
   395 			// Enable the second hand
       
   396 			((DAnalogDisplay*)iDisplay)->EnableHands(/*hours*/ETrue, /*mins*/ETrue, /*secs*/ETrue);		
       
   397 			}
       
   398 		else
       
   399 			{
       
   400 			//Enable seconds in digital clock
       
   401 			((DDigitalDisplay*)iDisplay)->LimitTimeResolutionToMinutes(EFalse);
       
   402 			}
       
   403 		} 
       
   404 		
       
   405 	if (aDateTime!=NULL)
       
   406 		iUniversalTime=TTime(*aDateTime);
       
   407 	else if ((iFunctions->Sync()!=MAnimGeneralFunctions::ESyncFlash) || (iFunctions->FlashStateOn()))
       
   408 		iUniversalTime+=iSecondsPerUpdate;
       
   409 	DoAnimateP();
       
   410 	}
       
   411 
       
   412 void DTimeDevice::DoAnimateP()
       
   413 	{
       
   414 	TFunctions functions(*iFunctions,*iWindowFunctions);
       
   415 	iDisplay->UpdateLP(functions, *iGc, Time());
       
   416 	}
       
   417 
       
   418 //  Minute Tick callback function here
       
   419 void DTimeDevice::MinuteTickCompleteL(const TTime& aNewUniversalTime)
       
   420 	{
       
   421 	if(iAnimatingOnMinTick)
       
   422 		{
       
   423 		iUniversalTime = aNewUniversalTime;
       
   424 		DoAnimateP();
       
   425 		CompleteAnimation();
       
   426 		}
       
   427 	}
       
   428 void DTimeDevice::CompleteAnimation()
       
   429 	{
       
   430 	// Do stuff which window server does when it finishes animating us
       
   431 	WindowFunctions()->DeactivateGc();
       
   432 #if defined(__WINS__)
       
   433 	WindowFunctions()->Update();
       
   434 #endif
       
   435 	}
       
   436 
       
   437 void DTimeDevice::HandleNotification(const TWsEvent& aEvent)
       
   438 	{
       
   439 	if(aEvent.Type() == EEventHeartbeatTimerStateChange)
       
   440 		{
       
   441 		TBool started = *(aEvent.Int());
       
   442 		if(started)
       
   443 			{
       
   444 			// Heartbeat timer started
       
   445 			// Indicate we should not animate on the minute tick
       
   446 			iAnimatingOnMinTick = EFalse;
       
   447 			// Stop the minute tick
       
   448 			iMinuteTick->Stop();
       
   449 			if(iDisplayIsAnalogue) // Only for analogue display
       
   450 				{
       
   451 				// Enable the second hand
       
   452 				((DAnalogDisplay*)iDisplay)->EnableHands(/*hours*/ETrue, /*mins*/ETrue, /*secs*/ETrue);		
       
   453 				}
       
   454 			else
       
   455 				{
       
   456 				//Enable seconds in digital clock
       
   457 				((DDigitalDisplay*)iDisplay)->LimitTimeResolutionToMinutes(EFalse);
       
   458 				}
       
   459 			}
       
   460 		else // stopped
       
   461 			{
       
   462 			// Heartbeat timer stopped
       
   463 			// Indicate we should animate on the minute tick
       
   464 			iAnimatingOnMinTick = ETrue;
       
   465 			// Start the minute tick if conditions are correct
       
   466 			SwitchToMinuteTickIfNecessaryL();
       
   467 			}
       
   468 		}
       
   469 	}
       
   470 	
       
   471 void DTimeDevice::SwitchToMinuteTickIfNecessaryL()
       
   472 	{
       
   473 	if(iAnimatingOnMinTick && iVisible)
       
   474 		{
       
   475 		// The clock should be animating on the minute tick and visible
       
   476 		// Check that the minute tick is not active
       
   477 		if(!iMinuteTick->IsActive())
       
   478 			{
       
   479 			// The minute tick has not been started so start and update display
       
   480 			// Start the minute tick
       
   481 			iMinuteTick->Start();
       
   482 			// Update time
       
   483 			iUniversalTime=TTime(iFunctions->SystemTime());
       
   484 			// Update display
       
   485 			if(iDisplayIsAnalogue) // Only for analogue display
       
   486 				{
       
   487 				// Disable the second hand
       
   488 				((DAnalogDisplay*)iDisplay)->DisableHands(/*hours*/EFalse, /*mins*/EFalse, /*secs*/ETrue);	
       
   489 				}
       
   490 			else
       
   491 				{
       
   492 				//Remove seconds from digital clock
       
   493 				((DDigitalDisplay*)iDisplay)->LimitTimeResolutionToMinutes(ETrue);
       
   494 				}
       
   495 			DoAnimateP();
       
   496 			CompleteAnimation();
       
   497 			}
       
   498 		}
       
   499 	else
       
   500 		{
       
   501 		// Conditions are not yet right for animating on minute tick
       
   502 		// make sure tick is Disabled
       
   503 		iMinuteTick->Stop();
       
   504 		}
       
   505 	}
       
   506 
       
   507 void DTimeDevice::FocusChanged(TBool /*aState*/)
       
   508 	{
       
   509 	if(!iFocusChangeCallback.IsActive())
       
   510  		{
       
   511 		iFocusChangeCallback.Call();
       
   512  		}
       
   513 	}
       
   514 
       
   515 void DTimeDevice::RedrawP()
       
   516 	{
       
   517 	iDisplay->DrawP(*iWindowFunctions, *iGc);
       
   518 	}
       
   519 
       
   520 TTime DTimeDevice::Time() const
       
   521 	{
       
   522 	return TimeGivenUniversalTime(iUniversalTime);
       
   523 	}
       
   524 
       
   525 void DTimeDevice::StripOutCharacter(TDes& aText, TChar aCharacter)
       
   526 	{
       
   527 	for (TInt positionOfCharacter=aText.Locate(aCharacter); positionOfCharacter!=KErrNotFound; positionOfCharacter=aText.Locate(aCharacter))
       
   528 		{
       
   529 		aText.Delete(positionOfCharacter,1);
       
   530 		}
       
   531 	}
       
   532 
       
   533 TInt DTimeDevice::FocusChangeCb(TAny* aThisPtr)
       
   534 	{
       
   535 	DTimeDevice* self = (DTimeDevice*)aThisPtr;
       
   536 	self->SwitchToMinuteTickIfNecessaryL();
       
   537 
       
   538 	return KErrNone;
       
   539 	}
       
   540 
       
   541 // DClock
       
   542 
       
   543 DClock::DClock()
       
   544 	{
       
   545 	__DECLARE_NAME(_S("DClock"));
       
   546 	}
       
   547 
       
   548 TInt DClock::CommandReplyLP(TInt aOpcode, TAny* aArgs)
       
   549 	{
       
   550 	switch (aOpcode)
       
   551 		{
       
   552 	case EClockCommandSetUniversalTimeOffset:
       
   553 		{
       
   554 		SClockCommandSetUniversalTimeOffsetArgs* clockArgs=(SClockCommandSetUniversalTimeOffsetArgs*)aArgs;
       
   555 		if (iUniversalTimeOffset!=clockArgs->iUniversalTimeOffset)
       
   556 			{
       
   557 			TFunctions functions(*iFunctions,*iWindowFunctions);
       
   558 			iUniversalTimeOffset=clockArgs->iUniversalTimeOffset;
       
   559 			iDisplay->UpdateLP(functions, *iGc, Time());
       
   560 			}
       
   561 		}
       
   562 		return KErrNone;
       
   563 	default:
       
   564 		return DTimeDevice::CommandReplyLP(aOpcode, aArgs);
       
   565 		}
       
   566 	}
       
   567 
       
   568 void DClock::DoConstructL(const TUint8*& aBytePtr)
       
   569 	{
       
   570 	SClockConstructorArgs* clockArgs=(SClockConstructorArgs*)aBytePtr;
       
   571 	iUniversalTimeOffset=clockArgs->iUniversalTimeOffset;
       
   572 	aBytePtr+=sizeof(SClockConstructorArgs);
       
   573 	}
       
   574 
       
   575 TTime DClock::TimeGivenUniversalTime(const TTime& aUniversalTime) const
       
   576 	{
       
   577 	return aUniversalTime+iUniversalTimeOffset;
       
   578 	}
       
   579