diff -r 000000000000 -r dd21522fd290 codhandler/codui/src/CodView.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/codhandler/codui/src/CodView.cpp Mon Mar 30 12:54:55 2009 +0300 @@ -0,0 +1,537 @@ +/* +* Copyright (c) 2004 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Implementation of class CCodView. +* +*/ + + +// INCLUDE FILES + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "CodView.h" +#include "CodLogger.h" +#include +#include +#include + +#include "eikon.hrh" + + +// ================= TYPES ======================= + +/** +* Mime type to resource id mapping entry. +*/ +struct TMimeAndResId + { + const TText8* iName; ///< MIME type. + TInt iResId; ///< Resource id. + }; + +// ================= CONSTANTS ======================= + +/// Number of bytes in a kilobyte. +LOCAL_D const TInt KCodKbyte = 1024; + +/** +* Null-terminated MIME-to-resId mapping table. +* Order of entries is important (from most specific to most generic), as +* entries are evaluated linearly. +*/ +LOCAL_D const TMimeAndResId KCodMimeAndResIds[] = + { +// { _S8( "game: no such MIME" ), R_QTN_CD_TYPE_GAME }, + { _S8( "application/vnd.nokia.ringing-tone" ), R_QTN_CD_TYPE_RTONE }, + { _S8( "application/x-nokiaGameData" ), R_QTN_CD_TYPE_GAME_LEVEL }, + { _S8( "application/vnd.oma.drm" ), R_QTN_CD_TYPE_NOT_CLASSIFIED }, + { _S8( "application/" ), R_QTN_CD_TYPE_APPLICATION }, + { _S8( "image/vnd.nokia.ota-bitmap" ), R_QTN_CD_TYPE_OPERATOR_LOGO }, + { _S8( "image/vnd.nok-oplogo" ), R_QTN_CD_TYPE_OPERATOR_LOGO }, + { _S8( "image/vnd.nok-picturemessage" ), R_QTN_CD_TYPE_PICTURE_MESSAGE }, + { _S8( "image/" ), R_QTN_CD_TYPE_IMAGE }, + { _S8( "audio/" ), R_QTN_CD_TYPE_SOUND }, + { _S8( "text/X-vCard" ), R_QTN_CD_TYPE_VCARD }, + { _S8( "text/" ), R_QTN_CD_TYPE_DOCUMENT }, + { _S8( "" ), R_QTN_CD_TYPE_NOT_CLASSIFIED }, + { NULL, 0 } + }; + +// ================= MEMBER FUNCTIONS ======================= + +// --------------------------------------------------------- +// CCodView:CCodView() +// --------------------------------------------------------- +// +CCodView::CCodView() + { + } + +// --------------------------------------------------------- +// CCodView:ConstructL() +// --------------------------------------------------------- +// +void CCodView::ConstructL() + { + CreateWindowL(); + TResourceReader rr; + iCoeEnv->CreateResourceReaderLC( rr, R_COD_UI_RTXED ); + ConstructFromResourceL( rr ); + CleanupStack::PopAndDestroy(); // rr + } + +// --------------------------------------------------------- +// CCodView:ConstructFromResourceL() +// --------------------------------------------------------- +// +void CCodView::ConstructFromResourceL( TResourceReader& aReader ) + { + iEditor = new (ELeave) CEikRichTextEditor(); + iEditor->ConstructFromResourceL( aReader ); + iEditor->SetContainerWindowL( *this ); + + CRichText* richText = iEditor->RichText(); + + iNameStyle = CParagraphStyle::NewL + ( + *richText->GlobalParaFormatLayer(), + *richText->GlobalCharFormatLayer() + ); + + iValueStyle = CParagraphStyle::NewL + ( + *richText->GlobalParaFormatLayer(), + *richText->GlobalCharFormatLayer() + ); + + SetStylesL(); + + iStyles = CStyleList::NewL(); + RParagraphStyleInfo nameStyleInfo( iNameStyle ); + User::LeaveIfError( iStyles->AppendL( &nameStyleInfo ) ); + RParagraphStyleInfo valueStyleInfo( iValueStyle ); + User::LeaveIfError( iStyles->AppendL( &valueStyleInfo ) ); + + richText->SetStyleListExternallyOwned( *iStyles ); + + iSbFrame = new (ELeave) CEikScrollBarFrame( this, NULL, ETrue ); + iSbFrame->SetScrollBarVisibilityL + ( CEikScrollBarFrame::EOff, CEikScrollBarFrame::EAuto ); + iSbFrame->SetTypeOfVScrollBar( CEikScrollBarFrame::EArrowHead ); + } + +// --------------------------------------------------------- +// CCodView::~CCodView() +// --------------------------------------------------------- +// +CCodView::~CCodView() + { + delete iUndefinedValue; + delete iSbFrame; + delete iEditor; + delete iStyles; + } + +// --------------------------------------------------------- +// CCodView:SetDataL() +// --------------------------------------------------------- +// +void CCodView::SetDataL( const CCodData& aData, TBool aCod ) + { + iEditor->RichText()->Reset(); + AddLineL( R_QTN_CD_DETAIL_NAME, aData.Count() > 1 && aData.Name().Length()? aData.Name() : (*aData[aData.ActiveDownload()]).Name() ); + HBufC* buf = AllocTypeNameL( DisplayType( aData ) ); + CleanupStack::PushL( buf ); + AddLineL( R_QTN_CD_DETAIL_TYPE, *buf ); + CleanupStack::PopAndDestroy( buf ); + if ( aCod ) + { + AddLineL( R_QTN_CD_DETAIL_PRICE, aData.Price() ); + } + AddLineL( R_QTN_CD_DETAIL_DESCRIPT, aData.Description() ); + + // Displaying size requires some extra fiddling with B/kB notation. + TInt size = aData.Size(); + if ( size >= KCodKbyte ) + { + // Round up. + buf = StringLoader::LoadLC + ( R_QTN_SIZE_KB, (size - 1) / KCodKbyte + 1, iCoeEnv ); + } + else + { + buf = StringLoader::LoadLC( R_QTN_SIZE_B, size, iCoeEnv ); + } + // R_QTN_SIZE_KB is " %N kB", and R_QTN_SIZE_B is " %N B" (with leading + // spaces!!!). Obviously this is a system resource which was adjusted to + // someone's particular "tabulating" needs... + // So we have to remove leading/trailing spaces. + buf->Des().Trim(); + AddLineL( R_QTN_CD_DETAIL_SIZE, *buf ); + CleanupStack::PopAndDestroy( buf ); + + AddLineL( R_QTN_CD_DETAIL_VENDOR, aData.Vendor() ); + delete iUndefinedValue; // Not needed anymore. + iUndefinedValue = NULL; + SizeChanged(); + } + +// --------------------------------------------------------- +// CCodView:Clear() +// --------------------------------------------------------- +// +void CCodView::Clear() + { + iEditor->RichText()->Reset(); + SizeChanged(); + } + +// --------------------------------------------------------- +// CCodView::MinimumSize() +// --------------------------------------------------------- +// +TSize CCodView::MinimumSize() + { + return iEikonEnv->EikAppUi()->ClientRect().Size(); + } + +// --------------------------------------------------------- +// CCodView::SizeChanged() +// --------------------------------------------------------- +// +void CCodView::SizeChanged() + { + if ( OwnsWindow() ) + { + // View as main control of App UI. + iEditor->SetRect( Rect() ); + } + else + { + // View in dialog. + // Dialog sets Rect() so it includes the softkey area. + TAknLayoutRect editorRect; + editorRect.LayoutRect + ( Rect(), AknLayout::main_pane( Rect(), 0, 0, 1 ) ); + iEditor->SetRect( editorRect.Rect() ); + } + iEditor->DrawNow(); + TRAP_IGNORE( UpdateScrollBarL( /*aTile=*/ETrue ) ); + } + +// --------------------------------------------------------- +// CCodView::CountComponentControls() +// --------------------------------------------------------- +// +TInt CCodView::CountComponentControls() const + { + return iSbFrame->CountComponentControls() + 1; + } + +// --------------------------------------------------------- +// CCodView::ComponentControl() +// --------------------------------------------------------- +// +CCoeControl* CCodView::ComponentControl( TInt aIndex ) const + { + if ( aIndex == 0 ) + { + return iEditor; + } + else + { + return iSbFrame->ComponentControl( aIndex - 1 ); + } + } + +// --------------------------------------------------------- +// CCodView::OfferKeyEventL() +// --------------------------------------------------------- +// +TKeyResponse CCodView::OfferKeyEventL +( const TKeyEvent& aKeyEvent, TEventCode aType ) + { + TKeyResponse response = EKeyWasNotConsumed; + switch ( aKeyEvent.iCode ) + { + case EKeyLeftUpArrow: // Northwest + case EStdKeyDevice10: // : Extra KeyEvent supports diagonal event simulator wedge + case EKeyUpArrow: // North + case EKeyRightUpArrow: // Northeast + case EStdKeyDevice11: // : Extra KeyEvent supports diagonal event simulator wedge + { + ScrollUpL(); + response = EKeyWasConsumed; + break; + } + + case EKeyLeftDownArrow: // Southwest + case EStdKeyDevice13: // : Extra KeyEvent supports diagonal event simulator wedge + case EKeyDownArrow: // South + case EKeyRightDownArrow: // Southeast + case EStdKeyDevice12: // : Extra KeyEvent supports diagonal event simulator wedge + { + ScrollDownL(); + response = EKeyWasConsumed; + break; + } + + default: + { + response = iEditor->OfferKeyEventL( aKeyEvent, aType ); + break; + } + } + return response; + } + +// --------------------------------------------------------- +// CCodView::Draw() +// --------------------------------------------------------- +// +void CCodView::Draw( const TRect& aRect ) const + { + SystemGc().Clear( aRect ); + } + +// ---------------------------------------------------------- +// CCodView::HandleResourceChange() +// ---------------------------------------------------------- +// +void CCodView::HandleResourceChange( TInt aType ) + { + CCoeControl::HandleResourceChange( aType ); + if ( aType == KEikDynamicLayoutVariantSwitch ) + { + TRAP_IGNORE( SetStylesL() ); // Fontspec might have changed. + SizeChanged(); // Relayout. + } + } + +// ---------------------------------------------------------- +// CCodView::SetStylesL() +// ---------------------------------------------------------- +// +void CCodView::SetStylesL() + { + TCharFormat charFormat; + TCharFormatMask charFormatMask; + charFormat.iFontPresentation.iTextColor = KRgbBlack; + charFormatMask.SetAttrib( EAttFontTypeface ); + charFormatMask.SetAttrib( EAttFontHeight ); + charFormatMask.SetAttrib( EAttColor ); + charFormat.iFontSpec = AknLayoutUtils::FontFromId + ( EAknLogicalFontPrimaryFont )->FontSpecInTwips(); + iNameStyle->CharFormatLayer()->SetL( charFormat, charFormatMask ); + charFormat.iFontSpec = AknLayoutUtils::FontFromId + ( EAknLogicalFontSecondaryFont )->FontSpecInTwips(); + iValueStyle->CharFormatLayer()->SetL( charFormat, charFormatMask ); + } + +// --------------------------------------------------------- +// CCodView:AddLineL() +// --------------------------------------------------------- +// +void CCodView::AddLineL( TInt aNameResId, const TDesC& aValue ) + { + TPtrC value( aValue ); + if ( !value.Length() ) + { + // Empty value. Show "undefined". + if ( !iUndefinedValue ) + { + // Not yet loaded, do it now. Subsequent calls will reuse + // this buffer, so it is not loaded more than once. + // After all lines are added, the buffer is deleted + // (in SetDataL()), to spare memory. + iUndefinedValue = iCoeEnv->AllocReadResourceL + ( R_QTN_CD_VALUE_UNDEFINED ); + } + value.Set( *iUndefinedValue ); + } + + CRichText* richText = iEditor->RichText(); + TInt start = richText->DocumentLength(); + if ( start ) + { + // This is not the first line. End previous paragraph. + richText->InsertL( start, CEditableText::EParagraphDelimiter ); + } + HBufC* name = iCoeEnv->AllocReadResourceLC( aNameResId ); + start = richText->DocumentLength(); + richText->InsertL( start, *name ); + TInt end = richText->DocumentLength(); + richText->ApplyParagraphStyleL + ( + *iStyles->At( 0 ).iStyle, + start, + end - start, + CParagraphStyle::ERetainNoSpecificFormats + ); + richText->InsertL( end, CEditableText::EParagraphDelimiter ); + CleanupStack::PopAndDestroy( name ); + start = richText->DocumentLength(); + richText->InsertL( start, value ); + end = richText->DocumentLength(); + richText->ApplyParagraphStyleL + ( + *iStyles->At( 1 ).iStyle, + start, + end - start, + CParagraphStyle::ERetainNoSpecificFormats + ); + // Paragraph delimiter is not added - next call will do it. + // This avoids an extra empty line (after the last). + } + +// --------------------------------------------------------------------------- +// CCodView::UpdateScrollBarL +// --------------------------------------------------------------------------- +// +void CCodView::UpdateScrollBarL( TBool aTile ) + { + CTextLayout* textLayout = iEditor->TextLayout(); + + if ( textLayout->IsBackgroundFormatting() ) + { + return; + } + + TRect viewRect( iEditor->TextView()->ViewRect() ); + TEikScrollBarModel vSbModel; + vSbModel.iThumbPosition = textLayout->PixelsAboveBand(); + vSbModel.iScrollSpan = + textLayout->FormattedHeightInPixels() - viewRect.Height(); + vSbModel.iThumbSpan = 1; + + CLOG(( \ + 5, \ + _L("rectHeight(%d) viewRectHeigh(%d) pixelsAboveBand(%d) formattedHeight(%d)"), \ + Rect().Height(), \ + viewRect.Height(), \ + textLayout->PixelsAboveBand(), \ + textLayout->FormattedHeightInPixels() \ + )); + + if ( vSbModel.iScrollSpan <= 0 ) + { + vSbModel.iThumbPosition = 0; + vSbModel.iScrollSpan = 0; + } + + if ( aTile ) + { + TEikScrollBarFrameLayout layout; + TEikScrollBarModel hSbModel; + iSbFrame->TileL + ( &hSbModel, &vSbModel, viewRect, viewRect, layout ); + } + + iSbFrame->MoveVertThumbTo( vSbModel.iThumbPosition ); + } + +// --------------------------------------------------------------------------- +// CCodView::AllocTypeNameL +// --------------------------------------------------------------------------- +// +HBufC* CCodView::AllocTypeNameL( const TDesC8& aMimeType ) + { + const TMimeAndResId* mapping; + TInt resId = R_QTN_CD_VALUE_UNDEFINED; + for ( mapping = &KCodMimeAndResIds[0]; mapping->iName; mapping++ ) + { + TPtrC8 name( mapping->iName ); + // Looking for partial match (leftmost part of aMimeType is compared + // to mapping->iName). + if ( name.Length() <= aMimeType.Length() ) + { + if ( aMimeType.Left( name.Length() ).CompareF( name ) == 0 ) + { + resId = mapping->iResId; + break; + } + } + } + return StringLoader::LoadL( resId, iCoeEnv ); + } + +// --------------------------------------------------------------------------- +// CCodView::ScrollUpL +// --------------------------------------------------------------------------- +// +void CCodView::ScrollUpL() + { + CTextLayout* textLayout = iEditor->TextLayout(); + if ( !textLayout->IsBackgroundFormatting() ) + { + if ( textLayout->PixelsAboveBand() > 0 ) + { + iEditor->MoveDisplayL( TCursorPosition::EFLineUp ); + UpdateScrollBarL( /*aTile=*/EFalse ); + } + } + } + +// --------------------------------------------------------------------------- +// CCodView::ScrollDownL +// --------------------------------------------------------------------------- +// +void CCodView::ScrollDownL() + { + CTextLayout* textLayout = iEditor->TextLayout(); + if ( !textLayout->IsBackgroundFormatting() ) + { + TRect viewRect( iEditor->TextView()->ViewRect() ); + if ( textLayout->FormattedHeightInPixels() - + textLayout->PixelsAboveBand() - viewRect.Height() > 0 ) + { + iEditor->MoveDisplayL( TCursorPosition::EFLineDown ); + UpdateScrollBarL( /*aTile=*/EFalse ); + } + } + } + +// --------------------------------------------------------------------------- +// CCodView::DisplayType +// --------------------------------------------------------------------------- +// +TPtrC8 CCodView::DisplayType( const CCodData& aData ) + { + for ( TInt i = 0; i < (*aData[aData.ActiveDownload()]).Types().MdcaCount(); i++ ) + { + TPtrC8 type( (*aData[aData.ActiveDownload()]).Types().MdcaPoint( i ) ); + if ( + type.Compare( KOma1DrmMessageContentType ) && + type.Compare( KOma1XmlRoContentType ) && + type.Compare( KOma1WbxmlRoContentType ) && + type.Compare( KOma2RoContentType ) && + type.Compare( KOma2TriggerContentType ) && + type.Compare( KOma1DcfContentType ) && + type.Compare( KOma2DcfContentType ) && + type.Compare( KOmaImportContentType ) + ) + { + return type; // Non-DRM, return it. + } + } + return (*aData[aData.ActiveDownload()]).Type(); // By default returns the first, whatever it is. + }