scrsaver/scrsaverplugins/SlideshowPlugin/src/SlideshowModel.cpp
branchRCL_3
changeset 23 e8d784ac1a4b
parent 0 040fcad49f44
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scrsaver/scrsaverplugins/SlideshowPlugin/src/SlideshowModel.cpp	Wed Sep 01 12:30:40 2010 +0100
@@ -0,0 +1,441 @@
+/*
+* Copyright (c) 2006 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:  Takes care of storing and serving the slides
+*               to Slideshow plugin
+*
+*/
+
+
+#include <e32math.h>
+#include <eikenv.h>
+#include <bautils.h>
+
+#include "SlideshowModel.h"
+#include "SlideshowPluginUtils.h"
+
+//------------------------------------------------------------------------------
+// CSlideshowModel::NewL
+//------------------------------------------------------------------------------
+//
+CSlideshowModel* CSlideshowModel::NewL()
+    {
+    CSlideshowModel* self = new (ELeave) CSlideshowModel();
+    
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    
+    return self;
+    }
+
+
+//------------------------------------------------------------------------------
+// CSlideshowModel::~CSlideshowModel
+//------------------------------------------------------------------------------
+//
+CSlideshowModel::~CSlideshowModel()
+    {
+    // Delete slide array
+    if (iSlides)
+        {
+        iSlides->ResetAndDestroy();
+        }
+    delete iSlides;
+    }
+
+
+//------------------------------------------------------------------------------
+// CSlideshowModel::CSlideshowModel
+//------------------------------------------------------------------------------
+//
+CSlideshowModel::CSlideshowModel()
+    : iNextSlide(-1)
+    {
+    }
+
+    
+//------------------------------------------------------------------------------
+// CSlideshowModel::ConstructL
+//------------------------------------------------------------------------------
+//
+void CSlideshowModel::ConstructL()
+    {
+    // Create slide array
+    iSlides = new(ELeave) CArrayPtrFlat<CSlideshowSlide>(
+        KSlideshowSlideArrayGranularity);
+
+    //Get random seed
+    TTime time;
+    time.HomeTime();
+    iRandSeed = time.Int64();
+    }
+
+
+//------------------------------------------------------------------------------
+// CSlideshowModel::NumberOfSlides
+//------------------------------------------------------------------------------
+//
+TInt CSlideshowModel::NumberOfSlides() const
+    {
+    //if the slide array is not NULL, return it's size
+    return iSlides ? iSlides->Count() : 0;
+    }
+    
+  
+//------------------------------------------------------------------------------
+// CSlideshowModel::AppendSlideL
+//------------------------------------------------------------------------------
+//
+void CSlideshowModel::AppendSlideL(CSlideshowSlide* aSlide)
+    {
+    // Sanity check
+    if (!iSlides)
+        {
+        ASSERT(EFalse);
+        return;
+        }
+
+    // Stash it in
+    iSlides->AppendL(aSlide);
+    }
+
+    
+//------------------------------------------------------------------------------
+// CSlideshowModel::InsertSlideL
+//------------------------------------------------------------------------------
+//
+void CSlideshowModel::InsertSlideL(TInt aIndex, CSlideshowSlide* aSlide)
+    {
+    if ((iSlides) && (aIndex >= 0) && (aIndex <= NumberOfSlides()))
+        {
+        // Squeeze it in
+        iSlides->InsertL(aIndex, aSlide);
+        }
+    else
+        {
+        ASSERT(EFalse);
+        }
+    }
+    
+
+//------------------------------------------------------------------------------
+// CSlideshowModel::DeleteSlide
+//------------------------------------------------------------------------------
+//
+void CSlideshowModel::DeleteSlide(TInt aIndex)
+    {
+    //Sanity check
+    if ((iSlides) && (aIndex >= 0) && (aIndex <= NumberOfSlides()))
+        {
+        // Grab hold of the slide for deletion, remove from array
+        // and compress the array
+        CSlideshowSlide* ptr = iSlides->At(aIndex);
+        
+        iSlides->Delete(aIndex);
+        delete ptr;
+        iSlides->Compress();
+        
+        }
+    else
+        {
+        ASSERT(EFalse);
+        }
+    }
+
+
+//------------------------------------------------------------------------------
+// CSlideshowModel::DeleteAll
+//------------------------------------------------------------------------------
+//
+void CSlideshowModel::DeleteAll()
+    {
+    //Sanity check
+    if (iSlides)
+        {
+        iSlides->ResetAndDestroy();
+        }
+    
+    iCurrentSlide = 0;
+    iNextSlide = -1;
+    }
+
+    
+//------------------------------------------------------------------------------
+// CSlideshowModel::SlideAt
+//------------------------------------------------------------------------------
+//
+CSlideshowSlide* CSlideshowModel::SlideAt(TInt aIndex) const
+    {
+    if ((iSlides) && (aIndex >= 0) && (aIndex < NumberOfSlides()))
+        {
+        //return the postion object
+        return iSlides->At(aIndex);
+        }
+    else
+        {
+        return NULL;
+        }
+    }
+
+
+//------------------------------------------------------------------------------
+// CSlideshowModel::NextSlide
+//------------------------------------------------------------------------------
+//
+CSlideshowSlide* CSlideshowModel::NextSlide(TBool /*aRandom */)
+    {
+    if (iNextSlide < 0)
+        {
+        // Next slide could not be prepared, or preparenextslide not called
+        return NULL;
+        }
+    
+    CSlideshowSlide* pSlide = SlideAt(iNextSlide);
+
+    if (!pSlide)
+        {
+        // Apparently there are no more slides - wrap around
+        iCurrentSlide = -1;
+        iNextSlide = 0;
+        pSlide = SlideAt(iNextSlide);
+        }
+
+    iCurrentSlide = iNextSlide;
+    return pSlide;
+    }
+
+    
+//------------------------------------------------------------------------------
+// CSlideshowModel::PrepareNextSlide
+//------------------------------------------------------------------------------
+//
+void CSlideshowModel::PrepareNextSlide(TBool aRandom, const TSize& aTargetSize)
+    {
+    SSPLOGGER_WRITE("Model::PrepareNextSlide(), model busy");
+    
+    SSPLOGGER_WRITEF(_L("SPP: iCurrentSlide %d, iNextSlide %d"),
+                     iCurrentSlide, iNextSlide);
+    
+    TBool slideOK = EFalse;
+    while (!slideOK)
+        {
+        TInt nSlides = NumberOfSlides();
+        // Any point in continuing?
+        if (nSlides == 0)
+            {
+            iNextSlide = -1;
+            break;
+            }
+
+        // Special cases, 1 or 2 slides only
+        if (nSlides == 1)
+            {
+            iNextSlide = 0;
+            SSPLOGGER_WRITEF(_L("SPP: One slide, next slide %d"), iNextSlide);
+            }
+        else if (nSlides == 2)
+            {
+            // Switch between slides even if random
+            iNextSlide = (iNextSlide == 0 ? 1 : 0);
+            SSPLOGGER_WRITEF(_L("SPP: 2 slides, next slide %d"), iNextSlide);            
+            }
+        else
+            {
+            // We got at least 3 slides, and can also do random
+            if (aRandom)
+                {
+                // Make sure we won't pick the same slide  
+                do
+                    {
+                    iNextSlide = Random(nSlides - 1);                    
+                    }
+                while (iNextSlide == iCurrentSlide);
+
+                SSPLOGGER_WRITEF(_L("SPP: Random, next slide %d"), iNextSlide);
+                }
+            else
+                {
+                iNextSlide++;
+
+                // Wrap?
+                if (iNextSlide >= nSlides)
+                    {
+                    SSPLOGGER_WRITE("Wrapping...");
+                    iNextSlide = 0;
+                    }
+                SSPLOGGER_WRITEF(_L("SPP: Continuous, next slide %d"),
+                                 iNextSlide);
+                }
+            }
+
+        // Get the slide
+        CSlideshowSlide* pSlide = SlideAt(iNextSlide);
+
+        if (!pSlide)
+            {
+            // Should not have happened - start from beginning
+            iNextSlide = 0;
+            SSPLOGGER_WRITEF(_L("SPP: Wrapping, next slide %d"),
+                    	iNextSlide);
+            pSlide = SlideAt(iNextSlide);
+            }
+
+        if (pSlide)
+            {
+            // Try loading the image, if image does not already exist
+            if (!pSlide->IsSlideDecoded())
+                {
+                SSPLOGGER_WRITE("Preparing next slide");
+               	if(iCurrentSlide != iNextSlide)
+                	{
+                	// relese currently deleted image from RAM.( We dont have caching)
+                	ReleaseCurrentSlide();
+               	    }
+               	if ((TInt)ETrue == pSlide->CouldNotDecodeFile())
+               		{
+               		// could not decode this file last time. so delete this slide from the 
+               		// list of slide and go to the next one.
+               		DeleteSlide(iNextSlide);
+                    iNextSlide--;
+                    continue;
+               		}
+                TRAPD(err, pSlide->PrepareSlideL(aTargetSize));
+                if (err == KErrNone)
+                	{
+                    //wait for slide to load.
+                	iCurrentSlide = iNextSlide;
+                    SSPLOGGER_WRITE("Started Decoding Wait");                    
+                    break;
+                    }
+                else
+                    {
+                    // Apparently the file was not a loadable image -
+                    // remove from slideset and try again
+                    SSPLOGGER_WRITEF(_L("SSP: Deleting slide %d"), iNextSlide);                    
+                    DeleteSlide(iNextSlide);
+                    iNextSlide--;
+                    continue; // can not load this image, go to the next one.
+                    }
+                }
+             else
+                {
+                // Slide is already decoded. This is cool, if the file is
+                // still there. Otherwise lose image and go on.
+                // should not come here as we dont any caching 
+                SSPLOGGER_WRITEF(_L("Slide %d already has image"), iNextSlide);
+
+                if (!BaflUtils::FileExists(CEikonEnv::Static()->FsSession(), 
+                    *(pSlide->FileName())))
+                    {
+                    SSPLOGGER_WRITE("Slide image file gone, dropping image");
+                    pSlide->ReleaseImage();
+                    continue; // continue with next image
+                    }
+                else
+                	{
+                	if(iCurrentSlide != iNextSlide)
+                		{
+                		ReleaseCurrentSlide();
+               	     	}
+                     break;
+                	}
+               }
+           }
+        }
+    SSPLOGGER_WRITE("Model::PrepareNextSlide() end, model no longer busy");    
+    }
+
+
+//------------------------------------------------------------------------------
+// CSlideshowModel::ReleaseCurrentSlide
+//------------------------------------------------------------------------------
+//
+void CSlideshowModel::ReleaseCurrentSlide()
+	{
+	CSlideshowSlide* pSlide = SlideAt(iCurrentSlide);
+	if(pSlide)
+		{
+		pSlide->ReleaseImage();
+		}
+	}
+
+
+//------------------------------------------------------------------------------
+// CSlideshowModel::ReleaseNextSlide
+//------------------------------------------------------------------------------
+//
+void CSlideshowModel::ReleaseNextSlide()
+    {
+    CSlideshowSlide* pSlide = SlideAt(iNextSlide);
+    if(pSlide)
+		{
+		pSlide->ReleaseImage();
+		}
+    iNextSlide --;
+    }
+
+
+//------------------------------------------------------------------------------
+// CSlideshowModel::SetReserveL
+//------------------------------------------------------------------------------
+//
+void CSlideshowModel::SetReserveL(TInt aCount)
+    {
+    if ((iSlides) && (aCount >= NumberOfSlides()))
+        {
+        iSlides->SetReserveL(aCount);
+        }
+    }
+
+//------------------------------------------------------------------------------
+// CSlideshowModel::SlideStatus
+//------------------------------------------------------------------------------
+//
+TInt CSlideshowModel::SlideStatus(CSlideshowSlide* aSlide)
+	{
+	 if(!aSlide)
+		 {
+		 return KStatusNoSlide;
+		 }
+	 else if(aSlide->IsSlideDecoded())
+		 {
+		 return KStatusSlideDecoded;
+		 }
+	 else if(aSlide->IsDecodingInProgress())
+		 {
+		 return KStatusDecodingInProgress;
+		 }
+	 else if (aSlide->CouldNotDecodeFile())
+		 {
+		 return KStatusSlideDecodeingFailed;
+		 }
+		 
+	 return KStatusSlideNotDecoding;
+	}
+    
+
+
+//------------------------------------------------------------------------------
+// CSlideshowModel::Random
+//------------------------------------------------------------------------------
+//
+TInt CSlideshowModel::Random(TInt aMax, TInt aMin /* = 0 */)
+    {
+    TInt range = aMax - aMin;
+    TInt rand = Math::Rand(iRandSeed);  
+    return (rand % range);
+    }
+
+
+//  End of File