2 * Copyright (C) 2005-2008 Team XBMC
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)
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.
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
23 #include "GUIWindowPictures.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"
42 #define CONTROL_BTNVIEWASICONS 2
43 #define CONTROL_BTNSORTBY 3
44 #define CONTROL_BTNSORTASC 4
45 #define CONTROL_LABELFILES 12
48 using namespace XFILE;
49 using namespace PLAYLIST;
51 #define CONTROL_BTNSLIDESHOW 6
52 #define CONTROL_BTNSLIDESHOW_RECURSIVE 7
53 #define CONTROL_SHUFFLE 9
55 CGUIWindowPictures::CGUIWindowPictures(void)
56 : CGUIMediaWindow(WINDOW_PICTURES, "MyPics.xml")
58 m_thumbLoader.SetObserver(this);
61 CGUIWindowPictures::~CGUIWindowPictures(void)
65 bool CGUIWindowPictures::OnMessage(CGUIMessage& message)
67 switch ( message.GetMessage() )
69 case GUI_MSG_WINDOW_DEINIT:
71 if (m_thumbLoader.IsLoading())
72 m_thumbLoader.StopThread();
74 if (message.GetParam1() != WINDOW_SLIDESHOW)
81 case GUI_MSG_WINDOW_INIT:
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);
87 m_dlgProgress = (CGUIDialogProgress*)g_windowManager.GetWindow(WINDOW_DIALOG_PROGRESS);
89 if (message.GetParam1() != WINDOW_SLIDESHOW)
94 if (!CGUIMediaWindow::OnMessage(message))
101 case GUI_MSG_CLICKED:
103 int iControl = message.GetSenderId();
104 if (iControl == CONTROL_BTNSLIDESHOW) // Slide Show
108 else if (iControl == CONTROL_BTNSLIDESHOW_RECURSIVE) // Recursive Slide Show
110 OnSlideShowRecursive();
112 else if (iControl == CONTROL_SHUFFLE)
114 g_guiSettings.ToggleBool("slideshow.shuffle");
117 else if (m_viewControl.HasControl(iControl)) // list/thumb control
119 int iItem = m_viewControl.GetSelectedItem();
120 int iAction = message.GetParam1();
122 // iItem is checked for validity inside these routines
123 if (iAction == ACTION_DELETE_ITEM)
125 // is delete allowed?
126 if (g_guiSettings.GetBool("filelists.allowfiledeletion"))
131 else if (iAction == ACTION_PLAYER_PLAY)
133 ShowPicture(iItem, true);
136 else if (iAction == ACTION_SHOW_INFO)
145 return CGUIMediaWindow::OnMessage(message);
148 void CGUIWindowPictures::UpdateButtons()
150 CGUIMediaWindow::UpdateButtons();
152 // Update the shuffle button
153 if (g_guiSettings.GetBool("slideshow.shuffle"))
155 CGUIMessage msg2(GUI_MSG_SELECTED, GetID(), CONTROL_SHUFFLE);
156 g_windowManager.SendMessage(msg2);
160 CGUIMessage msg2(GUI_MSG_DESELECTED, GetID(), CONTROL_SHUFFLE);
161 g_windowManager.SendMessage(msg2);
164 // check we can slideshow or recursive slideshow
165 int nFolders = m_vecItems->GetFolderCount();
166 if (nFolders == m_vecItems->Size())
168 CONTROL_DISABLE(CONTROL_BTNSLIDESHOW);
172 CONTROL_ENABLE(CONTROL_BTNSLIDESHOW);
174 if (m_guiState.get() && !m_guiState->HideParentDirItems())
176 if (m_vecItems->Size() == 0 || nFolders == 0)
178 CONTROL_DISABLE(CONTROL_BTNSLIDESHOW_RECURSIVE);
182 CONTROL_ENABLE(CONTROL_BTNSLIDESHOW_RECURSIVE);
186 void CGUIWindowPictures::OnPrepareFileItems(CFileItemList& items)
188 for (int i=0;i<items.Size();++i )
189 if (items[i]->GetLabel().Equals("folder.jpg"))
192 if (items.GetFolderCount()==items.Size() || !g_guiSettings.GetBool("pictures.usetags"))
195 // Start the music info loader thread
196 CPictureInfoLoader loader;
197 loader.SetProgressCallback(m_dlgProgress);
200 bool bShowProgress=!g_windowManager.HasModalDialog();
201 bool bProgressVisible=false;
203 unsigned int tick=CTimeUtils::GetTimeMS();
205 while (loader.IsLoading() && m_dlgProgress && !m_dlgProgress->IsCanceled())
208 { // Do we have to init a progress dialog?
209 unsigned int elapsed=CTimeUtils::GetTimeMS()-tick;
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);
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;
224 if (bProgressVisible && m_dlgProgress)
226 m_dlgProgress->Progress();
228 } // if (bShowProgress)
230 } // while (loader.IsLoading())
232 if (bProgressVisible && m_dlgProgress)
233 m_dlgProgress->Close();
236 bool CGUIWindowPictures::Update(const CStdString &strDirectory)
238 if (m_thumbLoader.IsLoading())
239 m_thumbLoader.StopThread();
241 if (!CGUIMediaWindow::Update(strDirectory))
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));
252 bool CGUIWindowPictures::OnClick(int iItem)
254 if ( iItem < 0 || iItem >= (int)m_vecItems->Size() ) return true;
255 CFileItemPtr pItem = m_vecItems->Get(iItem);
257 if (pItem->IsCBZ() || pItem->IsCBR())
259 CStdString strComicPath;
261 URIUtils::CreateArchivePath(strComicPath, "zip", pItem->m_strPath, "");
263 URIUtils::CreateArchivePath(strComicPath, "rar", pItem->m_strPath, "");
265 OnShowPictureRecursive(strComicPath);
268 else if (CGUIMediaWindow::OnClick(iItem))
274 bool CGUIWindowPictures::GetDirectory(const CStdString &strDirectory, CFileItemList& items)
276 if (!CGUIMediaWindow::GetDirectory(strDirectory, items))
280 if (items.GetLabel().IsEmpty() && m_rootDir.IsSource(items.m_strPath, g_settings.GetSourcesFromType("pictures"), &label))
281 items.SetLabel(label);
286 bool CGUIWindowPictures::OnPlayMedia(int iItem)
288 if (m_vecItems->Get(iItem)->IsVideo())
289 return CGUIMediaWindow::OnPlayMedia(iItem);
291 return ShowPicture(iItem, false);
294 bool CGUIWindowPictures::ShowPicture(int iItem, bool startSlideShow)
296 if ( iItem < 0 || iItem >= (int)m_vecItems->Size() ) return false;
297 CFileItemPtr pItem = m_vecItems->Get(iItem);
298 CStdString strPicture = pItem->m_strPath;
302 return MEDIA_DETECT::CAutorun::PlayDisc();
305 if (pItem->m_bIsShareOrDrive)
308 CGUIWindowSlideShow *pSlideShow = (CGUIWindowSlideShow *)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
311 if (g_application.IsPlayingVideo())
312 g_application.StopPlaying();
315 for (int i = 0; i < (int)m_vecItems->Size();++i)
317 CFileItemPtr pItem = m_vecItems->Get(i);
318 if (!pItem->m_bIsFolder && !(URIUtils::IsRAR(pItem->m_strPath) || URIUtils::IsZIP(pItem->m_strPath)) && pItem->IsPicture())
320 pSlideShow->Add(pItem.get());
324 if (pSlideShow->NumSlides() == 0)
327 pSlideShow->Select(strPicture);
330 pSlideShow->StartSlideShow(false);
332 g_windowManager.ActivateWindow(WINDOW_SLIDESHOW);
337 void CGUIWindowPictures::OnShowPictureRecursive(const CStdString& strPath)
339 CGUIWindowSlideShow *pSlideShow = (CGUIWindowSlideShow *)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
343 if (g_application.IsPlayingVideo())
344 g_application.StopPlaying();
345 pSlideShow->AddFromPath(strPath, true,
346 m_guiState->GetSortMethod(),
347 m_guiState->GetSortOrder());
348 if (pSlideShow->NumSlides())
349 g_windowManager.ActivateWindow(WINDOW_SLIDESHOW);
353 void CGUIWindowPictures::OnSlideShowRecursive(const CStdString &strPicture)
355 CGUIWindowSlideShow *pSlideShow = (CGUIWindowSlideShow *)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
358 CStdString strExtensions;
360 CGUIViewState* viewState=CGUIViewState::GetViewState(GetID(), items);
363 strExtensions = viewState->GetExtensions();
366 pSlideShow->RunSlideShow(strPicture, true,
367 g_guiSettings.GetBool("slideshow.shuffle"),false,
368 m_guiState->GetSortMethod(),
369 m_guiState->GetSortOrder(),
374 void CGUIWindowPictures::OnSlideShowRecursive()
376 CStdString strEmpty = "";
377 OnSlideShowRecursive(m_vecItems->m_strPath);
380 void CGUIWindowPictures::OnSlideShow()
382 OnSlideShow(m_vecItems->m_strPath);
385 void CGUIWindowPictures::OnSlideShow(const CStdString &strPicture)
387 CGUIWindowSlideShow *pSlideShow = (CGUIWindowSlideShow *)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
390 CStdString strExtensions;
392 CGUIViewState* viewState=CGUIViewState::GetViewState(GetID(), items);
395 strExtensions = viewState->GetExtensions();
398 pSlideShow->RunSlideShow(strPicture, false ,false, false,
399 m_guiState->GetSortMethod(),
400 m_guiState->GetSortOrder(),
405 void CGUIWindowPictures::OnRegenerateThumbs()
407 if (m_thumbLoader.IsLoading()) return;
408 m_thumbLoader.SetRegenerateThumbs(true);
409 m_thumbLoader.Load(*m_vecItems);
412 void CGUIWindowPictures::GetContextButtons(int itemNumber, CContextButtons &buttons)
415 if (itemNumber >= 0 && itemNumber < m_vecItems->Size())
416 item = m_vecItems->Get(itemNumber);
418 if (item && !item->GetPropertyBOOL("pluginreplacecontextitems"))
420 if ( m_vecItems->IsVirtualDirectoryRoot() && item)
422 CGUIDialogContextMenu::GetContextButtons("pictures", item, buttons);
428 if (!(item->m_bIsFolder || item->IsZIP() || item->IsRAR() || item->IsCBZ() || item->IsCBR()))
429 buttons.Add(CONTEXT_BUTTON_INFO, 13406); // picture info
430 buttons.Add(CONTEXT_BUTTON_VIEW_SLIDESHOW, item->m_bIsFolder ? 13317 : 13422); // View Slideshow
431 if (item->m_bIsFolder)
432 buttons.Add(CONTEXT_BUTTON_RECURSIVE_SLIDESHOW, 13318); // Recursive Slideshow
434 if (!m_thumbLoader.IsLoading())
435 buttons.Add(CONTEXT_BUTTON_REFRESH_THUMBS, 13315); // Create Thumbnails
436 if (g_guiSettings.GetBool("filelists.allowfiledeletion") && !item->IsReadOnly())
438 buttons.Add(CONTEXT_BUTTON_DELETE, 117);
439 buttons.Add(CONTEXT_BUTTON_RENAME, 118);
443 if (item->IsPlugin() || item->m_strPath.Left(9).Equals("script://") || m_vecItems->IsPlugin())
444 buttons.Add(CONTEXT_BUTTON_PLUGIN_SETTINGS, 1045);
446 buttons.Add(CONTEXT_BUTTON_GOTO_ROOT, 20128);
447 buttons.Add(CONTEXT_BUTTON_SWITCH_MEDIA, 523);
450 CGUIMediaWindow::GetContextButtons(itemNumber, buttons);
451 if (item && !item->GetPropertyBOOL("pluginreplacecontextitems"))
452 buttons.Add(CONTEXT_BUTTON_SETTINGS, 5); // Settings
455 bool CGUIWindowPictures::OnContextButton(int itemNumber, CONTEXT_BUTTON button)
457 CFileItemPtr item = (itemNumber >= 0 && itemNumber < m_vecItems->Size()) ? m_vecItems->Get(itemNumber) : CFileItemPtr();
458 if (m_vecItems->IsVirtualDirectoryRoot() && item)
460 if (CGUIDialogContextMenu::OnContextButton("pictures", item, button))
468 case CONTEXT_BUTTON_VIEW_SLIDESHOW:
469 if (item && item->m_bIsFolder)
470 OnSlideShow(item->m_strPath);
472 ShowPicture(itemNumber, true);
474 case CONTEXT_BUTTON_RECURSIVE_SLIDESHOW:
476 OnSlideShowRecursive(item->m_strPath);
478 case CONTEXT_BUTTON_INFO:
481 case CONTEXT_BUTTON_REFRESH_THUMBS:
482 OnRegenerateThumbs();
484 case CONTEXT_BUTTON_DELETE:
485 OnDeleteItem(itemNumber);
487 case CONTEXT_BUTTON_RENAME:
488 OnRenameItem(itemNumber);
490 case CONTEXT_BUTTON_SETTINGS:
491 g_windowManager.ActivateWindow(WINDOW_SETTINGS_MYPICTURES);
493 case CONTEXT_BUTTON_GOTO_ROOT:
496 case CONTEXT_BUTTON_SWITCH_MEDIA:
497 CGUIDialogContextMenu::SwitchMedia("pictures", m_vecItems->m_strPath);
502 return CGUIMediaWindow::OnContextButton(itemNumber, button);
505 void CGUIWindowPictures::OnItemLoaded(CFileItem *pItem)
507 CPictureThumbLoader::ProcessFoldersAndArchives(pItem);
510 void CGUIWindowPictures::LoadPlayList(const CStdString& strPlayList)
512 CLog::Log(LOGDEBUG,"CGUIWindowPictures::LoadPlayList()... converting playlist into slideshow: %s", strPlayList.c_str());
513 auto_ptr<CPlayList> pPlayList (CPlayListFactory::Create(strPlayList));
514 if ( NULL != pPlayList.get())
516 if (!pPlayList->Load(strPlayList))
518 CGUIDialogOK::ShowAndGetInput(6, 0, 477, 0);
519 return ; //hmmm unable to load playlist?
523 CPlayList playlist = *pPlayList;
524 if (playlist.size() > 0)
527 CGUIWindowSlideShow *pSlideShow = (CGUIWindowSlideShow *)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
530 if (g_application.IsPlayingVideo())
531 g_application.StopPlaying();
533 // convert playlist items into slideshow items
535 for (int i = 0; i < (int)playlist.size(); ++i)
537 CFileItemPtr pItem = playlist[i];
538 //CLog::Log(LOGDEBUG,"-- playlist item: %s", pItem->m_strPath.c_str());
539 if (pItem->IsPicture() && !(pItem->IsZIP() || pItem->IsRAR() || pItem->IsCBZ() || pItem->IsCBR()))
540 pSlideShow->Add(pItem.get());
543 // start slideshow if there are items
544 pSlideShow->StartSlideShow();
545 if (pSlideShow->NumSlides())
546 g_windowManager.ActivateWindow(WINDOW_SLIDESHOW);
550 void CGUIWindowPictures::OnInfo(int itemNumber)
552 CFileItemPtr item = (itemNumber >= 0 && itemNumber < m_vecItems->Size()) ? m_vecItems->Get(itemNumber) : CFileItemPtr();
553 if (!item || item->m_bIsFolder || item->IsZIP() || item->IsRAR() || item->IsCBZ() || item->IsCBR() || !item->IsPicture())
555 CGUIDialogPictureInfo *pictureInfo = (CGUIDialogPictureInfo *)g_windowManager.GetWindow(WINDOW_DIALOG_PICTURE_INFO);
558 pictureInfo->SetPicture(item.get());
559 pictureInfo->DoModal();
563 CStdString CGUIWindowPictures::GetStartFolder(const CStdString &dir)
565 if (dir.Equals("Plugins") || dir.Equals("Addons"))
566 return "addons://sources/image/";
570 m_rootDir.GetSources(shares);
571 bool bIsSourceName = false;
572 int iIndex = CUtil::GetMatchingSource(dir, shares, bIsSourceName);
575 if (iIndex < (int)shares.size() && shares[iIndex].m_iHasLock == 2)
577 CFileItem item(shares[iIndex]);
578 if (!g_passwordManager.IsItemUnlocked(&item,"pictures"))
582 return shares[iIndex].strPath;
585 return CGUIMediaWindow::GetStartFolder(dir);