codhandler/codui/src/CodView.cpp
changeset 0 dd21522fd290
child 37 cb62a4f66ebe
equal deleted inserted replaced
-1:000000000000 0:dd21522fd290
       
     1 /*
       
     2 * Copyright (c) 2004 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 the License "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:  Implementation of class CCodView.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 
       
    21 #include <eikrted.h>
       
    22 #include <txtrich.h>
       
    23 #include <barsread.h>
       
    24 #include <AknUtils.h>
       
    25 #include <AknDef.h>
       
    26 #include <StringLoader.h>
       
    27 #include <CodData.h>
       
    28 #include <CodDefs.h>
       
    29 #include <avkon.rsg>
       
    30 #include <CodUi.rsg>
       
    31 #include "CodView.h"
       
    32 #include "CodLogger.h"
       
    33 #include <Oma2Agent.h>
       
    34 #include <AknUtils.h>
       
    35 #include <AknLayout.cdl.h>
       
    36 
       
    37 #include "eikon.hrh"
       
    38 
       
    39 
       
    40 // ================= TYPES =======================
       
    41 
       
    42 /**
       
    43 * Mime type to resource id mapping entry.
       
    44 */
       
    45 struct TMimeAndResId
       
    46     {
       
    47     const TText8* iName;    ///< MIME type.
       
    48     TInt iResId;            ///< Resource id.
       
    49     };
       
    50 
       
    51 // ================= CONSTANTS =======================
       
    52 
       
    53 /// Number of bytes in a kilobyte.
       
    54 LOCAL_D const TInt KCodKbyte = 1024;
       
    55 
       
    56 /**
       
    57 * Null-terminated MIME-to-resId mapping table.
       
    58 * Order of entries is important (from most specific to most generic), as
       
    59 * entries are evaluated linearly.
       
    60 */
       
    61 LOCAL_D const TMimeAndResId KCodMimeAndResIds[] =
       
    62     {
       
    63 //      { _S8( "game: no such MIME" ),                  R_QTN_CD_TYPE_GAME },
       
    64         { _S8( "application/vnd.nokia.ringing-tone" ),  R_QTN_CD_TYPE_RTONE },
       
    65         { _S8( "application/x-nokiaGameData" ),         R_QTN_CD_TYPE_GAME_LEVEL },
       
    66         { _S8( "application/vnd.oma.drm" ),             R_QTN_CD_TYPE_NOT_CLASSIFIED },
       
    67         { _S8( "application/" ),                        R_QTN_CD_TYPE_APPLICATION },
       
    68         { _S8( "image/vnd.nokia.ota-bitmap" ),          R_QTN_CD_TYPE_OPERATOR_LOGO },
       
    69         { _S8( "image/vnd.nok-oplogo" ),                R_QTN_CD_TYPE_OPERATOR_LOGO },
       
    70         { _S8( "image/vnd.nok-picturemessage" ),        R_QTN_CD_TYPE_PICTURE_MESSAGE },
       
    71         { _S8( "image/" ),                              R_QTN_CD_TYPE_IMAGE },
       
    72         { _S8( "audio/" ),                              R_QTN_CD_TYPE_SOUND },
       
    73         { _S8( "text/X-vCard" ),                        R_QTN_CD_TYPE_VCARD },
       
    74         { _S8( "text/" ),                               R_QTN_CD_TYPE_DOCUMENT },
       
    75         { _S8( "" ),                                    R_QTN_CD_TYPE_NOT_CLASSIFIED },
       
    76         { NULL,                                         0 }
       
    77     };
       
    78 
       
    79 // ================= MEMBER FUNCTIONS =======================
       
    80 
       
    81 // ---------------------------------------------------------
       
    82 // CCodView:CCodView()
       
    83 // ---------------------------------------------------------
       
    84 //
       
    85 CCodView::CCodView()
       
    86     {
       
    87     }
       
    88 
       
    89 // ---------------------------------------------------------
       
    90 // CCodView:ConstructL()
       
    91 // ---------------------------------------------------------
       
    92 //
       
    93 void CCodView::ConstructL()
       
    94     {
       
    95     CreateWindowL();
       
    96     TResourceReader rr;
       
    97     iCoeEnv->CreateResourceReaderLC( rr, R_COD_UI_RTXED );
       
    98     ConstructFromResourceL( rr );
       
    99     CleanupStack::PopAndDestroy();  // rr
       
   100     }
       
   101 
       
   102 // ---------------------------------------------------------
       
   103 // CCodView:ConstructFromResourceL()
       
   104 // ---------------------------------------------------------
       
   105 //
       
   106 void CCodView::ConstructFromResourceL( TResourceReader& aReader )
       
   107     {
       
   108     iEditor = new (ELeave) CEikRichTextEditor();
       
   109     iEditor->ConstructFromResourceL( aReader );
       
   110     iEditor->SetContainerWindowL( *this );
       
   111 
       
   112     CRichText* richText = iEditor->RichText();
       
   113 
       
   114     iNameStyle = CParagraphStyle::NewL
       
   115         (
       
   116         *richText->GlobalParaFormatLayer(),
       
   117         *richText->GlobalCharFormatLayer()
       
   118         );
       
   119 
       
   120     iValueStyle = CParagraphStyle::NewL
       
   121         (
       
   122         *richText->GlobalParaFormatLayer(),
       
   123         *richText->GlobalCharFormatLayer()
       
   124         );
       
   125 
       
   126     SetStylesL();
       
   127 
       
   128     iStyles = CStyleList::NewL();
       
   129     RParagraphStyleInfo nameStyleInfo( iNameStyle );
       
   130     User::LeaveIfError( iStyles->AppendL( &nameStyleInfo ) );
       
   131     RParagraphStyleInfo valueStyleInfo( iValueStyle );
       
   132     User::LeaveIfError( iStyles->AppendL( &valueStyleInfo ) );
       
   133 
       
   134     richText->SetStyleListExternallyOwned( *iStyles );
       
   135 
       
   136     iSbFrame = new (ELeave) CEikScrollBarFrame( this, NULL, ETrue );
       
   137     iSbFrame->SetScrollBarVisibilityL
       
   138         ( CEikScrollBarFrame::EOff, CEikScrollBarFrame::EAuto );
       
   139     iSbFrame->SetTypeOfVScrollBar( CEikScrollBarFrame::EArrowHead );
       
   140     }
       
   141 
       
   142 // ---------------------------------------------------------
       
   143 // CCodView::~CCodView()
       
   144 // ---------------------------------------------------------
       
   145 //
       
   146 CCodView::~CCodView()
       
   147     {
       
   148     delete iUndefinedValue;
       
   149     delete iSbFrame;
       
   150     delete iEditor;
       
   151     delete iStyles;
       
   152     }
       
   153 
       
   154 // ---------------------------------------------------------
       
   155 // CCodView:SetDataL()
       
   156 // ---------------------------------------------------------
       
   157 //
       
   158 void CCodView::SetDataL( const CCodData& aData, TBool aCod )
       
   159     {
       
   160     iEditor->RichText()->Reset();
       
   161     AddLineL( R_QTN_CD_DETAIL_NAME, aData.Count() > 1 && aData.Name().Length()? aData.Name() : (*aData[aData.ActiveDownload()]).Name() );
       
   162     HBufC* buf = AllocTypeNameL( DisplayType( aData ) );
       
   163     CleanupStack::PushL( buf );
       
   164     AddLineL( R_QTN_CD_DETAIL_TYPE, *buf );
       
   165     CleanupStack::PopAndDestroy( buf );
       
   166     if ( aCod )
       
   167         {
       
   168         AddLineL( R_QTN_CD_DETAIL_PRICE, aData.Price() );
       
   169         }
       
   170     AddLineL( R_QTN_CD_DETAIL_DESCRIPT, aData.Description() );
       
   171 
       
   172     // Displaying size requires some extra fiddling with B/kB notation.
       
   173     TInt size = aData.Size();
       
   174     if ( size >= KCodKbyte )
       
   175         {
       
   176         // Round up.
       
   177         buf = StringLoader::LoadLC
       
   178             ( R_QTN_SIZE_KB, (size - 1) / KCodKbyte + 1, iCoeEnv );
       
   179         }
       
   180     else
       
   181         {
       
   182         buf = StringLoader::LoadLC( R_QTN_SIZE_B, size, iCoeEnv );
       
   183         }
       
   184     // R_QTN_SIZE_KB is " %N kB", and R_QTN_SIZE_B is " %N B" (with leading
       
   185     // spaces!!!). Obviously this is a system resource which was adjusted to
       
   186     // someone's particular "tabulating" needs...
       
   187     // So we have to remove leading/trailing spaces.
       
   188     buf->Des().Trim();
       
   189     AddLineL( R_QTN_CD_DETAIL_SIZE, *buf );
       
   190     CleanupStack::PopAndDestroy( buf );
       
   191 
       
   192     AddLineL( R_QTN_CD_DETAIL_VENDOR, aData.Vendor() );
       
   193     delete iUndefinedValue; // Not needed anymore.
       
   194     iUndefinedValue = NULL;
       
   195     SizeChanged();
       
   196     }
       
   197 
       
   198 // ---------------------------------------------------------
       
   199 // CCodView:Clear()
       
   200 // ---------------------------------------------------------
       
   201 //
       
   202 void CCodView::Clear()
       
   203     {
       
   204     iEditor->RichText()->Reset();
       
   205     SizeChanged();
       
   206     }
       
   207 
       
   208 // ---------------------------------------------------------
       
   209 // CCodView::MinimumSize()
       
   210 // ---------------------------------------------------------
       
   211 //
       
   212 TSize CCodView::MinimumSize()
       
   213     {
       
   214     return iEikonEnv->EikAppUi()->ClientRect().Size();
       
   215     }
       
   216 
       
   217 // ---------------------------------------------------------
       
   218 // CCodView::SizeChanged()
       
   219 // ---------------------------------------------------------
       
   220 //
       
   221 void CCodView::SizeChanged()
       
   222     {
       
   223     if ( OwnsWindow() )
       
   224         {
       
   225         // View as main control of App UI.
       
   226         iEditor->SetRect( Rect() );
       
   227         }
       
   228     else
       
   229         {
       
   230         // View in dialog.
       
   231         // Dialog sets Rect() so it includes the softkey area.
       
   232         TAknLayoutRect editorRect;
       
   233         editorRect.LayoutRect
       
   234             ( Rect(), AknLayout::main_pane( Rect(), 0, 0, 1 ) );
       
   235         iEditor->SetRect( editorRect.Rect() );
       
   236         }
       
   237     iEditor->DrawNow();
       
   238     TRAP_IGNORE( UpdateScrollBarL( /*aTile=*/ETrue ) );
       
   239     }
       
   240 
       
   241 // ---------------------------------------------------------
       
   242 // CCodView::CountComponentControls()
       
   243 // ---------------------------------------------------------
       
   244 //
       
   245 TInt CCodView::CountComponentControls() const
       
   246     {
       
   247     return iSbFrame->CountComponentControls() + 1;
       
   248     }
       
   249 
       
   250 // ---------------------------------------------------------
       
   251 // CCodView::ComponentControl()
       
   252 // ---------------------------------------------------------
       
   253 //
       
   254 CCoeControl* CCodView::ComponentControl( TInt aIndex ) const
       
   255     {
       
   256     if ( aIndex == 0 )
       
   257         {
       
   258         return iEditor;
       
   259         }
       
   260     else
       
   261         {
       
   262         return iSbFrame->ComponentControl( aIndex - 1 );
       
   263         }
       
   264     }
       
   265 
       
   266 // ---------------------------------------------------------
       
   267 // CCodView::OfferKeyEventL()
       
   268 // ---------------------------------------------------------
       
   269 //
       
   270 TKeyResponse CCodView::OfferKeyEventL
       
   271 ( const TKeyEvent& aKeyEvent, TEventCode aType )
       
   272     {
       
   273     TKeyResponse response = EKeyWasNotConsumed;
       
   274     switch ( aKeyEvent.iCode )
       
   275         {
       
   276         case EKeyLeftUpArrow:     // Northwest
       
   277         case EStdKeyDevice10:     //   : Extra KeyEvent supports diagonal event simulator wedge
       
   278         case EKeyUpArrow:         // North
       
   279         case EKeyRightUpArrow:    // Northeast
       
   280         case EStdKeyDevice11:     //   : Extra KeyEvent supports diagonal event simulator wedge
       
   281             {
       
   282             ScrollUpL();
       
   283             response = EKeyWasConsumed;
       
   284             break;
       
   285             }
       
   286 
       
   287         case EKeyLeftDownArrow:   // Southwest
       
   288         case EStdKeyDevice13:     //   : Extra KeyEvent supports diagonal event simulator wedge
       
   289         case EKeyDownArrow:       // South
       
   290         case EKeyRightDownArrow:  // Southeast
       
   291         case EStdKeyDevice12:     //   : Extra KeyEvent supports diagonal event simulator wedge
       
   292             {
       
   293             ScrollDownL();
       
   294             response = EKeyWasConsumed;
       
   295             break;
       
   296             }
       
   297 
       
   298         default:
       
   299             {
       
   300             response = iEditor->OfferKeyEventL( aKeyEvent, aType );
       
   301             break;
       
   302             }
       
   303         }
       
   304     return response;
       
   305     }
       
   306 
       
   307 // ---------------------------------------------------------
       
   308 // CCodView::Draw()
       
   309 // ---------------------------------------------------------
       
   310 //
       
   311 void CCodView::Draw( const TRect& aRect ) const
       
   312     {
       
   313     SystemGc().Clear( aRect );
       
   314     }
       
   315 
       
   316 // ----------------------------------------------------------
       
   317 // CCodView::HandleResourceChange()
       
   318 // ----------------------------------------------------------
       
   319 //
       
   320 void CCodView::HandleResourceChange( TInt aType )
       
   321     {
       
   322     CCoeControl::HandleResourceChange( aType );
       
   323     if ( aType == KEikDynamicLayoutVariantSwitch )
       
   324         {
       
   325         TRAP_IGNORE( SetStylesL() );    // Fontspec might have changed.
       
   326         SizeChanged();                  // Relayout.
       
   327         }
       
   328     }
       
   329 
       
   330 // ----------------------------------------------------------
       
   331 // CCodView::SetStylesL()
       
   332 // ----------------------------------------------------------
       
   333 //
       
   334 void CCodView::SetStylesL()
       
   335     {
       
   336     TCharFormat charFormat;
       
   337     TCharFormatMask charFormatMask;
       
   338     charFormat.iFontPresentation.iTextColor = KRgbBlack;
       
   339     charFormatMask.SetAttrib( EAttFontTypeface );
       
   340     charFormatMask.SetAttrib( EAttFontHeight );
       
   341     charFormatMask.SetAttrib( EAttColor );
       
   342     charFormat.iFontSpec = AknLayoutUtils::FontFromId
       
   343         ( EAknLogicalFontPrimaryFont )->FontSpecInTwips();
       
   344     iNameStyle->CharFormatLayer()->SetL( charFormat, charFormatMask );
       
   345     charFormat.iFontSpec = AknLayoutUtils::FontFromId
       
   346         ( EAknLogicalFontSecondaryFont )->FontSpecInTwips();
       
   347     iValueStyle->CharFormatLayer()->SetL( charFormat, charFormatMask );
       
   348     }
       
   349 
       
   350 // ---------------------------------------------------------
       
   351 // CCodView:AddLineL()
       
   352 // ---------------------------------------------------------
       
   353 //
       
   354 void CCodView::AddLineL( TInt aNameResId, const TDesC& aValue )
       
   355     {
       
   356     TPtrC value( aValue );
       
   357     if ( !value.Length() )
       
   358         {
       
   359         // Empty value. Show "undefined".
       
   360         if ( !iUndefinedValue )
       
   361             {
       
   362             // Not yet loaded, do it now. Subsequent calls will reuse
       
   363             // this buffer, so it is not loaded more than once.
       
   364             // After all lines are added, the buffer is deleted
       
   365             // (in SetDataL()), to spare memory.
       
   366             iUndefinedValue = iCoeEnv->AllocReadResourceL
       
   367                 ( R_QTN_CD_VALUE_UNDEFINED );
       
   368             }
       
   369         value.Set( *iUndefinedValue );
       
   370         }
       
   371 
       
   372     CRichText* richText = iEditor->RichText();
       
   373     TInt start = richText->DocumentLength();
       
   374     if ( start )
       
   375         {
       
   376         // This is not the first line. End previous paragraph.
       
   377         richText->InsertL( start, CEditableText::EParagraphDelimiter );
       
   378         }
       
   379     HBufC* name = iCoeEnv->AllocReadResourceLC( aNameResId );
       
   380     start = richText->DocumentLength();
       
   381     richText->InsertL( start, *name );
       
   382     TInt end = richText->DocumentLength();
       
   383     richText->ApplyParagraphStyleL
       
   384         (
       
   385         *iStyles->At( 0 ).iStyle,
       
   386         start,
       
   387         end - start,
       
   388         CParagraphStyle::ERetainNoSpecificFormats
       
   389         );
       
   390     richText->InsertL( end, CEditableText::EParagraphDelimiter );
       
   391     CleanupStack::PopAndDestroy( name );
       
   392     start = richText->DocumentLength();
       
   393     richText->InsertL( start, value );
       
   394     end = richText->DocumentLength();
       
   395     richText->ApplyParagraphStyleL
       
   396         (
       
   397         *iStyles->At( 1 ).iStyle,
       
   398         start,
       
   399         end - start,
       
   400         CParagraphStyle::ERetainNoSpecificFormats
       
   401         );
       
   402     // Paragraph delimiter is not added - next call will do it.
       
   403     // This avoids an extra empty line (after the last).
       
   404     }
       
   405 
       
   406 // ---------------------------------------------------------------------------
       
   407 // CCodView::UpdateScrollBarL
       
   408 // ---------------------------------------------------------------------------
       
   409 //
       
   410 void CCodView::UpdateScrollBarL( TBool aTile )
       
   411     {
       
   412     CTextLayout* textLayout = iEditor->TextLayout();
       
   413 
       
   414     if ( textLayout->IsBackgroundFormatting() )
       
   415         {
       
   416         return;
       
   417         }
       
   418 
       
   419     TRect viewRect( iEditor->TextView()->ViewRect() );
       
   420     TEikScrollBarModel vSbModel;
       
   421     vSbModel.iThumbPosition = textLayout->PixelsAboveBand();
       
   422     vSbModel.iScrollSpan =
       
   423         textLayout->FormattedHeightInPixels() - viewRect.Height();
       
   424     vSbModel.iThumbSpan = 1;
       
   425 
       
   426     CLOG(( \
       
   427         5, \
       
   428         _L("rectHeight(%d) viewRectHeigh(%d) pixelsAboveBand(%d) formattedHeight(%d)"), \
       
   429         Rect().Height(), \
       
   430         viewRect.Height(), \
       
   431         textLayout->PixelsAboveBand(), \
       
   432         textLayout->FormattedHeightInPixels() \
       
   433     ));
       
   434 
       
   435     if ( vSbModel.iScrollSpan <= 0 )
       
   436         {
       
   437         vSbModel.iThumbPosition = 0;
       
   438         vSbModel.iScrollSpan = 0;
       
   439         }
       
   440 
       
   441     if ( aTile )
       
   442         {
       
   443         TEikScrollBarFrameLayout layout;
       
   444         TEikScrollBarModel hSbModel;
       
   445         iSbFrame->TileL
       
   446             ( &hSbModel, &vSbModel, viewRect, viewRect, layout );
       
   447         }
       
   448 
       
   449     iSbFrame->MoveVertThumbTo( vSbModel.iThumbPosition );
       
   450     }
       
   451 
       
   452 // ---------------------------------------------------------------------------
       
   453 // CCodView::AllocTypeNameL
       
   454 // ---------------------------------------------------------------------------
       
   455 //
       
   456 HBufC* CCodView::AllocTypeNameL( const TDesC8& aMimeType )
       
   457     {
       
   458     const TMimeAndResId* mapping;
       
   459     TInt resId = R_QTN_CD_VALUE_UNDEFINED;
       
   460     for ( mapping = &KCodMimeAndResIds[0]; mapping->iName; mapping++ )
       
   461         {
       
   462         TPtrC8 name( mapping->iName );
       
   463         // Looking for partial match (leftmost part of aMimeType is compared
       
   464         // to mapping->iName).
       
   465         if ( name.Length() <= aMimeType.Length() )
       
   466             {
       
   467             if ( aMimeType.Left( name.Length() ).CompareF( name ) == 0 )
       
   468                 {
       
   469                 resId = mapping->iResId;
       
   470                 break;
       
   471                 }
       
   472             }
       
   473         }
       
   474     return StringLoader::LoadL( resId, iCoeEnv );
       
   475     }
       
   476 
       
   477 // ---------------------------------------------------------------------------
       
   478 // CCodView::ScrollUpL
       
   479 // ---------------------------------------------------------------------------
       
   480 //
       
   481 void CCodView::ScrollUpL()
       
   482     {
       
   483     CTextLayout* textLayout = iEditor->TextLayout();
       
   484     if ( !textLayout->IsBackgroundFormatting() )
       
   485         {
       
   486         if ( textLayout->PixelsAboveBand() > 0 )
       
   487             {
       
   488             iEditor->MoveDisplayL( TCursorPosition::EFLineUp );
       
   489             UpdateScrollBarL( /*aTile=*/EFalse );
       
   490             }
       
   491         }
       
   492     }
       
   493 
       
   494 // ---------------------------------------------------------------------------
       
   495 // CCodView::ScrollDownL
       
   496 // ---------------------------------------------------------------------------
       
   497 //
       
   498 void CCodView::ScrollDownL()
       
   499     {
       
   500     CTextLayout* textLayout = iEditor->TextLayout();
       
   501     if ( !textLayout->IsBackgroundFormatting() )
       
   502         {
       
   503         TRect viewRect( iEditor->TextView()->ViewRect() );
       
   504         if ( textLayout->FormattedHeightInPixels() -
       
   505              textLayout->PixelsAboveBand() - viewRect.Height() > 0 )
       
   506             {
       
   507             iEditor->MoveDisplayL( TCursorPosition::EFLineDown );
       
   508             UpdateScrollBarL( /*aTile=*/EFalse );
       
   509             }
       
   510         }
       
   511     }
       
   512 
       
   513 // ---------------------------------------------------------------------------
       
   514 // CCodView::DisplayType
       
   515 // ---------------------------------------------------------------------------
       
   516 //
       
   517 TPtrC8 CCodView::DisplayType( const CCodData& aData )
       
   518     {
       
   519     for ( TInt i = 0; i < (*aData[aData.ActiveDownload()]).Types().MdcaCount(); i++ )
       
   520         {
       
   521         TPtrC8 type( (*aData[aData.ActiveDownload()]).Types().MdcaPoint( i ) );
       
   522         if (
       
   523             type.Compare( KOma1DrmMessageContentType ) &&
       
   524             type.Compare( KOma1XmlRoContentType ) &&
       
   525             type.Compare( KOma1WbxmlRoContentType ) &&
       
   526             type.Compare( KOma2RoContentType ) &&
       
   527             type.Compare( KOma2TriggerContentType ) &&
       
   528             type.Compare( KOma1DcfContentType ) &&
       
   529             type.Compare( KOma2DcfContentType ) &&
       
   530             type.Compare( KOmaImportContentType )
       
   531            )
       
   532             {
       
   533             return type;    // Non-DRM, return it.
       
   534             }
       
   535         }
       
   536     return (*aData[aData.ActiveDownload()]).Type();    // By default returns the first, whatever it is.
       
   537     }