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 "profiles/ProfilesManager.h"
42 #include "settings/AdvancedSettings.h"
43 #include "settings/MediaSourceSettings.h"
44 #include "settings/Settings.h"
45 #include "guilib/Key.h"
46 #include "guilib/LocalizeStrings.h"
47 #include "utils/log.h"
49 #include "view/ViewState.h"
51 using namespace XFILE;
53 #define CONTROL_LIST 450
54 #define CONTROL_THUMBS 451
55 #define CONTROL_HEADING_LABEL 411
56 #define CONTROL_LABEL_PATH 412
57 #define CONTROL_OK 413
58 #define CONTROL_CANCEL 414
59 #define CONTROL_NEWFOLDER 415
60 #define CONTROL_FLIP 416
62 CGUIDialogFileBrowser::CGUIDialogFileBrowser()
63 : CGUIDialog(WINDOW_DIALOG_FILE_BROWSER, "FileBrowser.xml")
65 m_Directory = new CFileItem;
66 m_vecItems = new CFileItemList;
68 m_Directory->m_bIsFolder = true;
69 m_browsingForFolders = 0;
70 m_browsingForImages = false;
71 m_useFileDirectories = false;
72 m_addNetworkShareEnabled = false;
74 m_thumbLoader.SetObserver(this);
75 m_flipEnabled = false;
76 m_multipleSelection = false;
77 m_loadType = KEEP_IN_MEMORY;
80 CGUIDialogFileBrowser::~CGUIDialogFileBrowser()
86 bool CGUIDialogFileBrowser::OnAction(const CAction &action)
88 if (action.GetID() == ACTION_PARENT_DIR)
93 if ((action.GetID() == ACTION_CONTEXT_MENU || action.GetID() == ACTION_MOUSE_RIGHT_CLICK) && m_Directory->GetPath().empty())
95 int iItem = m_viewControl.GetSelectedItem();
96 if ((!m_addSourceType.empty() && iItem != m_vecItems->Size()-1))
97 return OnPopupMenu(iItem);
98 if (m_addNetworkShareEnabled && g_mediaManager.HasLocation(m_selectedPath))
100 // need to make sure this source is not an auto added location
101 // as users locations might have the same paths
102 CFileItemPtr pItem = (*m_vecItems)[iItem];
103 for (unsigned int i=0;i<m_shares.size();++i)
105 if (m_shares[i].strName.Equals(pItem->GetLabel()) && m_shares[i].m_ignore)
109 return OnPopupMenu(iItem);
115 return CGUIDialog::OnAction(action);
118 bool CGUIDialogFileBrowser::OnBack(int actionID)
120 if (actionID == ACTION_NAV_BACK && !m_vecItems->IsVirtualDirectoryRoot())
125 return CGUIDialog::OnBack(actionID);
128 bool CGUIDialogFileBrowser::OnMessage(CGUIMessage& message)
130 switch ( message.GetMessage() )
132 case GUI_MSG_WINDOW_DEINIT:
134 if (m_thumbLoader.IsLoading())
135 m_thumbLoader.StopThread();
136 CGUIDialog::OnMessage(message);
138 m_addNetworkShareEnabled = false;
143 case GUI_MSG_WINDOW_INIT:
145 m_bConfirmed = false;
148 // this code allows two different selection modes for directories
149 // end the path with a slash to start inside the directory
150 if (URIUtils::HasSlashAtEnd(m_selectedPath))
154 int iSource = CUtil::GetMatchingSource(m_selectedPath,m_shares,bFool);
156 if (iSource > -1 && iSource < (int)m_shares.size())
158 if (m_shares[iSource].strPath.Equals(m_selectedPath))
162 if (bFool && !CDirectory::Exists(m_selectedPath))
163 m_selectedPath.clear();
167 if (!CFile::Exists(m_selectedPath) && !CDirectory::Exists(m_selectedPath))
168 m_selectedPath.clear();
171 // find the parent folder if we are a file browser (don't do this for folders)
172 m_Directory->SetPath(m_selectedPath);
173 if (!m_browsingForFolders && !bIsDir)
174 m_Directory->SetPath(URIUtils::GetParentPath(m_selectedPath));
175 Update(m_Directory->GetPath());
176 m_viewControl.SetSelectedItem(m_selectedPath);
177 return CGUIDialog::OnMessage(message);
181 case GUI_MSG_CLICKED:
183 if (m_viewControl.HasControl(message.GetSenderId())) // list control
185 int iItem = m_viewControl.GetSelectedItem();
186 int iAction = message.GetParam1();
187 if (iItem < 0) break;
188 if (iAction == ACTION_SELECT_ITEM || iAction == ACTION_MOUSE_LEFT_CLICK)
193 else if (iAction == ACTION_HIGHLIGHT_ITEM && m_multipleSelection)
195 CFileItemPtr pItem = (*m_vecItems)[iItem];
196 if (!pItem->m_bIsShareOrDrive && !pItem->m_bIsFolder)
198 pItem->Select(!pItem->IsSelected());
199 CGUIMessage msg(GUI_MSG_ITEM_SELECT, GetID(), message.GetSenderId(), iItem + 1);
204 else if (message.GetSenderId() == CONTROL_OK)
206 if (m_browsingForFolders == 2)
208 int iItem = m_viewControl.GetSelectedItem();
212 strPath = m_selectedPath;
214 strPath = (*m_vecItems)[iItem]->GetPath();
216 CStdString strTest = URIUtils::AddFileToFolder(strPath, "1");
218 if (file.OpenForWrite(strTest,true))
221 CFile::Delete(strTest);
226 CGUIDialogOK::ShowAndGetInput(257,20072,0,0);
230 if (m_multipleSelection)
232 for (int iItem = 0; iItem < m_vecItems->Size(); ++iItem)
234 CFileItemPtr pItem = (*m_vecItems)[iItem];
235 if (pItem->IsSelected())
236 m_markedPath.push_back(pItem->GetPath());
244 else if (message.GetSenderId() == CONTROL_CANCEL)
249 else if (message.GetSenderId() == CONTROL_NEWFOLDER)
252 if (CGUIKeyboardFactory::ShowAndGetInput(strInput,g_localizeStrings.Get(119),false))
254 CStdString strPath = URIUtils::AddFileToFolder(m_vecItems->GetPath(), strInput);
255 if (CDirectory::Create(strPath))
256 Update(m_vecItems->GetPath());
258 CGUIDialogOK::ShowAndGetInput(20069,20072,20073,0);
261 else if (message.GetSenderId() == CONTROL_FLIP)
265 case GUI_MSG_SETFOCUS:
267 if (m_viewControl.HasControl(message.GetControlId()) && m_viewControl.GetCurrentControl() != message.GetControlId())
269 m_viewControl.SetFocused();
274 case GUI_MSG_NOTIFY_ALL:
275 { // Message is received only if this window is active
276 if (message.GetParam1() == GUI_MSG_REMOVED_MEDIA)
278 if (m_Directory->IsVirtualDirectoryRoot() && IsActive())
280 int iItem = m_viewControl.GetSelectedItem();
281 Update(m_Directory->GetPath());
282 m_viewControl.SetSelectedItem(iItem);
284 else if (m_Directory->IsRemovable())
285 { // check that we have this removable share still
286 if (!m_rootDir.IsInSource(m_Directory->GetPath()))
287 { // don't have this share any more
288 if (IsActive()) Update("");
291 m_history.ClearPathHistory();
292 m_Directory->SetPath("");
298 else if (message.GetParam1()==GUI_MSG_UPDATE_SOURCES)
299 { // State of the sources changed, so update our view
300 if (m_Directory->IsVirtualDirectoryRoot() && IsActive())
302 int iItem = m_viewControl.GetSelectedItem();
303 Update(m_Directory->GetPath());
304 m_viewControl.SetSelectedItem(iItem);
308 else if (message.GetParam1()==GUI_MSG_UPDATE_PATH)
312 if((message.GetStringParam() == m_Directory->GetPath()) ||
313 (m_Directory->IsMultiPath() && XFILE::CMultiPathDirectory::HasPath(m_Directory->GetPath(), message.GetStringParam())))
315 int iItem = m_viewControl.GetSelectedItem();
316 Update(m_Directory->GetPath());
317 m_viewControl.SetSelectedItem(iItem);
325 return CGUIDialog::OnMessage(message);
328 void CGUIDialogFileBrowser::ClearFileItems()
330 m_viewControl.Clear();
331 m_vecItems->Clear(); // will clean up everything
334 void CGUIDialogFileBrowser::OnSort()
337 m_vecItems->Sort(SortByLabel, SortOrderAscending);
340 void CGUIDialogFileBrowser::Update(const CStdString &strDirectory)
342 if (m_browsingForImages && m_thumbLoader.IsLoading())
343 m_thumbLoader.StopThread();
345 int iItem = m_viewControl.GetSelectedItem();
346 CStdString strSelectedItem = "";
347 if (iItem >= 0 && iItem < m_vecItems->Size())
349 CFileItemPtr pItem = (*m_vecItems)[iItem];
350 if (!pItem->IsParentFolder())
352 strSelectedItem = pItem->GetPath();
353 URIUtils::RemoveSlashAtEnd(strSelectedItem);
354 m_history.SetSelectedItem(strSelectedItem, m_Directory->GetPath().empty()?"empty":m_Directory->GetPath());
361 CStdString strParentPath;
363 if (!m_rootDir.GetDirectory(strDirectory, items,m_useFileDirectories))
365 CLog::Log(LOGERROR,"CGUIDialogFileBrowser::GetDirectory(%s) failed", CURL::GetRedacted(strDirectory).c_str());
367 // We assume, we can get the parent
369 CStdString strParentPath = m_history.GetParentPath();
370 m_history.RemoveParentPath();
371 Update(strParentPath);
375 // check if current directory is a root share
376 if (!m_rootDir.IsSource(strDirectory))
378 if (URIUtils::GetParentPath(strDirectory, strParentPath))
380 CFileItemPtr pItem(new CFileItem(".."));
381 pItem->SetPath(strParentPath);
382 pItem->m_bIsFolder = true;
383 pItem->m_bIsShareOrDrive = false;
384 items.AddFront(pItem, 0);
389 // yes, this is the root of a share
390 // add parent path to the virtual directory
391 CFileItemPtr pItem(new CFileItem(".."));
393 pItem->m_bIsShareOrDrive = false;
394 pItem->m_bIsFolder = true;
395 items.AddFront(pItem, 0);
400 m_vecItems->Copy(items);
401 m_Directory->SetPath(strDirectory);
402 m_strParentPath = strParentPath;
405 // if we're getting the root source listing
406 // make sure the path history is clean
407 if (strDirectory.empty())
408 m_history.ClearPathHistory();
410 // some evil stuff don't work with the '/' mask, e.g. shoutcast directory - make sure no files are in there
411 if (m_browsingForFolders)
413 for (int i=0;i<m_vecItems->Size();++i)
414 if (!(*m_vecItems)[i]->m_bIsFolder)
416 m_vecItems->Remove(i);
421 // No need to set thumbs
423 m_vecItems->FillInDefaultIcons();
427 if (m_Directory->GetPath().empty() && m_addNetworkShareEnabled &&
428 (CProfilesManager::Get().GetMasterProfile().getLockMode() == LOCK_MODE_EVERYONE ||
429 CProfilesManager::Get().IsMasterProfile() || g_passwordManager.bMasterUser))
430 { // we are in the virtual directory - add the "Add Network Location" item
431 CFileItemPtr pItem(new CFileItem(g_localizeStrings.Get(1032)));
432 pItem->SetPath("net://");
433 pItem->m_bIsFolder = true;
434 m_vecItems->Add(pItem);
436 if (m_Directory->GetPath().empty() && !m_addSourceType.empty())
438 CFileItemPtr pItem(new CFileItem(g_localizeStrings.Get(21359)));
439 pItem->SetPath("source://");
440 pItem->m_bIsFolder = true;
441 m_vecItems->Add(pItem);
444 m_viewControl.SetItems(*m_vecItems);
445 m_viewControl.SetCurrentView((m_browsingForImages && CAutoSwitch::ByFileCount(*m_vecItems)) ? DEFAULT_VIEW_ICONS : DEFAULT_VIEW_LIST);
447 CStdString strPath2 = m_Directory->GetPath();
448 URIUtils::RemoveSlashAtEnd(strPath2);
449 strSelectedItem = m_history.GetSelectedItem(strPath2==""?"empty":strPath2);
451 bool bSelectedFound = false;
452 for (int i = 0; i < (int)m_vecItems->Size(); ++i)
454 CFileItemPtr pItem = (*m_vecItems)[i];
455 strPath2 = pItem->GetPath();
456 URIUtils::RemoveSlashAtEnd(strPath2);
457 if (strPath2 == strSelectedItem)
459 m_viewControl.SetSelectedItem(i);
460 bSelectedFound = true;
465 // if we haven't found the selected item, select the first item
467 m_viewControl.SetSelectedItem(0);
469 m_history.AddPath(m_Directory->GetPath());
471 if (m_browsingForImages)
472 m_thumbLoader.Load(*m_vecItems);
475 void CGUIDialogFileBrowser::FrameMove()
477 int item = m_viewControl.GetSelectedItem();
480 // if we are browsing for folders, and not in the root directory, then we use the parent path,
481 // else we use the current file's path
482 if (m_browsingForFolders && !m_Directory->IsVirtualDirectoryRoot())
483 m_selectedPath = m_Directory->GetPath();
485 m_selectedPath = (*m_vecItems)[item]->GetPath();
486 if (m_selectedPath == "net://")
488 SET_CONTROL_LABEL(CONTROL_LABEL_PATH, g_localizeStrings.Get(1032)); // "Add Network Location..."
492 // Update the current path label
493 CURL url(m_selectedPath);
494 CStdString safePath = url.GetWithoutUserDetails();
495 SET_CONTROL_LABEL(CONTROL_LABEL_PATH, safePath);
497 if ((!m_browsingForFolders && (*m_vecItems)[item]->m_bIsFolder) || ((*m_vecItems)[item]->GetPath() == "image://Browse"))
499 CONTROL_DISABLE(CONTROL_OK);
503 CONTROL_ENABLE(CONTROL_OK);
505 if (m_browsingForFolders == 2)
507 CONTROL_ENABLE(CONTROL_NEWFOLDER);
511 CONTROL_DISABLE(CONTROL_NEWFOLDER);
515 CONTROL_ENABLE(CONTROL_FLIP);
519 CONTROL_DISABLE(CONTROL_FLIP);
522 CGUIDialog::FrameMove();
525 void CGUIDialogFileBrowser::OnClick(int iItem)
527 if ( iItem < 0 || iItem >= (int)m_vecItems->Size() ) return ;
528 CFileItemPtr pItem = (*m_vecItems)[iItem];
529 CStdString strPath = pItem->GetPath();
531 if (pItem->m_bIsFolder)
533 if (pItem->GetPath() == "net://")
534 { // special "Add Network Location" item
535 OnAddNetworkLocation();
538 if (pItem->GetPath() == "source://")
539 { // special "Add Source" item
543 if (!m_addSourceType.empty())
545 OnEditMediaSource(pItem.get());
548 if ( pItem->m_bIsShareOrDrive )
550 if ( !HaveDiscOrConnection( pItem->m_iDriveType ) )
555 else if (!m_browsingForFolders)
557 m_selectedPath = pItem->GetPath();
563 bool CGUIDialogFileBrowser::HaveDiscOrConnection( int iDriveType )
565 if ( iDriveType == CMediaSource::SOURCE_TYPE_DVD )
567 if ( !g_mediaManager.IsDiscInDrive() )
569 CGUIDialogOK::ShowAndGetInput(218, 219, 0, 0);
573 else if ( iDriveType == CMediaSource::SOURCE_TYPE_REMOTE )
575 // TODO: Handle not connected to a remote share
576 if ( !g_application.getNetwork().IsConnected() )
578 CGUIDialogOK::ShowAndGetInput(220, 221, 0, 0);
586 void CGUIDialogFileBrowser::GoParentFolder()
588 CStdString strPath(m_strParentPath), strOldPath(m_Directory->GetPath());
589 if (strPath.size() == 2)
590 if (strPath[1] == ':')
591 URIUtils::AddSlashAtEnd(strPath);
595 void CGUIDialogFileBrowser::OnWindowLoaded()
597 CGUIDialog::OnWindowLoaded();
598 m_viewControl.Reset();
599 m_viewControl.SetParentWindow(GetID());
600 m_viewControl.AddView(GetControl(CONTROL_LIST));
601 m_viewControl.AddView(GetControl(CONTROL_THUMBS));
604 void CGUIDialogFileBrowser::OnWindowUnload()
606 CGUIDialog::OnWindowUnload();
607 m_viewControl.Reset();
610 bool CGUIDialogFileBrowser::ShowAndGetImage(const CFileItemList &items, const VECSOURCES &shares, const CStdString &heading, CStdString &result, bool* flip, int label)
612 CStdString mask = ".png|.jpg|.bmp|.gif|.dds";
613 CGUIDialogFileBrowser *browser = new CGUIDialogFileBrowser();
616 g_windowManager.AddUniqueInstance(browser);
618 browser->m_browsingForImages = true;
619 browser->m_singleList = true;
620 browser->m_vecItems->Clear();
621 browser->m_vecItems->Append(items);
624 CFileItemPtr item(new CFileItem("image://Browse", false));
625 item->SetLabel(g_localizeStrings.Get(20153));
626 item->SetIconImage("DefaultFolder.png");
627 browser->m_vecItems->Add(item);
629 browser->SetHeading(heading);
630 browser->m_flipEnabled = flip?true:false;
632 bool confirmed(browser->IsConfirmed());
635 result = browser->m_selectedPath;
636 if (result == "image://Browse")
637 { // "Browse for thumb"
638 g_windowManager.Remove(browser->GetID());
640 return ShowAndGetImage(shares, g_localizeStrings.Get(label), result);
645 *flip = browser->m_bFlip != 0;
647 g_windowManager.Remove(browser->GetID());
653 bool CGUIDialogFileBrowser::ShowAndGetImage(const VECSOURCES &shares, const CStdString &heading, CStdString &path)
655 return ShowAndGetFile(shares, ".png|.jpg|.bmp|.gif|.tbn|.dds", heading, path, true); // true for use thumbs
658 bool CGUIDialogFileBrowser::ShowAndGetImageList(const VECSOURCES &shares, const CStdString &heading, CStdStringArray &path)
660 return ShowAndGetFileList(shares, ".png|.jpg|.bmp|.gif|.tbn|.dds", heading, path, true); // true for use thumbs
663 bool CGUIDialogFileBrowser::ShowAndGetDirectory(const VECSOURCES &shares, const CStdString &heading, CStdString &path, bool bWriteOnly)
665 // an extension mask of "/" ensures that no files are shown
668 VECSOURCES shareWritable;
669 for (unsigned int i=0;i<shares.size();++i)
671 if (shares[i].IsWritable())
672 shareWritable.push_back(shares[i]);
675 return ShowAndGetFile(shareWritable, "/w", heading, path);
678 return ShowAndGetFile(shares, "/", heading, path);
681 bool CGUIDialogFileBrowser::ShowAndGetFile(const VECSOURCES &shares, const CStdString &mask, const CStdString &heading, CStdString &path, bool useThumbs /* = false */, bool useFileDirectories /* = false */)
683 CGUIDialogFileBrowser *browser = new CGUIDialogFileBrowser();
686 g_windowManager.AddUniqueInstance(browser);
688 browser->m_useFileDirectories = useFileDirectories;
690 browser->m_browsingForImages = useThumbs;
691 browser->SetHeading(heading);
692 browser->SetSources(shares);
693 CStdString strMask = mask;
695 browser->m_browsingForFolders=1;
699 browser->m_browsingForFolders=2;
703 browser->m_browsingForFolders = 0;
705 browser->m_rootDir.SetMask(strMask);
706 browser->m_selectedPath = path;
707 browser->m_addNetworkShareEnabled = false;
709 bool confirmed(browser->IsConfirmed());
711 path = browser->m_selectedPath;
712 g_windowManager.Remove(browser->GetID());
717 // same as above, starting in a single directory
718 bool CGUIDialogFileBrowser::ShowAndGetFile(const CStdString &directory, const CStdString &mask, const CStdString &heading, CStdString &path, bool useThumbs /* = false */, bool useFileDirectories /* = false */, bool singleList /* = false */)
720 CGUIDialogFileBrowser *browser = new CGUIDialogFileBrowser();
723 g_windowManager.AddUniqueInstance(browser);
725 browser->m_useFileDirectories = useFileDirectories;
726 browser->m_browsingForImages = useThumbs;
727 browser->SetHeading(heading);
729 // add a single share for this directory
734 share.strPath = directory;
735 URIUtils::RemoveSlashAtEnd(share.strPath); // this is needed for the dodgy code in WINDOW_INIT
736 shares.push_back(share);
737 browser->SetSources(shares);
741 browser->m_vecItems->Clear();
742 CDirectory::GetDirectory(directory,*browser->m_vecItems);
743 CFileItemPtr item(new CFileItem("file://Browse", false));
744 item->SetLabel(g_localizeStrings.Get(20153));
745 item->SetIconImage("DefaultFolder.png");
746 browser->m_vecItems->Add(item);
747 browser->m_singleList = true;
749 CStdString strMask = mask;
751 browser->m_browsingForFolders=1;
755 browser->m_browsingForFolders=2;
759 browser->m_browsingForFolders = 0;
761 browser->m_rootDir.SetMask(strMask);
762 browser->m_selectedPath = directory;
763 browser->m_addNetworkShareEnabled = false;
765 bool confirmed(browser->IsConfirmed());
767 path = browser->m_selectedPath;
768 if (path == "file://Browse")
769 { // "Browse for thumb"
770 g_windowManager.Remove(browser->GetID());
773 g_mediaManager.GetLocalDrives(shares);
775 return ShowAndGetFile(shares, mask, heading, path, useThumbs,useFileDirectories);
777 g_windowManager.Remove(browser->GetID());
782 bool CGUIDialogFileBrowser::ShowAndGetFileList(const VECSOURCES &shares, const CStdString &mask, const CStdString &heading, CStdStringArray &path, bool useThumbs /* = false */, bool useFileDirectories /* = false */)
784 CGUIDialogFileBrowser *browser = new CGUIDialogFileBrowser();
787 g_windowManager.AddUniqueInstance(browser);
789 browser->m_useFileDirectories = useFileDirectories;
790 browser->m_multipleSelection = true;
791 browser->m_browsingForImages = useThumbs;
792 browser->SetHeading(heading);
793 browser->SetSources(shares);
794 browser->m_browsingForFolders = 0;
795 browser->m_rootDir.SetMask(mask);
796 browser->m_addNetworkShareEnabled = false;
798 bool confirmed(browser->IsConfirmed());
801 if (browser->m_markedPath.size())
802 path = browser->m_markedPath;
804 path.push_back(browser->m_selectedPath);
806 g_windowManager.Remove(browser->GetID());
811 void CGUIDialogFileBrowser::SetHeading(const CStdString &heading)
814 SET_CONTROL_LABEL(CONTROL_HEADING_LABEL, heading);
817 bool CGUIDialogFileBrowser::ShowAndGetSource(CStdString &path, bool allowNetworkShares, VECSOURCES* additionalShare /* = NULL */, const CStdString& strType /* = "" */)
820 // 1. Show Filebrowser with currently defined local, and optionally the network locations.
821 // 2. Have the "Add Network Location" option in addition.
822 // 3a. If the "Add Network Location" is pressed, then:
823 // a) Fire up the network location dialog to grab the new location
824 // b) Check the location by doing a GetDirectory() - if it fails, prompt the user
825 // to allow them to add currently disconnected network shares.
826 // c) Save this location to our xml file (network.xml)
828 // 3b. If the "Add Source" is pressed, then:
829 // a) Fire up the media source dialog to add the new location
830 // 4. Optionally allow user to browse the local and network locations for their share.
833 // Create a new filebrowser window
834 CGUIDialogFileBrowser *browser = new CGUIDialogFileBrowser();
835 if (!browser) return false;
837 // Add it to our window manager
838 g_windowManager.AddUniqueInstance(browser);
841 if (!strType.empty())
844 shares = *additionalShare;
845 browser->m_addSourceType = strType;
849 browser->SetHeading(g_localizeStrings.Get(1023));
851 g_mediaManager.GetLocalDrives(shares);
853 // Now the additional share if appropriate
856 shares.insert(shares.end(),additionalShare->begin(),additionalShare->end());
859 // Now add the network shares...
860 if (allowNetworkShares)
862 g_mediaManager.GetNetworkLocations(shares);
866 browser->SetSources(shares);
867 browser->m_rootDir.SetMask("/");
868 browser->m_rootDir.AllowNonLocalSources(false); // don't allow plug n play shares
869 browser->m_browsingForFolders = 1;
870 browser->m_addNetworkShareEnabled = allowNetworkShares;
871 browser->m_selectedPath = "";
873 bool confirmed = browser->IsConfirmed();
875 path = browser->m_selectedPath;
877 g_windowManager.Remove(browser->GetID());
882 void CGUIDialogFileBrowser::SetSources(const VECSOURCES &shares)
885 if (!m_shares.size() && m_addSourceType.empty())
886 g_mediaManager.GetLocalDrives(m_shares);
887 m_rootDir.SetSources(m_shares);
890 void CGUIDialogFileBrowser::OnAddNetworkLocation()
892 // ok, fire up the network location dialog
894 if (CGUIDialogNetworkSetup::ShowAndGetNetworkAddress(path))
896 // verify the path by doing a GetDirectory.
898 if (CDirectory::GetDirectory(path, items, "", DIR_FLAG_NO_FILE_DIRS | DIR_FLAG_ALLOW_PROMPT) || CGUIDialogYesNo::ShowAndGetInput(1001,1002,1003,1004))
899 { // add the network location to the shares list
901 share.strPath = path; //setPath(path);
903 share.strName = url.GetWithoutUserDetails();
904 URIUtils::RemoveSlashAtEnd(share.strName);
905 m_shares.push_back(share);
906 // add to our location manager...
907 g_mediaManager.AddNetworkLocation(path);
910 m_rootDir.SetSources(m_shares);
911 Update(m_vecItems->GetPath());
914 void CGUIDialogFileBrowser::OnAddMediaSource()
916 if (CGUIDialogMediaSource::ShowAndAddMediaSource(m_addSourceType))
918 SetSources(*CMediaSourceSettings::Get().GetSources(m_addSourceType));
923 void CGUIDialogFileBrowser::OnEditMediaSource(CFileItem* pItem)
925 if (CGUIDialogMediaSource::ShowAndEditMediaSource(m_addSourceType,pItem->GetLabel()))
927 SetSources(*CMediaSourceSettings::Get().GetSources(m_addSourceType));
932 bool CGUIDialogFileBrowser::OnPopupMenu(int iItem)
934 CContextButtons choices;
935 choices.Add(1, m_addSourceType.empty() ? 20133 : 21364);
936 choices.Add(2, m_addSourceType.empty() ? 20134 : 21365);
938 int btnid = CGUIDialogContextMenu::ShowAndGetChoice(choices);
941 if (m_addNetworkShareEnabled)
943 CStdString strOldPath=m_selectedPath,newPath=m_selectedPath;
944 VECSOURCES shares=m_shares;
945 if (CGUIDialogNetworkSetup::ShowAndGetNetworkAddress(newPath))
947 g_mediaManager.SetLocationPath(strOldPath,newPath);
948 for (unsigned int i=0;i<shares.size();++i)
950 if (URIUtils::CompareWithoutSlashAtEnd(shares[i].strPath, strOldPath))//getPath().Equals(strOldPath))
952 shares[i].strName = newPath;
953 shares[i].strPath = newPath;//setPath(newPath);
954 URIUtils::RemoveSlashAtEnd(shares[i].strName);
958 // re-open our dialog
960 m_rootDir.SetMask("/");
961 m_browsingForFolders = 1;
962 m_addNetworkShareEnabled = true;
963 m_selectedPath = newPath;
969 CFileItemPtr item = m_vecItems->Get(iItem);
970 OnEditMediaSource(item.get());
975 if (m_addNetworkShareEnabled)
977 g_mediaManager.RemoveLocation(m_selectedPath);
979 for (unsigned int i=0;i<m_shares.size();++i)
981 if (URIUtils::CompareWithoutSlashAtEnd(m_shares[i].strPath, m_selectedPath) && !m_shares[i].m_ignore) // getPath().Equals(m_selectedPath))
983 m_shares.erase(m_shares.begin()+i);
987 m_rootDir.SetSources(m_shares);
988 m_rootDir.SetMask("/");
990 m_browsingForFolders = 1;
991 m_addNetworkShareEnabled = true;
994 Update(m_Directory->GetPath());
998 CMediaSourceSettings::Get().DeleteSource(m_addSourceType,(*m_vecItems)[iItem]->GetLabel(),(*m_vecItems)[iItem]->GetPath());
999 SetSources(*CMediaSourceSettings::Get().GetSources(m_addSourceType));
1007 CFileItemPtr CGUIDialogFileBrowser::GetCurrentListItem(int offset)
1009 int item = m_viewControl.GetSelectedItem();
1010 if (item < 0 || !m_vecItems->Size()) return CFileItemPtr();
1012 item = (item + offset) % m_vecItems->Size();
1013 if (item < 0) item += m_vecItems->Size();
1014 return (*m_vecItems)[item];
1017 CGUIControl *CGUIDialogFileBrowser::GetFirstFocusableControl(int id)
1019 if (m_viewControl.HasControl(id))
1020 id = m_viewControl.GetCurrentControl();
1021 return CGUIWindow::GetFirstFocusableControl(id);