examples/sfexamples/Wikipedia/src/SearchContainer.cpp

00001 // 
00002 // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
00003 // All rights reserved.
00004 // This component and the accompanying materials are made available
00005 // under the terms of the License "Eclipse Public License v1.0"
00006 // which accompanies this distribution, and is available
00007 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
00008 // 
00009 // Initial Contributors:
00010 // Nokia Corporation - initial contribution.
00011 // 
00012 // Contributors:
00013 // 
00014 // Description:
00015 // 
00016 
00017 
00018 
00019 // INCLUDE FILES
00020 #include "SearchContainer.h"
00021 #include "SearchView.h"
00022 #include <aknlists.h>
00023 #include <aknsfld.h>
00024 #include <aknnavi.h>
00025 #include <aknnavide.h>
00026 #include <e32debug.h>
00027 #include "SqlSrvDemoAppUi.h"
00028 #include "WikiDb.h"
00029 #include "RecCountContainer.h"
00030 
00031 const TInt KMaxSearchLength = 255;
00032 const TInt KArraySize = 4;
00033 const TInt KFormatLen = 3;
00034 
00035 _LIT( KSplashText, "Start typing to search 2.2m Wikipedia articles" );
00036 _LIT( KZeroRecordsText, "" );
00037 _LIT( KNaviTextNull, "" );
00038 _LIT( KNaviTextMultiplePages, "Page %D ..." );
00039 _LIT( KNaviTextLastOfMultiplePages, "Page %D" );
00040 _LIT( KListItemFormat, "\t%S\t\t" );
00041 
00042 // ========================= MEMBER FUNCTIONS ==================================
00043 
00044 
00045 // -----------------------------------------------------------------------------
00046 // CSearchContainer::NewL()
00047 // Two-phased constructor.
00048 // -----------------------------------------------------------------------------
00049 //
00050 CSearchContainer* CSearchContainer::NewL( const TRect& aRect, CSearchView& aView, CRecCountContainer& aRecContainer )
00051     {
00052     CSearchContainer* self = CSearchContainer::NewLC( aRect, aView, aRecContainer );
00053     CleanupStack::Pop( self );
00054     return self;
00055     }
00056 
00057 // -----------------------------------------------------------------------------
00058 // CSearchContainer::NewLC()
00059 // Two-phased constructor.
00060 // -----------------------------------------------------------------------------
00061 //
00062 CSearchContainer* CSearchContainer::NewLC( const TRect& aRect, CSearchView& aView, CRecCountContainer& aRecContainer )
00063     {
00064     CSearchContainer* self = new ( ELeave ) CSearchContainer( aView, aRecContainer );
00065     CleanupStack::PushL( self );
00066     self->ConstructL( aRect );
00067     return self;
00068     }
00069 
00070 // -----------------------------------------------------------------------------
00071 // CSearchContainer::ConstructL()
00072 // Symbian 2nd phase constructor can leave.
00073 // -----------------------------------------------------------------------------
00074 //
00075 void CSearchContainer::ConstructL( const TRect& aRect )
00076     {
00077     iItemArray = new ( ELeave ) CDesCArrayFlat( KArraySize );  
00078     
00079     CreateWindowL();
00080 
00081     CreateListBoxL();
00082     CreateFindBoxL(); 
00083     RefreshL();
00084     
00085     SetRect( aRect );
00086     ActivateL();
00087     }
00088 
00089 CSearchContainer::~CSearchContainer()
00090         {
00091         delete iListBox;
00092         delete iFindBox;
00093     delete iNaviDecorator;      
00094         delete iItemArray;
00095         delete iSearchText;
00096         }
00097 
00098 CSearchContainer::CSearchContainer( CSearchView& aView, CRecCountContainer& aRecContainer ) :
00099         iView( aView ), iRecContainer( aRecContainer ), iWikiEngine( CSqlSrvDemoAppUi::WikiEngine() )
00100         {
00101         // No implementation required
00102         }
00103 
00104 // -----------------------------------------------------------------------------
00105 // CSearchContainer::CountComponentControls() const
00106 // returns number of controls inside this container.
00107 // -----------------------------------------------------------------------------
00108 //
00109 TInt CSearchContainer::CountComponentControls() const
00110     {
00111     TInt count = 0;
00112     if ( iListBox )
00113         {
00114         count++;
00115         }
00116     if ( iFindBox )
00117         {
00118         count++;
00119         }
00120     return count;
00121     }
00122 
00123 
00124 // -----------------------------------------------------------------------------
00125 // CSearchContainer::ComponentControl() const
00126 // returns pointer of controls inside this container
00127 // -----------------------------------------------------------------------------
00128 //
00129 CCoeControl* CSearchContainer::ComponentControl( TInt aIndex ) const
00130     {
00131     switch ( aIndex )
00132             {
00133             case 0:
00134                 return iListBox;
00135             case 1:
00136                 return iFindBox;
00137             default:
00138                 return NULL;
00139             }
00140     }
00141 
00142 // -----------------------------------------------------------------------------
00143 // CSearchContainer::SizeChanged
00144 // 
00145 // (other items were commented in a header).
00146 // -----------------------------------------------------------------------------
00147 //
00148 void CSearchContainer::SizeChanged()
00149     {
00150         // Set list box size.
00151         iListBox->SizeChanged();
00152 
00153     // Set find box size.
00154     AknFind::HandleFixedFindSizeChanged( this, iListBox, iFindBox );
00155     }
00156 
00157 // -----------------------------------------------------------------------------
00158 // CSearchContainer::HandleResourceChange
00159 // 
00160 // (other items were commented in a header).
00161 // -----------------------------------------------------------------------------
00162 //
00163 void CSearchContainer::HandleResourceChange(TInt aType)
00164     {
00165     CCoeControl::HandleResourceChange( aType );
00166     if ( aType == KEikDynamicLayoutVariantSwitch )
00167         {
00168         SetRect( iView.SearchRect() );
00169         }
00170     }  
00171 
00172 // -----------------------------------------------------------------------------
00173 // CSearchContainer::OfferKeyEventL
00174 // 
00175 // (other items were commented in a header).
00176 // -----------------------------------------------------------------------------
00177 //
00178 TKeyResponse CSearchContainer::OfferKeyEventL(
00179     const TKeyEvent& aKeyEvent, TEventCode aType )
00180     {
00181         TKeyResponse response = EKeyWasNotConsumed;
00182 
00183     switch  (aKeyEvent.iCode )
00184         {
00185         case EKeyUpArrow:
00186         case EKeyDownArrow:
00187             // Scrolling the list box. Forward to iListBox.
00188             response = iListBox->OfferKeyEventL( aKeyEvent, aType );
00189             break;
00190 
00191         case EKeyLeftArrow:
00192                 GotoPrevPageL();
00193             response = EKeyWasConsumed;         
00194                 break;
00195                 
00196         case EKeyRightArrow:
00197                 GotoNextPageL();
00198             response = EKeyWasConsumed;         
00199                 break;
00200                 
00201         case EKeyDevice3:
00202                 // Select key - handle it
00203                 HandleSelectCommandL();
00204             response = EKeyWasConsumed;
00205             break;
00206 
00207         default:
00208             // Forward key events to find box.
00209             response = iFindBox->OfferKeyEventL( aKeyEvent, aType );
00210             break;
00211         }
00212 
00213     return response;
00214     }
00215 
00216 // -----------------------------------------------------------------------------
00217 // CSearchContainer::HandleControlEventL
00218 // 
00219 // (other items were commented in a header).
00220 // -----------------------------------------------------------------------------
00221 //
00222 void CSearchContainer::HandleControlEventL( CCoeControl* aControl, TCoeEvent aEventType )
00223     {
00224         if ( aEventType == EEventStateChanged && aControl == iFindBox )
00225                 {
00226             HBufC* searchBuf = GetSearchTextLC();
00227         if ( *searchBuf != *iSearchText )
00228             {
00229             delete iSearchText;
00230             iSearchText = NULL;
00231             iSearchText = searchBuf->Des().AllocL();            
00232             UpdateListBoxL();
00233             }
00234         CleanupStack::PopAndDestroy( searchBuf );
00235                 }
00236     }
00237 
00238 void CSearchContainer::CountUpdatedL( TInt aError )
00239         {
00240         User::LeaveIfError( aError );
00241         SetRecCountAndDrawL( iWikiEngine.NumRecords() );
00242         }
00243 
00244 void CSearchContainer::RefreshL( TBool aResetNaviPane /* = EFalse */ )
00245         {
00246         if ( aResetNaviPane )
00247                 {
00248         SetNaviPaneTextL( KNaviTextNull, EFalse, EFalse );              
00249                 }
00250         else
00251                 {
00252             if ( !IsSearchTextPresent() )
00253                 {
00254                 iListBox->View()->SetListEmptyTextL( KSplashText );
00255                 SetNaviPaneTextL( KNaviTextNull, EFalse, EFalse );
00256                 SetRecCountAndDrawL( -1 );
00257                 }
00258             else
00259                 {
00260                 if ( iItemArray->MdcaCount() == 0 )
00261                         {
00262                     iListBox->View()->SetListEmptyTextL( KZeroRecordsText );
00263                         SetNaviPaneTextL( KNaviTextNull, EFalse, EFalse );      
00264                         }
00265                 else
00266                         {
00267                         HBufC* naviText = NULL;
00268                         TInt realCurPage = iWikiEngine.CurrentPage() + 1;
00269                         TInt realCurItem = iWikiEngine.CurrentItem() + 1;
00270                         TBool nextItemExists = iWikiEngine.DoesNextItemExist();
00271                         
00272                         if ( nextItemExists )
00273                                 {
00274                                 // This is one of multiple pages
00275                                 naviText = HBufC::NewLC( KNaviTextMultiplePages().Length() + KFormatLen );
00276                                 naviText->Des().Format( KNaviTextMultiplePages, realCurPage );
00277                                 }
00278                         else if ( realCurPage != 1 )
00279                                 {
00280                                 // This is the last of multiple pages
00281                                 naviText = HBufC::NewLC( KNaviTextLastOfMultiplePages().Length() + KFormatLen );
00282                                 naviText->Des().Format( KNaviTextLastOfMultiplePages, realCurPage );                            
00283                                 }
00284                         else
00285                                 {
00286                                 naviText = KNaviTextNull().AllocLC();   
00287                                 }
00288                         
00289                         SetNaviPaneTextL( *naviText, CanScrollPrev(), CanScrollNext() );
00290                         CleanupStack::PopAndDestroy( naviText );
00291                         }
00292                 }       
00293                 }
00294         }
00295 
00296 void CSearchContainer::CreateListBoxL()
00297         {       
00298     iListBox = new ( ELeave ) CAknSingleStyleListBox();
00299     iListBox->SetContainerWindowL( *this );
00300     iListBox->ConstructL( this );    
00301     iListBox->SetObserver( this );
00302     iListBox->Model()->SetItemTextArray( iItemArray );
00303     iListBox->Model()->SetOwnershipType( ELbmDoesNotOwnItemArray );
00304         }
00305 
00306 void CSearchContainer::CreateFindBoxL()
00307         {
00308     CAknSearchField::TSearchFieldStyle style( CAknSearchField::ESearch );
00309     CGulIcon* defaultIcon = NULL;
00310     iFindBox = CAknSearchField::NewL(
00311         *this, style, defaultIcon, KMaxSearchLength );
00312 
00313     iSearchText = HBufC::NewL( 0 );
00314     
00315     iFindBox->SetObserver( this );
00316         }
00317 
00318 // -----------------------------------------------------------------------------
00319 // CSearchContainer::SetNaviPaneTextL()
00320 // Changes text to navi pane
00321 // -----------------------------------------------------------------------------    
00322 void CSearchContainer::SetNaviPaneTextL( const TDesC& aText, TBool aShowLeft, TBool aShowRight )
00323     {
00324         // Create navipane pointer
00325         if ( !iNaviPane )
00326                 {
00327                 CEikStatusPane *sp = ( ( CAknAppUi* )iEikonEnv->EikAppUi() )->StatusPane();
00328                 
00329                 // Fetch pointer to the default navi pane control
00330                 iNaviPane = ( CAknNavigationControlContainer * )sp->ControlL( TUid::Uid( EEikStatusPaneUidNavi ) );
00331                 }
00332     
00333     if ( iNaviDecorator )
00334         {
00335         delete iNaviDecorator;
00336         iNaviDecorator = NULL;        
00337         }
00338         
00339     iNaviDecorator = iNaviPane->CreateNavigationLabelL( aText );
00340     iNaviDecorator->MakeScrollButtonVisible( ETrue );
00341     iNaviDecorator->SetScrollButtonDimmed( CAknNavigationDecorator::ELeftButton, !aShowLeft );
00342     iNaviDecorator->SetScrollButtonDimmed( CAknNavigationDecorator::ERightButton, !aShowRight );
00343 
00344     iNaviPane->PushL( *iNaviDecorator );
00345     }
00346 
00347 // -----------------------------------------------------------------------------
00348 // CSearchContainer::UpdateListBoxL
00349 // 
00350 // (other items were commented in a header).
00351 // -----------------------------------------------------------------------------
00352 //
00353 void CSearchContainer::UpdateListBoxL()
00354     {
00355         SetRecCountAndDrawL( -1 );
00356         iWikiEngine.SearchL( *iSearchText, this );
00357     PopulateItemArrayL();
00358     }
00359 
00360 void CSearchContainer::PopulateItemArrayL()
00361         {
00362         CDesCArray* items = new ( ELeave ) CDesCArrayFlat( KArraySize );
00363         TInt count = 0;
00364         if ( IsSearchTextPresent() )
00365                 {
00366                 while ( count < KItemsPerPage && iWikiEngine.Next() )
00367                         {       
00368                         // Append the title of the next item
00369                         TPtrC colText;
00370                         User::LeaveIfError( iWikiEngine.GetTitle( colText ) );
00371                         AppendItemToListL( *items, colText );
00372                         
00373                         // Increment counter
00374                         count++;
00375                         }
00376                 }
00377         
00378         // Replace the item array
00379         delete iItemArray;
00380         iItemArray = items;     
00381         
00382     iListBox->Model()->SetItemTextArray( iItemArray );
00383     iListBox->Model()->SetOwnershipType( ELbmDoesNotOwnItemArray );
00384     iListBox->SetCurrentItemIndex( 0 );
00385     iListBox->HandleItemAdditionL();
00386     
00387     RefreshL();
00388         }
00389 
00390 void CSearchContainer::HandleSelectCommandL()
00391         {
00392         // Get the index of the currently selected item
00393         TInt itemIndex = iListBox->CurrentItemIndex();
00394         
00395         if ( itemIndex != KErrNotFound ) // If there is no item selected then ignore
00396                 {
00397                 // Get the text of the current item
00398                 TPtrC itemText = iItemArray->MdcaPoint( itemIndex );
00399                 
00400                 // De-format the list item text to get the title alone
00401                 TPtrC itemTitle = DeFormatListItem( itemText );
00402                 
00403                 // Set the title of the current article
00404                 iWikiEngine.SetCurrentArticleL( itemTitle );
00405                 // Reset the navi pane
00406             RefreshL( ETrue );
00407             //  Activate the detail view
00408                 iView.OpenDetailViewL();
00409                 }
00410         }
00411 
00412 TBool CSearchContainer::CanScrollPrev()
00413         {
00414         return iWikiEngine.CurrentPage() > 0;
00415         }
00416 
00417 TBool CSearchContainer::CanScrollNext()
00418         {
00419         return ( IsSearchTextPresent() && iWikiEngine.DoesNextItemExist() );
00420         }
00421 
00422 void CSearchContainer::GotoPrevPageL()
00423         {
00424         if ( CanScrollPrev() )
00425                 {
00426                 iWikiEngine.PageUpL( *iSearchText );
00427             PopulateItemArrayL();
00428                 }
00429         }
00430 
00431 void CSearchContainer::GotoNextPageL()
00432         {
00433         if ( CanScrollNext() )
00434                 {
00435             PopulateItemArrayL();
00436                 }
00437         }
00438 
00439 HBufC* CSearchContainer::GetSearchTextLC()
00440         {
00441     TInt searchTextLength = iFindBox->TextLength();
00442     HBufC* searchBuf = HBufC::NewLC( searchTextLength );
00443     TPtr searchPtr = searchBuf->Des();
00444     iFindBox->GetSearchText( searchPtr );
00445     return searchBuf;
00446         }
00447 
00448 void CSearchContainer::AppendItemToListL( CDesCArray& aList, const TDesC& aItem )
00449         {
00450         HBufC* itemText = FormatListItemLC( aItem );
00451         aList.AppendL( *itemText );
00452         CleanupStack::PopAndDestroy( itemText );        
00453         }
00454 
00455 HBufC* CSearchContainer::FormatListItemLC( const TDesC& aItem )
00456         {
00457     HBufC* formattedItem = HBufC::NewLC( aItem.Length() + KFormatLen );
00458     formattedItem->Des().Format( KListItemFormat, &aItem );     
00459     return formattedItem;
00460         }
00461 
00462 TPtrC CSearchContainer::DeFormatListItem( const TDesC& aFormattedItem )
00463         {
00464         TPtrC rightPortion = aFormattedItem.Right( aFormattedItem.Length() - 1 );
00465         return rightPortion.Left( rightPortion.Length() - 2 );  
00466         }
00467 
00468 void CSearchContainer::SetRecCountAndDrawL( const TInt aRecCount )
00469         {
00470         iRecContainer.SetTextL( aRecCount );
00471         iRecContainer.DrawNow();
00472         }
00473 
00474 // End of File

Generated by  doxygen 1.6.2