|
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: Image transaction element |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include "xnbitmap.h" |
|
20 #include "xnnewsticker.h" |
|
21 #include "xntype.h" |
|
22 #include "xnmenu.h" |
|
23 #include "xnmenuadapter.h" |
|
24 #include "xnuiengineappif.h" |
|
25 |
|
26 #include <imageconversion.h> |
|
27 #include <gulicon.h> |
|
28 |
|
29 #include "imagetransactionelement.h" |
|
30 #include "xmluicontrollerpanic.h" |
|
31 #include "aixmluiutils.h" |
|
32 #include "xnuiengineappif.h" |
|
33 |
|
34 using namespace AiXmlUiController; |
|
35 using namespace XnImageInterface; |
|
36 using namespace ContentAccess; |
|
37 |
|
38 namespace AiXmlUiController |
|
39 { |
|
40 |
|
41 TBool IsNodeVisible( CXnNodeAppIf& aNode ) |
|
42 { |
|
43 CXnProperty* propVisibility = aNode.GetPropertyL( XnPropertyNames::style::common::KVisibility );; |
|
44 |
|
45 if( propVisibility ) |
|
46 { |
|
47 const TDesC8& visibility = propVisibility->StringValue(); |
|
48 |
|
49 if( visibility == XnPropertyNames::style::common::visibility::KHidden ) |
|
50 { |
|
51 return EFalse; |
|
52 } |
|
53 } |
|
54 |
|
55 CXnProperty* propDisplay = aNode.GetPropertyL( XnPropertyNames::style::common::KDisplay ); |
|
56 |
|
57 if( propDisplay ) |
|
58 { |
|
59 const TDesC8& display = propDisplay->StringValue(); |
|
60 |
|
61 if( display == XnPropertyNames::style::common::display::KNone ) |
|
62 { |
|
63 return EFalse; |
|
64 } |
|
65 } |
|
66 |
|
67 CXnProperty* propDisabled = aNode.GetPropertyL( XnPropertyNames::common::KDisabled ); |
|
68 |
|
69 if( propDisabled ) |
|
70 { |
|
71 const TDesC8& disabled = propDisabled->StringValue(); |
|
72 |
|
73 if( disabled == XnPropertyNames::KTrue ) |
|
74 { |
|
75 return EFalse; |
|
76 } |
|
77 } |
|
78 return ETrue; |
|
79 } |
|
80 /** |
|
81 * Uses CImageDecoder to decode images asynchronously. |
|
82 * When decoding is done, it tries to find target and set |
|
83 * image into element. Destroys itself at end of RunL method. |
|
84 */ |
|
85 class CKamikazeImageDecoder: public CActive |
|
86 { |
|
87 public: |
|
88 static CKamikazeImageDecoder* NewL( |
|
89 RFile& aFile, const TDesC8& aNodeId, |
|
90 const TDesC8& aNodeNs, TXnUiEngineAppIf& aUiEngine); |
|
91 ~CKamikazeImageDecoder(); |
|
92 public: |
|
93 /** |
|
94 * Start decoding and forget instance. |
|
95 * Destroyes itself. |
|
96 */ |
|
97 void DecodeLD(); |
|
98 private: |
|
99 // from CActive |
|
100 void DoCancel(); |
|
101 void RunL(); |
|
102 private: |
|
103 void ConstructL(RFile& aFile, const TDesC8& aNodeId,const TDesC8& aNodeNs); |
|
104 CKamikazeImageDecoder(TXnUiEngineAppIf& aUiEngine); |
|
105 void SetImageL(); |
|
106 private: |
|
107 /** |
|
108 * Image decoder. Own. |
|
109 */ |
|
110 CImageDecoder* iDecoder; |
|
111 /** |
|
112 * Target node id |
|
113 */ |
|
114 HBufC8* iNodeId; |
|
115 /** |
|
116 * Target node namespace |
|
117 */ |
|
118 HBufC8* iNodeNs; |
|
119 /** |
|
120 * Provides services to find target |
|
121 */ |
|
122 TXnUiEngineAppIf& iUiEngine; |
|
123 /** |
|
124 * Icon. Own. |
|
125 */ |
|
126 CGulIcon* iIcon; |
|
127 }; |
|
128 |
|
129 CKamikazeImageDecoder* CKamikazeImageDecoder::NewL( |
|
130 RFile& aFile, |
|
131 const TDesC8& aNodeId, |
|
132 const TDesC8& aNodeNs, |
|
133 TXnUiEngineAppIf& aUiEngine) |
|
134 { |
|
135 CKamikazeImageDecoder* p = new (ELeave)CKamikazeImageDecoder(aUiEngine); |
|
136 CleanupStack::PushL(p); |
|
137 p->ConstructL(aFile,aNodeId,aNodeNs); |
|
138 CleanupStack::Pop(p); |
|
139 return p; |
|
140 } |
|
141 |
|
142 CKamikazeImageDecoder::CKamikazeImageDecoder(TXnUiEngineAppIf& aUiEngine): |
|
143 CActive(CActive::EPriorityStandard ), iUiEngine(aUiEngine) |
|
144 { |
|
145 CActiveScheduler::Add( this ); |
|
146 } |
|
147 |
|
148 CKamikazeImageDecoder::~CKamikazeImageDecoder() |
|
149 { |
|
150 Cancel(); |
|
151 delete iDecoder; |
|
152 delete iNodeId; |
|
153 delete iNodeNs; |
|
154 delete iIcon; |
|
155 } |
|
156 |
|
157 void CKamikazeImageDecoder::ConstructL( |
|
158 RFile& aFile, |
|
159 const TDesC8& aNodeId, |
|
160 const TDesC8& aNodeNs) |
|
161 { |
|
162 // Create new decoder for file |
|
163 iDecoder = CImageDecoder::FileNewL( aFile, EView ); |
|
164 iNodeId = aNodeId.AllocL(); |
|
165 iNodeNs = aNodeNs.AllocL(); |
|
166 iIcon = CGulIcon::NewL(); |
|
167 } |
|
168 |
|
169 void CKamikazeImageDecoder::DecodeLD() |
|
170 { |
|
171 TFrameInfo frameInfo = iDecoder->FrameInfo(0); |
|
172 CFbsBitmap* bitmap = new( ELeave ) CFbsBitmap; |
|
173 iIcon->SetBitmap( bitmap ); |
|
174 |
|
175 User::LeaveIfError( bitmap->Create( frameInfo.iOverallSizeInPixels, |
|
176 frameInfo.iFrameDisplayMode ) ); |
|
177 |
|
178 CFbsBitmap* mask(0); |
|
179 if ( frameInfo.iFlags & TFrameInfo::ETransparencyPossible ) |
|
180 { |
|
181 mask = new( ELeave ) CFbsBitmap; |
|
182 iIcon->SetMask( mask ); |
|
183 User::LeaveIfError( mask->Create( frameInfo.iOverallSizeInPixels, |
|
184 ( ( frameInfo.iFlags & TFrameInfo::EAlphaChannel ) |
|
185 ? EGray256 : EGray2 ) ) ); |
|
186 } |
|
187 |
|
188 if(iIcon->Mask()) |
|
189 { |
|
190 iDecoder->Convert( &iStatus, *bitmap, *mask ); |
|
191 } |
|
192 else |
|
193 { |
|
194 iDecoder->Convert( &iStatus, *bitmap ); |
|
195 } |
|
196 SetActive(); |
|
197 } |
|
198 |
|
199 void CKamikazeImageDecoder::DoCancel() |
|
200 { |
|
201 iDecoder->Cancel(); |
|
202 } |
|
203 |
|
204 void CKamikazeImageDecoder::SetImageL() |
|
205 { |
|
206 |
|
207 // Find target |
|
208 CXnNodeAppIf* node = iUiEngine.FindNodeByIdL(*iNodeId,*iNodeNs); |
|
209 if(!node) |
|
210 { |
|
211 return; |
|
212 } |
|
213 |
|
214 const TDesC8& type = node->Type()->Type(); |
|
215 |
|
216 if ( type == XnImageInterface::MXnImageInterface::Type() ) |
|
217 { |
|
218 MXnImageInterface* imageIntr = NULL; |
|
219 if ( !XnComponentInterface::MakeInterfaceL( imageIntr, *node ) ) |
|
220 { |
|
221 return; |
|
222 } |
|
223 // Set new bitmaps. Ownership is transferred to MXnImageInterface |
|
224 iIcon->SetBitmapsOwnedExternally( ETrue ); |
|
225 imageIntr->SetContentBitmaps( iIcon->Bitmap(), iIcon->Mask() ); |
|
226 |
|
227 } |
|
228 else if ( type == XnNewstickerInterface::MXnNewstickerInterface::Type() ) |
|
229 { |
|
230 XnNewstickerInterface::MXnNewstickerInterface* newsTicker = NULL; |
|
231 XnComponentInterface::MakeInterfaceL( newsTicker, *node ); |
|
232 LeaveIfNull( newsTicker, KErrNotSupported ); |
|
233 |
|
234 User::LeaveIfError( newsTicker->SetSeparatorImageL( iIcon ) ); |
|
235 // Ownership of icon transferred to newsticker |
|
236 iIcon = NULL; |
|
237 } |
|
238 // Menu softkey icons |
|
239 else if ( ( ( type == KXnMenuItem || type == KXnMenu ) && |
|
240 IsNodeVisible( *node ) ) || |
|
241 type == XnPropertyNames::softkey::KNodeName ) |
|
242 { |
|
243 CXnNodeAppIf* menuBar = node->ParentL(); |
|
244 |
|
245 XnMenuInterface::MXnMenuInterface::TSoftKeyPosition softkeyPosition = |
|
246 XnMenuInterface::MXnMenuInterface::ELeft; |
|
247 |
|
248 CXnProperty* property = |
|
249 node->GetPropertyL( XnPropertyNames::softkey::KTypeAttribute ); |
|
250 if ( property && property->StringValue() == XnPropertyNames::softkey::type::KRight ) |
|
251 { |
|
252 softkeyPosition = XnMenuInterface::MXnMenuInterface::ERight; |
|
253 } |
|
254 else if ( property && property->StringValue() == XnPropertyNames::softkey::type::KLeft ) |
|
255 { |
|
256 softkeyPosition = XnMenuInterface::MXnMenuInterface::ELeft; |
|
257 } |
|
258 else // Image can be published only to RSK or LSK |
|
259 { |
|
260 return; |
|
261 } |
|
262 |
|
263 XnMenuInterface::MXnMenuInterface* menuIf = NULL; |
|
264 |
|
265 XnComponentInterface::MakeInterfaceL( menuIf, *menuBar ); |
|
266 if ( menuIf ) |
|
267 { |
|
268 // Use black mask and preserver aspect ratio |
|
269 |
|
270 menuIf->SetSoftKeyImageL( iIcon->Bitmap(), |
|
271 iIcon->Mask(), |
|
272 softkeyPosition, |
|
273 node, |
|
274 ETrue, |
|
275 ETrue ); |
|
276 iIcon->SetBitmapsOwnedExternally( ETrue ); |
|
277 } |
|
278 if( menuBar ) |
|
279 { |
|
280 iUiEngine.RefreshMenuL(); |
|
281 } |
|
282 } |
|
283 |
|
284 } |
|
285 |
|
286 void CKamikazeImageDecoder::RunL() |
|
287 { |
|
288 CleanupStack::PushL(this); |
|
289 if(iStatus == KErrNone) |
|
290 { |
|
291 SetImageL(); |
|
292 iUiEngine.RenderUIL(); |
|
293 } |
|
294 CleanupStack::PopAndDestroy(this); |
|
295 } |
|
296 |
|
297 // ======== MEMBER FUNCTIONS ======== |
|
298 |
|
299 CImageTransactionElement::CImageTransactionElement( |
|
300 AiUtility::CContentPriorityMap& aContentPriorityMap) |
|
301 : CTransactionElement(aContentPriorityMap) |
|
302 { |
|
303 } |
|
304 |
|
305 CImageTransactionElement* CImageTransactionElement::NewL( |
|
306 AiUtility::CContentPriorityMap& aContentPriorityMap) |
|
307 { |
|
308 CImageTransactionElement* self = new( ELeave ) CImageTransactionElement( |
|
309 aContentPriorityMap ); |
|
310 return self; |
|
311 } |
|
312 |
|
313 CImageTransactionElement::~CImageTransactionElement() |
|
314 { |
|
315 delete iNewIcon; |
|
316 delete iImageDecoder; |
|
317 } |
|
318 |
|
319 void CImageTransactionElement::InitializeL( CXnNodeAppIf& aTarget, |
|
320 CGulIcon* aIcon ) |
|
321 { |
|
322 CheckTypeL( aTarget ); |
|
323 |
|
324 LeaveIfNull( aIcon, KErrArgument ); |
|
325 |
|
326 SetTarget( aTarget ); |
|
327 iNewIcon = aIcon; |
|
328 } |
|
329 |
|
330 void CImageTransactionElement::InitializeL( CXnNodeAppIf& aTarget, |
|
331 RFile& aFile ) |
|
332 { |
|
333 CheckTypeL( aTarget ); |
|
334 |
|
335 const TDesC8* nodeId = &KNullDesC8; |
|
336 |
|
337 CXnProperty* property = aTarget.GetPropertyL(XnPropertyNames::common::KId); |
|
338 if(property) |
|
339 { |
|
340 nodeId = &property->StringValue(); |
|
341 } |
|
342 if ( iImageDecoder ) |
|
343 { |
|
344 delete iImageDecoder; |
|
345 iImageDecoder = NULL; |
|
346 } |
|
347 iImageDecoder = CKamikazeImageDecoder::NewL( |
|
348 aFile,*nodeId,aTarget.Namespace(),*aTarget.UiEngineL()); |
|
349 |
|
350 SetTarget( aTarget ); |
|
351 } |
|
352 |
|
353 |
|
354 void CImageTransactionElement::UpdateDataL() |
|
355 { |
|
356 if ( iImageDecoder ) |
|
357 { |
|
358 iImageDecoder->DecodeLD(); |
|
359 iImageDecoder = NULL; // self destroy |
|
360 } |
|
361 else |
|
362 { |
|
363 __ASSERT_DEBUG( iNewIcon, Panic( EBitmapNull ) ); |
|
364 |
|
365 const TDesC8& type = LeaveIfNull( Target().Type(), KErrNotSupported )->Type(); |
|
366 |
|
367 if ( type == XnImageInterface::MXnImageInterface::Type() ) |
|
368 { |
|
369 MXnImageInterface* imageIntr = NULL; |
|
370 if ( !XnComponentInterface::MakeInterfaceL( imageIntr, Target() ) ) |
|
371 { |
|
372 User::Leave( KErrNotSupported ); |
|
373 } |
|
374 // Set new bitmaps. Ownership is transferred to MXnImageInterface |
|
375 iNewIcon->SetBitmapsOwnedExternally( ETrue ); |
|
376 imageIntr->SetContentBitmaps( iNewIcon->Bitmap(), iNewIcon->Mask() ); |
|
377 } |
|
378 else if ( type == XnNewstickerInterface::MXnNewstickerInterface::Type() ) |
|
379 { |
|
380 XnNewstickerInterface::MXnNewstickerInterface* newsTicker = NULL; |
|
381 XnComponentInterface::MakeInterfaceL( newsTicker, Target() ); |
|
382 LeaveIfNull( newsTicker, KErrNotSupported ); |
|
383 |
|
384 User::LeaveIfError( newsTicker->SetSeparatorImageL( iNewIcon ) ); |
|
385 |
|
386 // Ownership of icon transferred to newsticker |
|
387 |
|
388 iNewIcon = NULL; |
|
389 } |
|
390 // Menu softkey icons |
|
391 else if ( ( ( type == KXnMenuItem || type == KXnMenu ) && |
|
392 IsNodeVisible( Target() ) ) || |
|
393 type == XnPropertyNames::softkey::KNodeName ) |
|
394 { |
|
395 CXnNodeAppIf* menuBar = Target().ParentL(); |
|
396 |
|
397 XnMenuInterface::MXnMenuInterface::TSoftKeyPosition softkeyPosition = |
|
398 XnMenuInterface::MXnMenuInterface::ELeft; |
|
399 |
|
400 CXnProperty* property = |
|
401 Target().GetPropertyL( XnPropertyNames::softkey::KTypeAttribute ); |
|
402 if ( property && property->StringValue() == XnPropertyNames::softkey::type::KRight ) |
|
403 { |
|
404 softkeyPosition = XnMenuInterface::MXnMenuInterface::ERight; |
|
405 } |
|
406 else if ( property && property->StringValue() == XnPropertyNames::softkey::type::KLeft ) |
|
407 { |
|
408 softkeyPosition = XnMenuInterface::MXnMenuInterface::ELeft; |
|
409 } |
|
410 else // Image can be published only to RSK or LSK |
|
411 { |
|
412 delete iNewIcon; |
|
413 iNewIcon = NULL; |
|
414 User::Leave( KErrNotSupported ); |
|
415 } |
|
416 |
|
417 XnMenuInterface::MXnMenuInterface* menuIf = NULL; |
|
418 |
|
419 XnComponentInterface::MakeInterfaceL( menuIf, *menuBar ); |
|
420 if ( menuIf ) |
|
421 { |
|
422 // Use black mask and preserver aspect ratio |
|
423 TRAPD(err, |
|
424 menuIf->SetSoftKeyImageL( iNewIcon->Bitmap(), |
|
425 iNewIcon->Mask(), |
|
426 softkeyPosition, |
|
427 &Target(), |
|
428 ETrue, |
|
429 ETrue ) |
|
430 ); |
|
431 // Menuinterface takes ownership |
|
432 if ( err == KErrNone ) |
|
433 { |
|
434 iNewIcon->SetBitmapsOwnedExternally( ETrue ); |
|
435 } |
|
436 if( menuBar ) |
|
437 { |
|
438 menuBar->UiEngineL()->RefreshMenuL(); |
|
439 } |
|
440 } |
|
441 } |
|
442 else |
|
443 { |
|
444 User::Leave( KErrNotSupported ); |
|
445 } |
|
446 } |
|
447 |
|
448 delete iNewIcon; |
|
449 iNewIcon = NULL; |
|
450 |
|
451 UpdateContentPriorityL(); |
|
452 } |
|
453 |
|
454 void CImageTransactionElement::Reset() |
|
455 { |
|
456 if ( iImageDecoder ) |
|
457 { |
|
458 delete iImageDecoder; |
|
459 iImageDecoder = NULL; |
|
460 } |
|
461 |
|
462 CTransactionElement::Reset(); |
|
463 |
|
464 delete iNewIcon; |
|
465 iNewIcon = NULL; |
|
466 } |
|
467 |
|
468 TBool CImageTransactionElement::IsSupported( CXnNodeAppIf& aTarget ) |
|
469 { |
|
470 // Get type info |
|
471 CXnType* typeInfo = aTarget.Type(); |
|
472 |
|
473 if ( !typeInfo ) |
|
474 { |
|
475 return EFalse; |
|
476 } |
|
477 |
|
478 const TDesC8& type = typeInfo->Type(); |
|
479 |
|
480 // image element and newsticker supported |
|
481 return ( type == XnImageInterface::MXnImageInterface::Type() || |
|
482 type == XnNewstickerInterface::MXnNewstickerInterface::Type() || |
|
483 type == XnMenuInterface::MXnMenuInterface::Type() || |
|
484 type == KXnMenuItem || |
|
485 type == KXnMenu || |
|
486 type == XnPropertyNames::softkey::KNodeName ); |
|
487 } |
|
488 |
|
489 void CImageTransactionElement::CheckTypeL( CXnNodeAppIf& aTarget ) |
|
490 { |
|
491 if ( !IsSupported( aTarget ) ) |
|
492 { |
|
493 User::Leave( KErrNotSupported ); |
|
494 } |
|
495 } |
|
496 } // ns |