2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
9 #include "GUIDialogFileBrowser.h"
11 #include "AutoSwitch.h"
13 #include "GUIDialogContextMenu.h"
14 #include "GUIDialogMediaSource.h"
15 #include "GUIDialogYesNo.h"
16 #include "GUIPassword.h"
17 #include "GUIUserMessages.h"
18 #include "ServiceBroker.h"
21 #include "filesystem/Directory.h"
22 #include "filesystem/File.h"
23 #include "filesystem/MultiPathDirectory.h"
24 #include "guilib/GUIComponent.h"
25 #include "guilib/GUIKeyboardFactory.h"
26 #include "guilib/GUIWindowManager.h"
27 #include "guilib/LocalizeStrings.h"
28 #include "input/Key.h"
29 #include "messaging/helpers/DialogOKHelper.h"
30 #include "network/GUIDialogNetworkSetup.h"
31 #include "network/Network.h"
32 #include "profiles/ProfileManager.h"
33 #include "settings/MediaSourceSettings.h"
34 #include "settings/SettingsComponent.h"
35 #include "storage/MediaManager.h"
36 #include "utils/FileExtensionProvider.h"
37 #include "utils/StringUtils.h"
38 #include "utils/URIUtils.h"
39 #include "utils/Variant.h"
40 #include "utils/log.h"
42 using namespace KODI::MESSAGING
;
43 using namespace XFILE
;
45 #define CONTROL_LIST 450
46 #define CONTROL_THUMBS 451
47 #define CONTROL_HEADING_LABEL 411
48 #define CONTROL_LABEL_PATH 412
49 #define CONTROL_OK 413
50 #define CONTROL_CANCEL 414
51 #define CONTROL_NEWFOLDER 415
52 #define CONTROL_FLIP 416
54 CGUIDialogFileBrowser::CGUIDialogFileBrowser()
55 : CGUIDialog(WINDOW_DIALOG_FILE_BROWSER
, "FileBrowser.xml")
57 m_Directory
= new CFileItem
;
58 m_vecItems
= new CFileItemList
;
60 m_Directory
->m_bIsFolder
= true;
61 m_browsingForFolders
= 0;
62 m_browsingForImages
= false;
63 m_useFileDirectories
= false;
64 m_addNetworkShareEnabled
= false;
66 m_thumbLoader
.SetObserver(this);
67 m_flipEnabled
= false;
69 m_multipleSelection
= false;
70 m_loadType
= KEEP_IN_MEMORY
;
73 CGUIDialogFileBrowser::~CGUIDialogFileBrowser()
79 bool CGUIDialogFileBrowser::OnAction(const CAction
&action
)
81 if (action
.GetID() == ACTION_PARENT_DIR
)
86 if ((action
.GetID() == ACTION_CONTEXT_MENU
|| action
.GetID() == ACTION_MOUSE_RIGHT_CLICK
) && m_Directory
->GetPath().empty())
88 int iItem
= m_viewControl
.GetSelectedItem();
89 if ((!m_addSourceType
.empty() && iItem
!= m_vecItems
->Size()-1))
90 return OnPopupMenu(iItem
);
91 if (m_addNetworkShareEnabled
&& CServiceBroker::GetMediaManager().HasLocation(m_selectedPath
))
93 // need to make sure this source is not an auto added location
94 // as users locations might have the same paths
95 CFileItemPtr pItem
= (*m_vecItems
)[iItem
];
96 for (unsigned int i
=0;i
<m_shares
.size();++i
)
98 if (StringUtils::EqualsNoCase(m_shares
[i
].strName
, pItem
->GetLabel()) && m_shares
[i
].m_ignore
)
102 return OnPopupMenu(iItem
);
108 return CGUIDialog::OnAction(action
);
111 bool CGUIDialogFileBrowser::OnBack(int actionID
)
113 if (actionID
== ACTION_NAV_BACK
&& !m_vecItems
->IsVirtualDirectoryRoot())
118 return CGUIDialog::OnBack(actionID
);
121 bool CGUIDialogFileBrowser::OnMessage(CGUIMessage
& message
)
123 switch ( message
.GetMessage() )
125 case GUI_MSG_WINDOW_DEINIT
:
127 if (m_thumbLoader
.IsLoading())
128 m_thumbLoader
.StopThread();
129 CGUIDialog::OnMessage(message
);
131 m_addNetworkShareEnabled
= false;
136 case GUI_MSG_WINDOW_INIT
:
138 m_bConfirmed
= false;
141 // this code allows two different selection modes for directories
142 // end the path with a slash to start inside the directory
143 if (URIUtils::HasSlashAtEnd(m_selectedPath
))
147 int iSource
= CUtil::GetMatchingSource(m_selectedPath
,m_shares
,bFool
);
149 if (iSource
> -1 && iSource
< (int)m_shares
.size())
151 if (URIUtils::PathEquals(m_shares
[iSource
].strPath
, m_selectedPath
))
155 if (bFool
&& !CDirectory::Exists(m_selectedPath
))
156 m_selectedPath
.clear();
160 if (!CFile::Exists(m_selectedPath
) && !CDirectory::Exists(m_selectedPath
))
161 m_selectedPath
.clear();
164 // find the parent folder if we are a file browser (don't do this for folders)
165 m_Directory
->SetPath(m_selectedPath
);
166 if (!m_browsingForFolders
&& !bIsDir
)
167 m_Directory
->SetPath(URIUtils::GetParentPath(m_selectedPath
));
168 Update(m_Directory
->GetPath());
169 m_viewControl
.SetSelectedItem(m_selectedPath
);
170 return CGUIDialog::OnMessage(message
);
174 case GUI_MSG_CLICKED
:
176 if (m_viewControl
.HasControl(message
.GetSenderId())) // list control
178 int iItem
= m_viewControl
.GetSelectedItem();
179 int iAction
= message
.GetParam1();
180 if (iItem
< 0) break;
181 CFileItemPtr pItem
= (*m_vecItems
)[iItem
];
182 if ((iAction
== ACTION_SELECT_ITEM
|| iAction
== ACTION_MOUSE_LEFT_CLICK
) &&
183 (!m_multipleSelection
|| pItem
->m_bIsShareOrDrive
|| pItem
->m_bIsFolder
))
188 else if ((iAction
== ACTION_HIGHLIGHT_ITEM
|| iAction
== ACTION_MOUSE_LEFT_CLICK
|| iAction
== ACTION_SELECT_ITEM
) &&
189 (m_multipleSelection
&& !pItem
->m_bIsShareOrDrive
&& !pItem
->m_bIsFolder
))
191 pItem
->Select(!pItem
->IsSelected());
192 CGUIMessage
msg(GUI_MSG_ITEM_SELECT
, GetID(), message
.GetSenderId(), iItem
+ 1);
196 else if (message
.GetSenderId() == CONTROL_OK
)
198 if (m_browsingForFolders
== 2)
200 int iItem
= m_viewControl
.GetSelectedItem();
204 strPath
= m_selectedPath
;
206 strPath
= (*m_vecItems
)[iItem
]->GetPath();
208 std::string strTest
= URIUtils::AddFileToFolder(strPath
, "1");
210 if (file
.OpenForWrite(strTest
,true))
213 CFile::Delete(strTest
);
218 HELPERS::ShowOKDialogText(CVariant
{257}, CVariant
{20072});
222 if (m_multipleSelection
)
224 for (int iItem
= 0; iItem
< m_vecItems
->Size(); ++iItem
)
226 CFileItemPtr pItem
= (*m_vecItems
)[iItem
];
227 if (pItem
->IsSelected())
228 m_markedPath
.push_back(pItem
->GetPath());
236 else if (message
.GetSenderId() == CONTROL_CANCEL
)
241 else if (message
.GetSenderId() == CONTROL_NEWFOLDER
)
243 std::string strInput
;
244 if (CGUIKeyboardFactory::ShowAndGetInput(strInput
, CVariant
{g_localizeStrings
.Get(119)}, false))
246 std::string strPath
= URIUtils::AddFileToFolder(m_vecItems
->GetPath(), strInput
);
247 if (CDirectory::Create(strPath
))
248 Update(m_vecItems
->GetPath());
250 HELPERS::ShowOKDialogText(CVariant
{20069}, CVariant
{20072});
253 else if (message
.GetSenderId() == CONTROL_FLIP
)
257 case GUI_MSG_SETFOCUS
:
259 if (m_viewControl
.HasControl(message
.GetControlId()) && m_viewControl
.GetCurrentControl() != message
.GetControlId())
261 m_viewControl
.SetFocused();
266 case GUI_MSG_NOTIFY_ALL
:
267 { // Message is received only if this window is active
268 if (message
.GetParam1() == GUI_MSG_REMOVED_MEDIA
)
270 if (m_Directory
->IsVirtualDirectoryRoot() && IsActive())
272 int iItem
= m_viewControl
.GetSelectedItem();
273 Update(m_Directory
->GetPath());
274 m_viewControl
.SetSelectedItem(iItem
);
276 else if (m_Directory
->IsRemovable())
277 { // check that we have this removable share still
278 if (!m_rootDir
.IsInSource(m_Directory
->GetPath()))
279 { // don't have this share any more
280 if (IsActive()) Update("");
283 m_history
.ClearPathHistory();
284 m_Directory
->SetPath("");
290 else if (message
.GetParam1()==GUI_MSG_UPDATE_SOURCES
)
291 { // State of the sources changed, so update our view
292 if (m_Directory
->IsVirtualDirectoryRoot() && IsActive())
294 int iItem
= m_viewControl
.GetSelectedItem();
295 Update(m_Directory
->GetPath());
296 m_viewControl
.SetSelectedItem(iItem
);
300 else if (message
.GetParam1()==GUI_MSG_UPDATE_PATH
)
304 if((message
.GetStringParam() == m_Directory
->GetPath()) ||
305 (m_Directory
->IsMultiPath() && XFILE::CMultiPathDirectory::HasPath(m_Directory
->GetPath(), message
.GetStringParam())))
307 int iItem
= m_viewControl
.GetSelectedItem();
308 Update(m_Directory
->GetPath());
309 m_viewControl
.SetSelectedItem(iItem
);
317 return CGUIDialog::OnMessage(message
);
320 void CGUIDialogFileBrowser::ClearFileItems()
322 m_viewControl
.Clear();
323 m_vecItems
->Clear(); // will clean up everything
326 void CGUIDialogFileBrowser::OnSort()
329 m_vecItems
->Sort(SortByLabel
, SortOrderAscending
);
332 void CGUIDialogFileBrowser::Update(const std::string
&strDirectory
)
334 const CURL
pathToUrl(strDirectory
);
336 if (m_browsingForImages
&& m_thumbLoader
.IsLoading())
337 m_thumbLoader
.StopThread();
339 int iItem
= m_viewControl
.GetSelectedItem();
340 std::string strSelectedItem
;
341 if (iItem
>= 0 && iItem
< m_vecItems
->Size())
343 CFileItemPtr pItem
= (*m_vecItems
)[iItem
];
344 if (!pItem
->IsParentFolder())
346 strSelectedItem
= pItem
->GetPath();
347 URIUtils::RemoveSlashAtEnd(strSelectedItem
);
348 m_history
.SetSelectedItem(strSelectedItem
, m_Directory
->GetPath().empty()?"empty":m_Directory
->GetPath());
355 std::string strParentPath
;
357 if (!m_rootDir
.GetDirectory(pathToUrl
, items
, m_useFileDirectories
, false))
359 CLog::Log(LOGERROR
, "CGUIDialogFileBrowser::GetDirectory({}) failed",
360 pathToUrl
.GetRedacted());
362 // We assume, we can get the parent
364 std::string strParentPath
= m_history
.GetParentPath();
365 m_history
.RemoveParentPath();
366 Update(strParentPath
);
370 // check if current directory is a root share
371 if (!m_rootDir
.IsSource(strDirectory
))
373 if (URIUtils::GetParentPath(strDirectory
, strParentPath
))
375 CFileItemPtr
pItem(new CFileItem(".."));
376 pItem
->SetPath(strParentPath
);
377 pItem
->m_bIsFolder
= true;
378 pItem
->m_bIsShareOrDrive
= false;
379 items
.AddFront(pItem
, 0);
384 // yes, this is the root of a share
385 // add parent path to the virtual directory
386 CFileItemPtr
pItem(new CFileItem(".."));
388 pItem
->m_bIsShareOrDrive
= false;
389 pItem
->m_bIsFolder
= true;
390 items
.AddFront(pItem
, 0);
395 m_vecItems
->Copy(items
);
396 m_Directory
->SetPath(strDirectory
);
397 m_strParentPath
= strParentPath
;
400 // if we're getting the root source listing
401 // make sure the path history is clean
402 if (strDirectory
.empty())
403 m_history
.ClearPathHistory();
405 // some evil stuff don't work with the '/' mask, e.g. shoutcast directory - make sure no files are in there
406 if (m_browsingForFolders
)
408 for (int i
=0;i
<m_vecItems
->Size();++i
)
409 if (!(*m_vecItems
)[i
]->m_bIsFolder
)
411 m_vecItems
->Remove(i
);
416 // No need to set thumbs
418 m_vecItems
->FillInDefaultIcons();
422 if (m_Directory
->GetPath().empty() && m_addNetworkShareEnabled
&&
423 (CServiceBroker::GetSettingsComponent()->GetProfileManager()->GetMasterProfile().getLockMode() == LOCK_MODE_EVERYONE
||
424 CServiceBroker::GetSettingsComponent()->GetProfileManager()->IsMasterProfile() || g_passwordManager
.bMasterUser
))
425 { // we are in the virtual directory - add the "Add Network Location" item
426 CFileItemPtr
pItem(new CFileItem(g_localizeStrings
.Get(1032)));
427 pItem
->SetPath("net://");
428 pItem
->m_bIsFolder
= true;
429 m_vecItems
->Add(pItem
);
431 if (m_Directory
->GetPath().empty() && !m_addSourceType
.empty())
433 CFileItemPtr
pItem(new CFileItem(g_localizeStrings
.Get(21359)));
434 pItem
->SetPath("source://");
435 pItem
->m_bIsFolder
= true;
436 m_vecItems
->Add(pItem
);
439 m_viewControl
.SetItems(*m_vecItems
);
440 m_viewControl
.SetCurrentView((m_browsingForImages
&& CAutoSwitch::ByFileCount(*m_vecItems
)) ? CONTROL_THUMBS
: CONTROL_LIST
);
442 std::string strPath2
= m_Directory
->GetPath();
443 URIUtils::RemoveSlashAtEnd(strPath2
);
444 strSelectedItem
= m_history
.GetSelectedItem(strPath2
==""?"empty":strPath2
);
446 bool bSelectedFound
= false;
447 for (int i
= 0; i
< m_vecItems
->Size(); ++i
)
449 CFileItemPtr pItem
= (*m_vecItems
)[i
];
450 strPath2
= pItem
->GetPath();
451 URIUtils::RemoveSlashAtEnd(strPath2
);
452 if (strPath2
== strSelectedItem
)
454 m_viewControl
.SetSelectedItem(i
);
455 bSelectedFound
= true;
460 // if we haven't found the selected item, select the first item
462 m_viewControl
.SetSelectedItem(0);
464 m_history
.AddPath(m_Directory
->GetPath());
466 if (m_browsingForImages
)
467 m_thumbLoader
.Load(*m_vecItems
);
470 void CGUIDialogFileBrowser::FrameMove()
472 int item
= m_viewControl
.GetSelectedItem();
475 // if we are browsing for folders, and not in the root directory, then we use the parent path,
476 // else we use the current file's path
477 if (m_browsingForFolders
&& !m_Directory
->IsVirtualDirectoryRoot())
478 m_selectedPath
= m_Directory
->GetPath();
480 m_selectedPath
= (*m_vecItems
)[item
]->GetPath();
481 if (m_selectedPath
== "net://")
483 SET_CONTROL_LABEL(CONTROL_LABEL_PATH
, g_localizeStrings
.Get(1032)); // "Add Network Location..."
487 // Update the current path label
488 CURL
url(m_selectedPath
);
489 std::string safePath
= url
.GetWithoutUserDetails();
490 SET_CONTROL_LABEL(CONTROL_LABEL_PATH
, safePath
);
492 if ((!m_browsingForFolders
&& (*m_vecItems
)[item
]->m_bIsFolder
) || ((*m_vecItems
)[item
]->GetPath() == "image://Browse"))
494 CONTROL_DISABLE(CONTROL_OK
);
498 CONTROL_ENABLE(CONTROL_OK
);
500 if (m_browsingForFolders
== 2)
502 CONTROL_ENABLE(CONTROL_NEWFOLDER
);
506 CONTROL_DISABLE(CONTROL_NEWFOLDER
);
510 CONTROL_ENABLE(CONTROL_FLIP
);
514 CONTROL_DISABLE(CONTROL_FLIP
);
517 CGUIDialog::FrameMove();
520 void CGUIDialogFileBrowser::OnClick(int iItem
)
522 if ( iItem
< 0 || iItem
>= m_vecItems
->Size() ) return ;
523 CFileItemPtr pItem
= (*m_vecItems
)[iItem
];
524 std::string strPath
= pItem
->GetPath();
526 if (pItem
->m_bIsFolder
)
528 if (pItem
->GetPath() == "net://")
529 { // special "Add Network Location" item
530 OnAddNetworkLocation();
533 if (pItem
->GetPath() == "source://")
534 { // special "Add Source" item
538 if (!m_addSourceType
.empty())
540 OnEditMediaSource(pItem
.get());
543 if ( pItem
->m_bIsShareOrDrive
)
545 if ( !HaveDiscOrConnection( pItem
->m_iDriveType
) )
550 else if (!m_browsingForFolders
)
552 m_selectedPath
= pItem
->GetPath();
558 bool CGUIDialogFileBrowser::HaveDiscOrConnection( int iDriveType
)
560 if ( iDriveType
== CMediaSource::SOURCE_TYPE_DVD
)
562 if (!CServiceBroker::GetMediaManager().IsDiscInDrive())
564 HELPERS::ShowOKDialogText(CVariant
{218}, CVariant
{219});
568 else if ( iDriveType
== CMediaSource::SOURCE_TYPE_REMOTE
)
570 //! @todo Handle not connected to a remote share
571 if ( !CServiceBroker::GetNetwork().IsConnected() )
573 HELPERS::ShowOKDialogText(CVariant
{220}, CVariant
{221});
581 void CGUIDialogFileBrowser::GoParentFolder()
583 std::string
strPath(m_strParentPath
);
584 if (strPath
.size() == 2)
585 if (strPath
[1] == ':')
586 URIUtils::AddSlashAtEnd(strPath
);
590 void CGUIDialogFileBrowser::OnWindowLoaded()
592 CGUIDialog::OnWindowLoaded();
593 m_viewControl
.Reset();
594 m_viewControl
.SetParentWindow(GetID());
595 m_viewControl
.AddView(GetControl(CONTROL_LIST
));
596 m_viewControl
.AddView(GetControl(CONTROL_THUMBS
));
599 void CGUIDialogFileBrowser::OnWindowUnload()
601 CGUIDialog::OnWindowUnload();
602 m_viewControl
.Reset();
605 bool CGUIDialogFileBrowser::ShowAndGetImage(const CFileItemList
&items
, const VECSOURCES
&shares
, const std::string
&heading
, std::string
&result
, bool* flip
, int label
)
607 CGUIDialogFileBrowser
*browser
= new CGUIDialogFileBrowser();
610 CServiceBroker::GetGUI()->GetWindowManager().AddUniqueInstance(browser
);
612 browser
->m_browsingForImages
= true;
613 browser
->m_singleList
= true;
614 browser
->m_vecItems
->Clear();
615 browser
->m_vecItems
->Append(items
);
618 CFileItemPtr
item(new CFileItem("image://Browse", false));
619 item
->SetLabel(g_localizeStrings
.Get(20153));
620 item
->SetArt("icon", "DefaultFolder.png");
621 browser
->m_vecItems
->Add(item
);
623 browser
->SetHeading(heading
);
624 browser
->m_flipEnabled
= flip
?true:false;
626 bool confirmed(browser
->IsConfirmed());
629 result
= browser
->m_selectedPath
;
630 if (result
== "image://Browse")
631 { // "Browse for thumb"
632 CServiceBroker::GetGUI()->GetWindowManager().Remove(browser
->GetID());
634 return ShowAndGetImage(shares
, g_localizeStrings
.Get(label
), result
);
639 *flip
= browser
->m_bFlip
!= 0;
641 CServiceBroker::GetGUI()->GetWindowManager().Remove(browser
->GetID());
647 bool CGUIDialogFileBrowser::ShowAndGetImage(const VECSOURCES
&shares
, const std::string
&heading
, std::string
&path
)
649 return ShowAndGetFile(shares
, CServiceBroker::GetFileExtensionProvider().GetPictureExtensions(), heading
, path
, true); // true for use thumbs
652 bool CGUIDialogFileBrowser::ShowAndGetImageList(const VECSOURCES
&shares
, const std::string
&heading
, std::vector
<std::string
> &path
)
654 return ShowAndGetFileList(shares
, CServiceBroker::GetFileExtensionProvider().GetPictureExtensions(), heading
, path
, true); // true for use thumbs
657 bool CGUIDialogFileBrowser::ShowAndGetDirectory(const VECSOURCES
&shares
, const std::string
&heading
, std::string
&path
, bool bWriteOnly
)
659 // an extension mask of "/" ensures that no files are shown
662 VECSOURCES shareWritable
;
663 for (unsigned int i
=0;i
<shares
.size();++i
)
665 if (shares
[i
].IsWritable())
666 shareWritable
.push_back(shares
[i
]);
669 return ShowAndGetFile(shareWritable
, "/w", heading
, path
);
672 return ShowAndGetFile(shares
, "/", heading
, path
);
675 bool CGUIDialogFileBrowser::ShowAndGetFile(const VECSOURCES
&shares
, const std::string
&mask
, const std::string
&heading
, std::string
&path
, bool useThumbs
/* = false */, bool useFileDirectories
/* = false */)
677 CGUIDialogFileBrowser
*browser
= new CGUIDialogFileBrowser();
680 CServiceBroker::GetGUI()->GetWindowManager().AddUniqueInstance(browser
);
682 browser
->m_useFileDirectories
= useFileDirectories
;
684 browser
->m_browsingForImages
= useThumbs
;
685 browser
->SetHeading(heading
);
686 browser
->SetSources(shares
);
687 std::string strMask
= mask
;
689 browser
->m_browsingForFolders
=1;
693 browser
->m_browsingForFolders
=2;
697 browser
->m_browsingForFolders
= 0;
699 browser
->m_rootDir
.SetMask(strMask
);
700 browser
->m_selectedPath
= path
;
701 browser
->m_addNetworkShareEnabled
= false;
703 bool confirmed(browser
->IsConfirmed());
705 path
= browser
->m_selectedPath
;
706 CServiceBroker::GetGUI()->GetWindowManager().Remove(browser
->GetID());
711 // same as above, starting in a single directory
712 bool CGUIDialogFileBrowser::ShowAndGetFile(const std::string
&directory
, const std::string
&mask
, const std::string
&heading
, std::string
&path
, bool useThumbs
/* = false */, bool useFileDirectories
/* = false */, bool singleList
/* = false */)
714 CGUIDialogFileBrowser
*browser
= new CGUIDialogFileBrowser();
717 CServiceBroker::GetGUI()->GetWindowManager().AddUniqueInstance(browser
);
719 browser
->m_useFileDirectories
= useFileDirectories
;
720 browser
->m_browsingForImages
= useThumbs
;
721 browser
->SetHeading(heading
);
723 // add a single share for this directory
728 share
.strPath
= directory
;
729 URIUtils::RemoveSlashAtEnd(share
.strPath
); // this is needed for the dodgy code in WINDOW_INIT
730 shares
.push_back(share
);
731 browser
->SetSources(shares
);
735 browser
->m_vecItems
->Clear();
736 CDirectory::GetDirectory(directory
,*browser
->m_vecItems
, "", DIR_FLAG_DEFAULTS
);
737 CFileItemPtr
item(new CFileItem("file://Browse", false));
738 item
->SetLabel(g_localizeStrings
.Get(20153));
739 item
->SetArt("icon", "DefaultFolder.png");
740 browser
->m_vecItems
->Add(item
);
741 browser
->m_singleList
= true;
743 std::string strMask
= mask
;
745 browser
->m_browsingForFolders
=1;
749 browser
->m_browsingForFolders
=2;
753 browser
->m_browsingForFolders
= 0;
755 browser
->m_rootDir
.SetMask(strMask
);
756 browser
->m_selectedPath
= directory
;
757 browser
->m_addNetworkShareEnabled
= false;
759 bool confirmed(browser
->IsConfirmed());
761 path
= browser
->m_selectedPath
;
762 if (path
== "file://Browse")
763 { // "Browse for thumb"
764 CServiceBroker::GetGUI()->GetWindowManager().Remove(browser
->GetID());
767 CServiceBroker::GetMediaManager().GetLocalDrives(shares
);
769 return ShowAndGetFile(shares
, mask
, heading
, path
, useThumbs
,useFileDirectories
);
771 CServiceBroker::GetGUI()->GetWindowManager().Remove(browser
->GetID());
776 bool CGUIDialogFileBrowser::ShowAndGetFileList(const VECSOURCES
&shares
, const std::string
&mask
, const std::string
&heading
, std::vector
<std::string
> &path
, bool useThumbs
/* = false */, bool useFileDirectories
/* = false */)
778 CGUIDialogFileBrowser
*browser
= new CGUIDialogFileBrowser();
781 CServiceBroker::GetGUI()->GetWindowManager().AddUniqueInstance(browser
);
783 browser
->m_useFileDirectories
= useFileDirectories
;
784 browser
->m_multipleSelection
= true;
785 browser
->m_browsingForImages
= useThumbs
;
786 browser
->SetHeading(heading
);
787 browser
->SetSources(shares
);
788 browser
->m_browsingForFolders
= 0;
789 browser
->m_rootDir
.SetMask(mask
);
790 browser
->m_addNetworkShareEnabled
= false;
792 bool confirmed(browser
->IsConfirmed());
795 if (browser
->m_markedPath
.size())
796 path
= browser
->m_markedPath
;
798 path
.push_back(browser
->m_selectedPath
);
800 CServiceBroker::GetGUI()->GetWindowManager().Remove(browser
->GetID());
805 void CGUIDialogFileBrowser::SetHeading(const std::string
&heading
)
808 SET_CONTROL_LABEL(CONTROL_HEADING_LABEL
, heading
);
811 bool CGUIDialogFileBrowser::ShowAndGetSource(std::string
&path
, bool allowNetworkShares
, VECSOURCES
* additionalShare
/* = NULL */, const std::string
& strType
/* = "" */)
814 // 1. Show Filebrowser with currently defined local, and optionally the network locations.
815 // 2. Have the "Add Network Location" option in addition.
816 // 3a. If the "Add Network Location" is pressed, then:
817 // a) Fire up the network location dialog to grab the new location
818 // b) Check the location by doing a GetDirectory() - if it fails, prompt the user
819 // to allow them to add currently disconnected network shares.
820 // c) Save this location to our xml file (network.xml)
822 // 3b. If the "Add Source" is pressed, then:
823 // a) Fire up the media source dialog to add the new location
824 // 4. Optionally allow user to browse the local and network locations for their share.
827 // Create a new filebrowser window
828 CGUIDialogFileBrowser
*browser
= new CGUIDialogFileBrowser();
829 if (!browser
) return false;
831 // Add it to our window manager
832 CServiceBroker::GetGUI()->GetWindowManager().AddUniqueInstance(browser
);
835 if (!strType
.empty())
838 shares
= *additionalShare
;
839 browser
->m_addSourceType
= strType
;
843 browser
->SetHeading(g_localizeStrings
.Get(1023));
845 CServiceBroker::GetMediaManager().GetLocalDrives(shares
);
847 // Now the additional share if appropriate
850 shares
.insert(shares
.end(),additionalShare
->begin(),additionalShare
->end());
853 // Now add the network shares...
854 if (allowNetworkShares
)
856 CServiceBroker::GetMediaManager().GetNetworkLocations(shares
);
860 browser
->SetSources(shares
);
861 browser
->m_rootDir
.SetMask("/");
862 browser
->m_rootDir
.AllowNonLocalSources(false); // don't allow plug n play shares
863 browser
->m_browsingForFolders
= 1;
864 browser
->m_addNetworkShareEnabled
= allowNetworkShares
;
865 browser
->m_selectedPath
= "";
867 bool confirmed
= browser
->IsConfirmed();
869 path
= browser
->m_selectedPath
;
871 CServiceBroker::GetGUI()->GetWindowManager().Remove(browser
->GetID());
876 void CGUIDialogFileBrowser::SetSources(const VECSOURCES
&shares
)
879 if (!m_shares
.size() && m_addSourceType
.empty())
880 CServiceBroker::GetMediaManager().GetLocalDrives(m_shares
);
881 m_rootDir
.SetSources(m_shares
);
884 void CGUIDialogFileBrowser::OnAddNetworkLocation()
886 // ok, fire up the network location dialog
888 if (CGUIDialogNetworkSetup::ShowAndGetNetworkAddress(path
))
890 // verify the path by doing a GetDirectory.
892 if (CDirectory::GetDirectory(path
, items
, "", DIR_FLAG_NO_FILE_DIRS
| DIR_FLAG_ALLOW_PROMPT
) || CGUIDialogYesNo::ShowAndGetInput(CVariant
{1001}, CVariant
{1002}))
893 { // add the network location to the shares list
895 share
.strPath
= path
; //setPath(path);
897 share
.strName
= url
.GetWithoutUserDetails();
898 URIUtils::RemoveSlashAtEnd(share
.strName
);
899 m_shares
.push_back(share
);
900 // add to our location manager...
901 CServiceBroker::GetMediaManager().AddNetworkLocation(path
);
904 m_rootDir
.SetSources(m_shares
);
905 Update(m_vecItems
->GetPath());
908 void CGUIDialogFileBrowser::OnAddMediaSource()
910 if (CGUIDialogMediaSource::ShowAndAddMediaSource(m_addSourceType
))
912 SetSources(*CMediaSourceSettings::GetInstance().GetSources(m_addSourceType
));
917 void CGUIDialogFileBrowser::OnEditMediaSource(CFileItem
* pItem
)
919 if (CGUIDialogMediaSource::ShowAndEditMediaSource(m_addSourceType
,pItem
->GetLabel()))
921 SetSources(*CMediaSourceSettings::GetInstance().GetSources(m_addSourceType
));
926 bool CGUIDialogFileBrowser::OnPopupMenu(int iItem
)
928 CContextButtons choices
;
929 choices
.Add(1, m_addSourceType
.empty() ? 20133 : 21364);
930 choices
.Add(2, m_addSourceType
.empty() ? 20134 : 21365);
932 int btnid
= CGUIDialogContextMenu::ShowAndGetChoice(choices
);
935 if (m_addNetworkShareEnabled
)
937 std::string strOldPath
=m_selectedPath
,newPath
=m_selectedPath
;
938 VECSOURCES shares
=m_shares
;
939 if (CGUIDialogNetworkSetup::ShowAndGetNetworkAddress(newPath
))
941 CServiceBroker::GetMediaManager().SetLocationPath(strOldPath
, newPath
);
943 for (unsigned int i
=0;i
<shares
.size();++i
)
945 if (URIUtils::CompareWithoutSlashAtEnd(shares
[i
].strPath
, strOldPath
))//getPath().Equals(strOldPath))
947 shares
[i
].strName
= url
.GetWithoutUserDetails();
948 shares
[i
].strPath
= newPath
;
949 URIUtils::RemoveSlashAtEnd(shares
[i
].strName
);
953 // refresh dialog content
955 m_rootDir
.SetMask("/");
956 m_browsingForFolders
= 1;
957 m_addNetworkShareEnabled
= true;
958 m_selectedPath
= url
.GetWithoutUserDetails();
959 Update(m_Directory
->GetPath());
960 m_viewControl
.SetSelectedItem(iItem
);
965 CFileItemPtr item
= m_vecItems
->Get(iItem
);
966 OnEditMediaSource(item
.get());
971 if (m_addNetworkShareEnabled
)
973 CServiceBroker::GetMediaManager().RemoveLocation(m_selectedPath
);
975 for (unsigned int i
=0;i
<m_shares
.size();++i
)
977 if (URIUtils::CompareWithoutSlashAtEnd(m_shares
[i
].strPath
, m_selectedPath
) && !m_shares
[i
].m_ignore
) // getPath().Equals(m_selectedPath))
979 m_shares
.erase(m_shares
.begin()+i
);
983 m_rootDir
.SetSources(m_shares
);
984 m_rootDir
.SetMask("/");
986 m_browsingForFolders
= 1;
987 m_addNetworkShareEnabled
= true;
990 Update(m_Directory
->GetPath());
994 CMediaSourceSettings::GetInstance().DeleteSource(m_addSourceType
,(*m_vecItems
)[iItem
]->GetLabel(),(*m_vecItems
)[iItem
]->GetPath());
995 SetSources(*CMediaSourceSettings::GetInstance().GetSources(m_addSourceType
));
1003 CFileItemPtr
CGUIDialogFileBrowser::GetCurrentListItem(int offset
)
1005 int item
= m_viewControl
.GetSelectedItem();
1006 if (item
< 0 || !m_vecItems
->Size()) return CFileItemPtr();
1008 item
= (item
+ offset
) % m_vecItems
->Size();
1009 if (item
< 0) item
+= m_vecItems
->Size();
1010 return (*m_vecItems
)[item
];
1013 CGUIControl
*CGUIDialogFileBrowser::GetFirstFocusableControl(int id
)
1015 if (m_viewControl
.HasControl(id
))
1016 id
= m_viewControl
.GetCurrentControl();
1017 return CGUIWindow::GetFirstFocusableControl(id
);