commondrm/drmencryptor/src/DRMEncryptorContainer.cpp
changeset 0 95b198f216e5
child 12 8a03a285ab14
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/commondrm/drmencryptor/src/DRMEncryptorContainer.cpp	Thu Dec 17 08:52:27 2009 +0200
@@ -0,0 +1,444 @@
+/*
+* Copyright (c) 2002-2009 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: 
+*
+*/
+
+
+// INCLUDE FILES
+
+#include <eiksbfrm.h>
+#include <eikscrlb.h>
+#include <eikrted.h>
+#include <txtrich.h>
+#include <barsread.h>
+#include <eikenv.h>
+#include <aknenv.h>
+#include <aknutils.h>
+#include <aknconsts.h>
+#include <txtfrmat.h>
+#include <AknBidiTextUtils.h>
+
+#include <DRMEncryptor.rsg>
+#include "DRMEncryptorContainer.h"
+#include "DRMEncryptorImage.h"
+#include "DRMEncryptor.hrh"
+
+// CONSTANTS
+
+_LIT( KDRMEncryptorPanicCategory, "DRMEncryptor" );
+
+enum TDRMEncryptorPanic
+    {
+    EDRMEncryptorNotSupported = 0
+    };
+
+// constructors
+
+CDRMEncryptorContainer::CDRMEncryptorContainer()
+    {
+    }
+
+void CDRMEncryptorContainer::ConstructL( const TRect& aRect )
+    {
+    CreateWindowL();
+
+    // In case of APAC layout, use APAC font
+    TAknLayoutId layoutId;
+    iAvkonEnv->GetCurrentLayoutId( layoutId );
+
+    if ( layoutId == EAknLayoutIdAPAC )
+        {
+        iFont = ApacPlain12();
+        }
+    else
+        {
+        iFont = LatinPlain12();
+        }
+
+    // Calculate various text positioning parameters
+    iBaseLineDelta = iFont->HeightInPixels() * 4 / 3;
+
+    TInt mainPaneWidth( aRect.iBr.iX - aRect.iTl.iX );
+    TInt mainPaneHeight( aRect.iBr.iY - aRect.iTl.iY );
+    // Line width is 87% of client rect, horizontal margins 13%
+    iLineWidth = mainPaneWidth * 87 / 100;
+
+    iTopBaseLineX = ( mainPaneWidth - iLineWidth ) / 2;
+
+    // top margin is 6.5% of the client rect
+    TInt topMargin = mainPaneHeight * 65 / 1000;
+    iTopBaseLineY = topMargin + iFont->AscentInPixels();
+
+    // minimum bottom margin is 3% of the client rect
+    TInt bottomMargin = mainPaneHeight * 3 / 100;
+    iLinesPerScreen =
+        ( mainPaneHeight - topMargin - bottomMargin ) / iBaseLineDelta;
+
+    iTextAlign = CGraphicsContext::ELeft;
+
+    // Every text line on screen is one entry in this array
+    iText = new( ELeave ) CArrayPtrFlat<HBufC>( 20 );
+    // Every image on screen is one entry in this array
+    iImages = new( ELeave ) CArrayPtrFlat<CDRMEncryptorImage>( 1 );
+    // This array contains indices for lines that start the subsequent
+    // screens, for custom scrolling
+    iScreenStarts = new( ELeave ) CArrayFixFlat<TInt>( 5 );
+    // Initialisation: first screen starts at line 0.
+    iScreenStarts->AppendL( 0 );
+
+    // Read text and image items to be shown on the screen from a resource file.
+
+    // real resource
+    TResourceReader reader;
+    iEikonEnv->CreateResourceReaderLC( reader, R_DRMENCRYPTOR_MAIN_TEXT );
+
+    TInt numItems( reader.ReadInt16() );
+
+    for ( TInt i = 0 ; i < numItems ; i++ )
+        {
+        TInt type = reader.ReadInt8();
+
+        if ( type == EDRMEncryptorTextItem )
+            {
+            HBufC* text = iEikonEnv->AllocReadResourceLC( reader.ReadInt32() );
+    SetTextL( *text );
+
+
+            CleanupStack::PopAndDestroy(); // text
+            }
+        else if ( type == EDRMEncryptorImageItem )
+            {
+            TPtrC bitmapFile = reader.ReadTPtrC();
+            TInt bitmapId = reader.ReadInt16();
+            SetImageL( bitmapFile, bitmapId );
+            }
+        else
+            {
+            User::Panic( KDRMEncryptorPanicCategory, EDRMEncryptorNotSupported );
+            }
+        }
+
+    CleanupStack::PopAndDestroy(); // reader
+
+    UpdateScrollIndicatorL();
+    SetRect( aRect );
+    ActivateL();
+    }
+
+// destructor
+
+CDRMEncryptorContainer::~CDRMEncryptorContainer()
+    {
+    delete iSBFrame;
+    delete iScreenStarts;
+
+    if ( iText )
+        {
+        iText->ResetAndDestroy();
+        delete iText;
+        }
+
+    if ( iImages )
+        {
+        iImages->ResetAndDestroy();
+        delete iImages;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CDRMEncryptorContainer::Draw()
+// -----------------------------------------------------------------------------
+
+void CDRMEncryptorContainer::Draw( const TRect& aRect ) const
+    {
+    CWindowGc& gc = SystemGc();
+
+    //  clear the area
+
+    gc.SetBrushColor( iEikonEnv->ControlColor( EColorWindowBackground, *this ) );
+    gc.SetBrushStyle( CGraphicsContext::ESolidBrush );
+    gc.Clear( aRect );
+
+    // draw text
+    gc.UseFont( iFont );
+
+    // index of the first line on the screen in the text array
+    TInt firstLine( (*iScreenStarts)[ iCurrentScreen ] );
+    // index of the last line on the screen in the text array
+    TInt lastLine( firstLine + iLinesPerScreen - 1 );
+
+    gc.SetBrushStyle( CGraphicsContext::ENullBrush );
+    TPoint position( iTopBaseLineX, iTopBaseLineY );
+    TPoint topLeft;
+    TSize rectSize( iLineWidth, iBaseLineDelta +iFont->DescentInPixels() );
+
+    for ( TInt index = firstLine ;
+          index < iText->Count() && index <= lastLine ;
+          index++, position.iY += iBaseLineDelta )
+        {
+        HBufC* text = (*iText)[ index ];
+
+        if ( text )
+            {
+            topLeft = TPoint( position.iX, position.iY-iBaseLineDelta );
+            gc.DrawText( *text,
+                         TRect( topLeft, rectSize ),
+                         iBaseLineDelta,
+                         iTextAlign );
+            }
+        }
+
+    gc.DiscardFont();
+
+    // draw images
+
+    for ( TInt i = 0 ; i < iImages->Count() ; i++ )
+        {
+        CDRMEncryptorImage* image = (*iImages)[ i ];
+
+        // If part of the image resides in visible lines, draw it.
+        if ( image->StartLine() <= lastLine && image->EndLine() >= firstLine )
+            {
+            position.SetXY( iTopBaseLineX, iTopBaseLineY );
+            position.iY += ( image->StartLine() - firstLine ) * iBaseLineDelta;
+
+            position.iY -= iBaseLineDelta - iFont->DescentInPixels();
+            // Now iY is the top line of rectangle where the picture is
+            // centered in.
+            position.iY += ( (image->Lines()+1) * iBaseLineDelta -
+                             iFont->HeightInPixels() -
+                             image->HeightInPixels() ) / 2;
+
+            // If text is right-aligned, also align images to the right.
+
+            if ( iTextAlign == CGraphicsContext::ERight )
+                {
+                position.iX += ( iLineWidth - image->WidthInPixels() );
+                }
+
+            gc.BitBlt( position, image->Bitmap(), aRect );
+            }
+        }
+
+    }
+
+// -----------------------------------------------------------------------------
+// CDRMEncryptorContainer::ActivateL()
+// -----------------------------------------------------------------------------
+
+void CDRMEncryptorContainer::ActivateL()
+    {
+    CCoeControl::ActivateL();
+    UpdateScrollIndicatorL();
+    }
+
+// -----------------------------------------------------------------------------
+// CDRMEncryptorContainer::SetTextL()
+// -----------------------------------------------------------------------------
+
+void CDRMEncryptorContainer::SetTextL( const TDesC& aText )
+    {
+    CArrayFix<TPtrC>* wrappedArray =
+        new( ELeave ) CArrayFixFlat<TPtrC>( 10 );
+
+    CleanupStack::PushL( wrappedArray );
+
+    HBufC* dataToDestroy =
+        AknBidiTextUtils::ConvertToVisualAndWrapToArrayL(
+            aText, iLineWidth, *iFont, *wrappedArray
+        );
+
+    TInt numLines( wrappedArray->Count() );
+    for ( TInt i = 0 ; i < numLines ; i++ )
+        {
+        HBufC* line = (*wrappedArray)[i].AllocLC();
+
+        if(!line->Length())
+            {
+            iText->AppendL( NULL );
+
+            CleanupStack::PopAndDestroy();  // line
+            }
+        else
+            {
+            iText->AppendL( line );
+            CleanupStack::Pop();  // line
+            }
+        }
+    iText->AppendL( NULL );
+
+    // If the last char was newline, add one extra, since
+    // wrapping automatically removes it.
+    if ( aText[ aText.Length() - 1 ] == '\n' )
+        {
+        iText->AppendL( NULL );
+        }
+
+    CleanupStack::PopAndDestroy(); // wrappedArray
+    delete dataToDestroy;
+
+    // update screen scrolling info array
+
+    TInt lastLine( iText->Count() - 1 );
+    TInt screenStart( (*iScreenStarts)[ iScreenStarts->Count() - 1 ] );
+
+    TBool firstNewScreenHandled( EFalse );
+
+    while ( lastLine >= screenStart + iLinesPerScreen )
+        {
+        if ( !firstNewScreenHandled && iDoNotShowLastLineAgain )
+            {
+            screenStart++;
+            firstNewScreenHandled = ETrue;
+            }
+
+        screenStart += iLinesPerScreen - 1;
+        iScreenStarts->AppendL( screenStart );
+        }
+
+    // if text, last line is shown again in next screen
+    iDoNotShowLastLineAgain = EFalse;
+    }
+
+// -----------------------------------------------------------------------------
+// CDRMEncryptorContainer::SetImageL()
+// -----------------------------------------------------------------------------
+
+void CDRMEncryptorContainer::SetImageL( const TDesC& aFileName, TInt aBitmapId )
+    {
+    TInt firstLineOfImage( iText->Count() );
+
+    CDRMEncryptorImage* image =
+    CDRMEncryptorImage::NewLC( aFileName, aBitmapId, firstLineOfImage, iBaseLineDelta );
+
+    // new lines to make room for the picture
+
+    for ( TInt i = 0 ; i < image->Lines() ; i++ )
+        {
+        iText->AppendL( NULL );
+        }
+
+    iImages->AppendL( image );
+    CleanupStack::Pop(); // image
+
+    // update screen scrolling info array
+
+    TInt lastLineOfImage( iText->Count() - 1 );
+    TInt screenStart( (*iScreenStarts)[ iScreenStarts->Count() - 1 ] );
+
+    TBool firstNewScreenHandled( EFalse );
+
+    // If the image was not fully shown in the first screen,
+    // start the next screen with the image.
+
+    if ( firstLineOfImage < screenStart + iLinesPerScreen &&
+         lastLineOfImage >= screenStart + iLinesPerScreen )
+        {
+        screenStart = firstLineOfImage;
+        iScreenStarts->AppendL( screenStart );
+        firstNewScreenHandled = ETrue;
+        }
+
+    while ( lastLineOfImage >= screenStart + iLinesPerScreen )
+        {
+        if ( !firstNewScreenHandled && iDoNotShowLastLineAgain )
+            {
+            screenStart++;
+            firstNewScreenHandled = ETrue;
+            }
+
+        screenStart += iLinesPerScreen - 1;
+        iScreenStarts->AppendL( screenStart );
+        }
+
+    if ( lastLineOfImage == screenStart + iLinesPerScreen - 1 )
+        {
+        iDoNotShowLastLineAgain = ETrue;
+        }
+    else
+        {
+        iDoNotShowLastLineAgain = EFalse;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CDRMEncryptorContainer::OfferKeyEventL()
+// -----------------------------------------------------------------------------
+
+TKeyResponse CDRMEncryptorContainer::OfferKeyEventL( const TKeyEvent& aKeyEvent,
+                                              TEventCode aType )
+    {
+    if ( aType == EEventKey && iScreenStarts->Count() > 1 )
+        {
+        switch ( aKeyEvent.iCode )
+            {
+            case EKeyUpArrow:
+                if ( iCurrentScreen > 0 )
+                    {
+                    iCurrentScreen--;
+                    DrawNow();
+                    UpdateScrollIndicatorL();
+                    }
+                break;
+
+            case EKeyDownArrow:
+                if ( iCurrentScreen < iScreenStarts->Count() - 1 )
+                    {
+                    iCurrentScreen++;
+                    DrawNow();
+                    UpdateScrollIndicatorL();
+                    }
+                break;
+
+            default:
+                break;
+            }
+        }
+
+    return EKeyWasConsumed;
+    }
+
+// -----------------------------------------------------------------------------
+// CDRMEncryptorContainer::UpdateScrollIndicatorL()
+// -----------------------------------------------------------------------------
+
+void CDRMEncryptorContainer::UpdateScrollIndicatorL()
+    {
+    if ( iScreenStarts->Count() <= 1 )
+        {
+        return;
+        }
+
+    if ( !iSBFrame )
+        {
+        iSBFrame = new( ELeave ) CEikScrollBarFrame( this, NULL, ETrue );
+        iSBFrame->SetScrollBarVisibilityL( CEikScrollBarFrame::EOff,
+                                           CEikScrollBarFrame::EAuto );
+        iSBFrame->SetTypeOfVScrollBar( CEikScrollBarFrame::EArrowHead );
+        }
+
+    TEikScrollBarModel hSbarModel;
+    TEikScrollBarModel vSbarModel;
+    vSbarModel.iThumbPosition = iCurrentScreen;
+    vSbarModel.iScrollSpan = iScreenStarts->Count();
+    vSbarModel.iThumbSpan = 1;
+
+    TEikScrollBarFrameLayout layout;
+    TRect rect( Rect() );
+    iSBFrame->TileL( &hSbarModel, &vSbarModel, rect, rect, layout );
+    iSBFrame->SetVFocusPosToThumbPos( vSbarModel.iThumbPosition );
+    }
+
+// End of File