camerauis/cameraapp/generic/src/CamBurstThumbnailGridModel.cpp
branchRCL_3
changeset 54 bac7acad7cb3
parent 0 1ddebce53859
equal deleted inserted replaced
53:61bc0f252b2b 54:bac7acad7cb3
       
     1 /*
       
     2 * Copyright (c) 2007 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 "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:  Class to model the contents of the burst post-capture view*
       
    15 */
       
    16 
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include <fbs.h>     
       
    21 #include <barsread.h>
       
    22 #include <eikenv.h>
       
    23 
       
    24 #include <cameraapp.rsg>
       
    25 #include <vgacamsettings.rsg>
       
    26 #include <StringLoader.h>
       
    27 #include <aknnotewrappers.h>
       
    28 
       
    29  
       
    30 #include "CamBurstThumbnailGridModel.h"
       
    31 #include "CamBurstThumbnailGrid.h"
       
    32 #include "CamBurstCaptureArray.h"
       
    33 #include "camlogging.h"
       
    34 #include "CamPanic.h"
       
    35 
       
    36 // Uncommenting the define below will allow wrapping of the grid from the first
       
    37 // element of the grid to the very last, and vice-versa.
       
    38 #define ALLOW_GRID_WRAPPING
       
    39 
       
    40 
       
    41 // ============================= LOCAL FUNCTIONS ===============================
       
    42 
       
    43 
       
    44 // ============================ MEMBER FUNCTIONS ===============================
       
    45 
       
    46 CCamBurstThumbnailGridModel::CCamBurstThumbnailGridModel() 
       
    47     {
       
    48     }
       
    49 
       
    50 
       
    51 // -----------------------------------------------------------------------------
       
    52 // CCamBurstCaptureItem::NewL
       
    53 // Two-phased constructor.
       
    54 // -----------------------------------------------------------------------------
       
    55 //
       
    56 CCamBurstThumbnailGridModel* CCamBurstThumbnailGridModel::NewL()
       
    57     {
       
    58     CCamBurstThumbnailGridModel* self = new( ELeave ) CCamBurstThumbnailGridModel();
       
    59     CleanupStack::PushL( self );
       
    60     self->ConstructL();
       
    61     CleanupStack::Pop();
       
    62     return self;
       
    63     }
       
    64 
       
    65 // -----------------------------------------------------------------------------
       
    66 // CCamBurstThumbnailGridModel::ConstructL
       
    67 // Symbian 2nd phase constructor can leave.
       
    68 // -----------------------------------------------------------------------------
       
    69 //
       
    70 void CCamBurstThumbnailGridModel::ConstructL()
       
    71     {
       
    72     iThumbSize.iWidth = 0;
       
    73     iThumbSize.iHeight = 0;
       
    74 
       
    75     iGridSizer = CCamThumbnailGridSizer::NewL( this, iThumbSize );        
       
    76     iTopLeftIndex = 0;
       
    77     }
       
    78 
       
    79 
       
    80 // -----------------------------------------------------------------------------
       
    81 // CCamBurstThumbnailGridModel::GridItem
       
    82 // Returns pointer to the requested item, or NULL if index is invalid
       
    83 // -----------------------------------------------------------------------------
       
    84 //
       
    85 CThumbnailGridItem* CCamBurstThumbnailGridModel::GridItem( TInt aIndex )
       
    86     {
       
    87     if ( aIndex >= iValidThumbGrid.Count() )
       
    88         {
       
    89         return NULL;
       
    90         }
       
    91     else 
       
    92         {
       
    93         return iValidThumbGrid[ aIndex ];
       
    94         }
       
    95     }
       
    96 
       
    97 // Note: Returns ONLY non-deleted cells
       
    98 // -----------------------------------------------------------------------------
       
    99 // CCamBurstThumbnailGridModel::Snapshot
       
   100 // Returns pointer to the requested item, or NULL if index is invalid
       
   101 // -----------------------------------------------------------------------------
       
   102 //
       
   103 const CFbsBitmap* CCamBurstThumbnailGridModel::Snapshot( TInt aIndex )
       
   104     {
       
   105     if ( aIndex >= iValidThumbGrid.Count() )
       
   106         {
       
   107         return NULL;
       
   108         }
       
   109     else 
       
   110         {        
       
   111         TInt ind = ConvertFromValidToGlobalIndex( aIndex );
       
   112         if ( ind != KErrNotFound )
       
   113             {
       
   114             return iBurstArray->Snapshot( ind );
       
   115             }
       
   116         else 
       
   117             {
       
   118             return NULL;
       
   119             }
       
   120         }
       
   121     }
       
   122 
       
   123 // Destructor
       
   124 CCamBurstThumbnailGridModel::~CCamBurstThumbnailGridModel()
       
   125   {
       
   126   PRINT( _L("Camera => ~CCamBurstThumbnailGridModel") );
       
   127 
       
   128   if ( iGridSizer )
       
   129       {
       
   130       iGridSizer->Cancel();
       
   131       }
       
   132   delete iGridSizer;
       
   133   
       
   134   // Delete the array and the objects pointed to
       
   135   iAllThumbGrid.ResetAndDestroy();
       
   136 
       
   137   // Note: As this points to the same thing as the array above, just 
       
   138   // delete the array, not the objects
       
   139   iValidThumbGrid.Reset();
       
   140 
       
   141   // Do NOT destroy the objects pointed to, just the list.
       
   142   iThumbObserver.Reset();     
       
   143   iHighlightObserver.Reset();
       
   144   iDeleteObserver.Reset();
       
   145   PRINT( _L("Camera <= ~CCamBurstThumbnailGridModel") );
       
   146   }
       
   147 
       
   148 // -----------------------------------------------------------------------------
       
   149 // CCamBurstThumbnailGridModel::AddCellL
       
   150 // Adds the cell to the internal structures.  Takes ownership of the cell.
       
   151 // -----------------------------------------------------------------------------
       
   152 //
       
   153 void CCamBurstThumbnailGridModel::AddCellL( CThumbnailGridItem* aCell )
       
   154     {
       
   155     // Add to the master list of grid items
       
   156     User::LeaveIfError( iAllThumbGrid.Append( aCell ) );
       
   157 
       
   158     // Add to the list of VALID (non deleted) grid items
       
   159     User::LeaveIfError( iValidThumbGrid.Append( aCell ) );
       
   160     }
       
   161 
       
   162 // -----------------------------------------------------------------------------
       
   163 // CCamBurstThumbnailGridModel::StartThumbnailL
       
   164 // -----------------------------------------------------------------------------
       
   165 //
       
   166 void CCamBurstThumbnailGridModel::StartThumbnailL( TInt aIndex )
       
   167     {        
       
   168     // Burst array may be released by the app when swicthing
       
   169     // views so do a check that it is still valid
       
   170     if ( iBurstArray )
       
   171         {
       
   172         const CFbsBitmap* source = iBurstArray->Snapshot( aIndex );
       
   173         if ( source )
       
   174             {
       
   175             iGridSizer->StartScaleL( *source, iThumbSize, aIndex );
       
   176             }
       
   177         }
       
   178     }
       
   179     
       
   180 // -----------------------------------------------------------------------------
       
   181 // CCamBurstThumbnailGridModel::CancelThumbnails
       
   182 // Cancels any outstanding thumbnail generation operation
       
   183 // -----------------------------------------------------------------------------
       
   184 //
       
   185 void CCamBurstThumbnailGridModel::CancelThumbnails()
       
   186     {
       
   187     if ( iGridSizer->IsActive() )
       
   188         {
       
   189         iGridSizer->Cancel();
       
   190         }
       
   191     }    
       
   192 
       
   193 // -----------------------------------------------------------------------------
       
   194 // CCamBurstThumbnailGridModel::ImageFilesDeletedL
       
   195 // -----------------------------------------------------------------------------
       
   196 //
       
   197 void CCamBurstThumbnailGridModel::ImageFilesDeleted()
       
   198     {
       
   199     
       
   200     TBool highlightDeleted = EFalse;
       
   201     
       
   202     TInt highlightIndex = ConvertFromValidToGlobalIndex( iCurrHighlight );
       
   203     
       
   204     for ( TInt i = 0; i < iBurstArray->Count(); i++ )
       
   205         {
       
   206         if ( iBurstArray->IsDeleted( i ) )
       
   207             {
       
   208             if ( highlightIndex == i )
       
   209                 {
       
   210                 highlightDeleted = ETrue;
       
   211                 }
       
   212             
       
   213             TRAPD( error, DeleteItemL( i ) );
       
   214             
       
   215             // DeleteItemL() leaves only when file can't be deleted and that should never
       
   216             // happen here as the files are already deleted
       
   217             __ASSERT_DEBUG( error == KErrNone, CamPanic( ECamPanicUi ) );
       
   218             error++; // remove compile warnings
       
   219             }
       
   220         }
       
   221     
       
   222     DoPostDeleteGridCheck( highlightDeleted );
       
   223     }
       
   224 
       
   225 // -----------------------------------------------------------------------------
       
   226 // CCamThumbnailGridSizer::SetThumbnailSize
       
   227 // -----------------------------------------------------------------------------
       
   228 //
       
   229 void CCamBurstThumbnailGridModel::SetThumbnailSize( const TSize aThumbSize )
       
   230     {
       
   231     
       
   232     if ( aThumbSize != iThumbSize )
       
   233         {
       
   234         iThumbSize = aThumbSize;
       
   235 		iGridSizer->SetSize( iThumbSize );
       
   236         // delete all thumbs because size has changed and they need to be regenerated
       
   237         TInt imagesRemaining = iBurstArray->ImagesRemaining();
       
   238         for ( TInt i = 0; i < imagesRemaining; i++ )
       
   239             {
       
   240             // delete display thumbnail
       
   241             delete iValidThumbGrid[i]->iDisplayThumb;
       
   242             iValidThumbGrid[i]->iDisplayThumb = NULL;   
       
   243             }
       
   244 
       
   245         // recalculate needed thumbs
       
   246         RecalculateThumbs();
       
   247 
       
   248         }
       
   249     }
       
   250 
       
   251 
       
   252 
       
   253 // -----------------------------------------------------------------------------
       
   254 // CCamBurstThumbnailGridModel::BitmapScaleCompleteL
       
   255 // Callback called when a bitmap scaling operation has completed.
       
   256 // We take ownership of the 'aBitmap' object
       
   257 // -----------------------------------------------------------------------------
       
   258 //
       
   259 void CCamBurstThumbnailGridModel::BitmapScaleCompleteL( TInt aErr, CFbsBitmap* aBitmap, TInt32 aInfo )
       
   260     {
       
   261     if ( aErr == KErrNone )
       
   262         {       
       
   263         // Update internal structure
       
   264         CThumbnailGridItem* item = iAllThumbGrid[aInfo];
       
   265         item->iDisplayThumb = aBitmap;
       
   266 
       
   267         // Inform observer(s) to ensure the screen is updated     
       
   268         NotifyModelObserver( EModelEventThumb );
       
   269         }    
       
   270     }      
       
   271     
       
   272 // -----------------------------------------------------------------------------
       
   273 // CCamBurstThumbnailGridModel::RecalculateThumbs
       
   274 // Called to check which thumbnails need creating, and start the procedure
       
   275 // -----------------------------------------------------------------------------
       
   276 //
       
   277 void CCamBurstThumbnailGridModel::RecalculateThumbs()
       
   278     {        
       
   279     // If in the grid below, items 3-8 were visible in the screen grid, 
       
   280     // items 0-2 and 9-11 would also have thumbnails generated to attempt
       
   281     // to reduce visible artifacts from calculating on the fly.
       
   282     //    [ 0 ][ 1 ][ 2 ]   <= Row above (not visible)
       
   283     //    [ 3 ][ 4 ][ 5 ]   <= First visible row
       
   284     //    [ 6 ][ 7 ][ 8 ]   <= Second visible row
       
   285     //    [ 9 ][ 10][ 11]   <= Row below (not visible)
       
   286     //
       
   287     
       
   288     // If we get to recalculate thumbnails, we need to cancel any outstanding 
       
   289     // rescale operation
       
   290     CancelThumbnails();
       
   291     
       
   292     // Work out the top left index. This is the top-left cell of the VIEWABLE
       
   293     // grid, less one row (which serves as a thumbnail cache)        
       
   294     TInt topLeftIndex = iTopLeftIndex - KGridWidth;
       
   295     if ( topLeftIndex < 0 )
       
   296         {
       
   297         topLeftIndex = 0;
       
   298         }
       
   299 
       
   300     // Work out the bottom right index. This is the bottom-right cell of the 
       
   301     // VIEWABLE grid, plus one row (which serves as a thumbnail cache)
       
   302     TInt botRightIndex = iTopLeftIndex + ( KGridWidth * iGridHeight ) - 1 + KGridWidth;
       
   303     if ( botRightIndex > iValidThumbGrid.Count() - 1 )
       
   304         {
       
   305         botRightIndex = iValidThumbGrid.Count() - 1;
       
   306         }
       
   307     
       
   308     // Delete the thumbnails for cells that are not immediately visible, and are
       
   309     // not in the next or last row.
       
   310     TInt i;
       
   311     TInt imagesRemaining = iBurstArray->ImagesRemaining();
       
   312     for ( i = 0; i < imagesRemaining; i++ )
       
   313         {
       
   314         if ( ( i < topLeftIndex || i > botRightIndex ) &&
       
   315             iValidThumbGrid[i]->iDisplayThumb ) 
       
   316             {
       
   317             // delete display thumbnail
       
   318             delete iValidThumbGrid[i]->iDisplayThumb;
       
   319             iValidThumbGrid[i]->iDisplayThumb = NULL;   
       
   320             }
       
   321         }
       
   322     
       
   323     // Queue up the thumbnails that need to be resized
       
   324     TRAPD( ignore, QueueThumbnailsL() );
       
   325     if ( ignore )
       
   326         { 
       
   327         // Do nothing ( removes build warning )
       
   328         }                   
       
   329     }
       
   330 
       
   331 
       
   332 // -----------------------------------------------------------------------------
       
   333 // CCamBurstThumbnailGridModel::QueueThumbnailsL
       
   334 // Queues the thumbnails to be resized as needed
       
   335 // -----------------------------------------------------------------------------
       
   336 //
       
   337 void CCamBurstThumbnailGridModel::QueueThumbnailsL()
       
   338     {
       
   339     //    [ 0 ][ 1 ][ 2 ]   <= Row above (not visible)
       
   340     //    [ 3 ][ 4 ][ 5 ]   <= First visible row
       
   341     //    [ 6 ][ 7 ][ 8 ]   <= Second visible row
       
   342     //    [ 9 ][ 10][ 11]   <= Row below (not visible)
       
   343     //    
       
   344     TInt start = iTopLeftIndex;
       
   345     TInt index = KErrNotFound; 
       
   346     TInt max = iTopLeftIndex + KGridSize;
       
   347     if ( max > iValidThumbGrid.Count() )
       
   348         {
       
   349         max = iValidThumbGrid.Count();
       
   350         }
       
   351     
       
   352     // Top priority is the set of thumbs visible AT THIS MOMENT
       
   353     TInt i;
       
   354     for ( i = start; i < max ; i++ )
       
   355         {
       
   356         if ( !iValidThumbGrid[i]->iDisplayThumb )
       
   357             {
       
   358             // If we get here, then 'i' is the index to the VALID set of items.
       
   359             // Need to convert this to the index in the GLOBAL set of items
       
   360             index = ConvertFromValidToGlobalIndex( i );
       
   361             StartThumbnailL( index );
       
   362             }
       
   363         }
       
   364 
       
   365     // SECOND top priority is the set of thumbs BELOW the visible set
       
   366     if ( iValidThumbGrid.Count() >= iTopLeftIndex + KGridSize ) 
       
   367         {
       
   368         start = iTopLeftIndex+KGridSize;
       
   369         max = i + KGridWidth;
       
   370         if ( max > iValidThumbGrid.Count() )
       
   371             {
       
   372             max = iValidThumbGrid.Count();
       
   373             }
       
   374 
       
   375         // If we have got here, we can cache the row *below* the 2nd visible row
       
   376         for ( i = start; i < max; i++ )
       
   377             {
       
   378             if ( !iValidThumbGrid[i]->iDisplayThumb )
       
   379                 {
       
   380                 // If we get here, then 'i' is the index to the VALID set of items.
       
   381                 // Need to convert this to the index in the GLOBAL set of items
       
   382                 index = ConvertFromValidToGlobalIndex( i );
       
   383                 StartThumbnailL( index );
       
   384                 }
       
   385             }
       
   386         }
       
   387 
       
   388     // THIRD priority is the set of thumbs ABOVE the visible set
       
   389     if ( iTopLeftIndex >= KGridWidth ) // ONLY if there IS a previous row
       
   390         {
       
   391         start = iTopLeftIndex - KGridWidth;
       
   392         max = iTopLeftIndex;
       
   393         // If we have got here, we can cache the row *above* this one.
       
   394         for ( i = start; i < max; i++ )
       
   395             {
       
   396             if ( !iValidThumbGrid[i]->iDisplayThumb )
       
   397                 {
       
   398                 // If we get here, then 'i' is the index to the VALID set of items.
       
   399                 // Need to convert this to the index in the GLOBAL set of items
       
   400                 index = ConvertFromValidToGlobalIndex( i );
       
   401                 StartThumbnailL( index );
       
   402                 }
       
   403             }
       
   404         }
       
   405     }
       
   406 
       
   407 // -----------------------------------------------------------------------------
       
   408 // CCamBurstThumbnailGridModel::ConvertFromValidToGlobalIndex
       
   409 // Converts from a valid-index (non-deleted only) to global (del & non-del) index
       
   410 // -----------------------------------------------------------------------------
       
   411 //
       
   412 TInt CCamBurstThumbnailGridModel::ConvertFromValidToGlobalIndex( TInt aValidIndex )   
       
   413     {       
       
   414     if ( aValidIndex < iValidThumbGrid.Count() )
       
   415         {
       
   416         CThumbnailGridItem* item = iValidThumbGrid[aValidIndex];
       
   417         return iAllThumbGrid.Find( item );    
       
   418         }
       
   419     else
       
   420         {
       
   421         return KErrNotFound;
       
   422         }
       
   423     }      
       
   424 
       
   425 // -----------------------------------------------------------------------------
       
   426 // CCamBurstThumbnailGridModel::SetBurstArrayL
       
   427 // -----------------------------------------------------------------------------
       
   428 //
       
   429 void CCamBurstThumbnailGridModel::SetBurstArrayL( CCamBurstCaptureArray* aArray )
       
   430     {
       
   431     PRINT( _L("Camera => CCamBurstThumbnailGridModel::SetBurstArrayL") );
       
   432 
       
   433     // If we've not been initialised yet, and have no data, then use the array
       
   434     // just passed in.  
       
   435     if ( iAllThumbGrid.Count() == 0 )
       
   436         {
       
   437         iBurstArray = aArray;
       
   438         
       
   439         // Build up model to match burst array
       
   440         if ( iBurstArray )
       
   441             {
       
   442             TInt i;
       
   443             TInt count = iBurstArray->Count();
       
   444             PRINT1( _L("Camera <> got %d thumbnails"), count );
       
   445             
       
   446             // Create a set of items to match the number in the burst array
       
   447             for ( i = 0; i < count; i++ )
       
   448                 {
       
   449                 CThumbnailGridItem* item = new ( ELeave ) CThumbnailGridItem();
       
   450 
       
   451                 CleanupStack::PushL( item );
       
   452                 item->iDisplayThumb = NULL;
       
   453                 item->iMarked = EFalse;
       
   454                 AddCellL( item );
       
   455                 CleanupStack::Pop( item );
       
   456 
       
   457                 if ( !iBurstArray->Snapshot( i ) )
       
   458                     {
       
   459                     DeleteItemL( i );
       
   460                     }
       
   461                 }
       
   462 
       
   463             // Setup the base grid height based on the number of items
       
   464             if ( NoOfValidCells() <= KSmallGridCellCount )
       
   465                 {
       
   466                 iGridHeight = KSmallGridHeight;
       
   467                 }
       
   468             else 
       
   469                 {
       
   470                 iGridHeight = KLargeGridHeight;
       
   471                 }
       
   472             
       
   473             // Start the generation of thumbnails
       
   474             RecalculateThumbs();
       
   475             }
       
   476         }
       
   477     PRINT( _L("Camera <= CCamBurstThumbnailGridModel::SetBurstArrayL") );
       
   478     }
       
   479 
       
   480 
       
   481 
       
   482 // -----------------------------------------------------------------------------
       
   483 // CCamBurstThumbnailGridModel::AddModelObserverL
       
   484 // -----------------------------------------------------------------------------
       
   485 //
       
   486 void CCamBurstThumbnailGridModel::AddModelObserverL( MThumbModelObserver* aObserver, TInt aMask )
       
   487     {
       
   488     if ( aMask & EModelEventHighlight )
       
   489         {
       
   490         User::LeaveIfError( iHighlightObserver.Append( aObserver ) );
       
   491         }
       
   492 
       
   493     if ( aMask & EModelEventDeleted )
       
   494         {
       
   495         User::LeaveIfError( iDeleteObserver.Append( aObserver ) );
       
   496         }
       
   497 
       
   498     if ( aMask & EModelEventThumb )
       
   499         {
       
   500         User::LeaveIfError( iThumbObserver.Append( aObserver ) );
       
   501         }   
       
   502     }
       
   503 
       
   504 // -----------------------------------------------------------------------------
       
   505 // CCamBurstThumbnailGridModel::RemoveModelObserver
       
   506 // -----------------------------------------------------------------------------
       
   507 //
       
   508 void CCamBurstThumbnailGridModel::RemoveModelObserver( MThumbModelObserver* aObserver, TInt aMask )
       
   509     {
       
   510     TInt pos;
       
   511     if ( aMask & EModelEventHighlight )
       
   512         {
       
   513         pos = iHighlightObserver.Find( aObserver );
       
   514         if ( pos != KErrNotFound )
       
   515             {
       
   516             iHighlightObserver.Remove( pos );
       
   517             }
       
   518         }
       
   519     if ( aMask & EModelEventDeleted )
       
   520         {
       
   521         pos = iDeleteObserver.Find( aObserver );
       
   522         if ( pos != KErrNotFound )
       
   523             {
       
   524             iDeleteObserver.Remove( pos );
       
   525             }
       
   526         }
       
   527     if ( aMask & EModelEventThumb )
       
   528         {
       
   529         pos = iThumbObserver.Find( aObserver );
       
   530         if ( pos != KErrNotFound )
       
   531             {
       
   532             iThumbObserver.Remove( pos );
       
   533             }
       
   534         }
       
   535     }
       
   536 
       
   537 // -----------------------------------------------------------------------------
       
   538 // CCamBurstThumbnailGridModel::NotifyModelObserver
       
   539 // -----------------------------------------------------------------------------
       
   540 //
       
   541 void CCamBurstThumbnailGridModel::NotifyModelObserver( TModelEvent aEvent, TInt /*aParam*/ )
       
   542     {
       
   543     TInt i;
       
   544     TInt count; 
       
   545 
       
   546     switch ( aEvent )        
       
   547         {        
       
   548         case EModelEventHighlight:
       
   549             {
       
   550             count = iHighlightObserver.Count();
       
   551             for ( i = 0; i < count; i++ )  
       
   552                 {
       
   553                 iHighlightObserver[i]->HighlightChanged();
       
   554                 }
       
   555             break;
       
   556             }
       
   557             
       
   558         case EModelEventDeleted:
       
   559             {
       
   560             count = iDeleteObserver.Count();
       
   561             for ( i = 0; i < count; i++ )  
       
   562                 {
       
   563                 iDeleteObserver[i]->ImagesDeleted();
       
   564                 }    
       
   565             break;
       
   566             }
       
   567 
       
   568         case EModelEventThumb:
       
   569             {
       
   570             count = iThumbObserver.Count();
       
   571             for ( i = 0; i < count; i++ )  
       
   572                 {
       
   573                 iThumbObserver[i]->ThumbnailGenerated();
       
   574                 }
       
   575             break;
       
   576             }
       
   577         default:
       
   578             break;  
       
   579         }
       
   580     }
       
   581 
       
   582 // -----------------------------------------------------------------------------
       
   583 // CCamBurstThumbnailGridModel::NoOfValidCells
       
   584 // -----------------------------------------------------------------------------
       
   585 //
       
   586 TInt CCamBurstThumbnailGridModel::NoOfValidCells()
       
   587     {
       
   588     //return iBurstArray->ImagesRemaining();
       
   589     return iValidThumbGrid.Count();
       
   590     }
       
   591 
       
   592 // -----------------------------------------------------------------------------
       
   593 // CCamBurstThumbnailGridModel::MoveHighlight
       
   594 // Tries to move the selection.  If no change is made, returns EFalse.
       
   595 // If change is made, returns ETrue (to inform of a redraw)
       
   596 // -----------------------------------------------------------------------------
       
   597 //
       
   598 TBool CCamBurstThumbnailGridModel::MoveHighlight( TMoveSelect aDir )
       
   599     {
       
   600     TInt oldTopLeft = iTopLeftIndex;
       
   601     TInt oldHighlight = iCurrHighlight;
       
   602 
       
   603     // cellX and cellY store the cell position in the X and Y axis as seen on 
       
   604     // the screen
       
   605     TInt cellX = ( iCurrHighlight - iTopLeftIndex ) % KGridWidth; // 0 - 2
       
   606     TInt cellY = ( iCurrHighlight - iTopLeftIndex ) / KGridWidth; // 0 - 1
       
   607 
       
   608     switch ( aDir )
       
   609         {
       
   610         case EMoveSelectLeft:
       
   611             {
       
   612             if ( iCurrHighlight > 0 )
       
   613                 {
       
   614                 iCurrHighlight --;
       
   615 
       
   616                 if ( cellX == 0 && cellY == 0 ) // At top left entry
       
   617                     {
       
   618                     iTopLeftIndex -= KGridWidth;
       
   619                     }
       
   620                 }
       
   621 #ifdef ALLOW_GRID_WRAPPING
       
   622             else 
       
   623                 {
       
   624                 TInt cells = iValidThumbGrid.Count();
       
   625                 TInt bottomX = ( cells ) % KGridWidth;
       
   626                 TInt bottomY = ( cells ) / KGridWidth;
       
   627                 // If over the allowed number of rows, and bottom row is full
       
   628                 if ( bottomY >= iGridHeight && bottomX == 0 )  
       
   629                     {
       
   630                     iTopLeftIndex = ( bottomY - iGridHeight ) * KGridWidth;    // 
       
   631                     }
       
   632                 else if ( bottomY >= ( iGridHeight - 1 ) ) // Over 1 row, 
       
   633                     {
       
   634                     iTopLeftIndex = ( bottomY - ( iGridHeight - 1 ) ) * KGridWidth;    
       
   635                     }
       
   636                 else // Only one (incomplete) row
       
   637                     { 
       
   638                     iTopLeftIndex = ( bottomY  ) * KGridWidth;    
       
   639                     }
       
   640                 
       
   641                 iCurrHighlight = cells - 1; // Last entry
       
   642                 }
       
   643 #endif // ALLOW_GRID_WRAPPING
       
   644             break;
       
   645             }
       
   646 
       
   647         case EMoveSelectRight:
       
   648             {
       
   649             if ( iCurrHighlight < ( iBurstArray->ImagesRemaining() - 1 ) )
       
   650                 {
       
   651                 iCurrHighlight ++;
       
   652 
       
   653                 if ( cellX == ( KGridWidth - 1 ) && cellY == ( iGridHeight - 1 ) ) 
       
   654                     {
       
   655                     iTopLeftIndex += KGridWidth;
       
   656                     }
       
   657                 }
       
   658 #ifdef ALLOW_GRID_WRAPPING
       
   659             else 
       
   660                 {
       
   661                 iCurrHighlight = 0; // Top left entry
       
   662                 iTopLeftIndex = 0;
       
   663                 }
       
   664 #endif // ALLOW_GRID_WRAPPING
       
   665 
       
   666             break;
       
   667             }
       
   668 
       
   669         case EMoveSelectUp:
       
   670             {
       
   671             if ( iCurrHighlight >= KGridWidth )
       
   672                 {
       
   673                 iCurrHighlight -= KGridWidth;
       
   674 
       
   675                 // if in TOP row, and we CAN move up, shift viewpoint up
       
   676                 if ( cellY == 0 ) 
       
   677                     {
       
   678                     iTopLeftIndex -= KGridWidth;
       
   679                     }
       
   680                 }
       
   681 #ifdef ALLOW_GRID_WRAPPING
       
   682             else // Then we need to wrap to the bottom of the previous grid
       
   683                 {
       
   684                 TInt cells = iValidThumbGrid.Count();
       
   685 
       
   686                 // startX holds the "x" value of initial selection
       
   687                 TInt startX = ( iCurrHighlight ) % KGridWidth; 
       
   688                 TInt bottomY = ( cells ) / KGridWidth; 
       
   689 
       
   690                 // If not in left-most grid, we'll be moving left and to bottom
       
   691                 if ( startX > 0 )
       
   692                     {
       
   693                     startX --;                    
       
   694                     }
       
   695                 else // Else in left most grid, so "jump" to right most.
       
   696                     {
       
   697                     if ( cells < KGridWidth )
       
   698                         {
       
   699                         startX = cells - 1;
       
   700                         }
       
   701                     else
       
   702                         {
       
   703                         startX = KGridWidth - 1;
       
   704                         }                    
       
   705                     }
       
   706 
       
   707                 // If all rows are full (so modulus is 0) bottomY division will
       
   708                 // be one too great, so compensate
       
   709                 if ( cells % KGridWidth == 0 )
       
   710                     { 
       
   711                     bottomY -- ;
       
   712                     }
       
   713                 iCurrHighlight = ( bottomY * KGridWidth ) + startX;
       
   714                 
       
   715                 // Check this item is filled in, if not, move "up" a row
       
   716                 if ( iCurrHighlight >= cells )
       
   717                     { 
       
   718                     // If more than one rows worth of items, can move to second to last row
       
   719                     if ( cells > KGridWidth )
       
   720                         {
       
   721                         bottomY --;
       
   722                         }
       
   723                     else // If only one row (or less)
       
   724                         {
       
   725                         startX = cells % KGridWidth;
       
   726                         }                    
       
   727 
       
   728                     // Will need to recalculate curr highlight following changes
       
   729                     iCurrHighlight = ( bottomY * KGridWidth ) + startX;
       
   730                     }
       
   731                 UpdateViewableGrid( EFalse );
       
   732                 }
       
   733 #endif // ALLOW_GRID_WRAPPING
       
   734             break;
       
   735             }
       
   736 
       
   737         case EMoveSelectDown:
       
   738             {
       
   739             if ( ( iCurrHighlight + KGridWidth ) <= ( iBurstArray->ImagesRemaining() - 1 ) )
       
   740                 {
       
   741                 iCurrHighlight += KGridWidth;
       
   742 
       
   743                 if ( cellY == ( iGridHeight-1 ) ) // if in BOTTOM row, and we CAN move down, shift viewpoint down
       
   744                     {
       
   745                     iTopLeftIndex += KGridWidth;
       
   746                     }
       
   747                 }
       
   748 #ifdef ALLOW_GRID_WRAPPING
       
   749             else // Then we need to wrap to the top of the next grid
       
   750                 {
       
   751                 TInt startX = ( iCurrHighlight ) % KGridWidth; 
       
   752                 TInt cells = iValidThumbGrid.Count();
       
   753                 TInt rightMostGrid;
       
   754 
       
   755                 if ( cells < KGridWidth )
       
   756                     {
       
   757                     rightMostGrid = cells;
       
   758                     }
       
   759                 else
       
   760                     {
       
   761                     rightMostGrid = KGridWidth;
       
   762                     }
       
   763                 
       
   764                 // If not in left-most grid, we'll be moving left and to bottom
       
   765                 if ( startX < ( rightMostGrid - 1 )  )
       
   766                     {                    
       
   767                     // Check we don't have less-than-a-row of cells left
       
   768                     if ( startX < ( cells - 1 ) )
       
   769                         {
       
   770                         startX ++;                    
       
   771                         }
       
   772                     else // If that is the case, move to the last one.
       
   773                         {
       
   774                         startX = cells - 1;
       
   775                         }
       
   776                     
       
   777                     }
       
   778                 else // Else in left most grid, so "jump" to right most.
       
   779                     {
       
   780                     startX = 0;
       
   781                     }                
       
   782 
       
   783                 // Calculate new highlight poisition.
       
   784                 iCurrHighlight = startX;
       
   785 
       
   786                 UpdateViewableGrid( ETrue );
       
   787                 }
       
   788 #endif // ALLOW_GRID_WRAPPING
       
   789             break;
       
   790             }
       
   791         }
       
   792         
       
   793     // Work out if the viewed items has changed.  If so, check whether we need 
       
   794     // to calculate any new thumbnails for display.
       
   795     if ( oldTopLeft != iTopLeftIndex )
       
   796         {
       
   797         RecalculateThumbs();
       
   798         }
       
   799 
       
   800     // Notify observers of the change
       
   801     NotifyModelObserver( EModelEventHighlight );    
       
   802 
       
   803     if ( iCurrHighlight != oldHighlight )
       
   804         {
       
   805         return ETrue;   // Highlight HAS changed
       
   806         }
       
   807     else 
       
   808         {
       
   809         return EFalse;  // No change
       
   810         }    
       
   811     }
       
   812 
       
   813 // Sets the higlighted burst item
       
   814 // informs model observer about the change
       
   815 // returns ETrue if highlight changed
       
   816 // returns EFalse if highlight was not changed
       
   817 TBool CCamBurstThumbnailGridModel::SetHighlight( TInt aIndex )
       
   818 	{
       
   819 	PRINT1( _L("Camera => CCamBurstThumbnailGridModel::SetHighlight( %d )"), aIndex );
       
   820 	
       
   821 	TInt oldHighlight = iCurrHighlight;
       
   822 	iCurrHighlight = aIndex;  
       
   823 
       
   824     PRINT( _L("Camera <= CCamBurstThumbnailGridModel::SetHighlight()") );
       
   825     
       
   826     if ( iCurrHighlight != oldHighlight )
       
   827         {
       
   828         return ETrue;   // Highlight HAS changed
       
   829         }
       
   830     else 
       
   831         {
       
   832         return EFalse;  // No change
       
   833         }  
       
   834 
       
   835 	}
       
   836 
       
   837 // -----------------------------------------------------------------------------
       
   838 // CCamBurstThumbnailGridModel::UpdateViewableGrid
       
   839 // -----------------------------------------------------------------------------
       
   840 //
       
   841 void CCamBurstThumbnailGridModel::UpdateViewableGrid( TBool aMovingUp )
       
   842     {          
       
   843     if ( NoOfValidCells() <= KBurstGridMaxVisibleThumbnails )
       
   844         {
       
   845         // no need to update if there are less cells than fit to screen at once
       
   846         return;
       
   847         }
       
   848     
       
   849     TInt posY = iCurrHighlight / KGridWidth; 
       
   850 
       
   851     // If moving up, when adjust the viewable area, the highlighted grid is 
       
   852     // in the top-most row.
       
   853     if ( aMovingUp )
       
   854         {        
       
   855         if ( posY >= ( iGridHeight - 1 ) )
       
   856             {
       
   857             iTopLeftIndex = ( posY - ( iGridHeight - 1 ) ) * KGridWidth;    
       
   858             }
       
   859         else // Only one (incomplete) row
       
   860             { 
       
   861             iTopLeftIndex = ( posY ) * KGridWidth;    
       
   862             }
       
   863         }
       
   864     // If moving down, when adjust the viewable area, the highlighted grid item
       
   865     // is in the bottom-most row
       
   866     else
       
   867         {   
       
   868         if ( posY >= ( iGridHeight - 1 ) )
       
   869             {
       
   870             iTopLeftIndex = ( posY - ( iGridHeight - 1 ) ) * KGridWidth;    
       
   871             }
       
   872         else // Only one (incomplete) row
       
   873             { 
       
   874             iTopLeftIndex = ( posY ) * KGridWidth;    
       
   875             }
       
   876         }
       
   877     }
       
   878 
       
   879 // -----------------------------------------------------------------------------
       
   880 // CCamBurstThumbnailGridModel::HighlightedGridIndex
       
   881 // -----------------------------------------------------------------------------
       
   882 //
       
   883 TInt CCamBurstThumbnailGridModel::HighlightedGridIndex()
       
   884     {
       
   885     return iCurrHighlight;
       
   886     }
       
   887 
       
   888 
       
   889 // -----------------------------------------------------------------------------
       
   890 // CCamBurstThumbnailGridModel::TopLeftGridIndex
       
   891 // -----------------------------------------------------------------------------
       
   892 //
       
   893 TInt CCamBurstThumbnailGridModel::TopLeftGridIndex()
       
   894     {   
       
   895     return iTopLeftIndex;
       
   896     }  
       
   897 
       
   898 // -----------------------------------------------------------------------------
       
   899 // CCamBurstThumbnailGridModel::HighlightedBurstIndex
       
   900 // As used for getting the index in the CONTROLLER's array, which contains
       
   901 // both non-deleted AND DELETED items in the array.
       
   902 // -----------------------------------------------------------------------------
       
   903 //
       
   904 TInt CCamBurstThumbnailGridModel::HighlightedBurstIndex()
       
   905     {
       
   906     TInt index = -1;
       
   907     if ( iCurrHighlight != KErrNotFound )
       
   908         {
       
   909         // The "Current Highlight" is the index to the VALID array (non-deleted only)
       
   910         // Need to find the equivalent index in the GLOBAL array (del and non-del)
       
   911         index = ConvertFromValidToGlobalIndex( iCurrHighlight );
       
   912         }    
       
   913 
       
   914     return index;
       
   915     }
       
   916 
       
   917 // -----------------------------------------------------------------------------
       
   918 // CCamBurstThumbnailGridModel::HighlightedImageName
       
   919 // -----------------------------------------------------------------------------
       
   920 //
       
   921 TPtrC CCamBurstThumbnailGridModel::HighlightedImageName()
       
   922     {
       
   923     if ( iCurrHighlight != KErrNotFound )
       
   924         {
       
   925         // The "Current Highlight" is the index to the VALID array (non-deleted only)
       
   926         // Need to find the equivalent index in the GLOBAL array (del and non-del)
       
   927         TInt index = ConvertFromValidToGlobalIndex( iCurrHighlight );
       
   928         if ( index != KErrNotFound )
       
   929             {
       
   930             return iBurstArray->ImageName( index );
       
   931             }
       
   932         }    
       
   933     return TPtrC();
       
   934     }
       
   935 
       
   936 // -----------------------------------------------------------------------------
       
   937 // CCamBurstThumbnailGridModel::ImageName
       
   938 // Returns the image name (no path or extension) of an item.
       
   939 // -----------------------------------------------------------------------------
       
   940 //
       
   941 TPtrC CCamBurstThumbnailGridModel::ImageName( TInt aIndex )
       
   942     {
       
   943     // The "Current Highlight" is the index to the VALID array (non-deleted only)
       
   944     // Need to find the equivalent index in the GLOBAL array (del and non-del)
       
   945     TInt index = ConvertFromValidToGlobalIndex( aIndex );
       
   946     if ( index != KErrNotFound )
       
   947         {
       
   948         return iBurstArray->ImageName( index );
       
   949         }
       
   950     return TPtrC();
       
   951     }
       
   952 
       
   953 // -----------------------------------------------------------------------------
       
   954 // CCamBurstThumbnailGridModel::ImageFullName
       
   955 // Returns the image name (with path and extension) of an item.
       
   956 // -----------------------------------------------------------------------------
       
   957 //
       
   958 TPtrC CCamBurstThumbnailGridModel::ImageFileName( TInt aIndex ) const
       
   959     {
       
   960     return iBurstArray->FileName( aIndex );
       
   961     }
       
   962 
       
   963 // -----------------------------------------------------------------------------
       
   964 // CCamBurstThumbnailGridModel::RefreshL
       
   965 // -----------------------------------------------------------------------------
       
   966 //
       
   967 void CCamBurstThumbnailGridModel::RefreshL()
       
   968     {
       
   969     // If this function is called, it is to check whether the currently 
       
   970     // highlighted image has not been deleted yet.  This may occur if it has
       
   971     // been viewed and deleted in the post-capture view.
       
   972 
       
   973     // Get the global index for the highlighted item
       
   974     TInt index = ConvertFromValidToGlobalIndex( iCurrHighlight );
       
   975 
       
   976     // Check it's deleted state
       
   977     TBool deleted = iBurstArray->IsDeleted( index );
       
   978 
       
   979     // If the item has been deleted from the BurstArray, we need to update
       
   980     // our state, so run the delete highlight code for the GridModel
       
   981     if ( deleted )
       
   982         {
       
   983         // Update internal state accordingly
       
   984         DeleteHighlightL();
       
   985         }
       
   986     }
       
   987 
       
   988 
       
   989 // -----------------------------------------------------------------------------
       
   990 // CCamBurstThumbnailGridModel::SetCurrentMark
       
   991 // -----------------------------------------------------------------------------
       
   992 //
       
   993 void CCamBurstThumbnailGridModel::SetCurrentMark( TBool aSet )
       
   994     {    
       
   995     if ( aSet ) // Setting the mark ON
       
   996         {
       
   997         iValidThumbGrid[iCurrHighlight]->iMarked = ETrue;
       
   998         iImagesMarked++;
       
   999         }    
       
  1000     else    // Setting the mark OFF
       
  1001         {
       
  1002         iValidThumbGrid[iCurrHighlight]->iMarked = EFalse;
       
  1003         iImagesMarked--;
       
  1004         }
       
  1005     NotifyModelObserver( EModelEventThumb );   // Force thumbnail redraw
       
  1006     }
       
  1007 
       
  1008 
       
  1009 // -----------------------------------------------------------------------------
       
  1010 // CCamBurstThumbnailGridModel::MarkAll
       
  1011 // -----------------------------------------------------------------------------
       
  1012 //
       
  1013 void CCamBurstThumbnailGridModel::MarkAll( TBool aMark )
       
  1014     {
       
  1015     TInt count = iValidThumbGrid.Count();
       
  1016     TInt i;
       
  1017 
       
  1018     // Go through each valid (non-deleted) item
       
  1019     for ( i = 0; i < count; i++ )
       
  1020         {
       
  1021         // If it's not already in the required state (marked or unmarked)
       
  1022         if ( !( iValidThumbGrid[i]->iMarked == aMark ) )
       
  1023             {
       
  1024             // ...change the state of the item
       
  1025             iValidThumbGrid[i]->iMarked = aMark;
       
  1026 
       
  1027             // ...and update the internal count
       
  1028             if ( aMark )
       
  1029                 {
       
  1030                 iImagesMarked++;
       
  1031                 }
       
  1032             else
       
  1033                 {
       
  1034                 iImagesMarked--;
       
  1035                 }
       
  1036             }
       
  1037         }
       
  1038     NotifyModelObserver( EModelEventThumb );   // Force thumbnail redraw
       
  1039     }
       
  1040 
       
  1041 // -----------------------------------------------------------------------------
       
  1042 // CCamBurstThumbnailGridModel::NoOfMarkedImages
       
  1043 // -----------------------------------------------------------------------------
       
  1044 //
       
  1045 TInt CCamBurstThumbnailGridModel::NoOfMarkedImages() const
       
  1046     {
       
  1047     return iImagesMarked;
       
  1048     }
       
  1049 
       
  1050 // -----------------------------------------------------------------------------
       
  1051 // CCamBurstThumbnailGridModel::NoOfImages
       
  1052 // -----------------------------------------------------------------------------
       
  1053 //
       
  1054 TInt CCamBurstThumbnailGridModel::NoOfImages() const
       
  1055     {
       
  1056     return iAllThumbGrid.Count();
       
  1057     }
       
  1058 
       
  1059 // -----------------------------------------------------------------------------
       
  1060 // CCamBurstThumbnailGridModel::IsMarkedL
       
  1061 // -----------------------------------------------------------------------------
       
  1062 //
       
  1063 TInt CCamBurstThumbnailGridModel::IsMarkedL( TInt aIndex )
       
  1064     {
       
  1065     if ( aIndex < 0 || aIndex >= iValidThumbGrid.Count() )
       
  1066         {
       
  1067         User::Leave( KErrArgument );
       
  1068         }
       
  1069     return iValidThumbGrid[aIndex]->iMarked;
       
  1070     }
       
  1071 
       
  1072 
       
  1073 
       
  1074 // -----------------------------------------------------------------------------
       
  1075 // CCamBurstThumbnailGridModel::DeleteMarkedL
       
  1076 // -----------------------------------------------------------------------------
       
  1077 //
       
  1078 void CCamBurstThumbnailGridModel::DeleteMarkedL()
       
  1079     {
       
  1080     // Keep track of if we've just deleted the highlighted item.  
       
  1081     // If so, we'll need to inform the view, later.
       
  1082     TBool highlightDeleted =  iValidThumbGrid[iCurrHighlight]->iMarked ;        
       
  1083 
       
  1084     TInt i;
       
  1085     TInt count = iAllThumbGrid.Count();
       
  1086     TInt error = KErrNone;
       
  1087     for ( i = 0; i < count; i++ )
       
  1088         {
       
  1089         if ( iAllThumbGrid[i]->iMarked )
       
  1090             {    
       
  1091             TRAP( error, DeleteItemL( i ) );
       
  1092             if ( error )
       
  1093                 {
       
  1094                 break;
       
  1095                 }
       
  1096             }
       
  1097         }
       
  1098     
       
  1099     // Do the recalculation required to adjust the positioning of items and
       
  1100     // the hightlight
       
  1101     DoPostDeleteGridCheck( highlightDeleted );
       
  1102     
       
  1103     if ( error && error != KErrInUse )
       
  1104         {
       
  1105         User::Leave( error );
       
  1106        }
       
  1107     }
       
  1108 
       
  1109 
       
  1110 // -----------------------------------------------------------------------------
       
  1111 // CCamBurstThumbnailGridModel::DeleteHighlightL
       
  1112 // -----------------------------------------------------------------------------
       
  1113 //
       
  1114 void CCamBurstThumbnailGridModel::DeleteHighlightL()
       
  1115     {
       
  1116     // Gets the global index of the currently highlighted item
       
  1117     TInt globalIndex = ConvertFromValidToGlobalIndex( iCurrHighlight );
       
  1118 
       
  1119     // Delete that item
       
  1120     
       
  1121     TRAPD( error, DeleteItemL( globalIndex ) );
       
  1122     
       
  1123     
       
  1124     // Check the internal state for any adjustments of visible items, new
       
  1125     // highlight position etc.
       
  1126     DoPostDeleteGridCheck( ETrue );
       
  1127     
       
  1128     if ( error && error != KErrInUse )
       
  1129         {
       
  1130         User::Leave( error );
       
  1131         }
       
  1132     }
       
  1133 
       
  1134 // -----------------------------------------------------------------------------
       
  1135 // CCamBurstThumbnailGridModel::DeleteItemL
       
  1136 // Internal function for deleting a particular item
       
  1137 // -----------------------------------------------------------------------------
       
  1138 //
       
  1139 void CCamBurstThumbnailGridModel::DeleteItemL( TInt aGlobalIndex )
       
  1140     {
       
  1141     PRINT( _L("Camera => CCamBurstThumbnailGridModel::DeleteItemL") );
       
  1142     // If this item was marked, clear the mark and adjust internal state
       
  1143     TInt err = KErrNone;
       
  1144     if ( !iBurstArray->IsDeleted( aGlobalIndex ) )
       
  1145         {
       
  1146         PRINT( _L("Camera <> iBurstArray->IsDeleted" ))
       
  1147         err = iBurstArray->SetDeleted( aGlobalIndex, ETrue );
       
  1148         PRINT1( _L("Camera <> CCamBurstThumbnailGridModel::DeleteItemL: First SetDelete returned %d"), err );
       
  1149         }
       
  1150     if ( err )
       
  1151         { 
       
  1152         err = iBurstArray->SetDeleted( aGlobalIndex, ETrue );
       
  1153         PRINT1( _L("Camera <> CCamBurstThumbnailGridModel::DeleteItemL: Second SetDelete returned %d"), err );
       
  1154         if ( err )
       
  1155             {
       
  1156             if ( err == KErrInUse )
       
  1157                 {
       
  1158                 // set error note text
       
  1159                 const TDesC& fullPath = iBurstArray->FileName( aGlobalIndex );
       
  1160                 TInt pos = fullPath.LocateReverse( '\\' );
       
  1161                 TPtrC fileName = fullPath.Right( fullPath.Length() - pos - 1 );
       
  1162                 HBufC* text = StringLoader::LoadLC( R_QTN_FLDR_CANT_DELETE_FILE_OPEN, fileName );
       
  1163                 // show error note
       
  1164                 CAknInformationNote* dlg = new (ELeave) CAknInformationNote(ETrue);
       
  1165                 dlg->ExecuteLD(text->Des());
       
  1166                 CleanupStack::PopAndDestroy( text );
       
  1167                 }
       
  1168             User::Leave( err );
       
  1169             //return;
       
  1170             }
       
  1171         }
       
  1172     if ( iAllThumbGrid[aGlobalIndex]->iMarked )
       
  1173         {            
       
  1174         iAllThumbGrid[aGlobalIndex]->iMarked = EFalse;
       
  1175         iImagesMarked--;    // No of marked items
       
  1176         }
       
  1177 
       
  1178     // Delete the display thumbnail
       
  1179     delete iAllThumbGrid[aGlobalIndex]->iDisplayThumb;
       
  1180     iAllThumbGrid[aGlobalIndex]->iDisplayThumb = NULL;                
       
  1181 
       
  1182     // Remove from VALID thumb list.            
       
  1183     CThumbnailGridItem* item = iAllThumbGrid[aGlobalIndex];
       
  1184     TInt index = iValidThumbGrid.Find( item );    
       
  1185 
       
  1186     if ( index != KErrNotFound )
       
  1187         {
       
  1188         iValidThumbGrid.Remove( index );
       
  1189         }
       
  1190     PRINT( _L("Camera <= CCamBurstThumbnailGridModel::DeleteItem") );
       
  1191     }
       
  1192 
       
  1193 // -----------------------------------------------------------------------------
       
  1194 // CCamBurstThumbnailGridModel::DoPostDeleteGridCheck
       
  1195 // Internal function called after an item has been deleted, to ensure the 
       
  1196 // correct items are visible, the highlight is valid etc.
       
  1197 // -----------------------------------------------------------------------------
       
  1198 //
       
  1199 void CCamBurstThumbnailGridModel::DoPostDeleteGridCheck( TBool /*aHighlightDeleted*/ )
       
  1200     {   
       
  1201     // Check the "highlighted" item.  If it's now out of range, move the 
       
  1202     // index to be the last valid entry.
       
  1203     if ( iCurrHighlight >= iValidThumbGrid.Count() )
       
  1204         { 
       
  1205         iCurrHighlight = iValidThumbGrid.Count() - 1;
       
  1206 
       
  1207         // Required to update the title pane with a new filename
       
  1208         NotifyModelObserver( EModelEventHighlight );
       
  1209         }
       
  1210 
       
  1211     // Else the highlight after a delete is still within range, so
       
  1212     // just inform the observers, so they can update the title pane with the
       
  1213     // correct filename
       
  1214     else 
       
  1215         {
       
  1216         NotifyModelObserver( EModelEventHighlight );
       
  1217         }
       
  1218 
       
  1219 
       
  1220     TInt imagesRemaining = iBurstArray->ImagesRemaining();
       
  1221     // Check whether the highlighted item is now visible... it may not be.
       
  1222     if ( iTopLeftIndex >= imagesRemaining ||
       
  1223          imagesRemaining <= KGridWidth * iGridHeight )
       
  1224         {
       
  1225         // If this has happened it's because the highlighted cell was one of 
       
  1226         // a large number of cells that has been deleted.  The "top left" 
       
  1227         // visible cell therefore needs to be updated to be the row above the 
       
  1228 
       
  1229         // If over a screens worth of items remaining, move "top left" to show 
       
  1230         // the bottom two rows
       
  1231         if ( imagesRemaining > ( KGridWidth * iGridHeight ) )
       
  1232             {
       
  1233             //            =     [ Total number of rows available   ] - [ two rows ]    * [Width]
       
  1234             iTopLeftIndex = ( ( ( iCurrHighlight + 1 ) / KGridWidth ) - iGridHeight ) * KGridWidth;            
       
  1235             }
       
  1236         else // Less than a screen's worth of items left, so set the first row as top left
       
  1237             {
       
  1238             iTopLeftIndex = 0;
       
  1239             }
       
  1240         }
       
  1241 
       
  1242     // Notify observers of a deletion.
       
  1243     NotifyModelObserver( EModelEventDeleted );
       
  1244         
       
  1245     // Check the thumbnails to see if any need remaking
       
  1246     RecalculateThumbs();
       
  1247     }
       
  1248 
       
  1249 // -----------------------------------------------------------------------------
       
  1250 // CCamBurstThumbnailGridModel::ScrollGrid( TBool aScrollDown )
       
  1251 // -----------------------------------------------------------------------------
       
  1252 //
       
  1253 void CCamBurstThumbnailGridModel::ScrollGrid( TBool aScrollDown, TInt aNewScrollPos )
       
  1254     {
       
  1255     
       
  1256     // scrollPosition tells where the scroll is (new starting row?)
       
  1257     
       
  1258     // calculate the new iTopLeftIndex
       
  1259     
       
  1260     iTopLeftIndex = aNewScrollPos * KGridWidth;
       
  1261     
       
  1262     PRINT1( _L("Camera <> CCamBurstThumbnailGridModel::ScrollGrid - new postition %d"), iTopLeftIndex );
       
  1263     
       
  1264     
       
  1265     }
       
  1266 
       
  1267 
       
  1268 
       
  1269 // -----------------------------------------------------------------------------
       
  1270 // CCamBurstThumbnailGridModel::GridHeight
       
  1271 // Returns the height of the visible grid, typically 2 or 3 cells high.
       
  1272 // -----------------------------------------------------------------------------
       
  1273 //
       
  1274 TInt CCamBurstThumbnailGridModel::GridHeight()
       
  1275     {
       
  1276     return iGridHeight;
       
  1277     }
       
  1278 // -----------------------------------------------------------------------------
       
  1279 // MThumbModelObserver::HighlightChanged
       
  1280 // Default implementation of the function
       
  1281 // -----------------------------------------------------------------------------
       
  1282 //
       
  1283 void MThumbModelObserver::HighlightChanged() 
       
  1284     {
       
  1285     // intentionally doing nothing
       
  1286     }
       
  1287 
       
  1288 // -----------------------------------------------------------------------------
       
  1289 // MThumbModelObserver::ImagesDeleted
       
  1290 // Default implementation of the function
       
  1291 // -----------------------------------------------------------------------------
       
  1292 //
       
  1293 void MThumbModelObserver::ImagesDeleted() 
       
  1294     {
       
  1295     // intentionally doing nothing
       
  1296     }
       
  1297 
       
  1298 // -----------------------------------------------------------------------------
       
  1299 // MThumbModelObserver::ThumbnailGenerated
       
  1300 // Default implementation of the function; does nothing.
       
  1301 // -----------------------------------------------------------------------------
       
  1302 //
       
  1303 void MThumbModelObserver::ThumbnailGenerated()
       
  1304     {
       
  1305     // intentionally doing nothing
       
  1306     }
       
  1307 
       
  1308 // -----------------------------------------------------------------------------
       
  1309 // CThumbnailGridItem::CThumbnailGridItem
       
  1310 // -----------------------------------------------------------------------------
       
  1311 //
       
  1312 CThumbnailGridItem::CThumbnailGridItem()
       
  1313     {
       
  1314     // intentionally doing nothing
       
  1315     }
       
  1316 
       
  1317 // -----------------------------------------------------------------------------
       
  1318 // CThumbnailGridItem::~CThumbnailGridItem
       
  1319 // -----------------------------------------------------------------------------
       
  1320 //
       
  1321 CThumbnailGridItem::~CThumbnailGridItem()
       
  1322     {   
       
  1323     delete iDisplayThumb;        
       
  1324     }
       
  1325 
       
  1326 
       
  1327 //  End of File