2 * Copyright (C) 2012-2020 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 "GUIWindowGames.h"
12 #include "GUIPassword.h"
13 #include "ServiceBroker.h"
16 #include "addons/gui/GUIDialogAddonInfo.h"
17 #include "application/Application.h"
18 #include "dialogs/GUIDialogContextMenu.h"
19 #include "dialogs/GUIDialogMediaSource.h"
20 #include "dialogs/GUIDialogProgress.h"
21 #include "guilib/GUIComponent.h"
22 #include "guilib/GUIWindowManager.h"
23 #include "guilib/WindowIDs.h"
24 #include "input/actions/ActionIDs.h"
25 #include "media/MediaLockState.h"
26 #include "playlists/PlayListTypes.h"
27 #include "settings/MediaSourceSettings.h"
28 #include "settings/Settings.h"
29 #include "settings/SettingsComponent.h"
30 #include "utils/StringUtils.h"
31 #include "utils/URIUtils.h"
38 #define CONTROL_BTNVIEWASICONS 2
39 #define CONTROL_BTNSORTBY 3
40 #define CONTROL_BTNSORTASC 4
42 CGUIWindowGames::CGUIWindowGames() : CGUIMediaWindow(WINDOW_GAMES
, "MyGames.xml")
46 bool CGUIWindowGames::OnMessage(CGUIMessage
& message
)
48 switch (message
.GetMessage())
50 case GUI_MSG_WINDOW_INIT
:
52 m_rootDir
.AllowNonLocalSources(true); //! @todo
54 // Is this the first time the window is opened?
55 if (m_vecItems
->GetPath() == "?" && message
.GetStringParam().empty())
56 message
.SetStringParam(CMediaSourceSettings::GetInstance().GetDefaultSource("games"));
59 m_dlgProgress
= CServiceBroker::GetGUI()->GetWindowManager().GetWindow
<CGUIDialogProgress
>(
60 WINDOW_DIALOG_PROGRESS
);
66 if (OnClickMsg(message
.GetSenderId(), message
.GetParam1()))
73 return CGUIMediaWindow::OnMessage(message
);
76 bool CGUIWindowGames::OnClickMsg(int controlId
, int actionId
)
78 if (!m_viewControl
.HasControl(controlId
)) // list/thumb control
81 const int iItem
= m_viewControl
.GetSelectedItem();
83 CFileItemPtr pItem
= m_vecItems
->Get(iItem
);
89 case ACTION_DELETE_ITEM
:
92 if (CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(
93 CSettings::SETTING_FILELISTS_ALLOWFILEDELETION
))
100 case ACTION_PLAYER_PLAY
:
106 case ACTION_SHOW_INFO
:
108 if (!m_vecItems
->IsPlugin())
110 if (pItem
->HasAddonInfo())
112 CGUIDialogAddonInfo::ShowForItem(pItem
);
125 void CGUIWindowGames::SetupShares()
127 CGUIMediaWindow::SetupShares();
129 // Don't convert zip files to directories. Otherwise, the files will be
130 // opened and scanned for games with a valid extension. If none are found,
131 // the .zip won't be shown.
133 // This is a problem for MAME roms, because the files inside the .zip don't
134 // have standard extensions.
136 m_rootDir
.SetFlags(XFILE::DIR_FLAG_NO_FILE_DIRS
);
139 bool CGUIWindowGames::OnClick(int iItem
, const std::string
& player
/* = "" */)
141 CFileItemPtr item
= m_vecItems
->Get(iItem
);
144 // Compensate for DIR_FLAG_NO_FILE_DIRS flag
145 if (URIUtils::IsArchive(item
->GetPath()))
147 bool bIsGame
= false;
149 // If zip file contains no games, assume it is a game
151 if (m_rootDir
.GetDirectory(CURL(item
->GetPath()), items
))
153 if (items
.Size() == 0)
158 item
->m_bIsFolder
= true;
161 if (!item
->m_bIsFolder
)
168 return CGUIMediaWindow::OnClick(iItem
, player
);
171 void CGUIWindowGames::GetContextButtons(int itemNumber
, CContextButtons
& buttons
)
173 CFileItemPtr item
= m_vecItems
->Get(itemNumber
);
175 if (item
&& !item
->GetProperty("pluginreplacecontextitems").asBoolean())
177 if (m_vecItems
->IsVirtualDirectoryRoot() || m_vecItems
->IsSourcesPath())
179 // Context buttons for a sources path, like "Add Source", "Remove Source", etc.
180 CGUIDialogContextMenu::GetContextButtons("games", item
, buttons
);
186 buttons
.Add(CONTEXT_BUTTON_PLAY_ITEM
, 208); // Play
189 if (CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(
190 CSettings::SETTING_FILELISTS_ALLOWFILEDELETION
) &&
193 buttons
.Add(CONTEXT_BUTTON_DELETE
, 117);
194 buttons
.Add(CONTEXT_BUTTON_RENAME
, 118);
199 CGUIMediaWindow::GetContextButtons(itemNumber
, buttons
);
202 bool CGUIWindowGames::OnContextButton(int itemNumber
, CONTEXT_BUTTON button
)
204 CFileItemPtr item
= m_vecItems
->Get(itemNumber
);
207 if (m_vecItems
->IsVirtualDirectoryRoot() || m_vecItems
->IsSourcesPath())
209 if (CGUIDialogContextMenu::OnContextButton("games", item
, button
))
211 Update(m_vecItems
->GetPath());
217 case CONTEXT_BUTTON_PLAY_ITEM
:
220 case CONTEXT_BUTTON_INFO
:
221 CGUIDialogAddonInfo::ShowForItem(item
);
223 case CONTEXT_BUTTON_DELETE
:
224 OnDeleteItem(itemNumber
);
226 case CONTEXT_BUTTON_RENAME
:
227 OnRenameItem(itemNumber
);
233 return CGUIMediaWindow::OnContextButton(itemNumber
, button
);
236 bool CGUIWindowGames::OnAddMediaSource()
238 return CGUIDialogMediaSource::ShowAndAddMediaSource("games");
241 bool CGUIWindowGames::GetDirectory(const std::string
& strDirectory
, CFileItemList
& items
)
243 if (!CGUIMediaWindow::GetDirectory(strDirectory
, items
))
248 if (items
.GetLabel().empty())
251 if (m_rootDir
.IsSource(items
.GetPath(), CMediaSourceSettings::GetInstance().GetSources("games"),
253 label
= std::move(source
);
257 items
.SetLabel(label
);
261 if (items
.GetContent().empty())
263 if (!items
.IsVirtualDirectoryRoot() && // Don't set content for root directory
264 !items
.IsPlugin()) // Don't set content for plugins
270 if (!content
.empty())
271 items
.SetContent(content
);
273 // Ensure a game info tag is created so that files are recognized as games
274 for (const CFileItemPtr
& item
: items
)
276 if (!item
->m_bIsFolder
)
277 item
->GetGameInfoTag();
283 std::string
CGUIWindowGames::GetStartFolder(const std::string
& dir
)
285 // From CGUIWindowPictures::GetStartFolder()
287 if (StringUtils::EqualsNoCase(dir
, "plugins") || StringUtils::EqualsNoCase(dir
, "addons"))
289 return "addons://sources/game/";
294 m_rootDir
.GetSources(shares
);
295 bool bIsSourceName
= false;
296 int iIndex
= CUtil::GetMatchingSource(dir
, shares
, bIsSourceName
);
299 if (iIndex
< static_cast<int>(shares
.size()) && shares
[iIndex
].m_iHasLock
== LOCK_STATE_LOCKED
)
301 CFileItem
item(shares
[iIndex
]);
302 if (!g_passwordManager
.IsItemUnlocked(&item
, "games"))
306 return shares
[iIndex
].strPath
;
309 return CGUIMediaWindow::GetStartFolder(dir
);
312 void CGUIWindowGames::OnItemInfo(int itemNumber
)
314 CFileItemPtr item
= m_vecItems
->Get(itemNumber
);
318 if (!m_vecItems
->IsPlugin())
320 if (item
->IsPlugin() || item
->IsScript())
321 CGUIDialogAddonInfo::ShowForItem(item
);
326 CGUIDialogGameInfo* gameInfo =
327 CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogGameInfo>(WINDOW_DIALOG_PICTURE_INFO);
330 gameInfo->SetGame(item);
336 bool CGUIWindowGames::PlayGame(const CFileItem
& item
)
338 CFileItem
itemCopy(item
);
339 return g_application
.PlayMedia(itemCopy
, "", PLAYLIST::TYPE_NONE
);