1 /*
2 * GPAC - Multimedia Framework C SDK
3 *
4 * Authors: Jean Le Feuvre
5 * Copyright (c) Telecom ParisTech 2006-2012
6 * All rights reserved
7 *
8 * This file is part of GPAC / Symbian GUI player
9 *
10 * GPAC is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation; either version 2, or (at your option)
13 * any later version.
14 *
15 * GPAC is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; see the file COPYING. If not, write to
22 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 */
25
26 #include <eiktxlbx.h>
27 #include <eiktxlbm.h>
28
29
30 #include <gpac/utf.h>
31
32 // INCLUDE FILES
33 #include "osmo4_ui.h"
34 #include "playlist.h"
35
36 #ifdef USE_SKIN
37 #include <aknlists.h>
38 #include <akntabgrp.h>
39 #include <AknsDrawUtils.h>// skin
40 #include <AknsBasicBackgroundControlContext.h> //skin
41 #endif
42
43
CPlaylist()44 CPlaylist::CPlaylist()
45 {
46 playlist_mode = 0;
47 view_all_files = 0;
48 }
~CPlaylist()49 CPlaylist::~CPlaylist()
50 {
51 delete iListBox;
52 delete iBackGround;
53 }
54
NewL(const TRect & aRect,GF_User * user)55 CPlaylist* CPlaylist::NewL( const TRect& aRect, GF_User *user)
56 {
57 CPlaylist* self = CPlaylist::NewLC( aRect, user);
58 CleanupStack::Pop( self );
59 return self;
60 }
NewLC(const TRect & aRect,GF_User * user)61 CPlaylist* CPlaylist::NewLC( const TRect& aRect, GF_User *user)
62 {
63 CPlaylist* self = new ( ELeave ) CPlaylist;
64 CleanupStack::PushL( self );
65 self->ConstructL( aRect, user);
66 return self;
67 }
68
ConstructL(const TRect & aRect,GF_User * user)69 void CPlaylist::ConstructL(const TRect& aRect, GF_User *user)
70 {
71 CreateWindowL();
72
73 #ifdef USE_SKIN
74 iListBox = new (ELeave) CAknSingleStyleListBox();
75 #else
76 iListBox = new (ELeave) CEikTextListBox();
77 #endif
78 iListBox->ConstructL(this);
79 iListBox->SetContainerWindowL(*this);
80 iListBox->SetListBoxObserver(this);
81
82 CDesCArray* textArray = new (ELeave) CDesCArrayFlat(16);
83 iListBox->Model()->SetItemTextArray( textArray );
84 iListBox->Model()->SetOwnershipType( ELbmOwnsItemArray );
85
86 // Creates scrollbar.
87 iListBox->CreateScrollBarFrameL( ETrue );
88 iListBox->ScrollBarFrame()->SetScrollBarVisibilityL(CEikScrollBarFrame::EAuto, CEikScrollBarFrame::EAuto);
89 //iListBox->ActivateL();
90
91 iListBox->SetFocus(ETrue);
92
93 SetRect(aRect);
94 ActivateL();
95 MakeVisible(EFalse);
96
97 strcpy(szCurrentDir, "");
98
99 #ifndef GPAC_GUI_ONLY
100 m_user = user;
101
102 strcpy(ext_list, "");
103 u32 count = gf_cfg_get_key_count(user->config, "MimeTypes");
104 for (u32 i=0; i<count; i++) {
105 char szKeyList[1000], *sKey;
106 const char *sMime = gf_cfg_get_key_name(user->config, "MimeTypes", i);
107 const char *opt = gf_cfg_get_key(user->config, "MimeTypes", sMime);
108 strcpy(szKeyList, opt+1);
109 sKey = strrchr(szKeyList, '\"');
110 if (!sKey) continue;
111 sKey[0] = 0;
112 strcat(ext_list, szKeyList);
113 strcat(ext_list, " ");
114 }
115
116 const char *opt = gf_cfg_get_key(m_user->config, "General", "LastWorkingDir");
117 if (opt) strcpy(szCurrentDir, opt);
118 #endif
119
120 }
121
SizeChanged()122 void CPlaylist::SizeChanged()
123 {
124 iListBox->SetRect( Rect() );
125 }
126
Draw(const TRect & aRect) const127 void CPlaylist::Draw(const TRect& aRect) const
128 {
129 #ifdef USE_SKIN
130 CWindowGc& gc = SystemGc();
131 MAknsSkinInstance* skin = AknsUtils::SkinInstance();
132 MAknsControlContext* cc = AknsDrawUtils::ControlContext( this );
133 AknsDrawUtils::Background( skin, cc, this, gc, aRect );
134 #endif
135
136 }
137
138 #ifdef USE_SKIN
MopSupplyObject(TTypeUid aId)139 TTypeUid::Ptr CPlaylist::MopSupplyObject(TTypeUid aId)
140 {
141 if(aId.iUid == MAknsControlContext::ETypeId && iBackGround) {
142 return MAknsControlContext::SupplyMopObject( aId, iBackGround);
143 }
144 return CCoeControl::MopSupplyObject( aId );
145 }
146 #endif
147
148
CountComponentControls() const149 TInt CPlaylist::CountComponentControls() const
150 {
151 return 1;
152 }
ComponentControl(TInt aIndex) const153 CCoeControl* CPlaylist::ComponentControl(TInt aIndex) const
154 {
155 switch (aIndex) {
156 case 0:
157 return iListBox;
158 default:
159 return NULL;
160 }
161 }
162
OfferKeyEventL(const TKeyEvent & aKeyEvent,TEventCode aType)163 TKeyResponse CPlaylist::OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType)
164 {
165 if (aType != EEventKey) return iListBox->OfferKeyEventL(aKeyEvent, aType);
166
167 switch (aKeyEvent.iScanCode) {
168 case EStdKeyEnter:
169 HandleSelection();
170 return EKeyWasConsumed;
171 default:
172 return iListBox->OfferKeyEventL(aKeyEvent, aType);
173 }
174 }
HandleListBoxEventL(CEikListBox * aListBox,TListBoxEvent aEventType)175 void CPlaylist::HandleListBoxEventL(CEikListBox* aListBox, TListBoxEvent aEventType )
176 {
177 if (aEventType == MEikListBoxObserver::EEventItemClicked ||
178 aEventType == MEikListBoxObserver::EEventEnterKeyPressed)
179
180 HandleSelection();
181 }
182
ShowHide(Bool show)183 void CPlaylist::ShowHide(Bool show)
184 {
185 if (show) {
186 RefreshPlaylist();
187 MakeVisible(ETrue);
188 DrawNow();
189 } else {
190 /*cleanup*/
191 ResetView();
192 MakeVisible(EFalse);
193 ((COsmo4AppUi *) CEikonEnv::Static()->AppUi())->SetTitle(NULL, 0);
194 }
195 }
196
197
FlushItemList()198 void CPlaylist::FlushItemList()
199 {
200 iListBox->HandleItemAdditionL();
201 iListBox->SetCurrentItemIndexAndDraw(0);
202 }
203
ResetView()204 void CPlaylist::ResetView()
205 {
206 CDesCArray* array = static_cast<CDesCArray*>(iListBox->Model()->ItemTextArray());
207 array->Reset();
208 iListBox->Reset();
209 }
210
AddItem(const char * name,int is_directory)211 void CPlaylist::AddItem(const char *name, int is_directory)
212 {
213 TBuf<100> tmp;
214 char szName[100];
215 CDesCArray* array = static_cast<CDesCArray*>(iListBox->Model()->ItemTextArray());
216
217 if (is_directory) {
218 #ifdef USE_SKIN
219 sprintf(szName, "\t+ %s\t\t", name);
220 #else
221 sprintf(szName, "+ %s", name);
222 #endif
223 } else {
224 #ifdef USE_SKIN
225 sprintf(szName, "\t%s\t\t", name);
226 #else
227 strcpy(szName, name);
228 #endif
229 }
230 tmp.SetLength(strlen(szName)+1);
231 tmp.Copy( TPtrC8(( TText8* ) szName) );
232 tmp.ZeroTerminate();
233 array->AppendL(tmp);
234 }
235
enum_dirs(void * cbk,char * name,char * path,GF_FileEnumInfo * file_info)236 static Bool enum_dirs(void *cbk, char *name, char *path, GF_FileEnumInfo *file_info)
237 {
238 CPlaylist *of = (CPlaylist *)cbk;
239 of->AddItem(name, 1);
240 return 0;
241 }
242
enum_files(void * cbk,char * name,char * path,GF_FileEnumInfo * file_info)243 static Bool enum_files(void *cbk, char *name, char *path, GF_FileEnumInfo *file_info)
244 {
245 CPlaylist *of = (CPlaylist *)cbk;
246 of->AddItem(name, 0);
247 return 0;
248 }
249
250
ScanDirectory(const char * dir)251 void CPlaylist::ScanDirectory(const char *dir)
252 {
253 ResetView();
254
255 if (!dir || !strlen(dir)) {
256 RFs iFs;
257 TDriveList aList;
258 iFs.Connect();
259 iFs.DriveList(aList);
260 for (TInt i=0; i<KMaxDrives; i++) {
261 if (aList[i]) {
262 TChar aDrive;
263 iFs.DriveToChar(i, aDrive);
264 sprintf(szCurrentDir, "%c:", (TUint)aDrive);
265 AddItem(szCurrentDir, 0);
266 }
267 }
268 iFs.Close();
269 FlushItemList();
270 strcpy(szCurrentDir, "");
271 return;
272 } else {
273 strcpy(szCurrentDir, dir);
274 AddItem("..", 1);
275 }
276
277 #ifndef GPAC_GUI_ONLY
278 gf_enum_directory((const char *) szCurrentDir, 1, enum_dirs, this, NULL);
279 gf_enum_directory((char *) szCurrentDir, 0, enum_files, this, view_all_files ? NULL : ext_list);
280 #endif
281 FlushItemList();
282
283 ((COsmo4AppUi *) CEikonEnv::Static()->AppUi())->SetTitle(szCurrentDir, 0);
284
285 }
286
GetSelectionName(char * szName)287 void CPlaylist::GetSelectionName(char *szName)
288 {
289 CDesCArray* array = static_cast<CDesCArray*>(iListBox->Model()->ItemTextArray());
290 TInt idx = iListBox->CurrentItemIndex();
291
292 #ifndef GPAC_GUI_ONLY
293
294 #if defined(_UNICODE)
295 size_t len;
296 /*handle terminating zero !!*/
297 u16 szNameUTF16[100];
298 len = (*array)[idx].Size();
299 memcpy(szNameUTF16, (*array)[idx].Ptr(), sizeof(u8)*len);
300 szNameUTF16[len/2] = 0;
301 const u16 *sptr = szNameUTF16;
302
303 /*skip initial '\t'*/
304 #ifdef USE_SKIN
305 sptr += 1;
306 #endif
307
308 len = gf_utf8_wcstombs(szName, 512, &sptr);
309 szName[len] = 0;
310
311
312 #else
313
314 char *src = (*array)[idx]).Ptr();
315 /*skip initial '\t'*/
316 #ifdef USE_SKIN
317 src += 1;
318 #endif
319 strcpy(szName, (const char *) src) ;
320 #endif
321
322 /*remove trailing "\t\t"*/
323 #ifdef USE_SKIN
324 len = strlen(szName);
325 szName[len-2] = 0;
326 #endif
327
328 #else
329 szName[0] = 0;
330 #endif
331
332 }
333
HandleSelection()334 void CPlaylist::HandleSelection()
335 {
336 char szName[100];
337 GetSelectionName(szName);
338
339 /*sub-directory*/
340 if ((szName[0] == '+') && (szName[1] == ' ')) {
341 /*browse up*/
342 if ((szName[2] == '.') && (szName[3] == '.')) {
343 char *prev = strrchr(szCurrentDir, '\\');
344 if (prev) {
345 prev[0] = 0;
346 ScanDirectory(szCurrentDir);
347 } else {
348 ScanDirectory(NULL);
349 }
350 } else {
351 strcat(szCurrentDir, "\\");
352 strcat(szCurrentDir, szName+2);
353 ScanDirectory(szCurrentDir);
354 }
355 } else if (szName[1] == ':') {
356 ScanDirectory(szName);
357 } else {
358 char szURL[1024];
359 COsmo4AppUi *app = (COsmo4AppUi *) CEikonEnv::Static()->AppUi();
360 if (playlist_mode) {
361 TInt idx = iListBox->CurrentItemIndex();
362 #ifndef GPAC_GUI_ONLY
363 const char *url = gf_cfg_get_key_name(m_user->config, "Playlist", idx);
364 if (url) app->PlayURL(url);
365 #endif
366 } else {
367 gf_cfg_set_key(m_user->config, "General", "LastWorkingDir", (const char *) szCurrentDir);
368 sprintf(szURL, "%s\\%s", szCurrentDir, szName);
369 app->PlayURL(szURL);
370 }
371 }
372 }
373
SelectionIsFile()374 Bool CPlaylist::SelectionIsFile()
375 {
376 char szName[100];
377 GetSelectionName(szName);
378 if ((szName[0] == '+') && (szName[1] == ' ')) return 0;
379 else if (szName[1] == ':') return 0;
380 return 1;
381 }
382
IsInPlaylist()383 Bool CPlaylist::IsInPlaylist()
384 {
385 char szURL[1024];
386 char szName[100];
387 GetSelectionName(szName);
388 if ((szName[0] == '+') && (szName[1] == ' ')) return 0;
389 else if (szName[1] == ':') return 0;
390
391 /*remove from playlist*/
392 sprintf(szURL, "%s\\%s", szCurrentDir, szName);
393 #ifndef GPAC_GUI_ONLY
394 const char *opt = gf_cfg_get_key(m_user->config, "Playlist", szURL);
395 if (opt) return 1;
396 #endif
397 return 0;
398 }
399
dir_add_files(void * cbk,char * name,char * path,GF_FileEnumInfo * file_info)400 static Bool dir_add_files(void *cbk, char *name, char *path, GF_FileEnumInfo *file_info)
401 {
402 CPlaylist *pl = (CPlaylist *)cbk;
403
404 #if 0
405 if (!bViewUnknownTypes && extension_list) {
406 char *ext = strrchr(name, '.');
407 if (!ext || !strstr(extension_list, ext+1)) return 0;
408 }
409 #endif
410
411 #ifndef GPAC_GUI_ONLY
412 gf_cfg_set_key(pl->m_user->config, "Playlist", path, "");
413 #endif
414
415 return 0;
416 }
417
418
RefreshPlaylist()419 void CPlaylist::RefreshPlaylist()
420 {
421 if (playlist_mode) {
422 #ifndef GPAC_GUI_ONLY
423 u32 count = gf_cfg_get_key_count(m_user->config, "Playlist");
424 ResetView();
425 for (u32 i=0; i<count; i++) {
426 const char *opt = gf_cfg_get_key_name(m_user->config, "Playlist", i);
427 const char *sep = strrchr(opt, '\\');
428 if (!sep) sep = strrchr(opt, '/');
429 AddItem(sep ? (sep+1) : opt, 0);
430 }
431 if (!count) AddItem("[empty]", 0);
432 #endif
433 FlushItemList();
434
435 ((COsmo4AppUi *) CEikonEnv::Static()->AppUi())->SetTitle("Playlist", 0);
436 } else {
437 ScanDirectory(szCurrentDir);
438 }
439 }
440
441
PlaylistAct(Osmo4_PLActions act)442 void CPlaylist::PlaylistAct(Osmo4_PLActions act)
443 {
444 char szURL[1024];
445 char szName[100];
446 CDesCArray*array;
447 TInt idx;
448 TInt count;
449
450 if (act==Osmo4PLClear) {
451 while (1) {
452 #ifndef GPAC_GUI_ONLY
453 const char *opt = gf_cfg_get_key_name(m_user->config, "Playlist", 0);
454 if (!opt) break;
455 gf_cfg_set_key(m_user->config, "Playlist", opt, NULL);
456 #endif
457 }
458 RefreshPlaylist();
459 return;
460 } else if (act == Osmo4PLToggleMode) {
461 playlist_mode = !playlist_mode;
462 RefreshPlaylist();
463 return;
464 } else if (act == Osmo4PLToggleAllFiles) {
465 view_all_files = !view_all_files;
466 RefreshPlaylist();
467 return;
468 } else if (act == Osmo4PLAdd) {
469 #ifndef GPAC_GUI_ONLY
470 GetSelectionName(szName);
471 if ((szName[0] == '+') && (szName[1] == ' ')) {
472 if ((szName[2] != '.') && (szName[3] != '.')) {
473 sprintf(szURL, "%s\\%s", szCurrentDir, szName+2);
474 gf_enum_directory(szURL, 0, dir_add_files, this, view_all_files ? NULL : ext_list);
475 }
476 } else if (szName[1] == ':') {
477 gf_enum_directory(szName, 0, dir_add_files, this, view_all_files ? NULL : ext_list);
478 } else {
479 sprintf(szURL, "%s\\%s", szCurrentDir, szName);
480 gf_cfg_set_key(m_user->config, "Playlist", szURL, "");
481 }
482 #endif
483 return;
484 }
485
486 GetSelectionName(szName);
487 if ((szName[0] == '+') && (szName[1] == ' ')) return;
488 else if (szName[1] == ':') return;
489
490 switch (act) {
491 /*remove from playlist*/
492 case Osmo4PLRem:
493 #ifndef GPAC_GUI_ONLY
494 sprintf(szURL, "%s\\%s", szCurrentDir, szName);
495 gf_cfg_set_key(m_user->config, "Playlist", szURL, NULL);
496 #endif
497 RefreshPlaylist();
498 break;
499 /*move up*/
500 case Osmo4PLMoveUp:
501 array = static_cast<CDesCArray*>(iListBox->Model()->ItemTextArray());
502 count = array->Count();
503 idx = iListBox->CurrentItemIndex();
504 sprintf(szURL, "%s\\%s", szCurrentDir, szName);
505 #ifndef GPAC_GUI_ONLY
506 gf_cfg_set_key(m_user->config, "Playlist", szURL, NULL);
507 gf_cfg_insert_key(m_user->config, "Playlist", szURL, "", idx-1);
508 #endif
509 RefreshPlaylist();
510 if (idx>1) iListBox->SetCurrentItemIndexAndDraw(idx-1);
511 break;
512 /*move down*/
513 case Osmo4PLMoveDown:
514 array = static_cast<CDesCArray*>(iListBox->Model()->ItemTextArray());
515 count = array->Count();
516 idx = iListBox->CurrentItemIndex();
517 sprintf(szURL, "%s\\%s", szCurrentDir, szName);
518 #ifndef GPAC_GUI_ONLY
519 gf_cfg_set_key(m_user->config, "Playlist", szURL, NULL);
520 gf_cfg_insert_key(m_user->config, "Playlist", szURL, "", idx+1);
521 #endif
522 RefreshPlaylist();
523 if (idx<count-1) iListBox->SetCurrentItemIndexAndDraw(idx+1);
524 break;
525 default:
526 break;
527 }
528 }
529
530