idlehomescreen/xmluicontroller/src/contentrenderer.cpp
changeset 0 f72a12da539e
child 4 4d54b72983ae
equal deleted inserted replaced
-1:000000000000 0:f72a12da539e
       
     1 /*
       
     2 * Copyright (c) 2005-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:  Content renderer implementation
       
    15 *
       
    16 */
       
    17 
       
    18 // System includes
       
    19 #include    <e32hashtab.h>
       
    20 #include    <utf.h>
       
    21 #include    <gulicon.h>
       
    22 
       
    23 // User includes
       
    24 
       
    25 #include    "contentrenderer.h"
       
    26 #include    "appui.h"
       
    27 #include    "activetransactionstack.h"
       
    28 #include    "transactionfactoryimpl.h"
       
    29 #include    "mtransaction.h"
       
    30 #include    "mtransactionelement.h"
       
    31 #include    "aixmluiutils.h"
       
    32 #include    "xmluicontroller.h"
       
    33 #include    "xmlnodeidgenerator.h"
       
    34 #include    "aixmluiconstants.h"
       
    35 #include    "aifweventhandler.h"
       
    36 #include    "databuffertransactionelement.h"
       
    37 #include    "newstickercallbackhandler.h"
       
    38 #include    "newstickertransactionelement.h"
       
    39 #include    "csspropertymap.h"
       
    40 #include    "policyevaluator.h"
       
    41 #include    "debug.h"
       
    42 #include    "xnuiengineappif.h"
       
    43 #include    "xnnodeappif.h"
       
    44 #include    "xnproperty.h"
       
    45 #include    "mxncomponentinterface.h"
       
    46 #include    "xntext.h"
       
    47 #include    "xnbitmap.h"
       
    48 #include    "xntype.h"
       
    49 #include    "xnmenuadapter.h"
       
    50 #include    "xnlistquerydialogadapter.h"
       
    51 #include    "mxncomponentinterface.h"
       
    52 #include    "aistrcnv.h"
       
    53 #include    "contentprioritymap.h"
       
    54 #include    "ainativeuiplugins.h"
       
    55 
       
    56 using namespace AiXmlUiController;
       
    57 using namespace AiUiDef::xml;
       
    58 using namespace XnTextInterface;
       
    59 using namespace XnImageInterface;
       
    60 
       
    61 namespace
       
    62     {
       
    63     typedef RPointerArray<CXnNodeAppIf> RXnNodeArray;
       
    64 
       
    65     /**
       
    66      * Gets content item iterator.
       
    67      *
       
    68      * @param aPlugin plugin to fetch the iterator
       
    69      * @param aContentType type of iterator (content/resource/event)
       
    70      * @return the iterator
       
    71      * @leave KErrNotSupported if plugin does not provide iterator
       
    72      */ 
       
    73     static MAiContentItemIterator& ContentItemIteratorL( MAiPropertyExtension& aPlugin,
       
    74                                                          TInt aContentType )
       
    75         {
       
    76         MAiContentItemIterator* iter =
       
    77             static_cast< MAiContentItemIterator* >( aPlugin.GetPropertyL( aContentType ) );
       
    78 
       
    79         if ( !iter )
       
    80             {
       
    81             User::Leave( KErrNotSupported );
       
    82             }
       
    83 
       
    84         return *iter;
       
    85         }
       
    86 
       
    87     /**
       
    88      * Gets the content priority associated in the property element.
       
    89      *
       
    90      * @param aPropertyElement the property element
       
    91      * @return priority value or KErrNotFound for non-prioritized element
       
    92      */
       
    93     TInt GetContentPriority( CXnNodeAppIf& aPropertyElement )
       
    94         {
       
    95         TInt32 priority( KErrNotFound );
       
    96         
       
    97         const TDesC8* name = PropertyValue( aPropertyElement,
       
    98                                             property::KName );
       
    99                                             
       
   100         
       
   101         if ( name && *name == name::KPriority )
       
   102             {
       
   103             const TDesC8* value = PropertyValue( aPropertyElement,
       
   104                                                  property::KValue );
       
   105             if ( value )
       
   106                 {
       
   107                 AiUtility::ParseInt( priority, *value );
       
   108                 }
       
   109             }
       
   110             
       
   111         return priority;
       
   112         }
       
   113     
       
   114     /**
       
   115      * Remove elements from array which do not contain priority or priority is not lower than
       
   116      * the given value.
       
   117      * 
       
   118      * @param aElements array of elements
       
   119      * @param aLastPriority upper bound of priority value (excluded from the array)
       
   120      */
       
   121     void RemoveNonPriorityElements( RPointerArray< CXnNodeAppIf>& aElements,
       
   122                                     TInt aLastPriority )
       
   123         {
       
   124         //  Remove non priority elements and higher priority elements
       
   125 
       
   126         TInt elementCount = aElements.Count();    
       
   127         for ( TInt i = 0; i < elementCount; )
       
   128             {
       
   129             CXnNodeAppIf* current = aElements[i];
       
   130             
       
   131             // Check name attribute
       
   132             const TDesC8* name = PropertyValue( *current, property::KName );
       
   133             
       
   134             if ( !name || *name != name::KPriority )
       
   135                 {
       
   136                 // Remove current
       
   137                 aElements.Remove( i );
       
   138                 --elementCount;
       
   139                 }
       
   140             else
       
   141                 {
       
   142                 // Check current priority
       
   143                 const TDesC8* value = PropertyValue( *current, property::KValue );
       
   144                 
       
   145                 if ( !value ) // value not present
       
   146                     {
       
   147                     aElements.Remove( i );
       
   148                     --elementCount;
       
   149                     continue;
       
   150                     }
       
   151                 
       
   152                 TInt32 currentPriority( KErrNotFound );
       
   153                 if ( AiUtility::ParseInt( currentPriority, *value ) != KErrNone )
       
   154                     {
       
   155                     // value is not integer
       
   156                     aElements.Remove( i );
       
   157                     --elementCount;
       
   158                     continue;
       
   159                     }
       
   160                     
       
   161                 if ( currentPriority < aLastPriority )
       
   162                     {
       
   163                     // Keep element and iterate further
       
   164                     ++i;
       
   165                     }
       
   166                 else
       
   167                     {
       
   168                     // priority is too high
       
   169                     aElements.Remove( i );
       
   170                     --elementCount;
       
   171                     }
       
   172                 }
       
   173             }
       
   174         }
       
   175     
       
   176     /**
       
   177      * Descending priority order for prioritized content selectors.
       
   178      *
       
   179      * @param aNode1 First node to compare
       
   180      * @param aNode2 Second node to compare
       
   181      * @return 0 nodes have equal priority
       
   182      * @return >0 aNode1 has lower priority
       
   183      * @return <0 aNode2 has lower priority
       
   184      */
       
   185     TInt DescendingPriorityOrder( const CXnNodeAppIf& aNode1,
       
   186                                   const CXnNodeAppIf& aNode2 )
       
   187         {
       
   188         // Array content has been validated, so no checks are needed
       
   189         const TDesC8* value1 = PropertyValue( aNode1,
       
   190                                               property::KValue );
       
   191         
       
   192         const TDesC8* value2 = PropertyValue( aNode2,
       
   193                                               property::KValue );
       
   194         
       
   195         TInt32 priority1( KErrNotFound );
       
   196         AiUtility::ParseInt( priority1, *value1 );
       
   197         
       
   198         TInt32 priority2( KErrNotFound );
       
   199         AiUtility::ParseInt( priority2, *value2 );
       
   200         
       
   201         if ( priority1 == priority2 )
       
   202             {
       
   203             return 0;
       
   204             }
       
   205             
       
   206         return ( priority1 < priority2 ) ? 1 : -1;
       
   207         }
       
   208     
       
   209     /**
       
   210      * Removes duplicate entries in content change array
       
   211      */
       
   212     void RemoveDuplicateContentChangesL( RAiPolicyElementArray& aArray )
       
   213         {
       
   214         for ( TInt i = 0; i < aArray.Count(); ++i )
       
   215             {
       
   216             HBufC* id = PropertyValueL( aArray[i].Target(), 
       
   217                                             AiUiDef::xml::property::KId );
       
   218             if ( id )
       
   219                 {
       
   220                 CleanupStack::PushL( id );
       
   221                 for ( TInt j = i; j < aArray.Count(); ++j )
       
   222                     {
       
   223                     HBufC* id2 = PropertyValueL( aArray[j].Target(), 
       
   224                                                            AiUiDef::xml::property::KId );
       
   225                     if ( id2)
       
   226                         {
       
   227                         CleanupStack::PushL( id2 );
       
   228                         // Same id and same policy
       
   229                         if ( i != j &&
       
   230                              id->Compare( *id2 ) == 0 && 
       
   231                              ( aArray[i].Policy().Compare( aArray[j].Policy()) == 0) 
       
   232                                 )
       
   233                             {
       
   234                             aArray.Remove( j );
       
   235                             --j;
       
   236                             }
       
   237                         }
       
   238                     CleanupStack::PopAndDestroy( id2 );
       
   239                     
       
   240                     }
       
   241                 CleanupStack::PopAndDestroy( id );
       
   242                 }
       
   243             }
       
   244         }
       
   245     /**
       
   246      * Cleanup item for cleanup of TPtrHashMapIter
       
   247      */            
       
   248     class TMapCleanupItem
       
   249         {
       
   250     public:
       
   251         
       
   252         TMapCleanupItem( TPtrHashMapIter< TDesC, TInt >& aIterator );
       
   253         
       
   254         /**
       
   255          * Removes the pointers in the map and deletes the objects
       
   256          * referenced by the pointers.
       
   257          */ 
       
   258         void Release();
       
   259                 
       
   260     private:
       
   261             
       
   262         TPtrHashMapIter< TDesC, TInt > iIterator;
       
   263         
       
   264         };
       
   265 
       
   266     /**
       
   267      * Helper to handle cleanup of map iterator
       
   268      * @param aMapCleanupItem 
       
   269      */
       
   270     void CleanupRelease( TAny* aMapCleanupItem )
       
   271         {
       
   272         if ( aMapCleanupItem )
       
   273             {
       
   274             static_cast< TMapCleanupItem* >( aMapCleanupItem )->Release();
       
   275             }
       
   276         }
       
   277 
       
   278     /**
       
   279      * Helper to push map iterator into cleanup stack.
       
   280      *
       
   281      * @param aCleanupItem item to push into cleanup stack
       
   282      **/
       
   283     void CleanupReleasePushL( TMapCleanupItem& aCleanupItem )
       
   284         {
       
   285         CleanupStack::PushL( TCleanupItem( CleanupRelease,
       
   286                                            &aCleanupItem ) );
       
   287         }
       
   288 
       
   289     
       
   290     }
       
   291 
       
   292 TMapCleanupItem::TMapCleanupItem( TPtrHashMapIter< TDesC, TInt >& aIterator )
       
   293     : iIterator( aIterator )
       
   294     {
       
   295     }
       
   296 
       
   297 void TMapCleanupItem::Release()
       
   298     {
       
   299     // Delete current key and value
       
   300     const TDesC* key = iIterator.CurrentKey();
       
   301     const TInt* value = iIterator.CurrentValue();
       
   302     
       
   303     delete key;
       
   304     delete value;
       
   305     
       
   306     // Remove mapping from the map.
       
   307     iIterator.RemoveCurrent();
       
   308     }
       
   309 
       
   310 
       
   311 
       
   312 // ============================ MEMBER FUNCTIONS ===============================
       
   313 
       
   314 CContentRenderer::CContentRenderer( CAppUi& aAppUi )
       
   315     : iAppUi( aAppUi )
       
   316     {
       
   317     }
       
   318 
       
   319 void CContentRenderer::ConstructL()
       
   320     {
       
   321     iContentPriorityMap = AiUtility::CContentPriorityMap::NewL();
       
   322     iPropertyMap = CCssPropertyMap::NewL();
       
   323     iFactory = CTransactionFactoryImpl::NewL(*iContentPriorityMap,
       
   324                                              *iPropertyMap);
       
   325     iStack = CActiveTransactionStack::NewL();
       
   326     iNodeIdGenerator = CXmlNodeIdGenerator::NewL();
       
   327     iTimer = CPeriodic::NewL( CActive::EPriorityStandard );
       
   328     iPolicyEvaluator = CPolicyEvaluator::NewL();
       
   329     }
       
   330 
       
   331 CContentRenderer* CContentRenderer::NewL( CAppUi& aAppUi )
       
   332     {
       
   333     CContentRenderer* self = new( ELeave ) CContentRenderer( aAppUi );
       
   334 
       
   335     CleanupStack::PushL( self );
       
   336     self->ConstructL();
       
   337     CleanupStack::Pop();
       
   338 
       
   339     return self;
       
   340     }
       
   341 
       
   342 CContentRenderer::~CContentRenderer()
       
   343     {
       
   344     delete iPolicyEvaluator;
       
   345     
       
   346     if ( iTimer )
       
   347         {
       
   348         iTimer->Cancel();
       
   349         delete iTimer;
       
   350         }
       
   351         
       
   352     delete iNodeIdGenerator;
       
   353     
       
   354     if ( iStack )
       
   355         {
       
   356         while ( !iStack->IsEmpty() )
       
   357             {
       
   358             MTransaction* tr = iStack->Pop();
       
   359             iFactory->ReleaseTransaction( tr );
       
   360             }
       
   361 
       
   362         delete iStack;
       
   363         }
       
   364     
       
   365     delete iFactory;
       
   366     
       
   367     iRefreshableUiElements.ResetAndDestroy();
       
   368     
       
   369     delete iNTClass;
       
   370     
       
   371     delete iPropertyMap;
       
   372     
       
   373     delete iContentPriorityMap;
       
   374     delete iCallbackHandler;
       
   375     }
       
   376 
       
   377 void CContentRenderer::SetEventHandler( MAiFwEventHandler& aFwEventHandler )
       
   378     {
       
   379     iFwEventHandler = &aFwEventHandler;
       
   380     }
       
   381 
       
   382 void CContentRenderer::Reset()
       
   383     {
       
   384     iContentPriorityMap->Reset();
       
   385     iPropertyMap->Reset();
       
   386     }
       
   387 
       
   388 void CContentRenderer::CleanPluginFromUi( MAiPropertyExtension& aPlugin )
       
   389     {
       
   390     // Create transaction to clean UI
       
   391     TInt txId = reinterpret_cast< TInt >( &aPlugin );
       
   392     
       
   393     TBool txCreated = ( StartTransaction( txId ) == KErrNone );
       
   394     
       
   395     // Clean plugin
       
   396     TRAPD( cleanError, CleanPluginFromUiL( aPlugin ) );
       
   397     
       
   398     // Commit transaction
       
   399     if ( txCreated )
       
   400         {
       
   401         if (cleanError )
       
   402             {
       
   403             CancelTransaction( txId );
       
   404             }
       
   405         else
       
   406             {
       
   407             Commit( txId );
       
   408             }
       
   409         }
       
   410     }
       
   411 
       
   412 TInt CContentRenderer::StartTransaction( TInt aTxId )
       
   413     {
       
   414     __PRINT(__DBG_FORMAT("\t[I]\tXML UI: Start transaction id=%d"), aTxId);
       
   415     __HEAP("XML UI: Start transaction");
       
   416     __TICK("XML UI: Start transaction");
       
   417     TRAPD( error, DoStartTransactionL( aTxId ) );
       
   418 
       
   419     if ( error )
       
   420         {
       
   421         SetImmediateMode( ETrue );
       
   422         }
       
   423 
       
   424     return error;
       
   425     }
       
   426 
       
   427 TInt CContentRenderer::Commit( TInt aTxId )
       
   428     {
       
   429     // Remove transaction with aTxId from stack
       
   430     MTransaction* tr = iStack->Remove( aTxId );
       
   431 
       
   432     if ( tr )
       
   433         {
       
   434         // Commit transaction        
       
   435         RPropertyHashMap propertyHashMap;
       
   436         
       
   437         TBool layoutChanged( EFalse );
       
   438         
       
   439         TRAPD( error, tr->CommitL( layoutChanged, propertyHashMap ) );
       
   440         if( error == KErrNone )
       
   441             {
       
   442             TRAP_IGNORE( SetPropertyArraysL( propertyHashMap ) );
       
   443             }
       
   444         propertyHashMap.Close();
       
   445 
       
   446         __TICK("XML UI: Commit transaction");
       
   447         __HEAP("XML UI: Commit transaction");
       
   448         __PRINT(__DBG_FORMAT("\t[I]\tXML UI: Commit transaction id=%d"), aTxId);
       
   449        
       
   450         StartContentRefresh();
       
   451         
       
   452         TRAP_IGNORE
       
   453             (
       
   454             iAppUi.UiEngineL()->RenderUIL();                                  //jtm+++
       
   455             ProcessContentChangesL( *tr );
       
   456             );
       
   457                 
       
   458         
       
   459         iFactory->ReleaseTransaction( tr );  
       
   460         
       
   461         return error;
       
   462         }
       
   463         
       
   464     return KErrNotSupported;
       
   465     }
       
   466 
       
   467 void CContentRenderer::ProcessContentChangesL( MTransaction& aTr )
       
   468     {
       
   469     TDblQueIter<CTransactionElement> iter = aTr.ElementIter();
       
   470     RAiPolicyElementArray contentChangedArray;
       
   471     CleanupClosePushL( contentChangedArray );
       
   472 
       
   473     while ( iter )
       
   474           {
       
   475           CTransactionElement* element = iter++;
       
   476           CXnNodeAppIf& target = element->Target();
       
   477           
       
   478           // Find own and parents policy/ContentChanged nodes 
       
   479           iPolicyEvaluator->EvaluateContentChangedPolicyL( target, 
       
   480                   contentChangedArray);
       
   481 
       
   482           iPolicyEvaluator->EvaluateContentChangedPolicyL( *(target.ParentL()), 
       
   483                   contentChangedArray);
       
   484           }
       
   485        
       
   486     ::RemoveDuplicateContentChangesL( contentChangedArray );
       
   487         
       
   488     for ( TInt i = 0; i < contentChangedArray.Count(); ++i )
       
   489         {
       
   490         ProcessContentChangeL( contentChangedArray[i] );
       
   491         }
       
   492     CleanupStack::PopAndDestroy();
       
   493     }
       
   494 
       
   495 void CContentRenderer::ProcessContentChangeL( TAiPolicyElement& aElement )
       
   496     {
       
   497     const TDesC8* id = PropertyValue( aElement.Target(), 
       
   498                                 AiUiDef::xml::property::KId );
       
   499     if ( id )
       
   500         {
       
   501         CXnNodeAppIf* targetNode = FindNodeByIdL( *id, aElement.Target().Namespace() );
       
   502         if ( targetNode )
       
   503             {                     
       
   504             if ( aElement.Policy() == AiUiDef::xml::value::KShowTooltips )
       
   505                 {
       
   506                 targetNode->ShowTooltipsL();
       
   507                 }                   
       
   508             }        
       
   509         }
       
   510     }
       
   511 
       
   512 TInt CContentRenderer::CancelTransaction( TInt aTxId )
       
   513     {
       
   514     // Remove transaction with aTxId from stack
       
   515     MTransaction* tr = iStack->Remove( aTxId );
       
   516 
       
   517     if ( tr )
       
   518         {
       
   519         // Release transaction to factory
       
   520         __TICK("XML UI: Cancel transaction");
       
   521         __HEAP("XML UI: Cancel transaction");
       
   522         __PRINT(__DBG_FORMAT("\t[I]\tXML UI: Cancel transaction id=%d"), aTxId);
       
   523 
       
   524         iFactory->ReleaseTransaction( tr );
       
   525 
       
   526         return KErrNone;
       
   527         }
       
   528 
       
   529     return KErrNotSupported;
       
   530     }
       
   531 
       
   532 TBool CContentRenderer::CanPublish( MAiPropertyExtension& aPlugin,
       
   533                                     TInt aContent,
       
   534                                     TInt aIndex )
       
   535     {
       
   536     TInt error( KErrNone );
       
   537     TInt retval( KErrNone );
       
   538     __PRINTS("*** UC: Init - Content Validation ***");
       
   539 	__TIME("UC: Content Validation",
       
   540         TRAP( error, retval = CanPublishL( aPlugin, aContent, aIndex ) );
       
   541         );
       
   542     __HEAP("UC: Content Validation");
       
   543     __PRINTS("*** UC: Done - Content Validation ***");
       
   544 
       
   545     return ( error == KErrNone && retval == KErrNone );
       
   546     }
       
   547 
       
   548 TInt CContentRenderer::Publish( MAiPropertyExtension& aPlugin,
       
   549                                 TInt aContent,
       
   550                                 TInt aResource,
       
   551                                 TInt aIndex )
       
   552     {
       
   553 	TInt error( KErrNone );
       
   554 	TInt retval( KErrNone );
       
   555 	__PRINTS("*** UC: Init - Content Publishing (Resource) ***");
       
   556 	__TIME("UC: Content Publishing (Resource)",
       
   557     	TRAP( error, retval = DoPublishL( aPlugin, aContent, aResource, aIndex ) );
       
   558     );
       
   559     __HEAP("UC: Content Publishing (Resource)");
       
   560     __PRINTS("*** UC: Done - Content Publishing (Resource) ***");
       
   561 
       
   562     if( !error && retval )
       
   563         {
       
   564         error = retval;
       
   565         }
       
   566     
       
   567     return error;
       
   568     }
       
   569 
       
   570 TInt CContentRenderer::Publish( MAiPropertyExtension& aPlugin,
       
   571                                 TInt aContent,
       
   572                                 const TDesC16& aText,
       
   573                                 TInt aIndex )
       
   574     {
       
   575     TInt error( KErrNone );
       
   576     TInt retval( KErrNone );
       
   577     
       
   578     __PRINTS("*** UC: Init - Content Publishing (Value-Text) ***");
       
   579    	__TIME("UC: Content Publishing (Value-Text)",
       
   580     	TRAP( error, retval = DoPublishL( aPlugin, aContent, aText, aIndex ) );
       
   581     );
       
   582     __HEAP("UC: Content Publishing (Value-Text)");
       
   583     __PRINTS("*** UC: Done - Content Publishing (Value-Text) ***");
       
   584 
       
   585     if( !error && retval )
       
   586         {
       
   587         error = retval;
       
   588         }
       
   589 
       
   590     return error;
       
   591     }
       
   592 
       
   593 TInt CContentRenderer::Publish( MAiPropertyExtension& aPlugin,
       
   594                                 TInt aContent,
       
   595                                 const TDesC8& aBuf,
       
   596                                 TInt aIndex )
       
   597     {
       
   598     TInt error( KErrNone );
       
   599     TInt retval( KErrNone );
       
   600     
       
   601     __PRINTS("*** UC: Init - Content Publishing (Value-Buf) ***");
       
   602     __TIME("UC: Content Publishing (Value-Buf)",
       
   603     	TRAP( error, retval = DoPublishL( aPlugin, aContent, aBuf, aIndex ) );
       
   604     )
       
   605     __HEAP("UC: Content Publishing (Value-Buf)");
       
   606     __PRINTS("*** UC: Done - Content Publishing (Value-Buf) ***");
       
   607 
       
   608     if( !error && retval )
       
   609         {
       
   610         error = retval;
       
   611         }
       
   612     
       
   613     return error;
       
   614     }
       
   615 
       
   616 TInt CContentRenderer::Publish( MAiPropertyExtension& aPlugin,
       
   617                                 TInt aContent,
       
   618                                 RFile& aFile,
       
   619                                 TInt aIndex )
       
   620     {
       
   621     TInt error( KErrNone );
       
   622     TInt retval( KErrNone );
       
   623     	
       
   624 	__PRINTS("*** UC: Init - Content Publishing (Value-RFile) ***");
       
   625     __TIME("UC: Content Publishing (Value-RFile)",
       
   626     	TRAP( error, retval = DoPublishL( aPlugin, aContent, aFile, aIndex ) );
       
   627     );
       
   628     __HEAP("UC: Content Publishing (Value-RFile)");
       
   629     __PRINTS("*** UC: Done - Content Publishing (Value-RFile) ***");
       
   630 
       
   631     if( !error && retval )
       
   632         {
       
   633         error = retval;
       
   634         }
       
   635     
       
   636     return error;
       
   637     }
       
   638 
       
   639 TInt CContentRenderer::Clean( MAiPropertyExtension& aPlugin, TInt aContent, TInt aIndex )
       
   640     {
       
   641     TInt error( KErrNone );
       
   642     TInt retval( KErrNone );
       
   643             
       
   644     __PRINTS("*** UC: Init - Content Publishing (Clean) ***");
       
   645     __TIME("UC: Content Publishing (Clean)",
       
   646     	TRAP( error, retval = DoCleanL( aPlugin, aContent, aIndex ) );
       
   647     );
       
   648     __HEAP("UC: Content Publishing (Clean)");
       
   649     __PRINTS("*** UC: Done - Content Publishing (Clean) ***");
       
   650 
       
   651     if( !error && retval )
       
   652         {
       
   653         error = retval;
       
   654         }
       
   655     
       
   656     return error;
       
   657     }
       
   658 
       
   659 TAny* CContentRenderer::Extension( TUid /*aUid*/ )
       
   660     {
       
   661     // No extensions supported
       
   662     return NULL;
       
   663     }
       
   664 
       
   665 TBool CContentRenderer::RequiresSubscription( 
       
   666     const TAiPublisherInfo& aPublisherInfo ) const
       
   667     {
       
   668     if ( aPublisherInfo.iNamespace == KNativeUiNamespace )
       
   669         {
       
   670         // Not targeted to this content renderer
       
   671         return EFalse;
       
   672         }
       
   673         
       
   674     return ETrue;
       
   675     }
       
   676 
       
   677 void CContentRenderer::DoStartTransactionL( TInt aTxId )
       
   678     {
       
   679     MTransaction* tr = iFactory->CreateTransactionL( aTxId );
       
   680     iStack->Push(tr);
       
   681     SetImmediateMode(EFalse);
       
   682     }
       
   683 
       
   684 TInt CContentRenderer::CanPublishL( MAiPropertyExtension& aPlugin,
       
   685                                     TInt aContent,
       
   686                                     TInt aIndex )
       
   687     {
       
   688     // Get content item for aContent
       
   689     MAiContentItemIterator& iter( 
       
   690             ContentItemIteratorL( aPlugin, EAiPublisherContent ) );
       
   691     
       
   692     const TAiContentItem& item( iter.ItemL( aContent ) );
       
   693 
       
   694     // Lookup ui element
       
   695     const TDesC& nodeId( iNodeIdGenerator->ContentNodeIdL( aPlugin, item ) );
       
   696 
       
   697     CXnNodeAppIf* property( FindNodeByClassL( nodeId, aIndex, 
       
   698                             aPlugin.PublisherInfoL()->iNamespace ) ); 
       
   699  
       
   700     if( !property )
       
   701         {
       
   702         return KErrNotFound;
       
   703         }
       
   704     
       
   705     // Check content priority
       
   706     TInt priority( GetContentPriority( *property ) );
       
   707 
       
   708     CXnNodeAppIf* target( property->ParentL() );
       
   709     
       
   710     if( !target )
       
   711         {
       
   712         return KErrNotSupported;
       
   713         }
       
   714 
       
   715     if ( !AllowPublishByPriority( *target, priority ) )
       
   716         {
       
   717         return KErrAccessDenied;        
       
   718         }
       
   719 
       
   720     // Check if content type is supported by target
       
   721     const TDesC8& contentType( ContentType( item ) );
       
   722 
       
   723     if ( !iFactory->IsSupported( *target, contentType ) &&
       
   724           target->Type()->Type() != XnPropertyNames::listquerydialog::KListQueryDialog )
       
   725         {
       
   726         return KErrNotSupported;
       
   727         }
       
   728     
       
   729     return KErrNone;
       
   730     }
       
   731 
       
   732 TInt CContentRenderer::DoPublishL( MAiPropertyExtension& aPlugin,
       
   733                                    TInt aContent,
       
   734                                    TInt aResource,
       
   735                                    TInt aIndex )
       
   736     {
       
   737     TAiPublisherInfo *info = static_cast<TAiPublisherInfo*>(aPlugin.GetPropertyL( EAiPublisherInfo ));
       
   738     if (!info)
       
   739         {
       
   740         return KErrNotFound;
       
   741         }
       
   742     // Read ref value.
       
   743     MAiContentItemIterator& refIter( ContentItemIteratorL( aPlugin, EAiPublisherResources ) );
       
   744     const TAiContentItem& ref( refIter.ItemL( aResource ) );
       
   745 
       
   746     const TDesC8& refType( ContentType( ref ) );
       
   747 
       
   748     // Resolve source node
       
   749     const TDesC& nodeId = iNodeIdGenerator->ResourceNodeIdL(aPlugin, ref);
       
   750     HBufC8* nodeId8 = CnvUtfConverter::ConvertFromUnicodeToUtf8L(nodeId);
       
   751     CleanupStack::PushL(nodeId8);
       
   752     CXnNodeAppIf* source = NULL;
       
   753     __TIME_MARK(xmlOverhead);
       
   754     source = FindNodeByIdL( *nodeId8, info->iNamespace );
       
   755     __TIME_ENDMARK("XML UI: Lookup node by id", xmlOverhead);
       
   756     __PRINT(__DBG_FORMAT("\t[I]\tXML UI: Lookup node by id=%S"), &nodeId);
       
   757     
       
   758     CleanupStack::PopAndDestroy(nodeId8);
       
   759     
       
   760     // Fetch content id
       
   761     MAiContentItemIterator& iter = ContentItemIteratorL( aPlugin, EAiPublisherContent );
       
   762     const TAiContentItem& item = iter.ItemL( aContent );
       
   763 
       
   764     const TDesC& targetId = iNodeIdGenerator->ContentNodeIdL(aPlugin, item);
       
   765 
       
   766     TInt retval( KErrNotSupported );
       
   767 
       
   768     // Check types
       
   769     if ( refType == KContentTypeText )
       
   770         {
       
   771         // Fetch text
       
   772         const TDesC8& text = source->GetPCData();
       
   773         
       
   774         // Delegate to data publishing function
       
   775         retval = PublishDataL( aPlugin,
       
   776                                targetId,
       
   777                                text,
       
   778                                refType,
       
   779                                aIndex,
       
   780                                source );
       
   781         }
       
   782     else if ( refType.Find( KContentTypeImage ) != KErrNotFound )
       
   783         {
       
   784         // Fetch icon
       
   785         CGulIcon* icon = LoadIconLC( *source ); 
       
   786         
       
   787        // Delegate to icon publishing function
       
   788         retval = PublishIconL( aPlugin,
       
   789                                targetId,
       
   790                                icon,
       
   791                                aIndex,
       
   792                                source );
       
   793         
       
   794         CleanupStack::Pop( icon );
       
   795         }
       
   796     
       
   797     return retval;
       
   798     }
       
   799 
       
   800 TInt CContentRenderer::DoPublishL( MAiPropertyExtension& aPlugin,
       
   801                                    TInt aContent,
       
   802                                    const TDesC16& aText,
       
   803                                    TInt aIndex )
       
   804     {
       
   805     // Resolve content item
       
   806     MAiContentItemIterator& iter( 
       
   807             ContentItemIteratorL( aPlugin, EAiPublisherContent ) );
       
   808     
       
   809     const TAiContentItem& item( iter.ItemL( aContent ) );
       
   810 
       
   811     const TDesC8& type( ContentType( item ) );
       
   812 
       
   813     if ( type == KContentTypeText )
       
   814         {
       
   815         // Find ui element
       
   816         const TDesC& nodeId = iNodeIdGenerator->ContentNodeIdL( aPlugin, item );
       
   817 
       
   818         __TIME_MARK(xmlOverhead);
       
   819 
       
   820         CXnNodeAppIf* property( FindNodeByClassL( nodeId, aIndex, 
       
   821                                                   aPlugin.PublisherInfoL()->iNamespace ) );
       
   822 
       
   823         if( !property )
       
   824             {
       
   825             return KErrNotFound;
       
   826             }
       
   827         
       
   828         TInt priority( GetContentPriority( *property ) );
       
   829         
       
   830         __TIME_ENDMARK("XML UI: Lookup node by class", xmlOverhead);
       
   831     	__PRINT(__DBG_FORMAT("\t[I]\tXML UI: Lookup node by class=%S"), &nodeId);
       
   832 
       
   833         //Navigate to parent
       
   834         CXnNodeAppIf* target( property->ParentL() );
       
   835 
       
   836         if( !target )
       
   837             {
       
   838             return KErrNotSupported;
       
   839             }
       
   840         
       
   841         // Check priority
       
   842         if ( AllowPublishByPriority( *target, priority ) )
       
   843             {
       
   844             // Check if target is newsticker
       
   845             MTransactionElement* element( NULL );
       
   846             
       
   847             if ( IsParentNewsticker( *target ) )
       
   848                 {
       
   849                 // Register callback interface for newsticker
       
   850                 CXnNodeAppIf *parent( target->ParentL() );
       
   851                 
       
   852                 if( !parent )
       
   853                     {
       
   854                     return KErrNotFound;
       
   855                     }
       
   856                                 
       
   857                 RegisterNewstickerCallbackInterfaceL( *parent );
       
   858                 
       
   859                 const TAiPublisherInfo* info( aPlugin.PublisherInfoL() );
       
   860                 
       
   861                 if ( info )
       
   862                     {
       
   863                     iNTPublisher.Set( info->iName );
       
   864                     iNTClass = AiUtility::CopyToBufferL( iNTClass, nodeId );
       
   865                     }
       
   866                 
       
   867                 element = iFactory->CreateNewsTickerTransactionElementL( *target,
       
   868                                                                     aText,
       
   869                                                                     priority, 
       
   870                                                                     aIndex );
       
   871                 }
       
   872             else if( target->Type()->Type() == 
       
   873                      XnListQueryDialogInterface::MXnListQueryDialogInterface::Type())
       
   874                 {
       
   875                 // Get the data interface for dialog and publish data
       
   876                 XnListQueryDialogInterface::MXnListQueryDialogInterface* listQuery( NULL );
       
   877                 XnComponentInterface::MakeInterfaceL( listQuery, *target );
       
   878                 LeaveIfNull( listQuery, KErrNotSupported );
       
   879                 listQuery->ReplaceItemL( aText, aIndex -1 );// plugins publish ordinals not indexes
       
   880                 return KErrNone;
       
   881                 }
       
   882             else
       
   883                 {
       
   884                 // Create transaction element for text
       
   885                 // Not put to cleanupstack, because element is from our pool!
       
   886                 element = iFactory->CreateTextTransactionElementL( *target,
       
   887                                                                     aText,
       
   888                                                                     priority );
       
   889                 }
       
   890             
       
   891             iPolicyEvaluator->EvaluateContentPolicyL( *target,
       
   892                                                       element->PolicyArray() );
       
   893             iPolicyEvaluator->EvaluateVisibilityPolicyL( *target,
       
   894                                                          element->PolicyArray() );
       
   895 
       
   896             ProcessTransactionElementL( element );
       
   897             }
       
   898         else
       
   899             {
       
   900             return KErrAccessDenied;            
       
   901             }
       
   902         }
       
   903     else
       
   904         {
       
   905         return KErrNotSupported;
       
   906         }
       
   907     
       
   908     return KErrNone;
       
   909     }
       
   910 
       
   911 TInt CContentRenderer::DoPublishL( MAiPropertyExtension& aPlugin,
       
   912                                    TInt aContent,
       
   913                                    const TDesC8& aBuf,
       
   914                                    TInt aIndex )
       
   915     {
       
   916     // resolve content item
       
   917     MAiContentItemIterator& iter( 
       
   918             ContentItemIteratorL( aPlugin, EAiPublisherContent ) );
       
   919     
       
   920     const TAiContentItem& item( iter.ItemL( aContent ) );
       
   921 
       
   922     const TDesC8& type( ContentType( item ) );
       
   923 
       
   924     TInt retval( KErrNotSupported );
       
   925     
       
   926     if( type == KContentTypeBitmap )
       
   927         {
       
   928         // Unpack icon from pointer
       
   929         CGulIcon* icon( LeaveIfNull( UnpackPtr<CGulIcon>( aBuf ), KErrArgument ) );
       
   930 
       
   931         const TDesC& nodeId( iNodeIdGenerator->ContentNodeIdL( aPlugin, item ) );
       
   932         
       
   933         // Publish icon
       
   934         retval = PublishIconL( aPlugin, nodeId, icon, aIndex );
       
   935         }
       
   936     else if ( type == KContentTypeImageSvg )
       
   937         {
       
   938         // Get node id
       
   939         const TDesC& nodeId( iNodeIdGenerator->ContentNodeIdL( aPlugin, item ) );
       
   940         
       
   941         // Publish SVG data
       
   942         retval = PublishDataL( aPlugin, nodeId, aBuf, KContentTypeImageSvg, aIndex );
       
   943         }
       
   944 
       
   945     return retval;
       
   946     }
       
   947 
       
   948 TInt CContentRenderer::DoPublishL( MAiPropertyExtension& aPlugin,
       
   949                                    TInt aContent,
       
   950                                    RFile& aFile,
       
   951                                    TInt aIndex)
       
   952     {
       
   953     //Resolve content item
       
   954     MAiContentItemIterator& iter( 
       
   955             ContentItemIteratorL( aPlugin, EAiPublisherContent ) );
       
   956     
       
   957     const TAiContentItem& item( iter.ItemL( aContent ) );
       
   958 
       
   959     const TDesC8& type( ContentType( item ) );
       
   960 
       
   961     // Image support
       
   962     if ( type.Find( KContentTypeImage ) != KErrNotFound )
       
   963         {
       
   964         // Find ui element
       
   965         const TDesC& nodeId( iNodeIdGenerator->ContentNodeIdL( aPlugin, item ) );
       
   966 
       
   967         CXnNodeAppIf* property( FindNodeByClassL( nodeId, aIndex, 
       
   968                                 aPlugin.PublisherInfoL()->iNamespace ) );
       
   969         
       
   970         if( !property )
       
   971             {
       
   972             return KErrNotFound;
       
   973             }
       
   974         
       
   975         // Check priority
       
   976         TInt priority( GetContentPriority( *property ) );
       
   977         
       
   978         CXnNodeAppIf* target( property->ParentL() );
       
   979         
       
   980         if( !target )
       
   981             {
       
   982             return KErrNotSupported;
       
   983             }
       
   984 
       
   985         if ( AllowPublishByPriority( *target, priority ) )
       
   986             {
       
   987             // Check if target is newsticker
       
   988             if ( IsParentNewsticker( *target ) )
       
   989                 {
       
   990                 // Register callback interface
       
   991                 CXnNodeAppIf *parent( target->ParentL() );
       
   992                 
       
   993                 if( !parent )
       
   994                     {
       
   995                     return KErrNotFound;
       
   996                     }
       
   997                                 
       
   998                 RegisterNewstickerCallbackInterfaceL( *parent );
       
   999                 
       
  1000                 const TAiPublisherInfo* info( aPlugin.PublisherInfoL() );
       
  1001                 
       
  1002                 if( info )
       
  1003                     {
       
  1004                     iNTPublisher.Set( info->iName );
       
  1005                     iNTClass = AiUtility::CopyToBufferL( iNTClass, nodeId );
       
  1006                     }
       
  1007                 }
       
  1008             
       
  1009             // Create transaction element for file
       
  1010             MTransactionElement* element =
       
  1011                 iFactory->CreateImageTransactionElementL( *target,
       
  1012                                                           aFile,
       
  1013                                                           priority );
       
  1014             
       
  1015             iPolicyEvaluator->EvaluateContentPolicyL( *target,
       
  1016                                                       element->PolicyArray() );
       
  1017             iPolicyEvaluator->EvaluateVisibilityPolicyL( *target,
       
  1018                                                          element->PolicyArray() );
       
  1019             
       
  1020             ProcessTransactionElementL( element );
       
  1021             }
       
  1022         else
       
  1023             {
       
  1024             return KErrAccessDenied;
       
  1025             }
       
  1026         }
       
  1027     else 
       
  1028         {
       
  1029         return KErrNotSupported;        
       
  1030         }
       
  1031     
       
  1032     return KErrNone;
       
  1033     }
       
  1034 
       
  1035 TInt CContentRenderer::DoCleanL( MAiPropertyExtension& aPlugin,
       
  1036                                  TInt aContent,
       
  1037                                  TInt aIndex )
       
  1038     {
       
  1039     // Resolve content item
       
  1040     MAiContentItemIterator& iter( 
       
  1041             ContentItemIteratorL( aPlugin, EAiPublisherContent ) );
       
  1042     
       
  1043     const TAiContentItem& item( iter.ItemL( aContent ) );
       
  1044 
       
  1045     const TDesC& nodeId( iNodeIdGenerator->ContentNodeIdL( aPlugin, item ) );
       
  1046 
       
  1047     CXnNodeAppIf* property( FindNodeByClassL( nodeId, aIndex, 
       
  1048                             aPlugin.PublisherInfoL()->iNamespace ) );
       
  1049 
       
  1050     if( !property )
       
  1051         {
       
  1052         return KErrNotFound;
       
  1053         }
       
  1054     
       
  1055     TInt priority( GetContentPriority( *property ) );
       
  1056 
       
  1057     // Navigate to parent
       
  1058     CXnNodeAppIf* target( property->ParentL() );
       
  1059 
       
  1060     if( !target )
       
  1061         {
       
  1062         return KErrNotSupported;
       
  1063         }
       
  1064     
       
  1065     if ( !AllowPublishByPriority( *target, priority ) )
       
  1066         {
       
  1067         return KErrAccessDenied;
       
  1068         }
       
  1069 
       
  1070     if ( IsParentNewsticker( *target ) )
       
  1071         {
       
  1072         CXnNodeAppIf *parent( target->ParentL() );
       
  1073         
       
  1074         if( !parent )
       
  1075             {
       
  1076             return KErrNotFound;
       
  1077             }
       
  1078                
       
  1079         RegisterNewstickerCallbackInterfaceL( *parent );
       
  1080         
       
  1081         const TAiPublisherInfo* info( aPlugin.PublisherInfoL() );
       
  1082         
       
  1083         if( info )
       
  1084             {
       
  1085             iNTPublisher.Set( info->iName );
       
  1086             iNTClass = AiUtility::CopyToBufferL( iNTClass, nodeId );
       
  1087             }
       
  1088         }
       
  1089     if( target->Type()->Type() ==
       
  1090         XnListQueryDialogInterface::MXnListQueryDialogInterface::Type())
       
  1091         {
       
  1092         // Get the data interface for dialog and delete data
       
  1093         XnListQueryDialogInterface::MXnListQueryDialogInterface* listQuery( NULL );
       
  1094         XnComponentInterface::MakeInterfaceL( listQuery, *target );
       
  1095         LeaveIfNull( listQuery, KErrNotSupported );
       
  1096         listQuery->DeleteItem( aIndex -1 );// plugins publish ordinals not indexes
       
  1097         return KErrNone;
       
  1098         }
       
  1099     
       
  1100     // Create transaction element for empty content
       
  1101     MTransactionElement* element =
       
  1102         iFactory->CreateEmptyContentTransactionElementL( *target, aIndex );
       
  1103 
       
  1104     iPolicyEvaluator->EvaluateEmptyContentPolicyL( *target,
       
  1105                                                    element->PolicyArray() );
       
  1106     iPolicyEvaluator->EvaluateVisibilityPolicyL( *target,
       
  1107                                                    element->PolicyArray() );
       
  1108 
       
  1109     ProcessTransactionElementL( element );
       
  1110       
       
  1111     if ( priority > KErrNotFound ) // Only for prioritized elements
       
  1112         {
       
  1113         // Add current ui element into content refresh map
       
  1114         HBufC* uiElementId = PropertyValueL( *target,
       
  1115                                          XnPropertyNames::common::KId );
       
  1116         return RefreshContentL( uiElementId, priority );
       
  1117         }
       
  1118     
       
  1119     return KErrNone;
       
  1120     }
       
  1121 
       
  1122 void CContentRenderer::SetImmediateMode( TBool aImmediateMode )
       
  1123     {
       
  1124     iImmediateMode = aImmediateMode;
       
  1125     }
       
  1126 
       
  1127 TBool CContentRenderer::IsImmediateMode() const
       
  1128     {
       
  1129     return iImmediateMode;
       
  1130     }
       
  1131 
       
  1132 void CContentRenderer::ProcessTransactionElementL( MTransactionElement* aElement )
       
  1133     {
       
  1134     LeaveIfNull( aElement, KErrArgument );
       
  1135     
       
  1136     if ( IsImmediateMode() || iStack->IsEmpty() )
       
  1137         {
       
  1138         // No transaction. Commit element immediately
       
  1139         TBool layoutChanged = EFalse;
       
  1140         
       
  1141         RPropertyHashMap propertyHashMap;
       
  1142         aElement->CommitL(layoutChanged, propertyHashMap);
       
  1143         SetPropertyArraysL( propertyHashMap );
       
  1144         propertyHashMap.Close();
       
  1145         
       
  1146         iFactory->ReleaseTransactionElement( aElement );
       
  1147         StartContentRefresh();
       
  1148         
       
  1149         // Re-layout
       
  1150         iAppUi.UiEngineL()->RenderUIL();
       
  1151         }
       
  1152     else
       
  1153         {
       
  1154         // Append transaction element to transaction
       
  1155         MTransaction* tr = iStack->Top();
       
  1156         tr->Append( *aElement );
       
  1157         }
       
  1158     }
       
  1159 
       
  1160 CXnNodeAppIf* CContentRenderer::FindNodeByClassL( const TDesC& aCid,
       
  1161                                                   TInt aIndex,
       
  1162                                                   const TDesC8& aNs )
       
  1163     {
       
  1164     // Find node
       
  1165     HBufC8* classId = CnvUtfConverter::ConvertFromUnicodeToUtf8L(aCid);
       
  1166     CleanupStack::PushL(classId);
       
  1167     
       
  1168     RPointerArray<CXnNodeAppIf> nodes = iAppUi.UiEngineL()->FindNodeByClassL( *classId, aNs );
       
  1169 
       
  1170     CleanupStack::PopAndDestroy(classId);
       
  1171 
       
  1172     CleanupClosePushL( nodes );
       
  1173 
       
  1174     for ( TInt i = 0; i < nodes.Count(); ++i )
       
  1175         {
       
  1176         CXnNodeAppIf* node = nodes[i];
       
  1177 
       
  1178         const TDesC8* name =
       
  1179             PropertyValue( *node, AiUiDef::xml::property::KName );
       
  1180 
       
  1181         if ( name && ( *name == AiUiDef::xml::name::KOrdinal ) )
       
  1182             {
       
  1183             const TDesC8* value =
       
  1184                 PropertyValue( *node, AiUiDef::xml::property::KValue );
       
  1185 
       
  1186             if ( value )
       
  1187                 {
       
  1188                 // Try to parse index from string either
       
  1189 
       
  1190                 TInt32 index( 0 );
       
  1191                 User::LeaveIfError( AiUtility::ParseInt( index, *value ) );
       
  1192 
       
  1193                 if ( index == aIndex )
       
  1194                     {
       
  1195                     CleanupStack::PopAndDestroy(&nodes);
       
  1196                     return node;
       
  1197                     }
       
  1198                 }
       
  1199             }
       
  1200         else if ( name && ( *name == AiUiDef::xml::name::KTarget ) )
       
  1201             {            
       
  1202             const TDesC8* target =
       
  1203                            PropertyValue( *node, AiUiDef::xml::property::KValue );
       
  1204             
       
  1205             CXnNodeAppIf* targetNode = FindNodeByIdL( *target, node->Namespace() );
       
  1206             if ( targetNode )
       
  1207                 {
       
  1208                 CleanupStack::PopAndDestroy( &nodes );
       
  1209                 return targetNode;
       
  1210                 }
       
  1211             }
       
  1212         else if ( nodes.Count() == 1 ) // Only one node in class
       
  1213             {
       
  1214             // No ordinal specified
       
  1215 			node = nodes[ 0 ];
       
  1216 			CleanupStack::PopAndDestroy(&nodes);
       
  1217             return node;
       
  1218             }
       
  1219         }
       
  1220     
       
  1221     CleanupStack::PopAndDestroy( &nodes );
       
  1222     
       
  1223     return NULL; // Never reached. Needed to omit compiler warning
       
  1224     }
       
  1225 
       
  1226 CXnNodeAppIf* CContentRenderer::FindNodeByIdL( const TDesC& aCid, const TDesC& aNs )
       
  1227     {
       
  1228     // Find node
       
  1229     return LeaveIfNull( iAppUi.UiEngineL()->FindNodeByIdL( aCid, aNs ),
       
  1230                         KErrNotFound );
       
  1231     }
       
  1232 
       
  1233 CXnNodeAppIf* CContentRenderer::FindNodeByIdL( const TDesC8& aCid, const TDesC8& aNs )
       
  1234     {
       
  1235     // Find node
       
  1236     return LeaveIfNull( iAppUi.UiEngineL()->FindNodeByIdL( aCid, aNs ),
       
  1237                         KErrNotFound );
       
  1238     }
       
  1239 
       
  1240 TInt CContentRenderer::PublishIconL( MAiPropertyExtension& aPlugin,
       
  1241                                      const TDesC& aCid,
       
  1242                                      CGulIcon* aIcon,
       
  1243                                      TInt aIndex,
       
  1244                                      CXnNodeAppIf* aResource )
       
  1245     {
       
  1246     // Find proiperty element by class
       
  1247     CXnNodeAppIf* property( FindNodeByClassL( aCid, aIndex, 
       
  1248                             aPlugin.PublisherInfoL()->iNamespace ) );
       
  1249     
       
  1250     if( !property )
       
  1251         {
       
  1252         return KErrNotFound;
       
  1253         }
       
  1254     
       
  1255     // Get priority information
       
  1256     TInt priority( GetContentPriority( *property ) );
       
  1257     
       
  1258     // Navigate to parent
       
  1259     CXnNodeAppIf* target( property->ParentL() );
       
  1260     
       
  1261     if( !target )
       
  1262         {
       
  1263         return KErrNotFound;
       
  1264         }
       
  1265 
       
  1266     // Check priority
       
  1267     if ( !AllowPublishByPriority( *target, priority ) )
       
  1268         {
       
  1269         return KErrAccessDenied;        
       
  1270         }
       
  1271     
       
  1272     // Special handling of newsticker
       
  1273     if ( IsParentNewsticker( *target ) )
       
  1274         {
       
  1275         // Register callback interface
       
  1276         CXnNodeAppIf *parent( target->ParentL() );
       
  1277         
       
  1278         if( !parent )
       
  1279             {
       
  1280             return KErrNotFound;
       
  1281             }
       
  1282                 
       
  1283         RegisterNewstickerCallbackInterfaceL( *parent );
       
  1284         
       
  1285         const TAiPublisherInfo* info( aPlugin.PublisherInfoL() );
       
  1286         
       
  1287         if( info )
       
  1288             {
       
  1289             iNTPublisher.Set( info->iName );
       
  1290             iNTClass = AiUtility::CopyToBufferL( iNTClass, aCid );
       
  1291             }
       
  1292         }
       
  1293 
       
  1294     MTransactionElement* element =
       
  1295         iFactory->CreateImageTransactionElementL( *target,
       
  1296                                                   aIcon,
       
  1297                                                   priority );
       
  1298 
       
  1299     if ( aResource )
       
  1300         {
       
  1301         iPolicyEvaluator->EvaluateResourcePolicyL( *target,
       
  1302                                                    *aResource,
       
  1303                                                    element->PolicyArray() );
       
  1304         iPolicyEvaluator->EvaluateContentPolicyL( *target,
       
  1305                                                   element->PolicyArray() );
       
  1306         iPolicyEvaluator->EvaluateVisibilityPolicyL( *target,
       
  1307                                                      element->PolicyArray() );
       
  1308         }
       
  1309 
       
  1310     else
       
  1311         {
       
  1312         iPolicyEvaluator->EvaluateContentPolicyL( *target,
       
  1313                                                   element->PolicyArray() );
       
  1314         iPolicyEvaluator->EvaluateVisibilityPolicyL( *target,
       
  1315                                                      element->PolicyArray() );
       
  1316         }
       
  1317 
       
  1318     ProcessTransactionElementL( element );
       
  1319     
       
  1320     return KErrNone;
       
  1321     }
       
  1322 
       
  1323 TInt CContentRenderer::PublishDataL( MAiPropertyExtension& aPlugin,
       
  1324                                      const TDesC& aCid,
       
  1325                                      const TDesC8& aData,
       
  1326                                      const TDesC8& aContentType,
       
  1327                                      TInt aIndex,
       
  1328                                      CXnNodeAppIf* aResource )
       
  1329     {
       
  1330     CXnNodeAppIf* property( FindNodeByClassL( aCid, aIndex, 
       
  1331                             aPlugin.PublisherInfoL()->iNamespace ) );
       
  1332 
       
  1333     if( !property )
       
  1334         {
       
  1335         return KErrNotFound;
       
  1336         }
       
  1337     
       
  1338     TInt priority( GetContentPriority( *property ) );
       
  1339     
       
  1340     // Navigate to parent
       
  1341     CXnNodeAppIf* target( property->ParentL() );
       
  1342     
       
  1343     if( !target )
       
  1344         {
       
  1345         return KErrNotFound;
       
  1346         }
       
  1347 
       
  1348     if ( !AllowPublishByPriority( *target, priority ) )
       
  1349         {
       
  1350         return KErrAccessDenied;        
       
  1351         }
       
  1352 
       
  1353     if ( !CDataBufferTransactionElement::IsSupported( *target, aContentType ) )
       
  1354         {
       
  1355         return KErrNotSupported;        
       
  1356         }
       
  1357         
       
  1358     // Handle newsticker 
       
  1359     if ( IsParentNewsticker( *target ) )
       
  1360         {
       
  1361         CXnNodeAppIf *parent( target->ParentL() );
       
  1362         
       
  1363         if( !parent )
       
  1364             {
       
  1365             return KErrNotFound;
       
  1366             }
       
  1367                 
       
  1368         RegisterNewstickerCallbackInterfaceL( *parent );
       
  1369         
       
  1370         const TAiPublisherInfo* info( aPlugin.PublisherInfoL() );
       
  1371         
       
  1372         if( info )
       
  1373             {
       
  1374             iNTPublisher.Set( info->iName );
       
  1375             iNTClass = AiUtility::CopyToBufferL( iNTClass, aCid );
       
  1376             }
       
  1377         }
       
  1378         
       
  1379     MTransactionElement* element =
       
  1380         iFactory->CreateDataBufferTransactionElementL( *target,
       
  1381                                                        aData,
       
  1382                                                        priority );
       
  1383     
       
  1384     if ( aResource )
       
  1385         {
       
  1386         iPolicyEvaluator->EvaluateResourcePolicyL( *target,
       
  1387                                                    *aResource,
       
  1388                                                    element->PolicyArray() );
       
  1389         iPolicyEvaluator->EvaluateContentPolicyL( *target,
       
  1390                                                   element->PolicyArray() );
       
  1391         iPolicyEvaluator->EvaluateVisibilityPolicyL( *target,
       
  1392                                                      element->PolicyArray() );
       
  1393         }
       
  1394     else
       
  1395         {
       
  1396         iPolicyEvaluator->EvaluateContentPolicyL( *target,
       
  1397                                                   element->PolicyArray() );
       
  1398         iPolicyEvaluator->EvaluateVisibilityPolicyL( *target,
       
  1399                                                      element->PolicyArray() );
       
  1400         }
       
  1401 
       
  1402     ProcessTransactionElementL( element );
       
  1403     
       
  1404     return KErrNone;
       
  1405     }
       
  1406 
       
  1407 TBool CContentRenderer::AllowPublishByPriority( CXnNodeAppIf& aUiElement,
       
  1408                                                 TInt aPriority ) const
       
  1409     {
       
  1410     // Get ui element id
       
  1411     const TDesC8* uiElementId = PropertyValue( aUiElement,
       
  1412                                                XnPropertyNames::common::KId );
       
  1413                                          
       
  1414     if ( uiElementId )
       
  1415         {
       
  1416         // compare given priority with the current value of ui element
       
  1417         return iContentPriorityMap->OverrideContent( *uiElementId, aPriority );
       
  1418         }
       
  1419     
       
  1420     return EFalse; // priority cannot be used, because ui element does not have id
       
  1421     }
       
  1422 
       
  1423 void CContentRenderer::StartContentRefresh()
       
  1424     {
       
  1425     // Cancel ongoing refresh
       
  1426     iTimer->Cancel();
       
  1427     
       
  1428     if ( iRefreshableUiElements.Count() > 0 )
       
  1429         {
       
  1430         // Refreshable elements exist. Start timer to make refresh asynchronous 
       
  1431         iTimer->Start( TTimeIntervalMicroSeconds32( 0 ),
       
  1432                        TTimeIntervalMicroSeconds32( 0 ),
       
  1433                        TCallBack( RefreshContentCallback, this ) );
       
  1434         }
       
  1435     }
       
  1436 
       
  1437 /**
       
  1438  * Adds ui element to list of refreshable elements
       
  1439  *
       
  1440  * @param aUiElementId ui element id
       
  1441  * @param aOldPriority old priority value
       
  1442  */                         
       
  1443 TInt CContentRenderer::RefreshContentL( HBufC* aUiElementId,
       
  1444                                         TInt aOldPriority )
       
  1445     {
       
  1446     if( !aUiElementId )
       
  1447         {
       
  1448         return KErrArgument;
       
  1449         }
       
  1450         
       
  1451     // Take ownership of aUiElementId
       
  1452     CleanupStack::PushL( aUiElementId );
       
  1453     
       
  1454     if ( !iFwEventHandler )
       
  1455         {
       
  1456         // Content refresh event cannot be sent
       
  1457         CleanupStack::PopAndDestroy( aUiElementId );
       
  1458         return KErrNotReady;
       
  1459         }
       
  1460     
       
  1461     // Find current mapping
       
  1462     TInt* oldPriority = iRefreshableUiElements.Find( *aUiElementId );
       
  1463     
       
  1464     if ( oldPriority )
       
  1465         {
       
  1466         // Update mapping
       
  1467         *oldPriority = aOldPriority;
       
  1468         CleanupStack::PopAndDestroy( aUiElementId );
       
  1469         }
       
  1470     else
       
  1471         {
       
  1472         // Create new mapping
       
  1473         oldPriority = new( ELeave ) TInt( aOldPriority );
       
  1474         CleanupStack::PushL( oldPriority );
       
  1475     
       
  1476         User::LeaveIfError( iRefreshableUiElements.Insert( aUiElementId,
       
  1477                                                            oldPriority ) );
       
  1478                                                        
       
  1479         CleanupStack::Pop( 2, aUiElementId );
       
  1480         }
       
  1481     
       
  1482     return KErrNone;
       
  1483     }
       
  1484 
       
  1485 /**
       
  1486  * Callback function to make content refreshing asynchronous
       
  1487  */    
       
  1488 TInt CContentRenderer::RefreshContentCallback( TAny* aContentRenderer )
       
  1489     {
       
  1490     if ( !aContentRenderer )
       
  1491         {
       
  1492         return KErrArgument;
       
  1493         }
       
  1494         
       
  1495     CContentRenderer* renderer = static_cast< CContentRenderer* >( aContentRenderer );
       
  1496     TRAP_IGNORE( renderer->SendRefreshContentEventL() );
       
  1497     return KErrNone;
       
  1498     }
       
  1499 
       
  1500 /**
       
  1501  * Sends Refresh content event to framework.
       
  1502  * Event is sent for content selectors with lower priority than the
       
  1503  * last content which has been cleaned from ui element.
       
  1504  */ 
       
  1505 void CContentRenderer::SendRefreshContentEventL()
       
  1506     {
       
  1507     // Cancel periodic timer.
       
  1508     iTimer->Cancel();
       
  1509     
       
  1510     // Get ui element id and old content priority
       
  1511     TPtrHashMapIter< TDesC, TInt> iter( iRefreshableUiElements );
       
  1512     iter.Reset();
       
  1513     
       
  1514     const TDesC* uiElementId = iter.NextKey(); // Never NULL
       
  1515     TInt priority = *( iter.CurrentValue() );
       
  1516     
       
  1517     //  Cleanup item for iterator 
       
  1518     TMapCleanupItem cleanup( iter );
       
  1519     CleanupReleasePushL( cleanup );
       
  1520     
       
  1521     // Lookup ui element
       
  1522     CXnNodeAppIf* uiElement = FindNodeByIdL( *uiElementId );
       
  1523     
       
  1524     // Remove current ui element from the map
       
  1525     CleanupStack::PopAndDestroy( &cleanup );
       
  1526     
       
  1527     // Find lower priority content elements associated to this ui element
       
  1528     RPointerArray< CXnNodeAppIf > children = uiElement->ChildrenL();
       
  1529     
       
  1530     // Remove higher priority content elements
       
  1531     RemoveNonPriorityElements( children, priority );
       
  1532         
       
  1533     // Sort array to descending order
       
  1534     children.Sort( TLinearOrder< CXnNodeAppIf >( DescendingPriorityOrder ) );
       
  1535     
       
  1536     // Send event for content selectors in descending priority order.
       
  1537     // Continue until first content gets published or array exhausts.
       
  1538     for ( TInt i = 0; i < children.Count(); ++i )
       
  1539         {
       
  1540         CXnNodeAppIf* current = children[ i ];
       
  1541         
       
  1542         // Get content selector
       
  1543         const HBufC* contentSelector = PropertyValueL( *current,
       
  1544                                                        XnPropertyNames::common::KClass );
       
  1545         
       
  1546         if ( contentSelector && iFwEventHandler->RefreshContent( *contentSelector ))
       
  1547             {
       
  1548             break;
       
  1549             }
       
  1550         }
       
  1551     
       
  1552     // Free content selector array
       
  1553     children.Reset();
       
  1554     
       
  1555     // Continue content refresh for next ui element.
       
  1556     StartContentRefresh();    
       
  1557     }
       
  1558 
       
  1559 void CContentRenderer::TitleScrolled( TInt aTitleIndex )
       
  1560     {
       
  1561     if ( iCallbackHandler )
       
  1562         {
       
  1563         TRAP_IGNORE( iCallbackHandler->TitleScrolledL( iNTPublisher,
       
  1564                                                        *iNTClass,
       
  1565                                                        aTitleIndex ) );
       
  1566         }
       
  1567     }
       
  1568     
       
  1569 void CContentRenderer::TitleToScroll( TInt aTitleIndex )
       
  1570     {
       
  1571     if ( iCallbackHandler )
       
  1572         {
       
  1573         TRAP_IGNORE( iCallbackHandler->TitleToScrollL( iNTPublisher,
       
  1574                                                        *iNTClass,
       
  1575                                                        aTitleIndex ) );        
       
  1576         }
       
  1577     }
       
  1578 
       
  1579 TBool CContentRenderer::IsParentNewsticker( CXnNodeAppIf& aTarget )
       
  1580     {
       
  1581     CXnNodeAppIf* parent = NULL;
       
  1582     TRAP_IGNORE( parent = aTarget.ParentL() );
       
  1583     if ( !parent )
       
  1584         {
       
  1585         return EFalse;
       
  1586         }
       
  1587     CXnType* typeInfo = parent->Type();
       
  1588     
       
  1589     if ( !typeInfo )
       
  1590         {
       
  1591         return EFalse;
       
  1592         }
       
  1593         
       
  1594     return ( typeInfo->Type() == XnNewstickerInterface::MXnNewstickerInterface::Type());
       
  1595     }
       
  1596     
       
  1597 void CContentRenderer::RegisterNewstickerCallbackInterfaceL( CXnNodeAppIf& aTarget )
       
  1598     {
       
  1599     if ( !iCallbackHandler )
       
  1600         {
       
  1601         // Instantiate callback handler
       
  1602         CNewstickerCallbackHandler* handler = CNewstickerCallbackHandler::NewLC( *iFwEventHandler );
       
  1603 
       
  1604         // Set callback handler
       
  1605         iCallbackHandler = handler;
       
  1606         CleanupStack::Pop( handler );
       
  1607         }
       
  1608         // Obtain newsticker component interface
       
  1609         XnNewstickerInterface::MXnNewstickerInterface* newsticker = NULL;
       
  1610         XnComponentInterface::MakeInterfaceL( newsticker, aTarget );
       
  1611         
       
  1612         LeaveIfNull( newsticker, KErrGeneral );
       
  1613         
       
  1614         // Set callback interface
       
  1615         newsticker->SetCallbackInterfaceL( this );
       
  1616     }
       
  1617 
       
  1618 void CContentRenderer::CleanPluginFromUiL( MAiPropertyExtension& aPlugin )
       
  1619     {
       
  1620     TInt itemCount = 0;
       
  1621     
       
  1622     // Resolve content items
       
  1623     MAiContentItemIterator& iter = ContentItemIteratorL( aPlugin, EAiPublisherContent );
       
  1624     iter.Reset();
       
  1625     
       
  1626     // Clean all content items
       
  1627     while ( iter.HasNext() )
       
  1628         {
       
  1629         const TAiContentItem& item = iter.NextL();
       
  1630 
       
  1631         const TDesC& nodeId = iNodeIdGenerator->ContentNodeIdL( aPlugin, item );
       
  1632         
       
  1633         // Find nodes
       
  1634         HBufC8* nodeId8 = CnvUtfConverter::ConvertFromUnicodeToUtf8L(nodeId);
       
  1635         CleanupStack::PushL(nodeId8);
       
  1636 
       
  1637         RPointerArray<CXnNodeAppIf> nodes = iAppUi.UiEngineL()->FindNodeByClassL( 
       
  1638             *nodeId8, aPlugin.PublisherInfoL()->iNamespace );
       
  1639 
       
  1640         CleanupStack::PopAndDestroy(nodeId8);
       
  1641 
       
  1642         itemCount += nodes.Count(); 
       
  1643         
       
  1644         CleanupClosePushL( nodes );
       
  1645 
       
  1646         for ( TInt i = 0; i < nodes.Count(); ++i )
       
  1647             {
       
  1648             CXnNodeAppIf* property = nodes[i];
       
  1649             
       
  1650             TInt priority = GetContentPriority( *property );
       
  1651 
       
  1652             // Navigate to parent
       
  1653             CXnNodeAppIf* target = LeaveIfNull( property->ParentL(), KErrNotFound );
       
  1654 
       
  1655             if ( AllowPublishByPriority( *target, priority ) )
       
  1656                 {
       
  1657                 // Create transaction element for empty content
       
  1658                 MTransactionElement* element =
       
  1659                     iFactory->CreateEmptyContentTransactionElementL( *target, 0 );
       
  1660 
       
  1661                 iPolicyEvaluator->EvaluateEmptyContentPolicyL( *target,
       
  1662                                                                element->PolicyArray() );
       
  1663                 iPolicyEvaluator->EvaluateVisibilityPolicyL( *target,
       
  1664                                                                element->PolicyArray() );
       
  1665                                                       
       
  1666                 ProcessTransactionElementL( element );
       
  1667                   
       
  1668                 if ( priority > KErrNotFound ) // Only for prioritized elements
       
  1669                     {
       
  1670                     // Add current ui element into content refresh map
       
  1671                     HBufC* uiElementId = PropertyValueL( *target,
       
  1672                                                          XnPropertyNames::common::KId );
       
  1673                     RefreshContentL( uiElementId, priority );
       
  1674                     }
       
  1675                 }
       
  1676             }
       
  1677             
       
  1678         CleanupStack::PopAndDestroy(&nodes);
       
  1679         }
       
  1680         
       
  1681     if ( itemCount == 0 )
       
  1682         {
       
  1683         //Nothing to clean from UI. Cancel transaction outside current trap harness
       
  1684         User::Leave( KErrNotFound );
       
  1685         }
       
  1686     }
       
  1687 
       
  1688 //  End of File