messagingappbase/smartmessaging/ringbc/src/RingingToneBioControl.cpp
changeset 0 72b543305e3a
child 2 0bf1d54f37d9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/messagingappbase/smartmessaging/ringbc/src/RingingToneBioControl.cpp	Thu Dec 17 08:44:11 2009 +0200
@@ -0,0 +1,1230 @@
+/*
+* Copyright (c) 2002-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:   BIO control for Ringing Tones.
+*
+*/
+
+
+
+// INCLUDE FILES
+
+#include "RingingToneBioControl.h"      // for CRingingToneBioControl
+#include "RingBCToneConverter.h"             // for CComNSMConverter
+#include "RingBC.hrh"
+#include "RingBCLog.h"
+
+#include <biocmtm.h>                    // for CBIOClientMtm
+#include <coeutils.h>                   // for ConeUtils
+#include <msgbiocontrolObserver.h>      // for MMsgBioControlObserver
+#include <StringLoader.h>               // for StringLoader
+#include <AknsUtils.h>
+#include <RingBC.rsg>                   // for resouce identifiers
+#include <ringbc.mbg>                   // for icons indexes
+#include <ProfileEngineSDKCRKeys.h>
+#include <MsgBioUtils.h>                // for MsgBioUtils
+#include <eikrted.h>                    // for CEikRichTextEditor
+#include <txtrich.h>                    // for CRichText
+#include <aknnotewrappers.h>            // for CAknInformationNote
+#include <Profile.hrh>                  // for EProfileRingingTypeSilent
+#include <bldvariant.hrh>
+#include <pathinfo.h>
+#include <featmgr.h>					// Feature manager
+#include <csxhelp/smart.hlp.hrh>
+#include <data_caging_path_literals.hrh>
+#include <applayout.cdl.h>				// LAF
+#include <aknlayoutscalable_apps.cdl.h>
+#include <mmsvattachmentmanager.h>
+
+#include <msgaudiocontrol.h>	//AudioControl
+#include <MsgEditorCommon.h>	//MsgEditorCommons utilities
+
+// CONSTANTS
+
+_LIT(KRingingToneFileExtension,".rng");
+_LIT(KResourceName, "ringbc.rsc" );
+_LIT(KRingBCMbmFileName, "ringbc.mif");
+
+// LOCAL CONSTANTS AND MACROS
+const TInt KComponentCountZero = 0;
+const TInt KNoOverWriteOrRecurse = 0;
+const TInt KLengthOfTitleRow = 100;
+const TInt KTextNameQueryMaxLength = 50;
+
+
+const TInt KRichEditor              = 1;
+const TInt KAudioControl            = 0;
+
+const TInt KRingVolumeZero = 0;
+
+const TInt KShowNoNotes = 0;
+const TInt KShowNotes = 1;
+
+const TInt KFrameExpansion = 10;
+
+// MODULE DATA STRUCTURES
+
+enum TOptionListLocation
+    {
+    EFirstMenuItem  = 0,
+    ESecondMenuItem
+    };
+
+// ================= MEMBER FUNCTIONS =======================
+
+// Two-phased constructor.
+EXPORT_C CMsgBioControl* CRingingToneBioControl::NewL(
+            MMsgBioControlObserver& aObserver,
+            CMsvSession* aSession,
+            TMsvId aId,
+            TMsgBioMode aEditorOrViewerMode,
+            const RFile* aFile)
+    {
+    CRingingToneBioControl* self =
+    	new( ELeave ) CRingingToneBioControl(
+    		aObserver,
+            aSession, aId, aEditorOrViewerMode,
+            aFile);
+
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop(self); // self
+
+    return self;
+
+    }
+
+// Destructor
+CRingingToneBioControl::~CRingingToneBioControl()
+    {
+    FeatureManager::UnInitializeLib();
+    delete iRichEditor;
+    delete iAudioControl;    
+    delete iToneTitle;
+    }
+
+// C++ default constructor.
+CRingingToneBioControl::CRingingToneBioControl(
+        MMsgBioControlObserver& aObserver,
+        CMsvSession* aSession,
+        TMsvId aId,
+        TMsgBioMode aEditorOrViewerMode,
+        const RFile* aFile):
+        CMsgBioControl(aObserver,
+            aSession,
+            aId,
+            aEditorOrViewerMode,
+            aFile)
+    {
+    }
+
+// Symbian OS default constructor can leave.
+void CRingingToneBioControl::ConstructL()
+    {
+    if( IsEditor() )   //Editor mode is not supported
+        {
+        User::Leave( KErrNotSupported );
+        }
+
+	FeatureManager::InitializeLibL();
+
+    LoadStandardBioResourceL();
+    LoadResourceL( KResourceName );
+
+    // checks if the message is valid
+    CheckMsgValidityL();
+    TakeTitleL();
+
+    }
+
+// ----------------------------------------------------------------------------
+// CRingingToneBioControl::CheckMsgValidityL
+// ----------------------------------------------------------------------------
+//
+void CRingingToneBioControl::CheckMsgValidityL()
+    {
+    RFile file;
+
+    CMsvEntry* entry = this->MsvSession(). GetEntryL(iId);
+    CleanupStack::PushL( entry );
+
+    CMsvStore* store = entry->ReadStoreL();
+	CleanupStack::PushL(store);
+
+	MMsvAttachmentManager& manager = store->AttachmentManagerL();
+	file = manager.GetAttachmentFileL(0);
+
+    CleanupClosePushL(file);
+
+    TInt size;
+    User::LeaveIfError(file.Size(size));
+    if (!size)
+        {
+        //the empty ringing tone is considered a corrupted message
+        User::Leave(KErrMsgBioMessageNotValid);
+        }
+	
+	HBufC8* dataBuf = HBufC8::NewLC(size);
+    TPtr8 data(dataBuf->Des());
+    User::LeaveIfError(file.Read(data, size));
+
+    CRingBCNSMConverter* conv = CRingBCNSMConverter::NewL();
+    CleanupStack::PushL( conv );
+    TBool res = conv->IsRingToneMimeTypeL(data);
+
+    if (!res)
+        {
+        User::Leave(KErrMsgBioMessageNotValid);
+        }
+        
+    CleanupStack::PopAndDestroy(5,entry); // entry,conv,store,file,dataBuf
+    }
+
+
+// ----------------------------------------------------------------------------
+// CRingingToneBioControl::ProcessCommandL
+// ----------------------------------------------------------------------------
+//
+void CRingingToneBioControl::ProcessCommandL( TInt aCommandId )
+    {
+    if ( aCommandId == ESoftkeyStop )
+		{
+		StopPlayback();
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// CRingingToneBioControl::SetAndGetSizeL
+// ----------------------------------------------------------------------------
+//
+void CRingingToneBioControl::SetAndGetSizeL( TSize& aSize )
+    {
+	//the heightadjustment calculates the height for the header elements and 
+	//the space between components
+   	TInt heightAdjustment = (MsgEditorCommons::MsgBaseLineDelta()*2)+
+   							MsgEditorCommons::MsgBaseLineOffset();
+   	
+   	aSize.iHeight -= heightAdjustment;
+   	SetSizeWithoutNotification( aSize  );
+    }
+
+// ----------------------------------------------------------------------------
+// CRingingToneBioControl::SetMenuCommandSetL
+// ----------------------------------------------------------------------------
+//
+void CRingingToneBioControl::SetMenuCommandSetL( CEikMenuPane& aMenuPane )
+    {
+    // if playing, do not show context sensitive menu.
+    if ( iPlayerState != EMsgAsyncControlStatePlaying )
+        {
+        AddMenuItemL(aMenuPane, R_SM_PLAYBACK, ERingtPlayback, EFirstMenuItem);
+        AddMenuItemL(aMenuPane,
+        	R_SM_ADD_COMPOSER, ERingtAddComposer, ESecondMenuItem);
+        }
+	}
+
+// ----------------------------------------------------------------------------
+// CRingingToneBioControl::CurrentLineRect
+// ----------------------------------------------------------------------------
+//
+TRect CRingingToneBioControl::CurrentLineRect() const
+    {
+    return iAudioControl->CurrentLineRect();
+    }
+
+// ----------------------------------------------------------------------------
+// CRingingToneBioControl::IsFocusChangePossible
+// ----------------------------------------------------------------------------
+//
+TBool CRingingToneBioControl::IsFocusChangePossible(
+        TMsgFocusDirection aDirection ) const
+    {
+    return iAudioControl->IsFocusChangePossible( aDirection );
+	}
+
+// ----------------------------------------------------------------------------
+// CRingingToneBioControl::HeaderTextL
+// ----------------------------------------------------------------------------
+//
+HBufC* CRingingToneBioControl::HeaderTextL() const
+    {
+    return iCoeEnv->AllocReadResourceL( R_SM_TITLE_RINGING_TONE );
+    }
+
+// ----------------------------------------------------------------------------
+// CRingingToneBioControl::HandleBioCommandL
+// ----------------------------------------------------------------------------
+//
+TBool CRingingToneBioControl::HandleBioCommandL(TInt aCommand)
+    {
+    aCommand -= iBioControlObserver.FirstFreeCommand();
+    TBool retValue(EFalse);
+    switch ( aCommand )
+        {
+        case ERingtPlayback:
+            PlaybackL();
+            retValue = ETrue;
+            break;
+        case ERingtAddComposer:
+            TrySaveToneL();
+            retValue = ETrue;
+            break;
+        default:
+            retValue = EFalse;
+            break;
+        }
+	return retValue;
+    }
+
+// ----------------------------------------------------------------------------
+// CRingingToneLogoBioControl::OptionMenuPermissionsL
+// ----------------------------------------------------------------------------
+//
+TUint32 CRingingToneBioControl::OptionMenuPermissionsL() const
+    {
+    if ( iPlayerState != EMsgAsyncControlStatePlaying )
+        {
+        return EMsgBioDelete
+        | EMsgBioMessInfo
+        | EMsgBioMove
+        | EMsgBioHelp
+        | EMsgBioExit;
+        }
+    else 
+        {
+        // do not show context sensitive menu.
+        return 0;
+        }
+    }
+
+
+
+// ----------------------------------------------------------------------------
+// CRingingToneBioControl::OfferKeyEventL
+// ----------------------------------------------------------------------------
+//
+TKeyResponse CRingingToneBioControl::OfferKeyEventL(
+        const TKeyEvent& /*aKeyEvent*/,
+        TEventCode /*aType*/ )
+    {
+    return EKeyWasConsumed;
+    }
+
+// ----------------------------------------------------------------------------
+// CRingingToneBioControl::GetHelpContext
+// ----------------------------------------------------------------------------
+//
+void CRingingToneBioControl::GetHelpContext(
+	TCoeHelpContext& aHelpContext) const
+	{
+	if ( FeatureManager::FeatureSupported( KFeatureIdHelp ) )
+		{
+		const TUid KUidSmart = {0x101F4CDA};
+
+		aHelpContext.iContext = KSMART_HLP_RINGVIEWER();
+		aHelpContext.iMajor = KUidSmart;
+		}
+	}
+
+// ----------------------------------------------------------------------------
+// CRingingToneBioControl::CountComponentControls
+// ----------------------------------------------------------------------------
+//
+TInt CRingingToneBioControl::CountComponentControls() const
+    {
+    TInt componentCount( KComponentCountZero );
+    if ( iAudioControl )
+        {
+        componentCount++;
+        }
+	if ( iRichEditor )        
+		{
+		componentCount++;
+		}
+    return componentCount;
+    }
+
+// ----------------------------------------------------------------------------
+// CRingingToneBioControl::ComponentControl
+// ----------------------------------------------------------------------------
+//
+CCoeControl* CRingingToneBioControl::ComponentControl( TInt aIndex ) const
+    {
+    if ( aIndex == KRichEditor )
+    	{
+    	return iRichEditor;
+    	}
+    if ( aIndex == KAudioControl )
+        {
+        return iAudioControl;
+        }
+    else
+    	{
+    	return NULL;
+    	}
+	}
+
+// ----------------------------------------------------------------------------
+// CRingingToneBioControl::HandleResourceChange
+// ----------------------------------------------------------------------------
+//
+void CRingingToneBioControl::HandleResourceChange( TInt aType )
+    {
+    if(aType == KEikDynamicLayoutVariantSwitch)
+    	{
+        TRAP_IGNORE(
+       		CorrectFormatToRichEditorL();
+        	iRichEditor->SetTextL( iToneTitle );
+        	FillBitmapMaskL();
+        	);
+        }
+    iAudioControl->HandleResourceChange( aType );
+    }
+
+// ----------------------------------------------------------------------------
+// CRingingToneBioControl::SizeChanged
+// ----------------------------------------------------------------------------
+//
+void CRingingToneBioControl::SizeChanged()
+    {
+    TRect rect = Rect();
+    TRect bitmapRect;
+    TAknWindowComponentLayout layout =
+	   	AknLayoutScalable_Apps::mce_image_pane_g5();
+    TAknLayoutRect LayoutRect;
+	LayoutRect.LayoutRect( rect, layout.LayoutLine() );
+	bitmapRect = LayoutRect.Rect();
+	TInt formattedHeight = iRichEditor->TextLayout()->FormattedHeightInPixels();
+	bitmapRect.Move(0,formattedHeight);
+
+	//the rectangle is grown to so that focused frame is visible
+	bitmapRect.Grow( KFrameExpansion, KFrameExpansion );
+	
+	// rect for richtext is positioned on the top of audio control
+	rect.iBr.iY = bitmapRect.iTl.iY;
+	iRichEditor->SetRect( rect );
+    iAudioControl->SetRect( bitmapRect );
+    }
+
+// ----------------------------------------------------------------------------
+// CRingingToneBioControl::FocusChanged
+// ----------------------------------------------------------------------------
+//
+void CRingingToneBioControl::FocusChanged( TDrawNow aDrawNow )
+    {
+	iAudioControl->SetFocus(IsFocused());
+	iRichEditor->FocusChanged(aDrawNow);
+    }
+
+// ----------------------------------------------------------------------------
+// CRingingToneBioControl::SetContainerWindowL
+// ----------------------------------------------------------------------------
+//
+void CRingingToneBioControl::SetContainerWindowL(
+	const CCoeControl& aContainer )
+    {
+    CCoeControl::SetContainerWindowL( aContainer );
+
+    //The reason for creating the audio control here is that the construction
+    //requires a parent with a window. So it cannot be done in ConstructL()
+    iAudioControl = CMsgAudioControl::NewL( *reinterpret_cast<CMsgEditorView*>(this), this, EMdaPriorityNormal, EMdaPriorityPreferenceQuality );
+	FillBitmapMaskL();
+
+    CreateRichEditorL();
+    }
+
+// ----------------------------------------------------------------------------
+// CRingingToneBioControl ::Draw()
+// ----------------------------------------------------------------------------
+//
+void CRingingToneBioControl::Draw(const TRect& /*aRect*/) const
+    {
+    }
+
+// ----------------------------------------------------------------------------
+// CRingingToneBioControl ::CorrectFormatToRichEditorL()
+// ----------------------------------------------------------------------------
+//
+void CRingingToneBioControl::CorrectFormatToRichEditorL()
+    {
+    CRichText* rich = iRichEditor->RichText();
+    TInt pos(rich->DocumentLength());
+
+    // font correction.
+    TCharFormat format;
+    TCharFormatMask mask;
+
+	TAknTextLineLayout editorLayout = AppLayout::Smart_Messages_Line_2( 0 );
+	const CFont* editorFont = AknLayoutUtils::FontFromId( editorLayout.FontId() );
+	format.iFontSpec = editorFont->FontSpecInTwips();
+
+    TRgb textColor;
+    if ( AknsUtils::GetCachedColor(
+	    AknsUtils::SkinInstance(),
+        textColor,
+        KAknsIIDQsnTextColors,
+        EAknsCIQsnTextColorsCG6 ) != KErrNone )
+	    {
+	    textColor = AKN_LAF_COLOR_STATIC( 215 );
+	    }
+
+    format.iFontPresentation.iTextColor = textColor;
+
+    mask.ClearAll();
+    mask.SetAttrib( EAttColor );
+    mask.SetAttrib(EAttFontStrokeWeight);
+    mask.SetAttrib(EAttFontHeight);
+    mask.SetAttrib(EAttFontTypeface);
+
+    rich->SetInsertCharFormatL(format, mask, pos);
+
+    // this is needed to set ringing tone title centered.
+    CParaFormat* paraFormat = CParaFormat::NewLC();
+    TParaFormatMask paraMask;
+
+    paraFormat->Reset();
+    paraFormat->iHorizontalAlignment = CParaFormat::ECenterAlign;
+    paraFormat->iVerticalAlignment = CParaFormat::ECenterAlign;
+
+    paraMask.SetAttrib(EAttAlignment);
+    paraMask.SetAttrib(EAttFontHeight);
+    paraMask.SetAttrib(EAttColor);
+
+    rich->ApplyParaFormatL(paraFormat, paraMask, 0, pos);
+
+    CleanupStack::PopAndDestroy(paraFormat);
+    }
+
+void CRingingToneBioControl::OpenFileL()
+	{
+	RFile file;
+
+	CMsvEntry* entry = this->MsvSession(). GetEntryL(iId);
+	CleanupStack::PushL( entry );
+
+	CMsvStore* store = entry->ReadStoreL();
+	CleanupStack::PushL(store);
+
+	MMsvAttachmentManager& manager = store->AttachmentManagerL();
+	file = manager.GetAttachmentFileL(0);
+	CleanupClosePushL(file);
+
+	//asynchronous loading of file
+	//the audio control takes a copy of the file
+	iAudioControl->LoadL(file);
+
+	//wait for the opening of file to complete
+	//in MsgMediaControlStateChanged
+    CActiveScheduler::Start();
+
+	CleanupStack::PopAndDestroy(3, entry);
+	}
+
+// ----------------------------------------------------------------------------
+// CRingingToneBioControl::PlaybackL
+// ----------------------------------------------------------------------------
+//
+void CRingingToneBioControl::PlaybackL()
+    {
+    if( iPlayerState != EMsgAsyncControlStateOpening ||
+		iPlayerState != EMsgAsyncControlStateAboutToPlay ||
+		iPlayerState != EMsgAsyncControlStatePlaying ||
+		iPlayerState != EMsgAsyncControlStateBuffering )
+    	{
+    	
+    	OpenFileL();
+    	
+    	//any other state than EMsgAsyncControlStateReady
+    	//constitutes a failed opening of media file
+    	if(iPlayerState == EMsgAsyncControlStateReady)
+    		{
+    		GetAndSetRingingToneVolumeL();
+		    iAudioControl->PlayL();
+
+		    iStopCba = CEikButtonGroupContainer::NewL (
+		    CEikButtonGroupContainer::ECba, CEikButtonGroupContainer::EHorizontal,
+		        this, R_RINGCONTROL_SOFTKEYS_STOP );
+
+		    const TSize screenSize = CCoeEnv::Static()->ScreenDevice()->SizeInPixels();
+		    iStopCba->SetBoundingRect( TRect( screenSize ) );
+    		}
+    	}
+    }
+
+void CRingingToneBioControl::StopPlayback()
+	{
+	iAudioControl->Stop();
+	
+	//after playback the file must be closed so that moving the ring tone
+	//message to another folder is possible 
+	iAudioControl->Close();
+	}
+
+// ----------------------------------------------------------------------------
+// CRingingToneBioControl::GetAndSetRingingToneVolumeL
+// ----------------------------------------------------------------------------
+//
+void CRingingToneBioControl::GetAndSetRingingToneVolumeL()
+    {
+    TInt ringingVol;
+    TInt ringingType;
+
+	CRepository* repository = CRepository::NewLC( KCRUidProfileEngine );
+
+	User::LeaveIfError( repository->Get( KProEngActiveRingingVolume, ringingVol ));
+	User::LeaveIfError(	repository->Get( KProEngActiveRingingType, ringingType ));
+
+	CleanupStack::PopAndDestroy(repository); //repository
+
+	//Some emulator versions crash in volume setting
+#ifndef __WINS__
+    if (ringingType == EProfileRingingTypeSilent)
+        {
+        RDebug::Print(_L("Profile: Ring type silent"));
+        iAudioControl->SetVolume(KRingVolumeZero);
+        }
+    else
+        {
+        RDebug::Print(_L("Ringing volume : %d"), ringingVol);
+        iAudioControl->SetVolume(ringingVol);
+        }
+#endif
+    }
+
+
+
+// ----------------------------------------------------------------------------
+// CRingingToneBioControl::CreateRichEditorL
+// ----------------------------------------------------------------------------
+//
+void CRingingToneBioControl::CreateRichEditorL()
+    {
+    iRichEditor = new( ELeave ) CEikRichTextEditor(TGulBorder::ENone);
+
+    TInt edwinFlags =
+    	CEikEdwin::ENoHorizScrolling |
+    	CEikEdwin::ENoAutoSelection |
+        CEikEdwin::EWidthInPixels |
+        CEikEdwin::EReadOnly |
+        CEikEdwin::EEdwinAlternativeWrapping;
+
+    iRichEditor->ConstructL(this,2 , 0, edwinFlags);
+
+    iRichEditor->SetMaximumHeightInLines(2);
+
+    // corrects font and alignment to centered.
+    CorrectFormatToRichEditorL();
+
+    iRichEditor->SetTextL( iToneTitle );    
+    }
+
+// ----------------------------------------------------------------------------
+// CRingingToneBioControl::FillBitmapMaskL
+// ----------------------------------------------------------------------------
+//
+void CRingingToneBioControl::FillBitmapMaskL()
+    {
+    
+    TParse *fp = new(ELeave) TParse();
+	fp->Set( KRingBCMbmFileName, &KDC_APP_BITMAP_DIR, NULL );
+	CleanupStack::PushL( fp );
+    
+    iAudioControl->LoadIconL(  fp->FullName(),
+                                KAknsIIDQgnPropOtaTone,
+                                EMbmRingbcQgn_prop_ota_tone,
+                                EMbmRingbcQgn_prop_ota_tone_mask);
+    
+    CleanupStack::PopAndDestroy(fp);
+                                    
+    TAknWindowComponentLayout layout =
+        		AknLayoutScalable_Apps::mce_image_pane_g5();
+    TAknLayoutRect LayoutRect;
+	LayoutRect.LayoutRect( Rect(), layout.LayoutLine() );
+	TRect bitmapRect;
+	bitmapRect = LayoutRect.Rect();                                
+	iAudioControl->SetIconSizeL(bitmapRect.Size());
+	iAudioControl->SetIconVisible(ETrue);
+    }
+
+
+// ----------------------------------------------------------------------------
+// CRingingToneBioControl::AddSongTitleToArrayL
+// ----------------------------------------------------------------------------
+//
+void CRingingToneBioControl::AddSongTitleToArrayL(CDesCArray& aItemArray) const
+    {
+    //Add titlerow to array
+    HBufC* dataRow = HBufC::NewLC(KLengthOfTitleRow);
+    TPtr rowPtr = dataRow->Des();
+    HBufC* baseString = StringLoader::LoadLC( R_BASE_STRING );
+
+    TInt maxLength(KLengthOfTitleRow - baseString->Length());
+
+    HBufC* tempName = HBufC::NewLC(KMaxFileName);
+
+    TPtr tempTPtr = tempName->Des();
+    tempTPtr.Copy(iToneTitle->Des());
+
+    if (iToneTitle->Length() > maxLength)
+        {
+        tempTPtr = iToneTitle->Des().Left(maxLength);
+        }
+
+    rowPtr.Format(*baseString, tempName);
+    CleanupStack::PopAndDestroy( 2, baseString );  //tempName, baseString
+    aItemArray.AppendL( rowPtr );
+    CleanupStack::PopAndDestroy(dataRow);  //dataRow
+    }
+
+// ----------------------------------------------------------------------------
+// CRingingToneBioControl ::IsOnlyDots
+// ----------------------------------------------------------------------------
+//
+TBool CRingingToneBioControl::IsOnlyDots(TDes& aTitle)
+    {
+    const TChar KSingleDot = '.';
+	_LIT(KDoubleDots,"..");
+
+    if(aTitle.Length()==1)
+        {
+
+        if( aTitle.Locate(KSingleDot) != KErrNotFound )
+            {
+            return ETrue;
+            }
+        }
+
+    else if(aTitle.Length()==2)
+        {
+
+        if( aTitle.Find(KDoubleDots) != KErrNotFound )
+            {
+            return ETrue;
+            }
+        }
+
+    return EFalse;
+    }
+
+// ----------------------------------------------------------------------------
+// CRingingToneBioControl::IsValidL
+// ----------------------------------------------------------------------------
+//
+TBool CRingingToneBioControl::IsValidL(TDes& aTitle, TBool aNotes)
+    {
+    RFs fileServer;
+    User::LeaveIfError( fileServer.Connect() );
+
+    //If name includes solely single dot or double dot, this note should be
+    //showed (Folders spec)
+    if( IsOnlyDots(aTitle) )
+        {
+
+        fileServer.Close();
+        if(aNotes)
+            {
+            InformationNoteL(R_FLDR_BAD_FILE_NAME);
+            }
+        return EFalse;
+
+        }
+
+    //only because of IsValidName does not check backslash, but file
+    //is not valid with it.
+    if( aTitle.Locate('\\') != KErrNotFound )
+        {
+
+        fileServer.Close();
+        if(aNotes)
+            {
+            InformationNoteL(R_FLDR_ILLEGAL_CHARACTERS);
+            }
+        return EFalse;
+
+        }
+    if( aTitle.Locate('\n') != KErrNotFound )
+        {
+        fileServer.Close();
+        if(aNotes)
+            {
+            InformationNoteL(R_FLDR_ILLEGAL_CHARACTERS);
+            }
+        return EFalse;
+        }
+
+    // check is there any special chars between 00h to 1Fh
+    for (TInt i=0; i<32; i++)
+        {
+        if (aTitle.Locate(i) !=KErrNotFound )
+            {
+            fileServer.Close();
+            if(aNotes)
+                {
+                InformationNoteL(R_FLDR_ILLEGAL_CHARACTERS);
+                }
+            return EFalse;
+
+            }
+
+        }
+
+    //Checking if filename is valid for saving purpose
+    if( !fileServer.IsValidName(aTitle) )
+        {
+
+        fileServer.Close();
+        if(aNotes)
+            {
+            InformationNoteL(R_FLDR_ILLEGAL_CHARACTERS);
+            }
+        return EFalse;
+
+        }
+
+    fileServer.Close();
+    return ETrue; //File name is valid
+
+    }
+
+// ----------------------------------------------------------------------------
+// CRingingToneBioControl::InformationNoteL
+// ----------------------------------------------------------------------------
+//
+void CRingingToneBioControl::InformationNoteL(TInt aStringResource)
+    {
+    HBufC* buf = StringLoader::LoadLC(aStringResource);
+
+    CAknInformationNote* note = new (ELeave) CAknInformationNote(ETrue);
+    note->ExecuteLD(*buf);
+
+    CleanupStack::PopAndDestroy(buf); //buf
+    }
+
+
+// ----------------------------------------------------------------------------
+// CRingingToneBioControl::ExistsL
+// ----------------------------------------------------------------------------
+//
+TBool CRingingToneBioControl::ExistsL(TDes& aTitle)
+    {
+    HBufC* path = CreatePathForSavingLC(aTitle);
+
+    if ( ConeUtils::FileExists(*path) )
+        {
+        CleanupStack::PopAndDestroy(path); //path;
+
+        return ETrue;
+        }
+
+    CleanupStack::PopAndDestroy(path); //path;
+    return EFalse;
+    }
+
+// ----------------------------------------------------------------------------
+// CRingingToneBioControl::AskNameL
+// ----------------------------------------------------------------------------
+//
+TBool CRingingToneBioControl::AskNameL(TDes& aTitle)
+    {
+    IncrementFileNameL( aTitle );
+
+    if (!NameQueryL(aTitle))
+        {
+        return EFalse;
+        }
+
+    return ETrue;
+    }
+
+// ----------------------------------------------------------------------------
+// CRingingToneBioControl::AskNameAndValidNameL
+// ----------------------------------------------------------------------------
+//
+TBool CRingingToneBioControl::AskAndValidNameL(TDes& aTitle)
+    {
+    do
+        {
+        if(!AskNameL(aTitle))
+            {
+            return EFalse;
+            }
+
+        } while (!IsValidL(aTitle,KShowNotes)) ;
+
+    return ETrue;
+    }
+
+
+// ----------------------------------------------------------------------------
+// CRingingToneBioControl::TrySaveToneL
+// ----------------------------------------------------------------------------
+//
+void CRingingToneBioControl::TrySaveToneL()
+    {
+    HBufC* saveTitle = HBufC::NewLC(KMaxFileName);
+    TPtr saveTitlePtr(saveTitle->Des());
+
+    saveTitlePtr.Copy(*iToneTitle); //initialize saveTitle
+
+    TBool okSave = ETrue; //No cancel pressed
+
+    //First case is special, cause if message have wrong kind of title,
+    //there will be default name in data query and no rename query.
+    if( !IsValidL(saveTitlePtr,KShowNoNotes) )
+        {
+        SetDefaultNameL(saveTitlePtr);
+
+        okSave = AskAndValidNameL(saveTitlePtr);
+        }
+
+    //Have to check if title already exists. If not, then save. But if
+    //it exists already, should ask if rename (rename query) and then ask
+    //for new name until user press cancel or give valid name. After that
+    //we should check if that already exists...
+    if(okSave)
+        {
+        while (ExistsL(saveTitlePtr))
+            {
+            if (!RenameQueryL(saveTitlePtr))
+                {
+                okSave = EFalse;
+                break;
+                }
+
+            if(!AskAndValidNameL(saveTitlePtr))
+                {
+                okSave = EFalse;
+                break;
+                }
+            };
+        }
+
+    //User did not press cancel in any place and it is saving time.
+    if(okSave)
+        {
+        SaveToneL(saveTitlePtr);
+        MsgBioUtils::ConfirmationNoteL(R_SM_NOTE_TONE_COPIED);
+        }
+
+    CleanupStack::PopAndDestroy(saveTitle); //saveTitle
+    }
+
+// ----------------------------------------------------------------------------
+// CRingingToneBioControl::CreatePathForSavingLC
+// ----------------------------------------------------------------------------
+//
+HBufC* CRingingToneBioControl::CreatePathForSavingLC(const TDesC& aName)
+    {
+    HBufC* targetPathAndName = TargetPathLC();
+
+    TPtr targetPathAndNamePtr = targetPathAndName->Des();
+
+    targetPathAndNamePtr.Append(aName);
+    targetPathAndNamePtr.Append(KRingingToneFileExtension);
+
+    return targetPathAndName;
+    }
+
+// ----------------------------------------------------------------------------
+// CRingingToneBioControl::RenameQueryL
+// ----------------------------------------------------------------------------
+//
+TBool CRingingToneBioControl::RenameQueryL(TDes& aTitle)
+    {
+    if ( !MsgBioUtils::ConfirmationQueryOkCancelL(
+    	*StringLoader::LoadLC( R_FLDR_RENAME_QUERY, aTitle ) ) )
+        {
+
+        CleanupStack::PopAndDestroy(); //StringLoader;
+        return EFalse;
+
+        }
+    CleanupStack::PopAndDestroy(); //StringLoader;
+
+    return ETrue;
+    }
+
+// ----------------------------------------------------------------------------
+// CRingingToneBioControl::SaveToneL
+// ----------------------------------------------------------------------------
+//
+TBool CRingingToneBioControl::SaveToneL(TDes& aTitle)
+    {
+    CFileMan* files = CFileMan::NewL(CCoeEnv::Static()->FsSession());
+    CleanupStack::PushL( files );
+
+    HBufC* targetPathAndName = CreatePathForSavingLC(aTitle);
+
+    CMsvEntry* entry = this->MsvSession(). GetEntryL(iId);
+    CleanupStack::PushL( entry );
+
+    CMsvStore* store = entry->ReadStoreL();
+	CleanupStack::PushL(store);
+
+	MMsvAttachmentManager& manager = store->AttachmentManagerL();
+
+	RFile ringFile;
+	ringFile = manager.GetAttachmentFileL(0);
+
+    CleanupStack::PopAndDestroy(2, entry);
+    CleanupClosePushL(ringFile);
+
+    TInt err = files->Copy(
+    	ringFile, *targetPathAndName, KNoOverWriteOrRecurse );
+    User::LeaveIfError(err);
+
+    CleanupStack::PopAndDestroy(3, files); //targetPathAndName, ringFile, files
+    return ETrue;
+    }
+
+// ----------------------------------------------------------------------------
+// CRingingToneBioControl::SetDefaultNameL
+// ----------------------------------------------------------------------------
+//
+void CRingingToneBioControl::SetDefaultNameL(TDes& aName)
+    {
+    aName.Copy(*StringLoader::LoadLC( R_SM_TONE_NAME ));
+    CleanupStack::PopAndDestroy(); //stringloader
+    }
+
+// ----------------------------------------------------------------------------
+// CRingingToneBioControl::NameQueryL
+// ----------------------------------------------------------------------------
+//
+TBool CRingingToneBioControl::NameQueryL(TDes& aName)
+    {
+    if (aName.Length() > KTextNameQueryMaxLength)
+        {
+        User::Leave(KErrOverflow);
+        }
+
+    CAknTextQueryDialog* queryDlg = new ( ELeave )
+                                     CAknTextQueryDialog( aName );
+    return queryDlg->ExecuteLD( R_SM_QUERY_RINGING_TONE );
+    }
+
+// ----------------------------------------------------------------------------
+// CRingingToneBioControl::TakeTitleL
+// ----------------------------------------------------------------------------
+//
+void CRingingToneBioControl::TakeTitleL()
+    {
+    //Read stream from file
+
+    RFile ringFile;
+
+    CMsvEntry* entry = this->MsvSession(). GetEntryL(iId);
+    CleanupStack::PushL( entry );
+
+    CMsvStore* store = entry->ReadStoreL();
+	CleanupStack::PushL(store);
+
+	MMsvAttachmentManager& manager = store->AttachmentManagerL();
+	ringFile = manager.GetAttachmentFileL(0);
+
+    CleanupStack::PopAndDestroy(2,entry);    //entry, store
+    CleanupClosePushL(ringFile);
+
+
+    TInt filelen;
+    User::LeaveIfError(ringFile.Size(filelen));
+
+    HBufC8* filedata8 = HBufC8::NewMaxLC(filelen);
+    TPtr8 dataPtr8 = filedata8->Des();
+    User::LeaveIfError(ringFile.Read(dataPtr8,filelen));
+
+    CleanupStack::Pop( filedata8 ); // pop the filedata temporarily
+    CleanupStack::PopAndDestroy(); // close and destory ringFile
+    CleanupStack::PushL( filedata8 ); // put the filedata back
+
+    CRingBCNSMConverter* conv = CRingBCNSMConverter::NewL();
+    CleanupStack::PushL( conv );
+
+	if ( iToneTitle )
+		{
+		delete iToneTitle;
+		iToneTitle = NULL;
+		}
+	iToneTitle = conv->TitleLC(dataPtr8); //The ownership changes here
+
+    CleanupStack::Pop(iToneTitle);
+    CleanupStack::PopAndDestroy(2, filedata8);  //conv, filedata8
+
+    // checks if there is no name for ringing tone
+    if (iToneTitle->Length() == 0)
+        {
+        delete iToneTitle;
+        iToneTitle = NULL;
+
+        // sets default name
+        iToneTitle = StringLoader::LoadL( R_SM_TONE_NAME );
+
+        // check that default name is not too long.
+        if (iToneTitle->Length() > KMaxFileName )
+            {
+
+            HBufC* tempName = HBufC::NewLC(KMaxFileName);
+            TPtr tempTPtr = tempName->Des();
+
+            tempTPtr.Copy(iToneTitle->Des().Left(KMaxFileName));
+
+            CleanupStack::Pop(tempName);
+
+	        delete iToneTitle;
+            iToneTitle = tempName;
+            }
+        }
+    }
+// ----------------------------------------------------------------------------
+// CRingingToneBioControl::IncrementFileName
+// ----------------------------------------------------------------------------
+//
+void CRingingToneBioControl::IncrementFileNameL(TDes& aFileName)
+    {
+    HBufC* path = CreatePathForSavingLC(aFileName);
+
+    while (ConeUtils::FileExists(*path))
+        {
+
+        MsgBioUtils::IncrementNameL(aFileName,KMaxFileName);
+
+        CleanupStack::PopAndDestroy(path);  //path
+        path = CreatePathForSavingLC(aFileName);
+
+        }
+
+    CleanupStack::PopAndDestroy(path); //path;
+    }
+
+
+// ----------------------------------------------------------------------------
+// CRingingToneBioControl ::TargetPathLC
+// ----------------------------------------------------------------------------
+//
+HBufC* CRingingToneBioControl::TargetPathLC()
+    {
+	TFileName path = PathInfo::PhoneMemoryRootPath();
+	path.Append( PathInfo::SimpleSoundsPath() );
+    ConeUtils::EnsurePathExistsL(path);
+    HBufC* savePath = HBufC::NewLC(KMaxPath + KMaxFileName);
+	TPtr ptr = savePath->Des();
+	ptr = path;
+	return savePath;
+    }
+
+// ----------------------------------------------------------------------------
+// CRingingToneBioControl ::VirtualHeight
+// ----------------------------------------------------------------------------
+//
+TInt CRingingToneBioControl::VirtualHeight()
+	{
+    return 0;
+	}
+
+// ----------------------------------------------------------------------------
+// CRingingToneBioControl ::VirtualVisibleTop
+// ----------------------------------------------------------------------------
+//
+TInt CRingingToneBioControl::VirtualVisibleTop()
+	{
+    return 0;
+	}
+
+void CRingingToneBioControl::MsgAsyncControlStateChanged( CMsgBaseControl& /*aControl*/,
+                                              TMsgAsyncControlState aNewState,
+                                              TMsgAsyncControlState aOldState )
+    {
+    iPlayerState = aNewState;
+    
+    if(aOldState == EMsgAsyncControlStateOpening)
+		{
+		//last state was opening so we go ahead with playing by stopping 
+		//the active scheduler that was started in OpenFileL -function
+		CActiveScheduler::Stop();
+		}
+    
+    switch( aNewState )
+    	{
+			//intentional fallthrough    			
+			case EMsgAsyncControlStateIdle:
+    		case EMsgAsyncControlStateStopped:
+    		case EMsgAsyncControlStateCorrupt:
+    		case EMsgAsyncControlStateNoRights:
+    			{
+    			//the Stop CBA has to be removed here because
+    			//playing could be stopped when the tune has finished or
+    			//the tune is corrupt
+    			delete iStopCba;
+    			iStopCba = NULL;
+    			break;
+    			}
+    	}
+    }
+
+
+#ifdef RD_SCALABLE_UI_V2    
+void CRingingToneBioControl::HandlePointerEventL( const TPointerEvent& aPointerEvent )
+    {
+    if ( AknLayoutUtils::PenEnabled() )
+        {
+        switch ( aPointerEvent.iType )
+            {
+            case TPointerEvent::EButton1Down:
+            	{
+                TBool hitted = iAudioControl->HitRegionContains( 
+                	aPointerEvent.iPosition, *this );
+                if( hitted )
+                   	{
+                	if( !iAudioControl->IsFocused() )	
+                		{
+                		//stylus touch to audio control sets it focused
+                		iAudioControl->SetFocus( IsFocused() );
+                		}
+					else if ( iPlayerState != EMsgAsyncControlStatePlaying && iAudioControl->IsFocused() )
+						{
+						//playback is triggered when focused control is touched with stylus
+						PlaybackL();
+						}
+                	else if ( iPlayerState == EMsgAsyncControlStatePlaying && iAudioControl->IsFocused() )
+                		{
+                		//stylus hit to audio control when playback is in 
+                		//progress stops the playing 
+                		StopPlayback();
+                		}
+                    }
+				else if ( iAudioControl->IsFocused() )
+					{
+					//hitting anywhere else than the control removes the focus from it
+					iAudioControl->SetFocus( EFalse );                    
+					}
+                break;                    
+            	}
+            default:
+                break;
+            }
+        }
+
+    }
+#else   
+void CRingingToneBioControl::HandlePointerEventL( const TPointerEvent& /*aPointerEvent*/ )
+    {
+    //no op
+    }
+#endif // RD_SCALABLE_UI_V2    
+
+void CRingingToneBioControl::MsgAsyncControlResourceChanged( CMsgBaseControl& /*aControl*/,
+											 				 TInt /*aType*/ )
+	{
+	//no op
+	}
+//  End of File