--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/scrsaver/scrsaverplugins/SlideshowPlugin/src/SlideshowPlugin.cpp Thu Dec 17 08:46:04 2009 +0200
@@ -0,0 +1,1083 @@
+/*
+* 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: This file implements the Slideshow Screensaver plugin.
+*
+*/
+
+
+
+#include <eikenv.h>
+#include <bautils.h>
+#include <data_caging_path_literals.hrh>
+#include <centralrepository.h>
+#include <DRMHelper.h>
+
+// #include <aknnotewrappers.h> AppendSlideL
+// #include <aknnavi.h>
+// #include <aknnavide.h>
+// #include <mmfcontrollerpluginresolver.h>
+#include <DRMHelperServerInternalCRKeys.h>
+#include <mmf/common/mmfcontrollerpluginresolver.h> // For CleanupResetAndDestroyPushL
+#include <pslninternalcrkeys.h>
+#include <pslnslidesetdialoginterface.h>
+
+// #include <NPNExtensions.h>
+#include <coecntrl.h>
+#include <ecom/ecom.h>
+
+#include <ContentListingFactory.h>
+#include <MCLFItem.h>
+
+#include <slideshowplugin.rsg>
+
+#include "SlideshowPlugin.h"
+#include "SlideshowSlide.h"
+#include "SlideshowPluginUtils.h"
+
+// Constants
+const TInt KSecsToMicros = 1000000;
+
+// Slideshow duration times (secs)
+const TInt KMinSlideshowTime = 1;
+const TInt KMaxSlideshowTime = 60;
+const TInt KDefaultSlideshowTime = 5;
+
+// Backlight times (secs)
+const TInt KMinLightsTime = 0;
+const TInt KMaxLightsTime = 30;
+const TInt KDefaultLightsTime = 0;
+
+// Slide times
+// const TInt KMinSlideTime = 1;
+// const TInt KMaxSlideTime = 30;
+const TInt KDefaultSlideTime = 5;
+
+// Refresh interval (Draw() call frequency) in secs.
+// For better resolution kept smaller than slide time
+const TInt KRefreshInterval = 1;
+
+// Slideshow type
+const TInt KSlideshowTypeContinuous = 0;
+const TInt KSlideshowTypeRandom = 1;
+
+// const TInt KScreensaverAnimPluginInterfaceUid = 0x102750CB;
+
+_LIT(KResourceFileName, "Z:SlideshowPlugin.rsc");
+
+
+CSlideshowSettings::CSlideshowSettings()
+ {
+ iSlideshowTime = KDefaultSlideshowTime;
+ iLightsTime = KDefaultLightsTime;
+ iSlideTime = KDefaultSlideTime;
+ iSlideshowType = KSlideshowTypeContinuous;
+ }
+
+// ============================ MEMBER FUNCTIONS =============================
+
+
+// ---------------------------------------------------------------------------
+// CSlideshowPlugin::NewL
+// ---------------------------------------------------------------------------
+//
+CSlideshowPlugin* CSlideshowPlugin::NewL()
+ {
+ CSlideshowPlugin* self = new (ELeave) CSlideshowPlugin;
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+
+// ----------------------------------------------------------------------------
+// CSlideshowPlugin::~CSlideshowPlugin
+// ----------------------------------------------------------------------------
+//
+CSlideshowPlugin::~CSlideshowPlugin()
+ {
+ if (iResourceOffset != 0)
+ {
+ iEikEnv->DeleteResourceFile(iResourceOffset);
+ }
+
+ // Close and delete CR handlers
+ NotifyCenrepChangeCancel();
+ UnInitializeCenRep();
+
+ // Close and delete P&S handlers
+ if (iSettingsChangedSubscriber)
+ {
+ iSettingsChangedSubscriber->StopSubscribe();
+ }
+ iSettingsChangedProperty.Close();
+ delete iSettingsChangedSubscriber;
+
+ delete iScreensaverName;
+ delete iSettings;
+ delete iDrmHelper;
+ delete iModel;
+
+ // First model, then engine, otherwise bad things happen
+ delete iCLFModel;
+ delete iCLFEngine;
+
+ // Logging done
+ SSPLOGGER_DELETE;
+ }
+
+// -----------------------------------------------------------------------------
+// CSlideshowPlugin::ConstructL
+// -----------------------------------------------------------------------------
+//
+void CSlideshowPlugin::ConstructL()
+ {
+ // Start logging
+ SSPLOGGER_CREATE;
+
+ iModel = CSlideshowModel::NewL();
+ iSettings = new (ELeave) CSlideshowSettings();
+
+ // Get nearest language resource file and add it to the
+ // eikon environment for the duration of the plugin life
+ TFileName fileName;
+ TParse lParse;
+
+ // Add the resource dir
+ lParse.Set(KResourceFileName, &KDC_RESOURCE_FILES_DIR, NULL);
+
+ // Get the filename with full path
+ fileName = lParse.FullName();
+
+ iEikEnv = CEikonEnv::Static();
+
+ BaflUtils::NearestLanguageFile(iEikEnv->FsSession(), fileName);
+
+ iResourceOffset = iEikEnv->AddResourceFileL(fileName);
+
+ // Load localised name of screensaver to be returned
+ // to Themes app in Name() query
+ iScreensaverName = iEikEnv->AllocReadResourceL(R_SLIDESHOW_SCREENSAVER_NAME);
+
+ InitializeCenRepL();
+
+ // Read settings
+ ReadSettings();
+
+ // Make sure random slides are loaded
+ iCLFModelUpToDate = EFalse;
+
+ iTimerUpdated = EFalse;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CSlideshowPlugin::CSlideshowPlugin
+// -----------------------------------------------------------------------------
+CSlideshowPlugin::CSlideshowPlugin()
+ {
+ }
+
+
+// --- MScreensaverPlugin ---
+
+
+// -----------------------------------------------------------------------------
+// CSlideshowPlugin::InitializeL
+// -----------------------------------------------------------------------------
+TInt CSlideshowPlugin::InitializeL(MScreensaverPluginHost *aHost)
+ {
+ SSPLOGGER_ENTERFN("InitializeL()");
+
+ iWaitActive = EFalse;
+ iDrawCount = 0;
+
+ if (!aHost)
+ {
+ return KErrArgument;
+ }
+
+ iHost = aHost;
+ // iHost->UseRefreshTimer( EFalse );
+
+ NotifyCenrepChangeL();
+
+ // No indicators while plugin running
+ iHost->OverrideStandardIndicators();
+
+ // Get display info
+ UpdateDisplayInfo();
+
+ // Attach and start watching settings changed key
+ User::LeaveIfError(iSettingsChangedProperty.Attach(
+ KPSUidScreenSaver, KScreenSaverPluginSettingsChanged));
+
+ iSettingsChangedSubscriber = new (ELeave) CPSSubscriber(
+ TCallBack(HandleSettingsChanged, this), iSettingsChangedProperty);
+ iSettingsChangedSubscriber->SubscribeL();
+
+ iDrmHelper = CDRMHelper::NewL(*iEikEnv);
+
+ // Load slides on start rather than here
+ // LoadSlidesL();
+
+ // Make sure random slides are loaded
+ iCLFModelUpToDate = EFalse;
+
+ SSPLOGGER_LEAVEFN("InitializeL()");
+
+ return KErrNone;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CSlideshowPlugin::Draw
+// -----------------------------------------------------------------------------
+TInt CSlideshowPlugin::Draw(CWindowGc& aGc)
+ {
+ SSPLOGGER_ENTERFN("Draw()");
+
+ // Clear the screen on the very first draw call after starting
+ if (iDrawCount < 0)
+ {
+ iDrawCount = 0;
+ aGc.SetBrushColor(KRgbBlack);
+ aGc.Clear();
+ }
+
+ // If still waiting for CLF, bail out
+ if (iWaitActive)
+ {
+ SSPLOGGER_WRITE("Draw(): Waiting for CLF, bail out");
+ SSPLOGGER_LEAVEFN("Draw()");
+ return KErrNone;
+ }
+ // Make sure we have something to display
+ if (iModel->NumberOfSlides() == 0)
+ {
+ SSPLOGGER_WRITE("Draw(): Nothing to display, suspending");
+ SSPLOGGER_LEAVEFN("Draw()");
+// iHost->Suspend( -1 ); // This place will be crashed when transform to default type
+ return KErrNotFound;
+ }
+
+ CSlideshowSlide* pSlide = iModel->NextSlide(EFalse);
+ // get the status of the slide
+ TInt status = iModel->SlideStatus(pSlide); // TInt decoded(1), decoding(2), not decoding(3),no slide (0)
+ // 4 could not decode the slide
+ if(KStatusDecodingInProgress == status)
+ {
+ // decoding in progress... return
+ // when ever decoding is going on.. call draw method every 1 second to check the status of the decoding
+ // and draw the image as soon as it is available ( otherwise Draw is called every 5 secods, very bad user responce)
+ if(iTimerUpdated)
+ {
+ iHost->SetRefreshTimerValue(KSecsToMicros);
+ iTimerUpdated = EFalse;
+ }
+ return KErrNone;
+ }
+ else if (KStatusSlideDecoded == status)
+ {
+ // File was decoded properly and available
+ SSPLOGGER_WRITEF(_L("SSP: Draw(): Got slide (%x), drawing"), pSlide);
+
+ // Consume slide's DRM rights
+ SlideshowUtil::DRMConsume(iDrmHelper, pSlide);
+
+ // Make sure the window is empty in case the bitmap doesn't
+ // fill the whole screen. Draw background black
+ aGc.SetBrushColor(KRgbBlack);
+ // aGc.SetBrushStyle(CGraphicsContext::ESolidBrush);
+ aGc.Clear();
+ // Draw image centered
+ DrawCentered(aGc, pSlide);
+ if(iHost && !iTimerUpdated)
+ {
+ iHost->SetRefreshTimerValue(iSettings->iSlideTime * KSecsToMicros);
+ iTimerUpdated = ETrue;
+ }
+ // Flush draw buffer so that the new image is displayed immediately
+ FlushDrawBuffer();
+ SSPLOGGER_WRITE("Draw(): Prepare next slide");
+
+ SSPLOGGER_LEAVEFN("Draw()");
+ }
+
+ // Prefetch image for the next slide
+ iModel->PrepareNextSlide(
+ (iSettings->iSlideshowType == KSlideshowTypeRandom), iDi.iRect.Size());
+
+ SSPLOGGER_LEAVEFN("Draw()");
+
+ return KErrNone;
+
+ }
+
+
+// -----------------------------------------------------------------------------
+// CSlideshowPlugin::Name
+// -----------------------------------------------------------------------------
+const TDesC16& CSlideshowPlugin::Name() const
+ {
+ if (iScreensaverName)
+ {
+ return *iScreensaverName;
+ }
+ else
+ {
+ return KNullDesC;
+ }
+ }
+
+
+// -----------------------------------------------------------------------------
+// CSlideshowPlugin::Capabilities
+// -----------------------------------------------------------------------------
+TInt CSlideshowPlugin::Capabilities()
+ {
+ return (EScpCapsConfigure | EScpCapsSelectionNotification);
+ }
+
+
+// -----------------------------------------------------------------------------
+// CSlideshowPlugin::PluginFunction
+// -----------------------------------------------------------------------------
+TInt CSlideshowPlugin::PluginFunction(
+ TScPluginCaps aFunction,
+ TAny* aParam)
+ {
+ TInt ret = KErrNone;
+
+ switch (aFunction)
+ {
+ case EScpCapsSelectionNotification:
+ case EScpCapsPreviewNotification:
+ // Peek into the slideset
+ TRAP(ret, LoadSlidesL());
+ if (ret!=KErrNone || iModel->NumberOfSlides() == 0)
+ {
+ SSPLOGGER_WRITE("No slides selected - launching settings");
+ TRAP(ret, ConfigureL(aParam));
+ // Check if at least one file is selected
+ TRAP(ret, LoadSlidesL());
+ if ( ret == KErrNone && iModel->NumberOfSlides() == 0)
+ {
+ // Don't Pop an error note, just return error
+ return KErrCancel;
+ }
+ }
+ break;
+ case EScpCapsConfigure:
+ // Configure command
+ TRAP(ret, ConfigureL(aParam));
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CSlideshowPlugin::HandleScreensaverEventL
+// -----------------------------------------------------------------------------
+TInt CSlideshowPlugin::HandleScreensaverEventL(
+ TScreensaverEvent aEvent,
+ TAny* /*aData*/ )
+ {
+ switch (aEvent)
+ {
+ case EScreensaverEventStopping:
+ StopPlugin();
+ break;
+
+ case EScreensaverEventStarting:
+ StartPlugin();
+ break;
+
+ case EScreensaverEventDisplayChanged:
+ UpdateDisplayInfo();
+ break;
+
+ case EScreensaverEventTimeout:
+ StopPlugin();
+ iHost->Suspend(-1);
+ break;
+
+ default:
+ break;
+ }
+ return KErrNone;
+ }
+
+
+// -----------------------------------------------------------------------------
+// From MCLFOperationObserver. Called by CLF when e.g. a content listing
+// operation is finished.
+// -----------------------------------------------------------------------------
+void CSlideshowPlugin::HandleOperationEventL(TCLFOperationEvent aOperationEvent,
+ TInt aError)
+ {
+ if (aOperationEvent == ECLFRefreshComplete)
+ {
+ iCLFError = aError;
+ EndWaitForCLF();
+ }
+
+ if (aOperationEvent == ECLFModelOutdated)
+ {
+ // Need to update random list on next start
+ iCLFModelUpToDate = EFalse;
+ }
+ }
+
+
+// -----------------------------------------------------------------------------
+// CSlideshowPlugin::ReadSettings
+// -----------------------------------------------------------------------------
+TInt CSlideshowPlugin::ReadSettings()
+ {
+ TInt err = KErrNone;
+
+ err = iSlideshowRepository->Get(
+ KThemesScreenSaverSlideSetDuration,
+ iSettings->iSlideshowTime);
+
+ if ((iSettings->iSlideshowTime < KMinSlideshowTime) ||
+ (iSettings->iSlideshowTime > KMaxSlideshowTime))
+ {
+ // Out of range, set to default
+ iSettings->iSlideshowTime = KDefaultSlideshowTime;
+ }
+
+ err = iSlideshowRepository->Get(
+ KThemesScreenSaverSlideSetBacklight,
+ iSettings->iLightsTime);
+
+ if ((iSettings->iLightsTime < KMinLightsTime) ||
+ (iSettings->iLightsTime > KMaxLightsTime))
+ {
+ // Out of range, set to default
+ iSettings->iLightsTime = KDefaultLightsTime;
+ }
+
+ err = iSlideshowRepository->Get(
+ KThemesScreenSaverSlideSetType,
+ iSettings->iSlideshowType);
+
+ // No setting for slide timing
+ iSettings->iSlideTime = KDefaultSlideTime;
+
+ return err;
+ }
+
+#if 0
+
+// -----------------------------------------------------------------------------
+// CSlideshowPlugin::UpdateFileName
+// -----------------------------------------------------------------------------
+//
+TBool CSlideshowPlugin::UpdateFileName()
+ {
+ if ( !BaflUtils::FileExists( iEikEnv->FsSession(),
+ iSettings->iFileName ) )
+ {
+ // File is deleted now, Show empty string
+ iSettings->iFileName.Copy( KEmptyString );
+ return ETrue;
+ }
+
+ TBool canbeautomated(EFalse);
+
+ TInt res = 0;
+ iDrmHelper->SetAutomatedType(
+ CDRMHelper::EAutomatedTypeScreenSaver );
+ res = iDrmHelper->CanSetAutomated( iSettings->iFileName,
+ canbeautomated );
+
+ if ( res || !canbeautomated)
+ {
+ iSettings->iFileName.Copy( KEmptyString );
+ return ETrue;
+ }
+ return EFalse;
+ }
+
+#endif
+
+// -----------------------------------------------------------------------------
+// CSlideshowPlugin::HandleRepositoryCallBack
+// -----------------------------------------------------------------------------
+//
+TInt CSlideshowPlugin::HandleRepositoryCallBack(TAny* aPtr)
+ {
+ STATIC_CAST(CSlideshowPlugin*, aPtr)->HandleCRSettingsChange(aPtr);
+ return KErrNone;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CSlideshowPlugin::HandleCRSettingsChange
+// -----------------------------------------------------------------------------
+//
+void CSlideshowPlugin::HandleCRSettingsChange(TAny* /*aPtr*/)
+ {
+ if (iSlideshowCRWatcher)
+ {
+ TInt changedKey = iSlideshowCRWatcher->ChangedKey();
+
+ switch (changedKey)
+ {
+ case KThemesScreenSaverSlideSetType:
+ case KThemesScreenSaverSlideSetBacklight:
+ case KThemesScreenSaverSlideSetDuration:
+ // Update settings
+ ReadSettings();
+ break;
+
+ default:
+ // Not interested in other keys
+ break;
+ }
+ }
+ }
+
+
+// -----------------------------------------------------------------------------
+// CSlideshowPlugin::HandleSettingsChanged
+// -----------------------------------------------------------------------------
+//
+TInt CSlideshowPlugin::HandleSettingsChanged(TAny* aPtr)
+ {
+ return (STATIC_CAST(CSlideshowPlugin*, aPtr)->SettingsChanged());
+ }
+
+
+// --- private functions ---
+
+
+// -----------------------------------------------------------------------------
+// CSlideshowPlugin::InitializeCenRepL
+// Connect Central Repository sessions
+// -----------------------------------------------------------------------------
+void CSlideshowPlugin::InitializeCenRepL()
+ {
+
+ TRAPD(err, iSlideshowRepository = CRepository::NewL(KCRUidThemes));
+ User::LeaveIfError(err);
+ }
+
+
+// -----------------------------------------------------------------------------
+// CSlideshowPlugin::NotifyCenrepChangeL
+// -----------------------------------------------------------------------------
+//
+void CSlideshowPlugin::NotifyCenrepChangeL()
+ {
+ iSlideshowCRWatcher = CRepositoryWatcher::NewL(
+ KCRUidThemes,
+ TCallBack(HandleRepositoryCallBack, this),
+ iSlideshowRepository);
+ }
+
+
+// -----------------------------------------------------------------------------
+// CSlideshowPlugin::NotifyCenrepChangeCancel
+// -----------------------------------------------------------------------------
+void CSlideshowPlugin::NotifyCenrepChangeCancel()
+ {
+ delete iSlideshowCRWatcher;
+ iSlideshowCRWatcher = NULL;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CSlideshowPlugin::UnInitializeCenRep
+// -----------------------------------------------------------------------------
+void CSlideshowPlugin::UnInitializeCenRep()
+ {
+ if (iSlideshowRepository)
+ {
+ delete iSlideshowRepository;
+ iSlideshowRepository = NULL;
+ }
+ }
+
+
+// Starts the saver when screensaver starts
+void CSlideshowPlugin::StartPlugin()
+ {
+ // Make sure we start from a clean slate
+ iDrawCount = -1;
+
+ // (Re-)load slideset. When done on every start this avoids
+ // having to keep track of gallery changes and images on MMC.
+ TRAP_IGNORE(LoadSlidesL());
+
+ if (iModel->NumberOfSlides() == 0)
+ {
+ iHost->RevertToDefaultSaver();
+ return;
+ }
+
+ iModel->PrepareNextSlide(
+ (iSettings->iSlideshowType == KSlideshowTypeRandom),
+ iDi.iRect.Size());
+
+ if (iHost)
+ {
+ // Start animating as per settings
+ iHost->RequestTimeout(iSettings->iSlideshowTime);
+ Lights(iSettings->iLightsTime);
+ // let the draw method be called every 1 second till first image is available
+ iHost->SetRefreshTimerValue(KRefreshInterval * KSecsToMicros);
+ SetDisplayMode();
+ }
+ }
+
+
+// Stops the plugin
+void CSlideshowPlugin::StopPlugin()
+ {
+ // Let go of pre-fetched images
+ iModel->ReleaseNextSlide();
+ iTimerUpdated = EFalse;
+ }
+
+
+// Draws centered slides
+void CSlideshowPlugin::DrawCentered(CWindowGc& aGc, CSlideshowSlide* aSlide)
+ {
+ CFbsBitmap* bitmap = aSlide->Image();
+
+ if (!bitmap)
+ return;
+
+ // Center the bitmap horizontally and vertically (crop off excess)
+ TPoint pos;
+ TRect rectToDraw;
+ TSize sizeBmp = bitmap->SizeInPixels();
+ TInt screenWidth = iDi.iRect.Width();
+ TInt screenHeight = iDi.iRect.Height();
+
+ // Horizontally
+ if (sizeBmp.iWidth <= screenWidth)
+ {
+ // Width fits on screen - center xpos
+ pos.iX = (screenWidth - sizeBmp.iWidth) / 2;
+
+ // Whole width of bmp can be drawn
+ rectToDraw.SetWidth(sizeBmp.iWidth);
+ }
+ else
+ {
+ // Bmp wider than screen - xpos top left
+ pos.iX = 0;
+
+ // Adjust draw rect position and width
+ rectToDraw.iTl.iX = (sizeBmp.iWidth - screenWidth) / 2;
+ rectToDraw.SetWidth(screenWidth);
+ }
+
+ // Vertically
+ if (sizeBmp.iHeight <= screenHeight)
+ {
+ // Height fits on screen - center ypos
+ pos.iY = (screenHeight - sizeBmp.iHeight) / 2;
+
+ // Whole height of bmp can be drawn
+ rectToDraw.SetHeight(sizeBmp.iHeight);
+ }
+ else
+ {
+ // Bmp higher than screen - ypos top left
+ pos.iY = 0;
+
+ // Adjust draw rect position and height
+ rectToDraw.iTl.iY = (sizeBmp.iHeight - screenHeight) / 2;
+ rectToDraw.SetHeight(screenHeight);
+ }
+
+ // Do the drawing
+ aGc.BitBlt(pos, bitmap, rectToDraw);
+ }
+
+
+// Loads the slides into the model
+void CSlideshowPlugin::LoadSlidesL()
+ {
+ SSPLOGGER_ENTERFN("LoadSlidesL()");
+
+ // Based on settings, load predefined set or random slides
+ if (iSettings->iSlideshowType == KSlideshowTypeRandom)
+ {
+ LoadRandomSlidesL();
+ }
+ else
+ {
+ LoadSlideSetL();
+ }
+
+ SSPLOGGER_LEAVEFN("LoadSlidesL()");
+ }
+
+
+// Load filenames from settings file stored in skin server directory
+void CSlideshowPlugin::LoadSlideSetL()
+ {
+ SSPLOGGER_ENTERFN("LoadSlideSetL()");
+
+ // Start by getting rid of possibly loaded slides
+ iModel->DeleteAll();
+
+ // Connect to skin server.
+ RAknsSrvSession skinSrv;
+ TInt error = skinSrv.Connect();
+ User::LeaveIfError(error);
+ CleanupClosePushL(skinSrv);
+
+ // Open images file
+ TInt fileSrvHandle;
+ TInt fileHandle;
+ fileSrvHandle = skinSrv.OpenImageInifile(EAknsSrvInifileSSSS, fileHandle);
+
+ // Adopt the handle to our process
+ RFile imgFile;
+ error = imgFile.AdoptFromServer(fileSrvHandle, fileHandle);
+ User::LeaveIfError(error);
+ CleanupClosePushL(imgFile);
+
+ // Read image filenames from file (as text)
+ TFileText textFile;
+ textFile.Set(imgFile);
+ textFile.Seek(ESeekStart);
+
+ // Read until EOF
+ TInt count = 0;
+ TFileName fileName;
+ while (textFile.Read(fileName) == KErrNone)
+ {
+ // Check that the file exists. If not, it is still OK, if it is
+ // on the memory card - it may show up later. Omit files from other
+ // drives that do not exist at the time of loading
+ TBool exists = BaflUtils::FileExists(iEikEnv->FsSession(), fileName);
+ TBool isOnMC = SlideshowUtil::IsOnMC(fileName);
+
+ if (!exists) // && (!isOnMC))
+ {
+ // Do not add nonexisting files // from other than memory card
+ continue;
+ }
+#if 0
+ // Check that the file's DRM rights allow it to be displayed (if not
+ // missing because not on MMC
+ if (!SlideshowUtil::DRMCheck(fileName))
+ {
+ // No point in adding files that cannot be displayed anyway
+ continue;
+ }
+#endif
+ // Create a slide with the filename and store it in the model
+ CSlideshowSlide* pSlide = CSlideshowSlide::NewL(fileName, isOnMC);
+ CleanupStack::PushL(pSlide);
+ iModel->AppendSlideL(pSlide);
+ CleanupStack::Pop(pSlide);
+
+ SSPLOGGER_WRITEF(_L("SSP: Slide %d added, file: %S"), count, &fileName);
+ count++;
+ }
+
+ CleanupStack::PopAndDestroy(2); // imgFile, skinSrv
+
+ SSPLOGGER_LEAVEFN("LoadSlideSetL()");
+ }
+
+
+// Load filenames from CLF
+void CSlideshowPlugin::LoadRandomSlidesL()
+ {
+ SSPLOGGER_ENTERFN("LoadRandomSlidesL()");
+
+ // No need to do anything, if model hasn't become
+ // outdated since last loading
+ if (iCLFModelUpToDate)
+ {
+ return;
+ }
+
+ // Start by getting rid of possibly loaded slides
+ iModel->DeleteAll();
+
+ // Make sure CLF is ready
+ ConnectToCLFL();
+
+ // Refresh CLF model
+ iCLFError = KErrNone;
+ iCLFModel->RefreshL();
+
+ // Wait for refresh to complete before continuing
+ WaitForCLF();
+
+ // On error bail out
+ if (iCLFError != KErrNone)
+ {
+ SSPLOGGER_WRITEF(_L("SSP: CLF refresh error %d"), iCLFError);
+ return;
+ }
+
+ // Model is up to date
+ iCLFModelUpToDate = ETrue;
+
+ // CLF model should now contain the image files in Gallery, proceed to
+ // load into our model
+ TInt nItems = iCLFModel->ItemCount();
+
+ // Loop through, add filenames
+ TInt count = 0;
+ for (TInt i = 0; i < nItems; i++)
+ {
+ // TFileName fileName;
+ TPtrC fileName;
+ TInt error = KErrNone;
+
+ const MCLFItem& item = iCLFModel->Item(i);
+
+ error = item.GetField(ECLFFieldIdFileNameAndPath, fileName);
+
+ // If OK, add to model
+ if (error == KErrNone)
+ {
+ // Check that the file exists. If not, it is still OK, if it is
+ // on the memory card - it may show up later. Omit files from other
+ // drives that do not exist at the time of loading
+ // TODO: Can be removed, as slides are loaded on every start
+ TBool exists = BaflUtils::FileExists(iEikEnv->FsSession(), fileName);
+ TBool isOnMC = SlideshowUtil::IsOnMC(fileName);
+
+ if (!exists) // && (!isOnMC))
+ {
+ // Do not add nonexisting files from other than memory card
+ continue;
+ }
+#if 0
+ // Check that the file's DRM rights allow it to be displayed (if not
+ // missing because not on MMC
+ if (!SlideshowUtil::DRMCheck(fileName))
+ {
+ // No point in adding files that cannot be displayed anyway
+ continue;
+ }
+#endif
+ // Create a slide with the filename and store it in the model
+ CSlideshowSlide* pSlide = CSlideshowSlide::NewL(fileName, isOnMC);
+ CleanupStack::PushL(pSlide);
+ iModel->AppendSlideL(pSlide);
+ CleanupStack::Pop(pSlide);
+
+ SSPLOGGER_WRITEF(_L("SSP: Slide %d added, file: %S"), count, &fileName);
+ count++;
+ }
+ }
+
+ SSPLOGGER_LEAVEFN("LoadRandomSlidesL()");
+ }
+
+
+// Requests display mode from host
+void CSlideshowPlugin::SetDisplayMode()
+ {
+ if (!iHost)
+ {
+ return;
+ }
+
+ // Exit partial mode
+ iHost->ExitPartialMode();
+ }
+
+
+// Requests lights
+void CSlideshowPlugin::Lights(TInt aSecs)
+ {
+ // Request nothing, if no time set (don't force lights off)
+ if ((iHost) && (aSecs > 0))
+ {
+ SSPLOGGER_WRITEF(_L("SSP: Request lights for %d secs"), aSecs);
+ iHost->RequestLights(aSecs);
+ }
+ }
+
+
+// Configure the plugin
+void CSlideshowPlugin::ConfigureL(TAny* /* aParam */)
+ {
+ // Look for screensaver slideset setting interface
+ RImplInfoPtrArray array;
+ const TUid slidesetInterface = { 0x102823AD };
+ const TUid slidesetImplUidScreensaver = { 0x102823AF };
+ const TEComResolverParams emptyParams;
+
+ REComSession::ListImplementationsL(
+ slidesetInterface,
+ emptyParams,
+ KRomOnlyResolverUid,
+ array);
+ CleanupResetAndDestroyPushL(array);
+
+ // Loop through implementations and look for screensaver
+ // slideset implementation (this is not really completely
+ // necessary, because we already know the implementation UID,
+ // but we want to be sure it's there, and on ROM only
+ TInt nCount = array.Count();
+ TUid implUid;
+
+ for (TInt i = 0; i < nCount; i++)
+ {
+ CImplementationInformation* info = array[i];
+
+ if (info->ImplementationUid() == slidesetImplUidScreensaver)
+ {
+ // Found
+ implUid = info->ImplementationUid();
+ break;
+ }
+ }
+
+ // Did we get it?
+ if (implUid != slidesetImplUidScreensaver)
+ {
+ User::Leave(KErrNotFound);
+ }
+
+ // Instantiate the interface
+ CPslnSlidesetDialogInterface* plugin =
+ CPslnSlidesetDialogInterface::NewL(implUid);
+
+ TInt dlgRet = KErrNone;
+ if (plugin)
+ {
+ dlgRet = plugin->ExecuteDialogLD();
+ }
+
+ // Cleanup
+ array.ResetAndDestroy();
+ CleanupStack::PopAndDestroy(); // array
+
+ User::LeaveIfError(dlgRet);
+ }
+
+
+// Updates the saved information about display
+void CSlideshowPlugin::UpdateDisplayInfo()
+ {
+ iDi.iSize = sizeof(TScreensaverDisplayInfo);
+ iHost->DisplayInfo(&iDi);
+ }
+
+
+// Flushes pending draws
+void CSlideshowPlugin::FlushDrawBuffer()
+ {
+ iEikEnv->WsSession().Flush();
+ }
+
+
+// -----------------------------------------------------------------------------
+// CSlideshowPlugin::SettingsChanged
+// Called when Themes reports a settings change through P & S
+// -----------------------------------------------------------------------------
+TInt CSlideshowPlugin::SettingsChanged()
+ {
+ // If current key value is nonzero, it means the settings
+ // have just changed, otherwise, no action necessary
+ TInt value = 0;
+ iSettingsChangedProperty.Get(value);
+
+ if (value == EScreenSaverPluginSettingsChanged)
+ {
+#if 0
+ // Slide file has changed - re-load images
+ TRAP_IGNORE(LoadSlidesL());
+ // Pre-fetch the fist image to be drawn
+ iModel->PrepareNextSlide(
+ (iSettings->iSlideshowType == KSlideshowTypeRandom),
+ iDi.iRect.Size());
+#endif
+ iSettingsChangedProperty.Set(EScreenSaverPluginSettingsNoChange);
+ }
+
+ return KErrNone;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CSlideshowPlugin::ConnectToCLFL
+// Connects to Content Listing Framework. Can be called many times,
+// connects only once
+// -----------------------------------------------------------------------------
+void CSlideshowPlugin::ConnectToCLFL()
+ {
+ if (!iCLFEngine)
+ {
+ iCLFEngine = ContentListingFactory::NewContentListingEngineLC();
+ CleanupStack::Pop(); // LC
+ }
+
+ if (!iCLFModel)
+ {
+ iCLFModel = iCLFEngine->CreateListModelLC(*this);
+ CleanupStack::Pop(); // LC
+ }
+
+ // Set image types to model
+ RArray<TInt> typeArray;
+ CleanupClosePushL(typeArray);
+ typeArray.AppendL(ECLFMediaTypeImage);
+ iCLFModel->SetWantedMediaTypesL(typeArray.Array());
+ CleanupStack::PopAndDestroy(&typeArray);
+ }
+
+
+// Begins wait for CLF
+void CSlideshowPlugin::WaitForCLF()
+ {
+ if (iWaitActive)
+ {
+ return;
+ }
+ else
+ {
+ iWaitActive = ETrue;
+ iWaiter.Start();
+ }
+ }
+
+
+// Ends wait for CLF
+void CSlideshowPlugin::EndWaitForCLF()
+ {
+ if (!iWaitActive)
+ {
+ return;
+ }
+ else
+ {
+ iWaiter.AsyncStop();
+ iWaitActive = EFalse;
+ }
+ }
+
+// End Of file.