FIX: Properly handle Pictures Play/Stop notif (fixes #13501; fixes #13503)
[vuplus_xbmc] / xbmc / pictures / GUIWindowPictures.cpp
1 /*
2  *      Copyright (C) 2005-2012 Team XBMC
3  *      http://www.xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20
21 #include "threads/SystemClock.h"
22 #include "system.h"
23 #include "GUIWindowPictures.h"
24 #include "URL.h"
25 #include "Util.h"
26 #include "Application.h"
27 #include "GUIPassword.h"
28 #include "dialogs/GUIDialogMediaSource.h"
29 #include "GUIDialogPictureInfo.h"
30 #include "addons/GUIDialogAddonInfo.h"
31 #include "dialogs/GUIDialogProgress.h"
32 #include "playlists/PlayListFactory.h"
33 #include "PictureInfoLoader.h"
34 #include "guilib/GUIWindowManager.h"
35 #include "dialogs/GUIDialogOK.h"
36 #include "dialogs/GUIDialogYesNo.h"
37 #include "playlists/PlayList.h"
38 #include "settings/Settings.h"
39 #include "settings/GUISettings.h"
40 #include "utils/TimeUtils.h"
41 #include "utils/log.h"
42 #include "utils/URIUtils.h"
43 #include "Autorun.h"
44 #include "interfaces/AnnouncementManager.h"
45
46 #define CONTROL_BTNVIEWASICONS      2
47 #define CONTROL_BTNSORTBY           3
48 #define CONTROL_BTNSORTASC          4
49 #define CONTROL_LABELFILES         12
50
51 using namespace std;
52 using namespace XFILE;
53 using namespace PLAYLIST;
54
55 #define CONTROL_BTNSLIDESHOW   6
56 #define CONTROL_BTNSLIDESHOW_RECURSIVE   7
57 #define CONTROL_SHUFFLE      9
58
59 CGUIWindowPictures::CGUIWindowPictures(void)
60     : CGUIMediaWindow(WINDOW_PICTURES, "MyPics.xml")
61 {
62   m_thumbLoader.SetObserver(this);
63   m_slideShowStarted = false;
64 }
65
66 void CGUIWindowPictures::OnInitWindow()
67 {
68   CGUIMediaWindow::OnInitWindow();
69   if (m_slideShowStarted)
70   {
71     CGUIWindowSlideShow* wndw = (CGUIWindowSlideShow*)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
72     CStdString path;
73     if (wndw && wndw->GetCurrentSlide())
74       URIUtils::GetDirectory(wndw->GetCurrentSlide()->GetPath(),path);
75     if (path.Equals(m_vecItems->GetPath()))
76     {
77       if (wndw && wndw->GetCurrentSlide())
78         m_viewControl.SetSelectedItem(wndw->GetCurrentSlide()->GetPath());
79       m_iSelectedItem = m_viewControl.GetSelectedItem();
80     }
81     m_slideShowStarted = false;
82   }
83 }
84
85 CGUIWindowPictures::~CGUIWindowPictures(void)
86 {
87 }
88
89 bool CGUIWindowPictures::OnMessage(CGUIMessage& message)
90 {
91   switch ( message.GetMessage() )
92   {
93   case GUI_MSG_WINDOW_DEINIT:
94     {
95       if (m_thumbLoader.IsLoading())
96         m_thumbLoader.StopThread();
97
98       if (message.GetParam1() != WINDOW_SLIDESHOW)
99       {
100         m_ImageLib.Unload();
101       }
102     }
103     break;
104
105   case GUI_MSG_WINDOW_INIT:
106     {
107       // is this the first time accessing this window?
108       if (m_vecItems->GetPath() == "?" && message.GetStringParam().IsEmpty())
109         message.SetStringParam(g_settings.m_defaultPictureSource);
110
111       m_dlgProgress = (CGUIDialogProgress*)g_windowManager.GetWindow(WINDOW_DIALOG_PROGRESS);
112
113       if (message.GetParam1() != WINDOW_SLIDESHOW)
114       {
115         m_ImageLib.Load();
116       }
117
118       if (!CGUIMediaWindow::OnMessage(message))
119         return false;
120
121       return true;
122     }
123     break;
124
125   case GUI_MSG_CLICKED:
126     {
127       int iControl = message.GetSenderId();
128       if (iControl == CONTROL_BTNSLIDESHOW) // Slide Show
129       {
130         OnSlideShow();
131       }
132       else if (iControl == CONTROL_BTNSLIDESHOW_RECURSIVE) // Recursive Slide Show
133       {
134         OnSlideShowRecursive();
135       }
136       else if (iControl == CONTROL_SHUFFLE)
137       {
138         g_guiSettings.ToggleBool("slideshow.shuffle");
139         g_settings.Save();
140       }
141       else if (m_viewControl.HasControl(iControl))  // list/thumb control
142       {
143         int iItem = m_viewControl.GetSelectedItem();
144         int iAction = message.GetParam1();
145
146         // iItem is checked for validity inside these routines
147         if (iAction == ACTION_DELETE_ITEM)
148         {
149           // is delete allowed?
150           if (g_guiSettings.GetBool("filelists.allowfiledeletion"))
151             OnDeleteItem(iItem);
152           else
153             return false;
154         }
155         else if (iAction == ACTION_PLAYER_PLAY)
156         {
157           ShowPicture(iItem, true);
158           return true;
159         }
160         else if (iAction == ACTION_SHOW_INFO)
161         {
162           OnInfo(iItem);
163           return true;
164         }
165       }
166     }
167     break;
168   }
169   return CGUIMediaWindow::OnMessage(message);
170 }
171
172 void CGUIWindowPictures::UpdateButtons()
173 {
174   CGUIMediaWindow::UpdateButtons();
175
176   // Update the shuffle button
177   if (g_guiSettings.GetBool("slideshow.shuffle"))
178   {
179     CGUIMessage msg2(GUI_MSG_SELECTED, GetID(), CONTROL_SHUFFLE);
180     g_windowManager.SendMessage(msg2);
181   }
182   else
183   {
184     CGUIMessage msg2(GUI_MSG_DESELECTED, GetID(), CONTROL_SHUFFLE);
185     g_windowManager.SendMessage(msg2);
186   }
187
188   // check we can slideshow or recursive slideshow
189   int nFolders = m_vecItems->GetFolderCount();
190   if (nFolders == m_vecItems->Size())
191   {
192     CONTROL_DISABLE(CONTROL_BTNSLIDESHOW);
193   }
194   else
195   {
196     CONTROL_ENABLE(CONTROL_BTNSLIDESHOW);
197   }
198   if (m_guiState.get() && !m_guiState->HideParentDirItems())
199     nFolders--;
200   if (m_vecItems->Size() == 0 || nFolders == 0)
201   {
202     CONTROL_DISABLE(CONTROL_BTNSLIDESHOW_RECURSIVE);
203   }
204   else
205   {
206     CONTROL_ENABLE(CONTROL_BTNSLIDESHOW_RECURSIVE);
207   }
208 }
209
210 void CGUIWindowPictures::OnPrepareFileItems(CFileItemList& items)
211 {
212   for (int i=0;i<items.Size();++i )
213     if (items[i]->GetLabel().Equals("folder.jpg"))
214       items.Remove(i);
215
216   if (items.GetFolderCount()==items.Size() || !g_guiSettings.GetBool("pictures.usetags"))
217     return;
218
219   // Start the music info loader thread
220   CPictureInfoLoader loader;
221   loader.SetProgressCallback(m_dlgProgress);
222   loader.Load(items);
223
224   bool bShowProgress=!g_windowManager.HasModalDialog();
225   bool bProgressVisible=false;
226
227   unsigned int tick=XbmcThreads::SystemClockMillis();
228
229   while (loader.IsLoading() && m_dlgProgress && !m_dlgProgress->IsCanceled())
230   {
231     if (bShowProgress)
232     { // Do we have to init a progress dialog?
233       unsigned int elapsed=XbmcThreads::SystemClockMillis()-tick;
234
235       if (!bProgressVisible && elapsed>1500 && m_dlgProgress)
236       { // tag loading takes more then 1.5 secs, show a progress dialog
237         CURL url(items.GetPath());
238
239         m_dlgProgress->SetHeading(189);
240         m_dlgProgress->SetLine(0, 505);
241         m_dlgProgress->SetLine(1, "");
242         m_dlgProgress->SetLine(2, url.GetWithoutUserDetails());
243         m_dlgProgress->StartModal();
244         m_dlgProgress->ShowProgressBar(true);
245         bProgressVisible = true;
246       }
247
248       if (bProgressVisible && m_dlgProgress)
249       { // keep GUI alive
250         m_dlgProgress->Progress();
251       }
252     } // if (bShowProgress)
253     Sleep(1);
254   } // while (loader.IsLoading())
255
256   if (bProgressVisible && m_dlgProgress)
257     m_dlgProgress->Close();
258 }
259
260 bool CGUIWindowPictures::Update(const CStdString &strDirectory, bool updateFilterPath /* = true */)
261 {
262   if (m_thumbLoader.IsLoading())
263     m_thumbLoader.StopThread();
264
265   if (!CGUIMediaWindow::Update(strDirectory, updateFilterPath))
266     return false;
267
268   m_vecItems->SetArt("thumb", "");
269   if (g_guiSettings.GetBool("pictures.generatethumbs"))
270     m_thumbLoader.Load(*m_vecItems);
271   m_vecItems->SetArt("thumb", CPictureThumbLoader::GetCachedImage(*m_vecItems, "thumb"));
272
273   return true;
274 }
275
276 bool CGUIWindowPictures::OnClick(int iItem)
277 {
278   if ( iItem < 0 || iItem >= (int)m_vecItems->Size() ) return true;
279   CFileItemPtr pItem = m_vecItems->Get(iItem);
280
281   if (pItem->IsCBZ() || pItem->IsCBR())
282   {
283     CStdString strComicPath;
284     if (pItem->IsCBZ())
285       URIUtils::CreateArchivePath(strComicPath, "zip", pItem->GetPath(), "");
286     else
287       URIUtils::CreateArchivePath(strComicPath, "rar", pItem->GetPath(), "");
288
289     OnShowPictureRecursive(strComicPath);
290     return true;
291   }
292   else if (CGUIMediaWindow::OnClick(iItem))
293     return true;
294
295   return false;
296 }
297
298 bool CGUIWindowPictures::GetDirectory(const CStdString &strDirectory, CFileItemList& items)
299 {
300   if (!CGUIMediaWindow::GetDirectory(strDirectory, items))
301     return false;
302
303   CStdString label;
304   if (items.GetLabel().IsEmpty() && m_rootDir.IsSource(items.GetPath(), g_settings.GetSourcesFromType("pictures"), &label)) 
305     items.SetLabel(label);
306
307   return true;
308 }
309
310 bool CGUIWindowPictures::OnPlayMedia(int iItem)
311 {
312   if (m_vecItems->Get(iItem)->IsVideo())
313     return CGUIMediaWindow::OnPlayMedia(iItem);
314
315   return ShowPicture(iItem, false);
316 }
317
318 bool CGUIWindowPictures::ShowPicture(int iItem, bool startSlideShow)
319 {
320   if ( iItem < 0 || iItem >= (int)m_vecItems->Size() ) return false;
321   CFileItemPtr pItem = m_vecItems->Get(iItem);
322   CStdString strPicture = pItem->GetPath();
323
324 #ifdef HAS_DVD_DRIVE
325   if (pItem->IsDVD())
326     return MEDIA_DETECT::CAutorun::PlayDiscAskResume(m_vecItems->Get(iItem)->GetPath());
327 #endif
328
329   if (pItem->m_bIsShareOrDrive)
330     return false;
331
332   CGUIWindowSlideShow *pSlideShow = (CGUIWindowSlideShow *)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
333   if (!pSlideShow)
334     return false;
335   if (g_application.IsPlayingVideo())
336     g_application.StopPlaying();
337
338   pSlideShow->Reset();
339   for (int i = 0; i < (int)m_vecItems->Size();++i)
340   {
341     CFileItemPtr pItem = m_vecItems->Get(i);
342     if (!pItem->m_bIsFolder && !(URIUtils::IsRAR(pItem->GetPath()) || 
343           URIUtils::IsZIP(pItem->GetPath())) && (pItem->IsPicture() || (
344                                 g_guiSettings.GetBool("pictures.showvideos") &&
345                                 pItem->IsVideo())))
346     {
347       pSlideShow->Add(pItem.get());
348     }
349   }
350
351   if (pSlideShow->NumSlides() == 0)
352     return false;
353
354   pSlideShow->Select(strPicture);
355
356   if (startSlideShow)
357     pSlideShow->StartSlideShow(false);
358   else 
359   {
360     CVariant param;
361     param["player"]["speed"] = 1;
362     param["player"]["playerid"] = PLAYLIST_PICTURE;
363     ANNOUNCEMENT::CAnnouncementManager::Announce(ANNOUNCEMENT::Player, "xbmc", "OnPlay", pSlideShow->GetCurrentSlide(), param);
364   }
365
366   m_slideShowStarted = true;
367   g_windowManager.ActivateWindow(WINDOW_SLIDESHOW);
368
369   return true;
370 }
371
372 void CGUIWindowPictures::OnShowPictureRecursive(const CStdString& strPath)
373 {
374   CGUIWindowSlideShow *pSlideShow = (CGUIWindowSlideShow *)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
375   if (pSlideShow)
376   {
377     // stop any video
378     if (g_application.IsPlayingVideo())
379       g_application.StopPlaying();
380     pSlideShow->AddFromPath(strPath, true,
381                             m_guiState->GetSortMethod(),
382                             m_guiState->GetSortOrder());
383     if (pSlideShow->NumSlides())
384     {
385       m_slideShowStarted = true;
386       g_windowManager.ActivateWindow(WINDOW_SLIDESHOW);
387     }
388   }
389 }
390
391 void CGUIWindowPictures::OnSlideShowRecursive(const CStdString &strPicture)
392 {
393   CGUIWindowSlideShow *pSlideShow = (CGUIWindowSlideShow *)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
394   if (pSlideShow)
395   {   
396     CStdString strExtensions;
397     CFileItemList items;
398     CGUIViewState* viewState=CGUIViewState::GetViewState(GetID(), items);
399     if (viewState)
400     {
401       strExtensions = viewState->GetExtensions();
402       delete viewState;
403     }
404     m_slideShowStarted = true;
405     pSlideShow->RunSlideShow(strPicture, true,
406                              g_guiSettings.GetBool("slideshow.shuffle"),false,
407                              m_guiState->GetSortMethod(),
408                              m_guiState->GetSortOrder(),
409                              strExtensions);
410   }
411 }
412
413 void CGUIWindowPictures::OnSlideShowRecursive()
414 {
415   CStdString strEmpty = "";
416   OnSlideShowRecursive(m_vecItems->GetPath());
417 }
418
419 void CGUIWindowPictures::OnSlideShow()
420 {
421   OnSlideShow(m_vecItems->GetPath());
422 }
423
424 void CGUIWindowPictures::OnSlideShow(const CStdString &strPicture)
425 {
426   CGUIWindowSlideShow *pSlideShow = (CGUIWindowSlideShow *)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
427   if (pSlideShow)
428   {    
429     CStdString strExtensions;
430     CFileItemList items;
431     CGUIViewState* viewState=CGUIViewState::GetViewState(GetID(), items);
432     if (viewState)
433     {
434       strExtensions = viewState->GetExtensions();
435       delete viewState;
436     }
437     m_slideShowStarted = true;
438     pSlideShow->RunSlideShow(strPicture, false ,false, false,
439                              m_guiState->GetSortMethod(),
440                              m_guiState->GetSortOrder(),
441                              strExtensions);
442   }
443 }
444
445 void CGUIWindowPictures::OnRegenerateThumbs()
446 {
447   if (m_thumbLoader.IsLoading()) return;
448   m_thumbLoader.SetRegenerateThumbs(true);
449   m_thumbLoader.Load(*m_vecItems);
450 }
451
452 void CGUIWindowPictures::GetContextButtons(int itemNumber, CContextButtons &buttons)
453 {
454   CFileItemPtr item;
455   if (itemNumber >= 0 && itemNumber < m_vecItems->Size())
456     item = m_vecItems->Get(itemNumber);
457
458   if (item && !item->GetProperty("pluginreplacecontextitems").asBoolean())
459   {
460     if ( m_vecItems->IsVirtualDirectoryRoot() && item)
461     {
462       CGUIDialogContextMenu::GetContextButtons("pictures", item, buttons);
463     }
464     else
465     {
466       if (item && !item->GetPath().Left(14).Equals("addons://more/"))
467       {
468         if (!m_vecItems->IsPlugin() && (item->IsPlugin() || item->IsScript()))
469           buttons.Add(CONTEXT_BUTTON_INFO, 24003); // Add-on info
470         if (!(item->m_bIsFolder || item->IsZIP() || item->IsRAR() || item->IsCBZ() || item->IsCBR() || item->IsScript()))
471         {
472           buttons.Add(CONTEXT_BUTTON_INFO, 13406); // picture info
473           buttons.Add(CONTEXT_BUTTON_VIEW_SLIDESHOW, item->m_bIsFolder ? 13317 : 13422);      // View Slideshow
474         }
475         if (item->m_bIsFolder)
476           buttons.Add(CONTEXT_BUTTON_RECURSIVE_SLIDESHOW, 13318);     // Recursive Slideshow
477
478         if (!m_thumbLoader.IsLoading())
479           buttons.Add(CONTEXT_BUTTON_REFRESH_THUMBS, 13315);         // Create Thumbnails
480         if (g_guiSettings.GetBool("filelists.allowfiledeletion") && !item->IsReadOnly())
481         {
482           buttons.Add(CONTEXT_BUTTON_DELETE, 117);
483           buttons.Add(CONTEXT_BUTTON_RENAME, 118);
484         }
485       }
486
487       if (item->IsPlugin() || item->IsScript() || m_vecItems->IsPlugin())
488         buttons.Add(CONTEXT_BUTTON_PLUGIN_SETTINGS, 1045);
489       else
490       {
491         buttons.Add(CONTEXT_BUTTON_GOTO_ROOT, 20128);
492         buttons.Add(CONTEXT_BUTTON_SWITCH_MEDIA, 523);
493       }
494     }
495   }
496   CGUIMediaWindow::GetContextButtons(itemNumber, buttons);
497   if (item && !item->GetProperty("pluginreplacecontextitems").asBoolean())
498     buttons.Add(CONTEXT_BUTTON_SETTINGS, 5);                  // Settings
499 }
500
501 bool CGUIWindowPictures::OnContextButton(int itemNumber, CONTEXT_BUTTON button)
502 {
503   CFileItemPtr item = (itemNumber >= 0 && itemNumber < m_vecItems->Size()) ? m_vecItems->Get(itemNumber) : CFileItemPtr();
504   if (m_vecItems->IsVirtualDirectoryRoot() && item)
505   {
506     if (CGUIDialogContextMenu::OnContextButton("pictures", item, button))
507     {
508       Update("");
509       return true;
510     }
511   }
512   switch (button)
513   {
514   case CONTEXT_BUTTON_VIEW_SLIDESHOW:
515     if (item && item->m_bIsFolder)
516       OnSlideShow(item->GetPath());
517     else
518       ShowPicture(itemNumber, true);
519     return true;
520   case CONTEXT_BUTTON_RECURSIVE_SLIDESHOW:
521     if (item)
522       OnSlideShowRecursive(item->GetPath());
523     return true;
524   case CONTEXT_BUTTON_INFO:
525     OnInfo(itemNumber);
526     return true;
527   case CONTEXT_BUTTON_REFRESH_THUMBS:
528     OnRegenerateThumbs();
529     return true;
530   case CONTEXT_BUTTON_DELETE:
531     OnDeleteItem(itemNumber);
532     return true;
533   case CONTEXT_BUTTON_RENAME:
534     OnRenameItem(itemNumber);
535     return true;
536   case CONTEXT_BUTTON_SETTINGS:
537     g_windowManager.ActivateWindow(WINDOW_SETTINGS_MYPICTURES);
538     return true;
539   case CONTEXT_BUTTON_GOTO_ROOT:
540     Update("");
541     return true;
542   case CONTEXT_BUTTON_SWITCH_MEDIA:
543     CGUIDialogContextMenu::SwitchMedia("pictures", m_vecItems->GetPath());
544     return true;
545   default:
546     break;
547   }
548   return CGUIMediaWindow::OnContextButton(itemNumber, button);
549 }
550
551 void CGUIWindowPictures::OnItemLoaded(CFileItem *pItem)
552 {
553   CPictureThumbLoader::ProcessFoldersAndArchives(pItem);
554 }
555
556 void CGUIWindowPictures::LoadPlayList(const CStdString& strPlayList)
557 {
558   CLog::Log(LOGDEBUG,"CGUIWindowPictures::LoadPlayList()... converting playlist into slideshow: %s", strPlayList.c_str());
559   auto_ptr<CPlayList> pPlayList (CPlayListFactory::Create(strPlayList));
560   if ( NULL != pPlayList.get())
561   {
562     if (!pPlayList->Load(strPlayList))
563     {
564       CGUIDialogOK::ShowAndGetInput(6, 0, 477, 0);
565       return ; //hmmm unable to load playlist?
566     }
567   }
568
569   CPlayList playlist = *pPlayList;
570   if (playlist.size() > 0)
571   {
572     // set up slideshow
573     CGUIWindowSlideShow *pSlideShow = (CGUIWindowSlideShow *)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
574     if (!pSlideShow)
575       return;
576     if (g_application.IsPlayingVideo())
577       g_application.StopPlaying();
578
579     // convert playlist items into slideshow items
580     pSlideShow->Reset();
581     for (int i = 0; i < (int)playlist.size(); ++i)
582     {
583       CFileItemPtr pItem = playlist[i];
584       //CLog::Log(LOGDEBUG,"-- playlist item: %s", pItem->GetPath().c_str());
585       if (pItem->IsPicture() && !(pItem->IsZIP() || pItem->IsRAR() || pItem->IsCBZ() || pItem->IsCBR()))
586         pSlideShow->Add(pItem.get());
587     }
588
589     // start slideshow if there are items
590     pSlideShow->StartSlideShow();
591     if (pSlideShow->NumSlides())
592       g_windowManager.ActivateWindow(WINDOW_SLIDESHOW);
593   }
594 }
595
596 void CGUIWindowPictures::OnInfo(int itemNumber)
597 {
598   CFileItemPtr item = (itemNumber >= 0 && itemNumber < m_vecItems->Size()) ? m_vecItems->Get(itemNumber) : CFileItemPtr();
599   if (!item)
600     return;
601   if (!m_vecItems->IsPlugin() && (item->IsPlugin() || item->IsScript()))
602   {
603     CGUIDialogAddonInfo::ShowForItem(item);
604     return;
605   }
606   if (item->m_bIsFolder || item->IsZIP() || item->IsRAR() || item->IsCBZ() || item->IsCBR() || !item->IsPicture())
607     return;
608   CGUIDialogPictureInfo *pictureInfo = (CGUIDialogPictureInfo *)g_windowManager.GetWindow(WINDOW_DIALOG_PICTURE_INFO);
609   if (pictureInfo)
610   {
611     pictureInfo->SetPicture(item.get());
612     pictureInfo->DoModal();
613   }
614 }
615
616 CStdString CGUIWindowPictures::GetStartFolder(const CStdString &dir)
617 {
618   if (dir.Equals("Plugins") || dir.Equals("Addons"))
619     return "addons://sources/image/";
620
621   SetupShares();
622   VECSOURCES shares;
623   m_rootDir.GetSources(shares);
624   bool bIsSourceName = false;
625   int iIndex = CUtil::GetMatchingSource(dir, shares, bIsSourceName);
626   if (iIndex > -1)
627   {
628     if (iIndex < (int)shares.size() && shares[iIndex].m_iHasLock == 2)
629     {
630       CFileItem item(shares[iIndex]);
631       if (!g_passwordManager.IsItemUnlocked(&item,"pictures"))
632         return "";
633     }
634     if (bIsSourceName)
635       return shares[iIndex].strPath;
636     return dir;
637   }
638   return CGUIMediaWindow::GetStartFolder(dir);
639 }