branch | RCL_3 |
changeset 21 | cb96c29156b2 |
parent 19 | a12246c97fcc |
child 23 | 455f89b7fcc5 |
19:a12246c97fcc | 21:cb96c29156b2 |
---|---|
129 _LIT( KMPXCollDetailsItemsFormat, "%S\t%S" ); |
129 _LIT( KMPXCollDetailsItemsFormat, "%S\t%S" ); |
130 |
130 |
131 _LIT( KCategoryEmpty, "" ); |
131 _LIT( KCategoryEmpty, "" ); |
132 |
132 |
133 const TInt KIncrementalDelayNone = 0; |
133 const TInt KIncrementalDelayNone = 0; |
134 const TInt KIncrementalDelayHalfSecond = 1000000; |
134 const TInt KIncrementalDelayHalfSecond = 500000; |
135 const TInt KIncrementalFetchBlockSize = 400; |
135 const TInt KIncrementalFetchBlockSize = 400; |
136 const TInt KIncrementalDirectionCount = 8; |
136 const TInt KIncrementalDirectionCount = 8; |
137 const TInt KWaitNoteImpUid = 0x101FFC6C; // refresh wait note UID |
137 const TInt KWaitNoteImpUid = 0x101FFC6C; // refresh wait note UID |
138 #ifdef __ENABLE_PODCAST_IN_MUSIC_MENU |
138 #ifdef __ENABLE_PODCAST_IN_MUSIC_MENU |
139 const TInt KMusicMenuPodcastMenuItemIndex = 4; // podcast menu item index |
139 const TInt KMusicMenuPodcastMenuItemIndex = 4; // podcast menu item index |
165 |
165 |
166 // Music collection browse type |
166 // Music collection browse type |
167 const TInt KMPXCollectionArtistAlbum( 3 ); |
167 const TInt KMPXCollectionArtistAlbum( 3 ); |
168 const TInt KMPXCollectionGenre( 5 ); |
168 const TInt KMPXCollectionGenre( 5 ); |
169 |
169 |
170 _LIT(KEmptyTitle, " "); |
|
170 |
171 |
171 // ======== MEMBER FUNCTIONS ======== |
172 // ======== MEMBER FUNCTIONS ======== |
172 |
173 |
173 // --------------------------------------------------------------------------- |
174 // --------------------------------------------------------------------------- |
174 // Two-phased constructor. |
175 // Two-phased constructor. |
355 |
356 |
356 iMarkedAll = EFalse; |
357 iMarkedAll = EFalse; |
357 // grab the current process priority |
358 // grab the current process priority |
358 RProcess proc; |
359 RProcess proc; |
359 iPriority = proc.Priority(); |
360 iPriority = proc.Priority(); |
361 iGoToNowPlaying = EFalse; |
|
360 } |
362 } |
361 |
363 |
362 void CMPXCollectionViewHgImp::HandleStatusPaneSizeChange() |
364 void CMPXCollectionViewHgImp::HandleStatusPaneSizeChange() |
363 { |
365 { |
364 MPX_FUNC( "CMPXCollectionViewHgImp::HandleStatusPaneSizeChange" ); |
366 MPX_FUNC( "CMPXCollectionViewHgImp::HandleStatusPaneSizeChange" ); |
984 title.Compare( KNullDesC ) == 0 ) |
986 title.Compare( KNullDesC ) == 0 ) |
985 { |
987 { |
986 // check for unknown entry |
988 // check for unknown entry |
987 // if it's the last entry, and it's null text |
989 // if it's the last entry, and it's null text |
988 // load "unknown" text to display in prompt |
990 // load "unknown" text to display in prompt |
989 HBufC* unknownText( StringLoader::LoadLC( R_MPX_QTN_MP_UNKNOWN ) ); |
|
990 waitNoteText = StringLoader::LoadLC( |
991 waitNoteText = StringLoader::LoadLC( |
991 R_MPX_QTN_MUS_QUERY_CONF_DELETE_ALL, *unknownText ); |
992 R_MPX_QTN_MUS_QUERY_CONF_DELETE_ALL_UNKNOWN); |
992 promptTxt = StringLoader::LoadL( |
993 promptTxt = StringLoader::LoadLC( |
993 R_MPX_QTN_NMP_QUERY_CONF_DELETE_GROUP, *unknownText ); |
994 R_MPX_QTN_NMP_QUERY_CONF_DELETE_GROUP_UNKNOWN); |
994 CleanupStack::Pop( waitNoteText ); |
|
995 CleanupStack::PopAndDestroy( unknownText ); |
|
996 CleanupStack::PushL( waitNoteText ); |
|
997 CleanupStack::PushL( promptTxt ); |
|
998 } |
995 } |
999 else |
996 else |
1000 { |
997 { |
1001 waitNoteText = StringLoader::LoadLC( |
998 waitNoteText = StringLoader::LoadLC( |
1002 R_MPX_QTN_MUS_QUERY_CONF_DELETE_ALL, title ); |
999 R_MPX_QTN_MUS_QUERY_CONF_DELETE_ALL, title ); |
1515 MPX_FUNC( "CMPXCollectionViewHgImp::ActivateReorderGrabbedModeL" ); |
1512 MPX_FUNC( "CMPXCollectionViewHgImp::ActivateReorderGrabbedModeL" ); |
1516 iIsGrabbed = ETrue; |
1513 iIsGrabbed = ETrue; |
1517 TInt currentItem( iContainer->CurrentLbxItemIndex() ); |
1514 TInt currentItem( iContainer->CurrentLbxItemIndex() ); |
1518 iContainer->EnableFindBox( EFalse ); |
1515 iContainer->EnableFindBox( EFalse ); |
1519 iContainer->SetReorderGrabbedMode( ETrue, currentItem ); |
1516 iContainer->SetReorderGrabbedMode( ETrue, currentItem ); |
1517 // mark the grabbed item |
|
1518 iContainer->MarkGrabedItemL( currentItem ); |
|
1520 if ( !iContainer->IsInReorderMode() ) |
1519 if ( !iContainer->IsInReorderMode() ) |
1521 { |
1520 { |
1522 iContainer->UpdateReorderTitleIconL(); |
1521 iContainer->UpdateReorderTitleIconL(); |
1523 |
1522 |
1524 if ( iTitle ) |
1523 if ( iTitle ) |
1539 iOriginalDuration = iDuration->AllocL(); |
1538 iOriginalDuration = iDuration->AllocL(); |
1540 delete iDuration; |
1539 delete iDuration; |
1541 iDuration = NULL; |
1540 iDuration = NULL; |
1542 } |
1541 } |
1543 iContainer->ActivateReorderMode( ETrue ); |
1542 iContainer->ActivateReorderMode( ETrue ); |
1544 SetNewCbaL( R_MPX_CUI_REORDER_DROP_CANCEL_CBA ); |
1543 SetNewCbaL( R_MPX_CUI_REORDER_CANCEL_CBA ); |
1545 } |
1544 } |
1546 iContainer->SetLbxCurrentItemIndexAndDraw( currentItem ); |
1545 iContainer->SetLbxCurrentItemIndexAndDraw( currentItem ); |
1547 UpdateReorderNaviPaneL(); |
1546 UpdateReorderNaviPaneL(); |
1548 } |
1547 } |
1549 |
1548 |
1594 iOriginalDuration = NULL; |
1593 iOriginalDuration = NULL; |
1595 } |
1594 } |
1596 iContainer->ActivateReorderMode( EFalse ); |
1595 iContainer->ActivateReorderMode( EFalse ); |
1597 iContainer->EnableFindBox( ETrue ); |
1596 iContainer->EnableFindBox( ETrue ); |
1598 } |
1597 } |
1598 iHandlingKeyEvent = ETrue; |
|
1599 iContainer->HandleLbxItemAdditionPreserveIndexL(); |
1599 iContainer->HandleLbxItemAdditionPreserveIndexL(); |
1600 } |
1600 } |
1601 |
1601 |
1602 // ----------------------------------------------------------------------------- |
1602 // ----------------------------------------------------------------------------- |
1603 // Change the button group |
1603 // Change the button group |
4134 RArray<TMPXAttribute> attrs; |
4134 RArray<TMPXAttribute> attrs; |
4135 CleanupClosePushL( attrs ); |
4135 CleanupClosePushL( attrs ); |
4136 TArray<TMPXAttribute> ary = attrs.Array(); |
4136 TArray<TMPXAttribute> ary = attrs.Array(); |
4137 iIncrementalOpenUtil->SetDelay( KIncrementalDelayNone ); |
4137 iIncrementalOpenUtil->SetDelay( KIncrementalDelayNone ); |
4138 iIncrementalOpenUtil->StartL( ary, KIncrementalFetchBlockSize, |
4138 iIncrementalOpenUtil->StartL( ary, KIncrementalFetchBlockSize, |
4139 KErrNotFound, CMPXCollectionOpenUtility::EFetchNormal ); |
4139 KErrNotFound, CMPXCollectionOpenUtility::EFetchDown ); |
4140 iIncrementalOpenUtil->SetDelay( KIncrementalDelayHalfSecond ); |
4140 iIncrementalOpenUtil->SetDelay( KIncrementalDelayHalfSecond ); |
4141 CleanupStack::PopAndDestroy( &attrs ); |
4141 CleanupStack::PopAndDestroy( &attrs ); |
4142 |
4142 |
4143 if (iContainer) |
4143 if (iContainer) |
4144 { |
4144 { |
5238 } |
5238 } |
5239 break; |
5239 break; |
5240 } |
5240 } |
5241 case EMPXCmdGoToNowPlaying: |
5241 case EMPXCmdGoToNowPlaying: |
5242 { |
5242 { |
5243 iGoToNowPlaying = ETrue; |
|
5243 AppUi()->HandleCommandL( aCommand ); |
5244 AppUi()->HandleCommandL( aCommand ); |
5244 break; |
5245 break; |
5245 } |
5246 } |
5246 case EMPXCmdGoToAllSongs: |
5247 case EMPXCmdGoToAllSongs: |
5247 { |
5248 { |
6067 if (iTitle) |
6068 if (iTitle) |
6068 { |
6069 { |
6069 delete iTitle; |
6070 delete iTitle; |
6070 iTitle = NULL; |
6071 iTitle = NULL; |
6071 } |
6072 } |
6073 // for Avkon calling Deactivate, not manually hiding window contorls, reset iGoToNowPlaying |
|
6074 iGoToNowPlaying = EFalse; |
|
6072 // Cleanup view deactivation observer |
6075 // Cleanup view deactivation observer |
6073 AppUi()->RemoveViewDeactivationObserver( this ); |
6076 AppUi()->RemoveViewDeactivationObserver( this ); |
6074 } |
6077 } |
6075 |
6078 |
6076 // --------------------------------------------------------------------------- |
6079 // --------------------------------------------------------------------------- |
6811 KMPXUSBUnblockingPSStatus, |
6814 KMPXUSBUnblockingPSStatus, |
6812 usbUnblockingStatus); |
6815 usbUnblockingStatus); |
6813 |
6816 |
6814 HandleInitMusicMenuPaneL(aMenuPane); |
6817 HandleInitMusicMenuPaneL(aMenuPane); |
6815 aMenuPane->SetItemDimmed( EMPXCmdGoToNowPlaying, NowPlayingOptionVisibilityL() ); |
6818 aMenuPane->SetItemDimmed( EMPXCmdGoToNowPlaying, NowPlayingOptionVisibilityL() ); |
6816 if ( isListEmpty ) |
6819 aMenuPane->SetItemDimmed( EMPXCmdFind, ETrue ); |
6820 aMenuPane->SetItemDimmed( EMPXCmdUpnpPlayVia, ETrue ); |
|
6821 aMenuPane->SetItemDimmed( EMPXCmdUPnPAiwCmdCopyToExternalCriteria, ETrue ); |
|
6822 aMenuPane->SetItemDimmed( EMPXCmdCreatePlaylist, ETrue ); |
|
6823 aMenuPane->SetItemDimmed( EMPXCmdAddToPlaylist, ETrue ); |
|
6824 aMenuPane->SetItemDimmed( EMPXCmdReorder, ETrue ); |
|
6825 aMenuPane->SetItemDimmed( EMPXCmdSend, ETrue ); |
|
6826 aMenuPane->SetItemDimmed( EMPXCmdDelete, ETrue ); |
|
6827 aMenuPane->SetItemDimmed( EMPXCmdRemove, ETrue ); |
|
6828 aMenuPane->SetItemDimmed( EMPXCmdPlayItem, ETrue ); |
|
6829 |
|
6830 if( iContainer->IsInReorderMode() ) |
|
6831 break; |
|
6832 |
|
6833 if ( usbUnblockingStatus == EMPXUSBUnblockingPSStatusActive ) |
|
6817 { |
6834 { |
6818 aMenuPane->SetItemDimmed( EMPXCmdFind, ETrue ); |
6835 aMenuPane->SetItemDimmed( EMPXCmdAddSongs, ETrue ); |
6819 aMenuPane->SetItemDimmed( EMPXCmdUpnpPlayVia, ETrue ); |
6836 aMenuPane->SetItemDimmed( EMPXCmdSend, SendOptionVisibilityL() ); |
6820 aMenuPane->SetItemDimmed( EMPXCmdUPnPAiwCmdCopyToExternalCriteria, ETrue ); |
6837 aMenuPane->SetItemDimmed( EMPXCmdRemove, ETrue ); |
6821 aMenuPane->SetItemDimmed( EMPXCmdCreatePlaylist, ETrue ); |
|
6822 aMenuPane->SetItemDimmed( EMPXCmdAddToPlaylist, ETrue ); |
|
6823 aMenuPane->SetItemDimmed( EMPXCmdReorder, ETrue ); |
6838 aMenuPane->SetItemDimmed( EMPXCmdReorder, ETrue ); |
6824 aMenuPane->SetItemDimmed( EMPXCmdSend, ETrue ); |
6839 } |
6825 aMenuPane->SetItemDimmed( EMPXCmdDelete, ETrue ); |
6840 else |
6826 aMenuPane->SetItemDimmed( EMPXCmdRemove, ETrue ); |
6841 { |
6827 aMenuPane->SetItemDimmed( EMPXCmdPlayItem, ETrue ); |
6842 TInt selectionCount( 0 ); |
6843 iSelectionIndexCache = iContainer->CurrentSelectionIndicesL(); // not owned |
|
6844 if ( iSelectionIndexCache) |
|
6845 { |
|
6846 selectionCount = iSelectionIndexCache->Count(); |
|
6847 } |
|
6848 // do not display add songs option when marking is on or USB is connected |
|
6828 if ( usbUnblockingStatus == EMPXUSBUnblockingPSStatusActive ) |
6849 if ( usbUnblockingStatus == EMPXUSBUnblockingPSStatusActive ) |
6829 { |
6850 { |
6830 aMenuPane->SetItemDimmed( EMPXCmdAddSongs, ETrue ); |
6851 aMenuPane->SetItemDimmed( EMPXCmdAddSongs, ETrue ); |
6831 } |
6852 } |
6832 else |
6853 else |
6833 { |
6854 { |
6834 aMenuPane->SetItemDimmed( EMPXCmdAddSongs, EFalse ); |
6855 aMenuPane->SetItemDimmed( EMPXCmdAddSongs, selectionCount > 0 ); |
6856 } |
|
6857 |
|
6858 if ( iContainer->CurrentLbxItemIndex() > KErrNotFound ) |
|
6859 { |
|
6860 aMenuPane->SetItemDimmed( EMPXCmdSend, SendOptionVisibilityL() ); |
|
6861 aMenuPane->SetItemDimmed( EMPXCmdRemove, EFalse ); |
|
6862 if ( iContainer->CurrentListItemCount() > 1 ) |
|
6863 { |
|
6864 aMenuPane->SetItemDimmed( EMPXCmdReorder, EFalse ); |
|
6865 } |
|
6835 } |
6866 } |
6836 } |
6867 } |
6837 else |
|
6838 { |
|
6839 aMenuPane->SetItemDimmed( EMPXCmdUpnpPlayVia, ETrue ); |
|
6840 aMenuPane->SetItemDimmed( EMPXCmdUPnPAiwCmdCopyToExternalCriteria, ETrue ); |
|
6841 aMenuPane->SetItemDimmed( EMPXCmdFind, ETrue ); |
|
6842 aMenuPane->SetItemDimmed( EMPXCmdCreatePlaylist, ETrue ); |
|
6843 aMenuPane->SetItemDimmed( EMPXCmdAddToPlaylist, ETrue ); |
|
6844 aMenuPane->SetItemDimmed( EMPXCmdReorder, ETrue ); |
|
6845 aMenuPane->SetItemDimmed( EMPXCmdDelete, ETrue ); |
|
6846 aMenuPane->SetItemDimmed( EMPXCmdSend, ETrue ); |
|
6847 aMenuPane->SetItemDimmed( EMPXCmdRemove, ETrue ); |
|
6848 aMenuPane->SetItemDimmed( EMPXCmdPlayItem, ETrue ); |
|
6849 |
6868 |
6850 |
6869 CMPXCollectionViewListBoxArray* array = |
6851 |
|
6852 if ( usbUnblockingStatus == EMPXUSBUnblockingPSStatusActive ) |
|
6853 { |
|
6854 aMenuPane->SetItemDimmed( EMPXCmdAddSongs, ETrue ); |
|
6855 aMenuPane->SetItemDimmed( EMPXCmdSend, SendOptionVisibilityL() ); |
|
6856 aMenuPane->SetItemDimmed( EMPXCmdRemove, ETrue ); |
|
6857 } |
|
6858 else |
|
6859 { |
|
6860 TInt selectionCount( 0 ); |
|
6861 iSelectionIndexCache = iContainer->CurrentSelectionIndicesL(); // not owned |
|
6862 if ( iSelectionIndexCache) |
|
6863 { |
|
6864 selectionCount = iSelectionIndexCache->Count(); |
|
6865 } |
|
6866 // do not display add songs option when marking is on or USB is connected |
|
6867 if ( usbUnblockingStatus == EMPXUSBUnblockingPSStatusActive ) |
|
6868 { |
|
6869 aMenuPane->SetItemDimmed( EMPXCmdAddSongs, ETrue ); |
|
6870 } |
|
6871 else |
|
6872 { |
|
6873 aMenuPane->SetItemDimmed( EMPXCmdAddSongs, selectionCount > 0 ); |
|
6874 } |
|
6875 |
|
6876 if ( iContainer->CurrentLbxItemIndex() > KErrNotFound ) |
|
6877 { |
|
6878 aMenuPane->SetItemDimmed( EMPXCmdSend, SendOptionVisibilityL() ); |
|
6879 aMenuPane->SetItemDimmed( EMPXCmdRemove, EFalse ); |
|
6880 } |
|
6881 } |
|
6882 } |
|
6883 |
|
6884 CMPXCollectionViewListBoxArray* array = |
|
6885 static_cast<CMPXCollectionViewListBoxArray*>( |
6870 static_cast<CMPXCollectionViewListBoxArray*>( |
6886 iContainer->ListBoxArray() ); |
6871 iContainer->ListBoxArray() ); |
6887 const CMPXMedia& containerMedia = array->ContainerMedia(); |
6872 const CMPXMedia& containerMedia = array->ContainerMedia(); |
6888 |
6873 |
6889 if ( containerMedia.IsSupported( KMPXMediaGeneralNonPermissibleActions ) ) |
6874 if ( containerMedia.IsSupported( KMPXMediaGeneralNonPermissibleActions ) ) |
6907 aMenuPane->SetItemDimmed( EMPXCmdRename, ETrue ); |
6892 aMenuPane->SetItemDimmed( EMPXCmdRename, ETrue ); |
6908 aMenuPane->SetItemDimmed( EMPXCmdPlaylistDetails, ETrue ); |
6893 aMenuPane->SetItemDimmed( EMPXCmdPlaylistDetails, ETrue ); |
6909 aMenuPane->SetItemDimmed( EMPXCmdUseAsCascade, ETrue ); |
6894 aMenuPane->SetItemDimmed( EMPXCmdUseAsCascade, ETrue ); |
6910 aMenuPane->SetItemDimmed( EMPXCmdAlbumArt, ETrue ); |
6895 aMenuPane->SetItemDimmed( EMPXCmdAlbumArt, ETrue ); |
6911 aMenuPane->SetItemDimmed( EMPXCmdFindInMusicShop, ETrue ); |
6896 aMenuPane->SetItemDimmed( EMPXCmdFindInMusicShop, ETrue ); |
6912 |
6897 aMenuPane->SetItemDimmed( EMPXCmdSongDetails, ETrue ); |
6898 |
|
6899 if( iContainer->IsInReorderMode() ) |
|
6900 break; |
|
6901 |
|
6913 TInt selectionCount( 0 ); |
6902 TInt selectionCount( 0 ); |
6914 iSelectionIndexCache = iContainer->CurrentSelectionIndicesL(); // not owned |
6903 iSelectionIndexCache = iContainer->CurrentSelectionIndicesL(); // not owned |
6915 if ( iSelectionIndexCache) |
6904 if ( iSelectionIndexCache) |
6916 { |
6905 { |
6917 selectionCount = iSelectionIndexCache->Count(); |
6906 selectionCount = iSelectionIndexCache->Count(); |
7148 { |
7137 { |
7149 if ( iContainer->IsInReorderMode() ) |
7138 if ( iContainer->IsInReorderMode() ) |
7150 { |
7139 { |
7151 ProcessCommandL( iContainer->IsInReorderMode() ? |
7140 ProcessCommandL( iContainer->IsInReorderMode() ? |
7152 EMPXCmdReorderDrop : EMPXCmdReorderGrab ); |
7141 EMPXCmdReorderDrop : EMPXCmdReorderGrab ); |
7153 iIsGrabbed = !iIsGrabbed; |
7142 } |
7154 } |
7143 else if ( !iHandlingKeyEvent ) |
7155 else if ( !iHandlingKeyEvent ) |
|
7156 { |
7144 { |
7157 TMPXPlaybackState pbState( iPlaybackUtility->StateL() ); |
7145 TMPXPlaybackState pbState( iPlaybackUtility->StateL() ); |
7158 TBool isEqual( EFalse ); |
7146 TBool isEqual( EFalse ); |
7159 if ( pbState == EPbStatePlaying || pbState == EPbStatePaused ) |
7147 if ( pbState == EPbStatePlaying || pbState == EPbStatePaused ) |
7160 { |
7148 { |
7287 { |
7275 { |
7288 case EMPXCmdReorderDrop: |
7276 case EMPXCmdReorderDrop: |
7289 { |
7277 { |
7290 SaveCurrentPlaylistL(); |
7278 SaveCurrentPlaylistL(); |
7291 iContainer->ConfirmReorderL(); |
7279 iContainer->ConfirmReorderL(); |
7292 DeactivateReorderGrabbedModeL( EFalse ); |
7280 DeactivateReorderGrabbedModeL( ETrue ); |
7293 SetNewCbaL( R_MPX_CUI_REORDER_GRAB_DONE_CBA ); |
|
7294 break; |
7281 break; |
7295 } |
7282 } |
7296 case EMPXCmdReorderGrab: |
7283 case EMPXCmdReorderGrab: |
7297 { |
7284 { |
7298 SetNewCbaL( R_MPX_CUI_REORDER_DROP_CANCEL_CBA ); |
7285 SetNewCbaL( R_MPX_CUI_REORDER_DROP_CANCEL_CBA ); |
7945 if( iInSongDetails ) |
7932 if( iInSongDetails ) |
7946 { |
7933 { |
7947 iInSongDetails = EFalse; |
7934 iInSongDetails = EFalse; |
7948 } |
7935 } |
7949 } |
7936 } |
7937 else if ( ( aCurrentViewType.iUid == KMPXPluginTypePlaybackUid ) && ( iGoToNowPlaying == EFalse ) ) |
|
7938 { |
|
7939 // It is view switching when launched from other applications |
|
7940 // hide this view to avoid flickering |
|
7941 // since this view is the current active view, it receives this event |
|
7942 |
|
7943 if ( iContainer ) |
|
7944 { |
|
7945 iContainer->HideContainerWindow(); |
|
7946 |
|
7947 // set title to blank to avoid title flickering |
|
7948 CAknTitlePane* title( static_cast<CAknTitlePane*> |
|
7949 ( StatusPane()->ControlL( TUid::Uid( EEikStatusPaneUidTitle )))); |
|
7950 if ( title ) |
|
7951 { |
|
7952 title->SetTextL(KEmptyTitle); |
|
7953 title->DrawNow(); |
|
7954 } |
|
7955 } |
|
7956 } |
|
7950 } |
7957 } |
7951 |
7958 |
7952 // ----------------------------------------------------------------------------- |
7959 // ----------------------------------------------------------------------------- |
7953 // CMPXCollectionViewHgImp::HandleViewUpdate |
7960 // CMPXCollectionViewHgImp::HandleViewUpdate |
7954 // ----------------------------------------------------------------------------- |
7961 // ----------------------------------------------------------------------------- |