2 * Copyright (C) 2005-2013 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, see
17 * <http://www.gnu.org/licenses/>.
21 #include "GUIDialogFileBrowser.h"
23 #include "utils/URIUtils.h"
24 #include "network/GUIDialogNetworkSetup.h"
25 #include "GUIDialogMediaSource.h"
26 #include "GUIDialogContextMenu.h"
27 #include "storage/MediaManager.h"
28 #include "AutoSwitch.h"
29 #include "network/Network.h"
30 #include "GUIPassword.h"
31 #include "guilib/GUIWindowManager.h"
32 #include "Application.h"
33 #include "GUIDialogOK.h"
34 #include "GUIDialogYesNo.h"
35 #include "guilib/GUIKeyboardFactory.h"
36 #include "GUIUserMessages.h"
37 #include "filesystem/Directory.h"
38 #include "filesystem/File.h"
40 #include "filesystem/MultiPathDirectory.h"
41 #include "settings/AdvancedSettings.h"
42 #include "settings/Settings.h"
43 #include "settings/GUISettings.h"
44 #include "guilib/LocalizeStrings.h"
45 #include "utils/log.h"
48 using namespace XFILE;
50 #define CONTROL_LIST 450
51 #define CONTROL_THUMBS 451
52 #define CONTROL_HEADING_LABEL 411
53 #define CONTROL_LABEL_PATH 412
54 #define CONTROL_OK 413
55 #define CONTROL_CANCEL 414
56 #define CONTROL_NEWFOLDER 415
57 #define CONTROL_FLIP 416
59 CGUIDialogFileBrowser::CGUIDialogFileBrowser()
60 : CGUIDialog(WINDOW_DIALOG_FILE_BROWSER, "FileBrowser.xml")
62 m_Directory = new CFileItem;
63 m_vecItems = new CFileItemList;
65 m_Directory->m_bIsFolder = true;
66 m_browsingForFolders = 0;
67 m_browsingForImages = false;
68 m_useFileDirectories = false;
69 m_addNetworkShareEnabled = false;
71 m_thumbLoader.SetObserver(this);
72 m_flipEnabled = false;
73 m_multipleSelection = false;
74 m_loadType = KEEP_IN_MEMORY;
77 CGUIDialogFileBrowser::~CGUIDialogFileBrowser()
83 bool CGUIDialogFileBrowser::OnAction(const CAction &action)
85 if (action.GetID() == ACTION_PARENT_DIR)
90 if ((action.GetID() == ACTION_CONTEXT_MENU || action.GetID() == ACTION_MOUSE_RIGHT_CLICK) && m_Directory->GetPath().IsEmpty())
92 int iItem = m_viewControl.GetSelectedItem();
93 if ((!m_addSourceType.IsEmpty() && iItem != m_vecItems->Size()-1))
94 return OnPopupMenu(iItem);
95 if (m_addNetworkShareEnabled && g_mediaManager.HasLocation(m_selectedPath))
97 // need to make sure this source is not an auto added location
98 // as users locations might have the same paths
99 CFileItemPtr pItem = (*m_vecItems)[iItem];
100 for (unsigned int i=0;i<m_shares.size();++i)
102 if (m_shares[i].strName.Equals(pItem->GetLabel()) && m_shares[i].m_ignore)
106 return OnPopupMenu(iItem);
112 return CGUIDialog::OnAction(action);
115 bool CGUIDialogFileBrowser::OnBack(int actionID)
117 if (actionID == ACTION_NAV_BACK && !m_vecItems->IsVirtualDirectoryRoot())
122 return CGUIDialog::OnBack(actionID);
125 bool CGUIDialogFileBrowser::OnMessage(CGUIMessage& message)
127 switch ( message.GetMessage() )
129 case GUI_MSG_WINDOW_DEINIT:
131 if (m_thumbLoader.IsLoading())
132 m_thumbLoader.StopThread();
133 CGUIDialog::OnMessage(message);
135 m_addNetworkShareEnabled = false;
140 case GUI_MSG_WINDOW_INIT:
142 m_bConfirmed = false;
145 // this code allows two different selection modes for directories
146 // end the path with a slash to start inside the directory
147 if (URIUtils::HasSlashAtEnd(m_selectedPath))
151 int iSource = CUtil::GetMatchingSource(m_selectedPath,m_shares,bFool);
153 if (iSource > -1 && iSource < (int)m_shares.size())
155 if (m_shares[iSource].strPath.Equals(m_selectedPath))
159 if (bFool && !CDirectory::Exists(m_selectedPath))
160 m_selectedPath.Empty();
164 if (!CFile::Exists(m_selectedPath) && !CDirectory::Exists(m_selectedPath))
165 m_selectedPath.Empty();
168 // find the parent folder if we are a file browser (don't do this for folders)
169 m_Directory->SetPath(m_selectedPath);
170 if (!m_browsingForFolders && !bIsDir)
171 m_Directory->SetPath(URIUtils::GetParentPath(m_selectedPath));
172 Update(m_Directory->GetPath());
173 m_viewControl.SetSelectedItem(m_selectedPath);
174 return CGUIDialog::OnMessage(message);
178 case GUI_MSG_CLICKED:
180 if (m_viewControl.HasControl(message.GetSenderId())) // list control
182 int iItem = m_viewControl.GetSelectedItem();
183 int iAction = message.GetParam1();
184 if (iItem < 0) break;
185 if (iAction == ACTION_SELECT_ITEM || iAction == ACTION_MOUSE_LEFT_CLICK)
190 else if (iAction == ACTION_HIGHLIGHT_ITEM && m_multipleSelection)
192 CFileItemPtr pItem = (*m_vecItems)[iItem];
193 if (!pItem->m_bIsShareOrDrive && !pItem->m_bIsFolder)
195 pItem->Select(!pItem->IsSelected());
196 CGUIMessage msg(GUI_MSG_ITEM_SELECT, GetID(), message.GetSenderId(), iItem + 1);
201 else if (message.GetSenderId() == CONTROL_OK)
203 if (m_browsingForFolders == 2)
206 int iItem = m_viewControl.GetSelectedItem();
210 strPath = m_selectedPath;
212 strPath = (*m_vecItems)[iItem]->GetPath();
214 URIUtils::AddFileToFolder(strPath,"1",strTest);
216 if (file.OpenForWrite(strTest,true))
219 CFile::Delete(strTest);
224 CGUIDialogOK::ShowAndGetInput(257,20072,0,0);
228 if (m_multipleSelection)
230 for (int iItem = 0; iItem < m_vecItems->Size(); ++iItem)
232 CFileItemPtr pItem = (*m_vecItems)[iItem];
233 if (pItem->IsSelected())
234 m_markedPath.push_back(pItem->GetPath());
242 else if (message.GetSenderId() == CONTROL_CANCEL)
247 else if (message.GetSenderId() == CONTROL_NEWFOLDER)
250 if (CGUIKeyboardFactory::ShowAndGetInput(strInput,g_localizeStrings.Get(119),false))
253 URIUtils::AddFileToFolder(m_vecItems->GetPath(),strInput,strPath);
254 if (CDirectory::Create(strPath))
255 Update(m_vecItems->GetPath());
257 CGUIDialogOK::ShowAndGetInput(20069,20072,20073,0);
260 else if (message.GetSenderId() == CONTROL_FLIP)
264 case GUI_MSG_SETFOCUS:
266 if (m_viewControl.HasControl(message.GetControlId()) && m_viewControl.GetCurrentControl() != message.GetControlId())
268 m_viewControl.SetFocused();
273 case GUI_MSG_NOTIFY_ALL:
274 { // Message is received only if this window is active
275 if (message.GetParam1() == GUI_MSG_REMOVED_MEDIA)
277 if (m_Directory->IsVirtualDirectoryRoot() && IsActive())
279 int iItem = m_viewControl.GetSelectedItem();
280 Update(m_Directory->GetPath());
281 m_viewControl.SetSelectedItem(iItem);
283 else if (m_Directory->IsRemovable())
284 { // check that we have this removable share still
285 if (!m_rootDir.IsInSource(m_Directory->GetPath()))
286 { // don't have this share any more
287 if (IsActive()) Update("");
290 m_history.ClearPathHistory();
291 m_Directory->SetPath("");
297 else if (message.GetParam1()==GUI_MSG_UPDATE_SOURCES)
298 { // State of the sources changed, so update our view
299 if (m_Directory->IsVirtualDirectoryRoot() && IsActive())
301 int iItem = m_viewControl.GetSelectedItem();
302 Update(m_Directory->GetPath());
303 m_viewControl.SetSelectedItem(iItem);
307 else if (message.GetParam1()==GUI_MSG_UPDATE_PATH)
311 if((message.GetStringParam() == m_Directory->GetPath()) ||
312 (m_Directory->IsMultiPath() && XFILE::CMultiPathDirectory::HasPath(m_Directory->GetPath(), message.GetStringParam())))
314 int iItem = m_viewControl.GetSelectedItem();
315 Update(m_Directory->GetPath());
316 m_viewControl.SetSelectedItem(iItem);
324 return CGUIDialog::OnMessage(message);
327 void CGUIDialogFileBrowser::ClearFileItems()
329 m_viewControl.Clear();
330 m_vecItems->Clear(); // will clean up everything
333 void CGUIDialogFileBrowser::OnSort()
336 m_vecItems->Sort(SORT_METHOD_LABEL, SortOrderAscending);
339 void CGUIDialogFileBrowser::Update(const CStdString &strDirectory)
341 if (m_browsingForImages && m_thumbLoader.IsLoading())
342 m_thumbLoader.StopThread();
344 int iItem = m_viewControl.GetSelectedItem();
345 CStdString strSelectedItem = "";
346 if (iItem >= 0 && iItem < m_vecItems->Size())
348 CFileItemPtr pItem = (*m_vecItems)[iItem];
349 if (!pItem->IsParentFolder())
351 strSelectedItem = pItem->GetPath();
352 URIUtils::RemoveSlashAtEnd(strSelectedItem);
353 m_history.SetSelectedItem(strSelectedItem, m_Directory->GetPath().IsEmpty()?"empty":m_Directory->GetPath());
360 CStdString strParentPath;
362 if (!m_rootDir.GetDirectory(strDirectory, items,m_useFileDirectories))
364 CLog::Log(LOGERROR,"CGUIDialogFileBrowser::GetDirectory(%s) failed", strDirectory.c_str());
366 // We assume, we can get the parent
368 CStdString strParentPath = m_history.GetParentPath();
369 m_history.RemoveParentPath();
370 Update(strParentPath);
374 // check if current directory is a root share
375 if (!m_rootDir.IsSource(strDirectory))
377 if (URIUtils::GetParentPath(strDirectory, strParentPath))
379 CFileItemPtr pItem(new CFileItem(".."));
380 pItem->SetPath(strParentPath);
381 pItem->m_bIsFolder = true;
382 pItem->m_bIsShareOrDrive = false;
383 items.AddFront(pItem, 0);
388 // yes, this is the root of a share
389 // add parent path to the virtual directory
390 CFileItemPtr pItem(new CFileItem(".."));
392 pItem->m_bIsShareOrDrive = false;
393 pItem->m_bIsFolder = true;
394 items.AddFront(pItem, 0);
399 m_vecItems->Copy(items);
400 m_Directory->SetPath(strDirectory);
401 m_strParentPath = strParentPath;
404 // if we're getting the root source listing
405 // make sure the path history is clean
406 if (strDirectory.IsEmpty())
407 m_history.ClearPathHistory();
409 // some evil stuff don't work with the '/' mask, e.g. shoutcast directory - make sure no files are in there
410 if (m_browsingForFolders)
412 for (int i=0;i<m_vecItems->Size();++i)
413 if (!(*m_vecItems)[i]->m_bIsFolder)
415 m_vecItems->Remove(i);
420 // No need to set thumbs
422 m_vecItems->FillInDefaultIcons();
426 if (m_Directory->GetPath().IsEmpty() && m_addNetworkShareEnabled &&
427 (g_settings.GetMasterProfile().getLockMode() == LOCK_MODE_EVERYONE ||
428 g_settings.IsMasterUser() || g_passwordManager.bMasterUser))
429 { // we are in the virtual directory - add the "Add Network Location" item
430 CFileItemPtr pItem(new CFileItem(g_localizeStrings.Get(1032)));
431 pItem->SetPath("net://");
432 pItem->m_bIsFolder = true;
433 m_vecItems->Add(pItem);
435 if (m_Directory->GetPath().IsEmpty() && !m_addSourceType.IsEmpty())
437 CFileItemPtr pItem(new CFileItem(g_localizeStrings.Get(21359)));
438 pItem->SetPath("source://");
439 pItem->m_bIsFolder = true;
440 m_vecItems->Add(pItem);
443 m_viewControl.SetItems(*m_vecItems);
444 m_viewControl.SetCurrentView((m_browsingForImages && CAutoSwitch::ByFileCount(*m_vecItems)) ? DEFAULT_VIEW_ICONS : DEFAULT_VIEW_LIST);
446 CStdString strPath2 = m_Directory->GetPath();
447 URIUtils::RemoveSlashAtEnd(strPath2);
448 strSelectedItem = m_history.GetSelectedItem(strPath2==""?"empty":strPath2);
450 bool bSelectedFound = false;
451 for (int i = 0; i < (int)m_vecItems->Size(); ++i)
453 CFileItemPtr pItem = (*m_vecItems)[i];
454 strPath2 = pItem->GetPath();
455 URIUtils::RemoveSlashAtEnd(strPath2);
456 if (strPath2 == strSelectedItem)
458 m_viewControl.SetSelectedItem(i);
459 bSelectedFound = true;
464 // if we haven't found the selected item, select the first item
466 m_viewControl.SetSelectedItem(0);
468 m_history.AddPath(m_Directory->GetPath());
470 if (m_browsingForImages)
471 m_thumbLoader.Load(*m_vecItems);
474 void CGUIDialogFileBrowser::FrameMove()
476 int item = m_viewControl.GetSelectedItem();
479 // if we are browsing for folders, and not in the root directory, then we use the parent path,
480 // else we use the current file's path
481 if (m_browsingForFolders && !m_Directory->IsVirtualDirectoryRoot())
482 m_selectedPath = m_Directory->GetPath();
484 m_selectedPath = (*m_vecItems)[item]->GetPath();
485 if (m_selectedPath == "net://")
487 SET_CONTROL_LABEL(CONTROL_LABEL_PATH, g_localizeStrings.Get(1032)); // "Add Network Location..."
491 // Update the current path label
492 CURL url(m_selectedPath);
493 CStdString safePath = url.GetWithoutUserDetails();
494 SET_CONTROL_LABEL(CONTROL_LABEL_PATH, safePath);
496 if ((!m_browsingForFolders && (*m_vecItems)[item]->m_bIsFolder) || ((*m_vecItems)[item]->GetPath() == "image://Browse"))
498 CONTROL_DISABLE(CONTROL_OK);
502 CONTROL_ENABLE(CONTROL_OK);
504 if (m_browsingForFolders == 2)
506 CONTROL_ENABLE(CONTROL_NEWFOLDER);
510 CONTROL_DISABLE(CONTROL_NEWFOLDER);
514 CONTROL_ENABLE(CONTROL_FLIP);
518 CONTROL_DISABLE(CONTROL_FLIP);
521 CGUIDialog::FrameMove();
524 void CGUIDialogFileBrowser::OnClick(int iItem)
526 if ( iItem < 0 || iItem >= (int)m_vecItems->Size() ) return ;
527 CFileItemPtr pItem = (*m_vecItems)[iItem];
528 CStdString strPath = pItem->GetPath();
530 if (pItem->m_bIsFolder)
532 if (pItem->GetPath() == "net://")
533 { // special "Add Network Location" item
534 OnAddNetworkLocation();
537 if (pItem->GetPath() == "source://")
538 { // special "Add Source" item
542 if (!m_addSourceType.IsEmpty())
544 OnEditMediaSource(pItem.get());
547 if ( pItem->m_bIsShareOrDrive )
549 if ( !HaveDiscOrConnection( pItem->m_iDriveType ) )
554 else if (!m_browsingForFolders)
556 m_selectedPath = pItem->GetPath();
562 bool CGUIDialogFileBrowser::HaveDiscOrConnection( int iDriveType )
564 if ( iDriveType == CMediaSource::SOURCE_TYPE_DVD )
566 if ( !g_mediaManager.IsDiscInDrive() )
568 CGUIDialogOK::ShowAndGetInput(218, 219, 0, 0);
572 else if ( iDriveType == CMediaSource::SOURCE_TYPE_REMOTE )
574 // TODO: Handle not connected to a remote share
575 if ( !g_application.getNetwork().IsConnected() )
577 CGUIDialogOK::ShowAndGetInput(220, 221, 0, 0);
585 void CGUIDialogFileBrowser::GoParentFolder()
587 CStdString strPath(m_strParentPath), strOldPath(m_Directory->GetPath());
588 if (strPath.size() == 2)
589 if (strPath[1] == ':')
590 URIUtils::AddSlashAtEnd(strPath);
594 void CGUIDialogFileBrowser::OnWindowLoaded()
596 CGUIDialog::OnWindowLoaded();
597 m_viewControl.Reset();
598 m_viewControl.SetParentWindow(GetID());
599 m_viewControl.AddView(GetControl(CONTROL_LIST));
600 m_viewControl.AddView(GetControl(CONTROL_THUMBS));
603 void CGUIDialogFileBrowser::OnWindowUnload()
605 CGUIDialog::OnWindowUnload();
606 m_viewControl.Reset();
609 bool CGUIDialogFileBrowser::ShowAndGetImage(const CFileItemList &items, const VECSOURCES &shares, const CStdString &heading, CStdString &result, bool* flip, int label)
611 CStdString mask = ".png|.jpg|.bmp|.gif|.dds";
612 CGUIDialogFileBrowser *browser = new CGUIDialogFileBrowser();
615 g_windowManager.AddUniqueInstance(browser);
617 browser->m_browsingForImages = true;
618 browser->m_singleList = true;
619 browser->m_vecItems->Clear();
620 browser->m_vecItems->Append(items);
623 CFileItemPtr item(new CFileItem("image://Browse", false));
624 item->SetLabel(g_localizeStrings.Get(20153));
625 item->SetIconImage("DefaultFolder.png");
626 browser->m_vecItems->Add(item);
628 browser->SetHeading(heading);
629 browser->m_flipEnabled = flip?true:false;
631 bool confirmed(browser->IsConfirmed());
634 result = browser->m_selectedPath;
635 if (result == "image://Browse")
636 { // "Browse for thumb"
637 g_windowManager.Remove(browser->GetID());
639 return ShowAndGetImage(shares, g_localizeStrings.Get(label), result);
644 *flip = browser->m_bFlip != 0;
646 g_windowManager.Remove(browser->GetID());
652 bool CGUIDialogFileBrowser::ShowAndGetImage(const VECSOURCES &shares, const CStdString &heading, CStdString &path)
654 return ShowAndGetFile(shares, ".png|.jpg|.bmp|.gif|.tbn|.dds", heading, path, true); // true for use thumbs
657 bool CGUIDialogFileBrowser::ShowAndGetImageList(const VECSOURCES &shares, const CStdString &heading, CStdStringArray &path)
659 return ShowAndGetFileList(shares, ".png|.jpg|.bmp|.gif|.tbn|.dds", heading, path, true); // true for use thumbs
662 bool CGUIDialogFileBrowser::ShowAndGetDirectory(const VECSOURCES &shares, const CStdString &heading, CStdString &path, bool bWriteOnly)
664 // an extension mask of "/" ensures that no files are shown
667 VECSOURCES shareWritable;
668 for (unsigned int i=0;i<shares.size();++i)
670 if (shares[i].IsWritable())
671 shareWritable.push_back(shares[i]);
674 return ShowAndGetFile(shareWritable, "/w", heading, path);
677 return ShowAndGetFile(shares, "/", heading, path);
680 bool CGUIDialogFileBrowser::ShowAndGetFile(const VECSOURCES &shares, const CStdString &mask, const CStdString &heading, CStdString &path, bool useThumbs /* = false */, bool useFileDirectories /* = false */)
682 CGUIDialogFileBrowser *browser = new CGUIDialogFileBrowser();
685 g_windowManager.AddUniqueInstance(browser);
687 browser->m_useFileDirectories = useFileDirectories;
689 browser->m_browsingForImages = useThumbs;
690 browser->SetHeading(heading);
691 browser->SetSources(shares);
692 CStdString strMask = mask;
694 browser->m_browsingForFolders=1;
698 browser->m_browsingForFolders=2;
702 browser->m_browsingForFolders = 0;
704 browser->m_rootDir.SetMask(strMask);
705 browser->m_selectedPath = path;
706 browser->m_addNetworkShareEnabled = false;
708 bool confirmed(browser->IsConfirmed());
710 path = browser->m_selectedPath;
711 g_windowManager.Remove(browser->GetID());
716 // same as above, starting in a single directory
717 bool CGUIDialogFileBrowser::ShowAndGetFile(const CStdString &directory, const CStdString &mask, const CStdString &heading, CStdString &path, bool useThumbs /* = false */, bool useFileDirectories /* = false */, bool singleList /* = false */)
719 CGUIDialogFileBrowser *browser = new CGUIDialogFileBrowser();
722 g_windowManager.AddUniqueInstance(browser);
724 browser->m_useFileDirectories = useFileDirectories;
725 browser->m_browsingForImages = useThumbs;
726 browser->SetHeading(heading);
728 // add a single share for this directory
733 share.strPath = directory;
734 URIUtils::RemoveSlashAtEnd(share.strPath); // this is needed for the dodgy code in WINDOW_INIT
735 shares.push_back(share);
736 browser->SetSources(shares);
740 browser->m_vecItems->Clear();
741 CDirectory::GetDirectory(directory,*browser->m_vecItems);
742 CFileItemPtr item(new CFileItem("file://Browse", false));
743 item->SetLabel(g_localizeStrings.Get(20153));
744 item->SetIconImage("DefaultFolder.png");
745 browser->m_vecItems->Add(item);
746 browser->m_singleList = true;
748 CStdString strMask = mask;
750 browser->m_browsingForFolders=1;
754 browser->m_browsingForFolders=2;
758 browser->m_browsingForFolders = 0;
760 browser->m_rootDir.SetMask(strMask);
761 browser->m_selectedPath = directory;
762 browser->m_addNetworkShareEnabled = false;
764 bool confirmed(browser->IsConfirmed());
766 path = browser->m_selectedPath;
767 if (path == "file://Browse")
768 { // "Browse for thumb"
769 g_windowManager.Remove(browser->GetID());
772 g_mediaManager.GetLocalDrives(shares);
774 return ShowAndGetFile(shares, mask, heading, path, useThumbs,useFileDirectories);
776 g_windowManager.Remove(browser->GetID());
781 bool CGUIDialogFileBrowser::ShowAndGetFileList(const VECSOURCES &shares, const CStdString &mask, const CStdString &heading, CStdStringArray &path, bool useThumbs /* = false */, bool useFileDirectories /* = false */)
783 CGUIDialogFileBrowser *browser = new CGUIDialogFileBrowser();
786 g_windowManager.AddUniqueInstance(browser);
788 browser->m_useFileDirectories = useFileDirectories;
789 browser->m_multipleSelection = true;
790 browser->m_browsingForImages = useThumbs;
791 browser->SetHeading(heading);
792 browser->SetSources(shares);
793 browser->m_browsingForFolders = 0;
794 browser->m_rootDir.SetMask(mask);
795 browser->m_addNetworkShareEnabled = false;
797 bool confirmed(browser->IsConfirmed());
800 if (browser->m_markedPath.size())
801 path = browser->m_markedPath;
803 path.push_back(browser->m_selectedPath);
805 g_windowManager.Remove(browser->GetID());
810 void CGUIDialogFileBrowser::SetHeading(const CStdString &heading)
813 SET_CONTROL_LABEL(CONTROL_HEADING_LABEL, heading);
816 bool CGUIDialogFileBrowser::ShowAndGetSource(CStdString &path, bool allowNetworkShares, VECSOURCES* additionalShare /* = NULL */, const CStdString& strType /* = "" */)
819 // 1. Show Filebrowser with currently defined local, and optionally the network locations.
820 // 2. Have the "Add Network Location" option in addition.
821 // 3a. If the "Add Network Location" is pressed, then:
822 // a) Fire up the network location dialog to grab the new location
823 // b) Check the location by doing a GetDirectory() - if it fails, prompt the user
824 // to allow them to add currently disconnected network shares.
825 // c) Save this location to our xml file (network.xml)
827 // 3b. If the "Add Source" is pressed, then:
828 // a) Fire up the media source dialog to add the new location
829 // 4. Optionally allow user to browse the local and network locations for their share.
832 // Create a new filebrowser window
833 CGUIDialogFileBrowser *browser = new CGUIDialogFileBrowser();
834 if (!browser) return false;
836 // Add it to our window manager
837 g_windowManager.AddUniqueInstance(browser);
840 if (!strType.IsEmpty())
843 shares = *additionalShare;
844 browser->m_addSourceType = strType;
848 browser->SetHeading(g_localizeStrings.Get(1023));
850 g_mediaManager.GetLocalDrives(shares);
852 // Now the additional share if appropriate
855 shares.insert(shares.end(),additionalShare->begin(),additionalShare->end());
858 // Now add the network shares...
859 if (allowNetworkShares)
861 g_mediaManager.GetNetworkLocations(shares);
865 browser->SetSources(shares);
866 browser->m_rootDir.SetMask("/");
867 browser->m_rootDir.AllowNonLocalSources(false); // don't allow plug n play shares
868 browser->m_browsingForFolders = 1;
869 browser->m_addNetworkShareEnabled = allowNetworkShares;
870 browser->m_selectedPath = "";
872 bool confirmed = browser->IsConfirmed();
874 path = browser->m_selectedPath;
876 g_windowManager.Remove(browser->GetID());
881 void CGUIDialogFileBrowser::SetSources(const VECSOURCES &shares)
884 if (!m_shares.size() && m_addSourceType.IsEmpty())
885 g_mediaManager.GetLocalDrives(m_shares);
886 m_rootDir.SetSources(m_shares);
889 void CGUIDialogFileBrowser::OnAddNetworkLocation()
891 // ok, fire up the network location dialog
893 if (CGUIDialogNetworkSetup::ShowAndGetNetworkAddress(path))
895 // verify the path by doing a GetDirectory.
897 if (CDirectory::GetDirectory(path, items, "", DIR_FLAG_NO_FILE_DIRS | DIR_FLAG_ALLOW_PROMPT) || CGUIDialogYesNo::ShowAndGetInput(1001,1002,1003,1004))
898 { // add the network location to the shares list
900 share.strPath = path; //setPath(path);
902 share.strName = url.GetWithoutUserDetails();
903 URIUtils::RemoveSlashAtEnd(share.strName);
904 m_shares.push_back(share);
905 // add to our location manager...
906 g_mediaManager.AddNetworkLocation(path);
909 m_rootDir.SetSources(m_shares);
910 Update(m_vecItems->GetPath());
913 void CGUIDialogFileBrowser::OnAddMediaSource()
915 if (CGUIDialogMediaSource::ShowAndAddMediaSource(m_addSourceType))
917 SetSources(*g_settings.GetSourcesFromType(m_addSourceType));
922 void CGUIDialogFileBrowser::OnEditMediaSource(CFileItem* pItem)
924 if (CGUIDialogMediaSource::ShowAndEditMediaSource(m_addSourceType,pItem->GetLabel()))
926 SetSources(*g_settings.GetSourcesFromType(m_addSourceType));
931 bool CGUIDialogFileBrowser::OnPopupMenu(int iItem)
933 CContextButtons choices;
934 choices.Add(1, m_addSourceType.IsEmpty() ? 20133 : 21364);
935 choices.Add(2, m_addSourceType.IsEmpty() ? 20134 : 21365);
937 int btnid = CGUIDialogContextMenu::ShowAndGetChoice(choices);
940 if (m_addNetworkShareEnabled)
942 CStdString strOldPath=m_selectedPath,newPath=m_selectedPath;
943 VECSOURCES shares=m_shares;
944 if (CGUIDialogNetworkSetup::ShowAndGetNetworkAddress(newPath))
946 g_mediaManager.SetLocationPath(strOldPath,newPath);
947 for (unsigned int i=0;i<shares.size();++i)
949 if (URIUtils::CompareWithoutSlashAtEnd(shares[i].strPath, strOldPath))//getPath().Equals(strOldPath))
951 shares[i].strName = newPath;
952 shares[i].strPath = newPath;//setPath(newPath);
953 URIUtils::RemoveSlashAtEnd(shares[i].strName);
957 // re-open our dialog
959 m_rootDir.SetMask("/");
960 m_browsingForFolders = 1;
961 m_addNetworkShareEnabled = true;
962 m_selectedPath = newPath;
968 CFileItemPtr item = m_vecItems->Get(iItem);
969 OnEditMediaSource(item.get());
974 if (m_addNetworkShareEnabled)
976 g_mediaManager.RemoveLocation(m_selectedPath);
978 for (unsigned int i=0;i<m_shares.size();++i)
980 if (URIUtils::CompareWithoutSlashAtEnd(m_shares[i].strPath, m_selectedPath) && !m_shares[i].m_ignore) // getPath().Equals(m_selectedPath))
982 m_shares.erase(m_shares.begin()+i);
986 m_rootDir.SetSources(m_shares);
987 m_rootDir.SetMask("/");
989 m_browsingForFolders = 1;
990 m_addNetworkShareEnabled = true;
993 Update(m_Directory->GetPath());
997 g_settings.DeleteSource(m_addSourceType,(*m_vecItems)[iItem]->GetLabel(),(*m_vecItems)[iItem]->GetPath());
998 SetSources(*g_settings.GetSourcesFromType(m_addSourceType));
1006 CFileItemPtr CGUIDialogFileBrowser::GetCurrentListItem(int offset)
1008 int item = m_viewControl.GetSelectedItem();
1009 if (item < 0 || !m_vecItems->Size()) return CFileItemPtr();
1011 item = (item + offset) % m_vecItems->Size();
1012 if (item < 0) item += m_vecItems->Size();
1013 return (*m_vecItems)[item];
1016 CGUIControl *CGUIDialogFileBrowser::GetFirstFocusableControl(int id)
1018 if (m_viewControl.HasControl(id))
1019 id = m_viewControl.GetCurrentControl();
1020 return CGUIWindow::GetFirstFocusableControl(id);