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