|
1 /* |
|
2 * Copyright (c) 2005 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: Screensaver GifAnimation plug-in container source file |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 #include <eikenv.h> |
|
23 #include <w32std.h> |
|
24 #include <e32base.h> |
|
25 #include <e32std.h> |
|
26 |
|
27 #include <IHLImageFactory.h> // IHLImageFactory |
|
28 #include <IHLViewerFactory.h> // IHLViewerFactory |
|
29 #include <MIHLImageViewer.h> // MIHLImageViewer |
|
30 #include <MIHLFileImage.h> // MIHLFileImage |
|
31 #include <MIHLBitmap.h> // MIHLBitmap |
|
32 #include <MIHLImageViewer.h> // MIHLImageViewer |
|
33 #include <MIHLViewerObserver.h> |
|
34 #include <bautils.h> |
|
35 |
|
36 #include "GifAnimationPlugin.h" |
|
37 #include "GifAnimationUtils.h" |
|
38 |
|
39 |
|
40 // ======== MEMBER FUNCTIONS ======== |
|
41 |
|
42 // --------------------------------------------------------------------------- |
|
43 // Instance factory |
|
44 // --------------------------------------------------------------------------- |
|
45 // |
|
46 CGifAnimationPluginControl* CGifAnimationPluginControl::NewL( |
|
47 CCoeControl *aParentControl, |
|
48 MPluginAdapter* aPluginAdapter ) |
|
49 { |
|
50 ASSERT( aPluginAdapter ); |
|
51 DBG_TRACE_FN_BEGIN; |
|
52 CGifAnimationPluginControl* tmp = |
|
53 new ( ELeave )CGifAnimationPluginControl(); |
|
54 CleanupStack::PushL( tmp ); |
|
55 tmp->ConstructL( aParentControl, aPluginAdapter ); |
|
56 CleanupStack::Pop(); |
|
57 DBG_TRACE_FN_END; |
|
58 return tmp; |
|
59 } |
|
60 |
|
61 // --------------------------------------------------------------------------- |
|
62 // 2nd phase constructor |
|
63 // --------------------------------------------------------------------------- |
|
64 // |
|
65 void CGifAnimationPluginControl::ConstructL( CCoeControl* aParentControl, |
|
66 MPluginAdapter* aPluginAdapter ) |
|
67 { |
|
68 DBG_TRACE_FN_BEGIN; |
|
69 |
|
70 iPluginAdapter = aPluginAdapter; |
|
71 isViewerBitmapChangedL = EFalse; |
|
72 |
|
73 if ( aParentControl != NULL ) |
|
74 { |
|
75 CreateWindowL( aParentControl ); |
|
76 } |
|
77 else |
|
78 { |
|
79 CreateWindowL(); |
|
80 } |
|
81 ActivateL(); |
|
82 |
|
83 MakeVisible( ETrue ); // make it invisible for now |
|
84 |
|
85 DBG_TRACE_FN_END; |
|
86 } |
|
87 |
|
88 // --------------------------------------------------------------------------- |
|
89 // Constructor |
|
90 // --------------------------------------------------------------------------- |
|
91 // |
|
92 CGifAnimationPluginControl::CGifAnimationPluginControl() |
|
93 : iSourceImage( NULL ), |
|
94 iDrawingBitmap( NULL ), |
|
95 iScalingBitmap( NULL ), |
|
96 iScalingBitmapMask( NULL ), |
|
97 iEngine( NULL ), |
|
98 iAnimationState( EAnimationNotReady ), |
|
99 iLastError( KErrNone ) |
|
100 { |
|
101 DBG_TRACE_FN_BEGIN; |
|
102 // nothing goes here |
|
103 DBG_TRACE_FN_END; |
|
104 } |
|
105 |
|
106 // --------------------------------------------------------------------------- |
|
107 // Destructor. |
|
108 // --------------------------------------------------------------------------- |
|
109 // |
|
110 CGifAnimationPluginControl::~CGifAnimationPluginControl() |
|
111 { |
|
112 DBG_TRACE_FN_BEGIN; |
|
113 |
|
114 DeleteAnimation(); |
|
115 |
|
116 iPluginAdapter = NULL; |
|
117 |
|
118 DBG_TRACE_FN_END; |
|
119 } |
|
120 |
|
121 // --------------------------------------------------------- |
|
122 // Loads the image into display. |
|
123 // Param aImageFileName image file name - expected to be valid image |
|
124 // --------------------------------------------------------- |
|
125 // |
|
126 void CGifAnimationPluginControl::LoadImageL( const TDesC& aImageFileName ) |
|
127 { |
|
128 DBG_TRACE_FN_BEGIN; |
|
129 iFileName.Copy( aImageFileName ); |
|
130 |
|
131 iLastError = KErrNotReady; // if asked before loading is complete+Draw() |
|
132 TRAPD( error, DoImageLoadingL() ); |
|
133 if ( error ) |
|
134 { |
|
135 iLastError = error; |
|
136 DeleteAnimation(); |
|
137 DBG_TRACE_FN_END; |
|
138 User::Leave( error ); // re-throw it |
|
139 } |
|
140 else |
|
141 { |
|
142 DBG_TRACE( "Animation loaded" ); |
|
143 iAnimationState = EAnimationLoading; |
|
144 iLastError = KErrNone; |
|
145 } |
|
146 DBG_TRACE_FN_END; |
|
147 } |
|
148 |
|
149 // --------------------------------------------------------- |
|
150 // Return ETrue if loaded image is animation. |
|
151 // --------------------------------------------------------- |
|
152 // |
|
153 TBool CGifAnimationPluginControl::IsAnimation() const |
|
154 { |
|
155 DBG_TRACE_FN_BEGIN; |
|
156 if ( iSourceImage |
|
157 && iLastError == KErrNone ) // we did not have any error loading picture |
|
158 { |
|
159 DBG_TRACE_FN_END; |
|
160 return iSourceImage->IsAnimation(); |
|
161 } |
|
162 DBG_TRACE_FN_END; |
|
163 return EFalse; |
|
164 } |
|
165 |
|
166 |
|
167 // --------------------------------------------------------- |
|
168 // Return TInt with image loading error. |
|
169 // --------------------------------------------------------- |
|
170 // |
|
171 TBool CGifAnimationPluginControl::GetLastError() const |
|
172 { |
|
173 DBG_TRACE_FN_BEGIN; |
|
174 // |
|
175 DBG_TRACE_FN_END; |
|
176 return iLastError; |
|
177 } |
|
178 |
|
179 // --------------------------------------------------------- |
|
180 // Start animation. |
|
181 // --------------------------------------------------------- |
|
182 // |
|
183 void CGifAnimationPluginControl::StartAnimationL() |
|
184 { |
|
185 DBG_TRACE_FN_BEGIN; |
|
186 |
|
187 if ( iEngine == NULL ) // animation was stopped, |
|
188 { // need to re-load animation file |
|
189 DoImageLoadingL(); |
|
190 } |
|
191 |
|
192 // start animation |
|
193 if ( iEngine && IsAnimation() ) |
|
194 { |
|
195 iEngine->Play(); |
|
196 iAnimationState = EAnimationPlaying; |
|
197 } |
|
198 |
|
199 DBG_TRACE_FN_END; |
|
200 } |
|
201 |
|
202 // --------------------------------------------------------- |
|
203 // Stop animation. |
|
204 // --------------------------------------------------------- |
|
205 // |
|
206 void CGifAnimationPluginControl::StopAnimation() |
|
207 { |
|
208 DBG_TRACE_FN_BEGIN; |
|
209 |
|
210 // bugfix for JPYO-6KXHRW |
|
211 MakeVisible( EFalse ); |
|
212 |
|
213 |
|
214 // instead of just stopping player, we delete it. |
|
215 // This is because of stability issues with the start-stop-destroy cycle |
|
216 DeleteAnimation(); |
|
217 DBG_TRACE_FN_END; |
|
218 } |
|
219 |
|
220 // --------------------------------------------------------- |
|
221 // Called when size is changed. |
|
222 // --------------------------------------------------------- |
|
223 // |
|
224 void CGifAnimationPluginControl::SizeChanged() |
|
225 { |
|
226 DBG_TRACE_FN_BEGIN; |
|
227 if ( iEngine ) |
|
228 { |
|
229 iEngine->SetViewerSize( Size() ); |
|
230 } |
|
231 DBG_TRACE_FN_END; |
|
232 } |
|
233 |
|
234 // --------------------------------------------------------------------------- |
|
235 // Overriden CCoeControl::Draw() |
|
236 // --------------------------------------------------------------------------- |
|
237 // |
|
238 void CGifAnimationPluginControl::Draw( const TRect& /*aRect*/ ) const |
|
239 { |
|
240 //DBG_TRACE_FN_BEGIN; |
|
241 CWindowGc& gc = SystemGc(); |
|
242 TRect rect( Rect() ); |
|
243 |
|
244 DBG_TRACE( "Draw: Clearing background" ); |
|
245 gc.Clear( Rect() ); |
|
246 gc.SetBrushColor( KRgbBlack ); |
|
247 gc.SetBrushStyle( CGraphicsContext::ESolidBrush); |
|
248 gc.DrawRect( rect ); |
|
249 |
|
250 if ( iDrawingBitmap |
|
251 && iEngine |
|
252 && iLastError == KErrNone // loading was successful |
|
253 && isViewerBitmapChangedL ) // need to check whether first ViewerBitmapChangedL |
|
254 // has been called; |
|
255 { |
|
256 TSize screenSize( rect.Size() ); |
|
257 TPoint destinationPoint( |
|
258 ( screenSize.iWidth-iTargetNewSize.iWidth ) / 2, |
|
259 ( screenSize.iHeight-iTargetNewSize.iHeight ) / 2 ); |
|
260 |
|
261 TSize drawingBitmapSize( iDrawingBitmap->Bitmap().SizeInPixels() ); |
|
262 if ( drawingBitmapSize.iHeight == iTargetNewSize.iHeight |
|
263 && drawingBitmapSize.iWidth == iTargetNewSize.iWidth ) |
|
264 { |
|
265 // we use unscaled version as size is Ok |
|
266 iDrawingBitmap->Draw( gc, |
|
267 destinationPoint, |
|
268 iTargetNewSize ); |
|
269 } |
|
270 else |
|
271 { |
|
272 // we use scaled version |
|
273 if ( iDrawingBitmap->HasMask() ) |
|
274 { |
|
275 gc.BitBltMasked( destinationPoint, |
|
276 iScalingBitmap, |
|
277 iTargetNewSize, |
|
278 iScalingBitmapMask, |
|
279 EFalse ); |
|
280 } |
|
281 else |
|
282 { |
|
283 gc.BitBlt( destinationPoint, |
|
284 iScalingBitmap ); |
|
285 } |
|
286 } |
|
287 } |
|
288 else // image is not ready or broken |
|
289 { |
|
290 DBG_TRACE( "image is not ready or broken" ); |
|
291 } |
|
292 //DBG_TRACE_FN_END; |
|
293 } |
|
294 |
|
295 // --------------------------------------------------------- |
|
296 // CGifAnimationPluginControl::DoImageLoadingL |
|
297 // --------------------------------------------------------- |
|
298 // |
|
299 void CGifAnimationPluginControl::DoImageLoadingL() |
|
300 { |
|
301 DBG_TRACE_FN_BEGIN; |
|
302 |
|
303 RFs& fs = CEikonEnv::Static()->FsSession(); |
|
304 TBool fileExists = BaflUtils::FileExists( fs, iFileName ); |
|
305 if ( !fileExists ) |
|
306 { |
|
307 DBG_TRACE_FN_END; |
|
308 User::Leave( KErrPathNotFound ); |
|
309 } |
|
310 |
|
311 |
|
312 RFile fileHandle; |
|
313 CleanupClosePushL( fileHandle ); |
|
314 iLastError = fileHandle.Open( fs, iFileName, EFileRead | EFileShareReadersOnly ); |
|
315 User::LeaveIfError(iLastError); |
|
316 |
|
317 // delete old instances, if any |
|
318 DeleteAnimation(); |
|
319 |
|
320 // create new objects |
|
321 if ( iDrawingBitmap == NULL ) |
|
322 { |
|
323 iDrawingBitmap = IHLBitmap::CreateL(); |
|
324 } |
|
325 |
|
326 TInt drmOption( 0 ); |
|
327 if ( isPreviewMode ) |
|
328 { |
|
329 drmOption = MIHLFileImage::EOptionNoDRMConsume; |
|
330 } |
|
331 iSourceImage = IHLImageFactory::OpenFileImageL( fileHandle, |
|
332 0, // image index |
|
333 drmOption ); |
|
334 |
|
335 // calculate target size so that picture fits the screen and centered |
|
336 TSize sourceSize( iSourceImage->Size() ); |
|
337 TSize maxSize = Size(); |
|
338 |
|
339 iTargetSize = TSize( Min( sourceSize.iWidth, maxSize.iWidth ), |
|
340 Min( sourceSize.iHeight, maxSize.iHeight ) ); |
|
341 |
|
342 if ( sourceSize.iWidth < maxSize.iWidth |
|
343 && sourceSize.iHeight < maxSize.iHeight ) |
|
344 { |
|
345 // scale up N-times |
|
346 TInt upScale = Min( maxSize.iWidth / sourceSize.iWidth, |
|
347 maxSize.iHeight / sourceSize.iHeight ); |
|
348 iTargetSize = TSize( sourceSize.iWidth * upScale, |
|
349 sourceSize.iHeight * upScale ); |
|
350 const TUint32 options( 0 ); // no flags set |
|
351 // we do not want IHL do scaling, so targetSize= sourceSize |
|
352 iEngine = IHLViewerFactory::CreateImageViewerL( sourceSize, |
|
353 *iSourceImage, |
|
354 *iDrawingBitmap, |
|
355 *this, |
|
356 options ); |
|
357 iTargetNewSize = iTargetSize; |
|
358 } |
|
359 else |
|
360 { |
|
361 //The image needs to be scaled down. We pass the target size to |
|
362 //IHL so that it doesn't come back with an OOM situation in case |
|
363 //the resolution is too high. |
|
364 // scale up N-times |
|
365 TReal downScale = Min( TReal(maxSize.iWidth) / TReal(sourceSize.iWidth), |
|
366 TReal(maxSize.iHeight) / TReal(sourceSize.iHeight) ); |
|
367 iTargetSize = TSize( sourceSize.iWidth * downScale, |
|
368 sourceSize.iHeight * downScale ); |
|
369 const TUint32 options( 0 ); // no flags set |
|
370 TReal widthRatio( TReal( iTargetSize.iWidth ) / TReal( sourceSize.iWidth ) ); |
|
371 TReal heightRatio( TReal( iTargetSize.iHeight ) / TReal( sourceSize.iHeight ) ); |
|
372 if( options & MIHLImageViewer::EOptionIgnoreAspectRatio ) |
|
373 { |
|
374 downScale = ( widthRatio > heightRatio ) ? widthRatio : heightRatio; |
|
375 } |
|
376 else |
|
377 { |
|
378 downScale = ( widthRatio < heightRatio ) ? widthRatio : heightRatio; |
|
379 } |
|
380 TReal widthZoomRatio( downScale ); |
|
381 TReal heightZoomRatio( downScale ); |
|
382 if( options & MIHLImageViewer::EOptionIgnoreAspectRatio ) |
|
383 { |
|
384 TReal widthRatio( TReal( iTargetSize.iWidth ) / TReal( sourceSize.iWidth ) ); |
|
385 TReal heightRatio( TReal( iTargetSize.iHeight ) / TReal( sourceSize.iHeight ) ); |
|
386 if( widthRatio < heightRatio ) |
|
387 { |
|
388 widthZoomRatio = widthZoomRatio * widthRatio / heightRatio; |
|
389 } |
|
390 else |
|
391 { |
|
392 heightZoomRatio = heightZoomRatio * heightRatio / widthRatio; |
|
393 } |
|
394 } |
|
395 iTargetNewSize = TSize( sourceSize.iWidth * widthZoomRatio, |
|
396 sourceSize.iHeight * heightZoomRatio ); |
|
397 // we do not want IHL do scaling, so targetSize= sourceSize |
|
398 iEngine = IHLViewerFactory::CreateImageViewerL( iTargetSize, |
|
399 *iSourceImage, |
|
400 *iDrawingBitmap, |
|
401 *this, |
|
402 options ); |
|
403 } |
|
404 |
|
405 // create bitmaps needed for manual scaling |
|
406 TDisplayMode dMode = CEikonEnv::Static()->DefaultDisplayMode(); |
|
407 if ( iScalingBitmap == NULL ) |
|
408 { |
|
409 iScalingBitmap = new( ELeave ) CFbsBitmap; |
|
410 iScalingBitmap->Create( iTargetSize, dMode ); |
|
411 } |
|
412 |
|
413 if ( iScalingBitmapMask == NULL ) |
|
414 { |
|
415 iScalingBitmapMask = new( ELeave ) CFbsBitmap; |
|
416 iScalingBitmapMask->Create( iTargetSize, EGray256 ); |
|
417 } |
|
418 |
|
419 CleanupStack::PopAndDestroy( &fileHandle ); |
|
420 DBG_TRACE_FN_END; |
|
421 } |
|
422 |
|
423 // --------------------------------------------------------- |
|
424 // CGifAnimationPluginControl::CheckFileIsValidL |
|
425 // --------------------------------------------------------- |
|
426 // |
|
427 void CGifAnimationPluginControl::CheckFileIsValidL( |
|
428 const TDesC& aImageFileName ) |
|
429 { |
|
430 DBG_TRACE_FN_BEGIN; |
|
431 |
|
432 ASSERT( aImageFileName.Size() ); |
|
433 CGifAnimationPluginControl* temp = |
|
434 new ( ELeave )CGifAnimationPluginControl(); |
|
435 CleanupStack::PushL( temp ); |
|
436 temp->SetSize( TSize( 100, 100 ) ); |
|
437 temp->SetPreviewMode(); |
|
438 temp->LoadImageL( aImageFileName ); |
|
439 temp->DeleteAnimation(); |
|
440 CleanupStack::PopAndDestroy( temp ); |
|
441 |
|
442 DBG_TRACE_FN_END; |
|
443 } |
|
444 |
|
445 // --------------------------------------------------------- |
|
446 // CGifAnimationPluginControl::DeleteAnimation |
|
447 // --------------------------------------------------------- |
|
448 // |
|
449 void CGifAnimationPluginControl::DeleteAnimation() |
|
450 { |
|
451 DBG_TRACE_FN_BEGIN; |
|
452 if ( iEngine ) |
|
453 { |
|
454 iAnimationState = EAnimationNotReady; |
|
455 iEngine->Stop(); |
|
456 delete iEngine; |
|
457 iEngine = NULL; |
|
458 } |
|
459 |
|
460 if ( iSourceImage ) |
|
461 { |
|
462 delete iSourceImage; |
|
463 iSourceImage = NULL; |
|
464 } |
|
465 |
|
466 if ( iDrawingBitmap ) |
|
467 { |
|
468 delete iDrawingBitmap; |
|
469 iDrawingBitmap = NULL; |
|
470 } |
|
471 |
|
472 if ( iScalingBitmap ) |
|
473 { |
|
474 delete iScalingBitmap; |
|
475 iScalingBitmap = NULL; |
|
476 } |
|
477 |
|
478 if ( iScalingBitmapMask ) |
|
479 { |
|
480 delete iScalingBitmapMask; |
|
481 iScalingBitmapMask = NULL; |
|
482 } |
|
483 |
|
484 |
|
485 DBG_TRACE_FN_END; |
|
486 } |
|
487 |
|
488 // --------------------------------------------------------- |
|
489 // Handle bitmap change notifications. State is changed accordingly |
|
490 // if this is the first frame. |
|
491 // --------------------------------------------------------- |
|
492 // |
|
493 void CGifAnimationPluginControl::ViewerBitmapChangedL() |
|
494 { |
|
495 switch ( iAnimationState ) |
|
496 { |
|
497 case EAnimationLoading: |
|
498 { |
|
499 iAnimationState = EAnimationPlaying; |
|
500 break; |
|
501 } |
|
502 case EAnimationPlaying: |
|
503 { |
|
504 // do nothing |
|
505 break; |
|
506 } |
|
507 case EAnimationNotReady: |
|
508 default: |
|
509 { |
|
510 break; |
|
511 } |
|
512 } |
|
513 |
|
514 if( iAnimationState == EAnimationPlaying ) |
|
515 { |
|
516 if ( iDrawingBitmap |
|
517 && iEngine |
|
518 && iLastError == KErrNone ) // loading was successful |
|
519 { |
|
520 TSize drawingBitmapSize( iDrawingBitmap->Bitmap().SizeInPixels() ); |
|
521 if ( drawingBitmapSize.iHeight == iTargetNewSize.iHeight |
|
522 && drawingBitmapSize.iWidth == iTargetNewSize.iWidth ) |
|
523 { |
|
524 // we do not need to do scaling |
|
525 } |
|
526 else |
|
527 { |
|
528 // we need to do scaling |
|
529 CFbsBitmapDevice* bitmapDevice = CFbsBitmapDevice::NewL( iScalingBitmap ); |
|
530 CleanupStack::PushL(bitmapDevice); |
|
531 CFbsBitGc* graphicsContext = NULL; |
|
532 User::LeaveIfError( bitmapDevice->CreateContext( graphicsContext ) ); |
|
533 CleanupStack::PushL( graphicsContext ); |
|
534 TRect srcRect( iSourceImage->Size() ); |
|
535 graphicsContext->DrawBitmap( iTargetSize, &iDrawingBitmap->Bitmap(), srcRect ); |
|
536 CleanupStack::PopAndDestroy( 2 );//graphicsContext,bitmapDevice |
|
537 |
|
538 if ( iDrawingBitmap->HasMask() ) |
|
539 { |
|
540 CFbsBitmapDevice* bitmapMaskDevice = CFbsBitmapDevice::NewL( iScalingBitmapMask ); |
|
541 CleanupStack::PushL(bitmapMaskDevice); |
|
542 CFbsBitGc* graphicsMaskContext = NULL; |
|
543 User::LeaveIfError( bitmapMaskDevice->CreateContext( graphicsMaskContext ) ); |
|
544 CleanupStack::PushL( graphicsMaskContext ); |
|
545 graphicsMaskContext->DrawBitmap( iTargetSize, &iDrawingBitmap->Mask(), srcRect ); |
|
546 CleanupStack::PopAndDestroy( 2 );//graphicsContext,bitmapDevice |
|
547 } |
|
548 } |
|
549 } |
|
550 isViewerBitmapChangedL = ETrue; |
|
551 MakeVisible( ETrue ); |
|
552 DrawNow(); |
|
553 } |
|
554 } |
|
555 |
|
556 // --------------------------------------------------------- |
|
557 // Handles engine errors. |
|
558 // --------------------------------------------------------- |
|
559 // |
|
560 void CGifAnimationPluginControl::ViewerError( TInt aError ) |
|
561 { |
|
562 DBG_TRACE_FN_BEGIN; |
|
563 iLastError = aError; |
|
564 HandleCallback( aError ); |
|
565 DBG_TRACE_FN_END; |
|
566 } |
|
567 |
|
568 |
|
569 // --------------------------------------------------------- |
|
570 // Handles error codes; stores the error |
|
571 // --------------------------------------------------------- |
|
572 // |
|
573 void CGifAnimationPluginControl::HandleCallback( TInt aError ) |
|
574 { |
|
575 DBG_TRACE_FN_BEGIN; |
|
576 |
|
577 if ( aError ) |
|
578 { |
|
579 InformPluginFinished(); |
|
580 } |
|
581 |
|
582 DBG_TRACE_FN_END; |
|
583 } |
|
584 |
|
585 |
|
586 // --------------------------------------------------------- |
|
587 // Informs that plug-in wants to terminate |
|
588 // --------------------------------------------------------- |
|
589 // |
|
590 void CGifAnimationPluginControl::InformPluginFinished() |
|
591 { |
|
592 |
|
593 ASSERT( iPluginAdapter ); |
|
594 |
|
595 StopAnimation(); |
|
596 |
|
597 TRAP_IGNORE(iPluginAdapter->PluginFinishedL()); |
|
598 } |
|
599 |
|
600 void CGifAnimationPluginControl::SetPreviewMode() |
|
601 { |
|
602 isPreviewMode = ETrue; |
|
603 } |