summaryrefslogtreecommitdiffstats
path: root/xbmc/interfaces/legacy/Dialog.cpp
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 18:07:22 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 18:07:22 +0000
commitc04dcc2e7d834218ef2d4194331e383402495ae1 (patch)
tree7333e38d10d75386e60f336b80c2443c1166031d /xbmc/interfaces/legacy/Dialog.cpp
parentInitial commit. (diff)
downloadkodi-c04dcc2e7d834218ef2d4194331e383402495ae1.tar.xz
kodi-c04dcc2e7d834218ef2d4194331e383402495ae1.zip
Adding upstream version 2:20.4+dfsg.upstream/2%20.4+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'xbmc/interfaces/legacy/Dialog.cpp')
-rw-r--r--xbmc/interfaces/legacy/Dialog.cpp622
1 files changed, 622 insertions, 0 deletions
diff --git a/xbmc/interfaces/legacy/Dialog.cpp b/xbmc/interfaces/legacy/Dialog.cpp
new file mode 100644
index 0000000..6dd00f1
--- /dev/null
+++ b/xbmc/interfaces/legacy/Dialog.cpp
@@ -0,0 +1,622 @@
+ /*
+ * Copyright (C) 2005-2018 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+#include "Dialog.h"
+
+#include "LanguageHook.h"
+#include "ListItem.h"
+#include "ModuleXbmcgui.h"
+#include "ServiceBroker.h"
+#include "WindowException.h"
+#include "dialogs/GUIDialogColorPicker.h"
+#include "dialogs/GUIDialogContextMenu.h"
+#include "dialogs/GUIDialogFileBrowser.h"
+#include "dialogs/GUIDialogKaiToast.h"
+#include "dialogs/GUIDialogNumeric.h"
+#include "dialogs/GUIDialogSelect.h"
+#include "dialogs/GUIDialogTextViewer.h"
+#include "dialogs/GUIDialogYesNo.h"
+#include "guilib/GUIComponent.h"
+#include "guilib/GUIKeyboardFactory.h"
+#include "guilib/GUIWindowManager.h"
+#include "messaging/helpers/DialogOKHelper.h"
+#include "music/dialogs/GUIDialogMusicInfo.h"
+#include "settings/MediaSourceSettings.h"
+#include "storage/MediaManager.h"
+#include "utils/StringUtils.h"
+#include "utils/Variant.h"
+#include "utils/XTimeUtils.h"
+#include "utils/log.h"
+#include "video/dialogs/GUIDialogVideoInfo.h"
+
+ using namespace KODI::MESSAGING;
+
+#define ACTIVE_WINDOW CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow()
+
+namespace XBMCAddon
+{
+ namespace xbmcgui
+ {
+ Dialog::~Dialog() = default;
+
+ bool Dialog::yesno(const String& heading,
+ const String& message,
+ const String& nolabel,
+ const String& yeslabel,
+ int autoclose,
+ int defaultbutton)
+ {
+ return yesNoCustomInternal(heading, message, nolabel, yeslabel, emptyString, autoclose,
+ defaultbutton) == 1;
+ }
+
+ int Dialog::yesnocustom(const String& heading,
+ const String& message,
+ const String& customlabel,
+ const String& nolabel,
+ const String& yeslabel,
+ int autoclose,
+ int defaultbutton)
+ {
+ return yesNoCustomInternal(heading, message, nolabel, yeslabel, customlabel, autoclose,
+ defaultbutton);
+ }
+
+ int Dialog::yesNoCustomInternal(const String& heading,
+ const String& message,
+ const String& nolabel,
+ const String& yeslabel,
+ const String& customlabel,
+ int autoclose,
+ int defaultbutton)
+ {
+ DelayedCallGuard dcguard(languageHook);
+ CGUIDialogYesNo* pDialog =
+ CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogYesNo>(
+ WINDOW_DIALOG_YES_NO);
+ if (pDialog == nullptr)
+ throw WindowException("Error: Window is null");
+
+ return pDialog->ShowAndGetInput(CVariant{heading}, CVariant{message}, CVariant{nolabel},
+ CVariant{yeslabel}, CVariant{customlabel}, autoclose,
+ defaultbutton);
+ }
+
+ bool Dialog::info(const ListItem* item)
+ {
+ DelayedCallGuard dcguard(languageHook);
+ const AddonClass::Ref<xbmcgui::ListItem> listitem(item);
+ if (listitem->item->HasVideoInfoTag())
+ {
+ CGUIDialogVideoInfo::ShowFor(*listitem->item);
+ return true;
+ }
+ else if (listitem->item->HasMusicInfoTag())
+ {
+ CGUIDialogMusicInfo::ShowFor(listitem->item.get());
+ return true;
+ }
+ return false;
+ }
+
+ int Dialog::contextmenu(const std::vector<String>& list)
+ {
+ DelayedCallGuard dcguard(languageHook);
+ CGUIDialogContextMenu* pDialog= CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogContextMenu>(WINDOW_DIALOG_CONTEXT_MENU);
+ if (pDialog == NULL)
+ throw WindowException("Error: Window is NULL, this is not possible :-)");
+
+ CContextButtons choices;
+ for(unsigned int i = 0; i < list.size(); i++)
+ {
+ choices.Add(i, list[i]);
+ }
+ return pDialog->Show(choices);
+ }
+
+
+ int Dialog::select(const String& heading, const std::vector<Alternative<String, const ListItem* > > & list, int autoclose, int preselect, bool useDetails)
+ {
+ DelayedCallGuard dcguard(languageHook);
+ CGUIDialogSelect* pDialog= CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogSelect>(WINDOW_DIALOG_SELECT);
+ if (pDialog == NULL)
+ throw WindowException("Error: Window is NULL, this is not possible :-)");
+
+ pDialog->Reset();
+ if (!heading.empty())
+ pDialog->SetHeading(CVariant{heading});
+ for (const auto& item : list)
+ {
+ AddonClass::Ref<ListItem> ritem = item.which() == XBMCAddon::first ? ListItem::fromString(item.former()) : AddonClass::Ref<ListItem>(item.later());
+ CFileItemPtr& fileItem = ritem->item;
+ pDialog->Add(*fileItem);
+ }
+ if (preselect > -1)
+ pDialog->SetSelected(preselect);
+ if (autoclose > 0)
+ pDialog->SetAutoClose(autoclose);
+ pDialog->SetUseDetails(useDetails);
+ pDialog->Open();
+
+ return pDialog->GetSelectedItem();
+ }
+
+
+ std::unique_ptr<std::vector<int>> Dialog::multiselect(const String& heading,
+ const std::vector<Alternative<String, const ListItem* > > & options, int autoclose, const std::vector<int>& preselect, bool useDetails)
+ {
+ DelayedCallGuard dcguard(languageHook);
+ CGUIDialogSelect* pDialog = CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogSelect>(WINDOW_DIALOG_SELECT);
+ if (pDialog == nullptr)
+ throw WindowException("Error: Window is NULL");
+
+ pDialog->Reset();
+ pDialog->SetMultiSelection(true);
+ pDialog->SetHeading(CVariant{heading});
+
+ for (const auto& item : options)
+ {
+ AddonClass::Ref<ListItem> ritem = item.which() == XBMCAddon::first ? ListItem::fromString(item.former()) : AddonClass::Ref<ListItem>(item.later());
+ CFileItemPtr& fileItem = ritem->item;
+ pDialog->Add(*fileItem);
+ }
+ if (autoclose > 0)
+ pDialog->SetAutoClose(autoclose);
+ pDialog->SetUseDetails(useDetails);
+ pDialog->SetSelected(preselect);
+ pDialog->Open();
+
+ if (pDialog->IsConfirmed())
+ return std::unique_ptr<std::vector<int>>(new std::vector<int>(pDialog->GetSelectedItems()));
+ else
+ return std::unique_ptr<std::vector<int>>();
+ }
+
+ bool Dialog::ok(const String& heading, const String& message)
+ {
+ DelayedCallGuard dcguard(languageHook);
+ return HELPERS::ShowOKDialogText(CVariant{heading}, CVariant{message});
+ }
+
+ void Dialog::textviewer(const String& heading, const String& text, bool usemono)
+ {
+ DelayedCallGuard dcguard(languageHook);
+
+ CGUIDialogTextViewer* pDialog = CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogTextViewer>(WINDOW_DIALOG_TEXT_VIEWER);
+ if (pDialog == NULL)
+ throw WindowException("Error: Window is NULL, this is not possible :-)");
+ if (!heading.empty())
+ pDialog->SetHeading(heading);
+ if (!text.empty())
+ pDialog->SetText(text);
+ pDialog->UseMonoFont(usemono);
+ pDialog->Open();
+ }
+
+
+ Alternative<String, std::vector<String> > Dialog::browse(int type, const String& heading,
+ const String& s_shares, const String& maskparam, bool useThumbs,
+ bool useFileDirectories, const String& defaultt,
+ bool enableMultiple)
+ {
+ Alternative<String, std::vector<String> > ret;
+ if (enableMultiple)
+ ret.later() = browseMultiple(type,heading,s_shares,maskparam,useThumbs,useFileDirectories,defaultt);
+ else
+ ret.former() = browseSingle(type,heading,s_shares,maskparam,useThumbs,useFileDirectories,defaultt);
+ return ret;
+ }
+
+ String Dialog::browseSingle(int type, const String& heading, const String& s_shares,
+ const String& maskparam, bool useThumbs,
+ bool useFileDirectories,
+ const String& defaultt )
+ {
+ DelayedCallGuard dcguard(languageHook);
+ std::string value;
+ std::string mask = maskparam;
+ VECSOURCES *shares = CMediaSourceSettings::GetInstance().GetSources(s_shares);
+
+ VECSOURCES localShares;
+ if (!shares)
+ {
+ CServiceBroker::GetMediaManager().GetLocalDrives(localShares);
+ if (StringUtils::CompareNoCase(s_shares, "local") != 0)
+ CServiceBroker::GetMediaManager().GetNetworkLocations(localShares);
+ }
+ else // always append local drives
+ {
+ localShares = *shares;
+ CServiceBroker::GetMediaManager().GetLocalDrives(localShares);
+ }
+
+ if (useFileDirectories && !maskparam.empty())
+ mask += "|.rar|.zip";
+
+ value = defaultt;
+ if (type == 1)
+ CGUIDialogFileBrowser::ShowAndGetFile(localShares, mask, heading, value, useThumbs, useFileDirectories);
+ else if (type == 2)
+ CGUIDialogFileBrowser::ShowAndGetImage(localShares, heading, value);
+ else
+ CGUIDialogFileBrowser::ShowAndGetDirectory(localShares, heading, value, type != 0);
+ return value;
+ }
+
+ std::vector<String> Dialog::browseMultiple(int type, const String& heading, const String& s_shares,
+ const String& mask, bool useThumbs,
+ bool useFileDirectories, const String& defaultt )
+ {
+ DelayedCallGuard dcguard(languageHook);
+ VECSOURCES *shares = CMediaSourceSettings::GetInstance().GetSources(s_shares);
+ std::vector<String> valuelist;
+ String lmask = mask;
+
+ VECSOURCES localShares;
+ if (!shares)
+ {
+ CServiceBroker::GetMediaManager().GetLocalDrives(localShares);
+ if (StringUtils::CompareNoCase(s_shares, "local") != 0)
+ CServiceBroker::GetMediaManager().GetNetworkLocations(localShares);
+ }
+ else // always append local drives
+ {
+ localShares = *shares;
+ CServiceBroker::GetMediaManager().GetLocalDrives(localShares);
+ }
+
+ if (useFileDirectories && !lmask.empty())
+ lmask += "|.rar|.zip";
+
+ if (type == 1)
+ CGUIDialogFileBrowser::ShowAndGetFileList(localShares, lmask, heading, valuelist, useThumbs, useFileDirectories);
+ else if (type == 2)
+ CGUIDialogFileBrowser::ShowAndGetImageList(localShares, heading, valuelist);
+ else
+ throw WindowException("Error: Cannot retrieve multiple directories using browse %s is NULL.",s_shares.c_str());
+
+ return valuelist;
+ }
+
+ String Dialog::numeric(int inputtype, const String& heading, const String& defaultt, bool bHiddenInput)
+ {
+ DelayedCallGuard dcguard(languageHook);
+ std::string value;
+ KODI::TIME::SystemTime timedate;
+ KODI::TIME::GetLocalTime(&timedate);
+
+ if (!heading.empty())
+ {
+ if (inputtype == 1)
+ {
+ if (!defaultt.empty() && defaultt.size() == 10)
+ {
+ const std::string& sDefault = defaultt;
+ timedate.day = atoi(sDefault.substr(0, 2).c_str());
+ timedate.month = atoi(sDefault.substr(3, 4).c_str());
+ timedate.year = atoi(sDefault.substr(sDefault.size() - 4).c_str());
+ }
+ if (CGUIDialogNumeric::ShowAndGetDate(timedate, heading))
+ value =
+ StringUtils::Format("{:2}/{:2}/{:4}", timedate.day, timedate.month, timedate.year);
+ else
+ return emptyString;
+ }
+ else if (inputtype == 2)
+ {
+ if (!defaultt.empty() && defaultt.size() == 5)
+ {
+ const std::string& sDefault = defaultt;
+ timedate.hour = atoi(sDefault.substr(0, 2).c_str());
+ timedate.minute = atoi(sDefault.substr(3, 2).c_str());
+ }
+ if (CGUIDialogNumeric::ShowAndGetTime(timedate, heading))
+ value = StringUtils::Format("{:2}:{:02}", timedate.hour, timedate.minute);
+ else
+ return emptyString;
+ }
+ else if (inputtype == 3)
+ {
+ value = defaultt;
+ if (!CGUIDialogNumeric::ShowAndGetIPAddress(value, heading))
+ return emptyString;
+ }
+ else if (inputtype == 4)
+ {
+ value = defaultt;
+ if (!CGUIDialogNumeric::ShowAndVerifyNewPassword(value))
+ return emptyString;
+ }
+ else
+ {
+ value = defaultt;
+ if (!CGUIDialogNumeric::ShowAndGetNumber(value, heading, 0, bHiddenInput))
+ return emptyString;
+ }
+ }
+ return value;
+ }
+
+ void Dialog::notification(const String& heading, const String& message, const String& icon, int time, bool sound)
+ {
+ DelayedCallGuard dcguard(languageHook);
+
+ std::string strIcon = getNOTIFICATION_INFO();
+ int iTime = TOAST_DISPLAY_TIME;
+
+ if (time > 0)
+ iTime = time;
+ if (!icon.empty())
+ strIcon = icon;
+
+ if (strIcon == getNOTIFICATION_INFO())
+ CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, heading, message, iTime, sound);
+ else if (strIcon == getNOTIFICATION_WARNING())
+ CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Warning, heading, message, iTime, sound);
+ else if (strIcon == getNOTIFICATION_ERROR())
+ CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error, heading, message, iTime, sound);
+ else
+ CGUIDialogKaiToast::QueueNotification(strIcon, heading, message, iTime, sound);
+ }
+
+ String Dialog::input(const String& heading, const String& defaultt, int type, int option, int autoclose)
+ {
+ DelayedCallGuard dcguard(languageHook);
+ std::string value(defaultt);
+ KODI::TIME::SystemTime timedate;
+ KODI::TIME::GetLocalTime(&timedate);
+
+ switch (type)
+ {
+ case INPUT_ALPHANUM:
+ {
+ bool bHiddenInput = (option & ALPHANUM_HIDE_INPUT) == ALPHANUM_HIDE_INPUT;
+ if (!CGUIKeyboardFactory::ShowAndGetInput(value, CVariant{heading}, true, bHiddenInput, autoclose))
+ value = emptyString;
+ }
+ break;
+ case INPUT_NUMERIC:
+ {
+ if (!CGUIDialogNumeric::ShowAndGetNumber(value, heading, autoclose))
+ value = emptyString;
+ }
+ break;
+ case INPUT_DATE:
+ {
+ if (!defaultt.empty() && defaultt.size() == 10)
+ {
+ const std::string& sDefault = defaultt;
+ timedate.day = atoi(sDefault.substr(0, 2).c_str());
+ timedate.month = atoi(sDefault.substr(3, 4).c_str());
+ timedate.year = atoi(sDefault.substr(sDefault.size() - 4).c_str());
+ }
+ if (CGUIDialogNumeric::ShowAndGetDate(timedate, heading))
+ value = StringUtils::Format("{:2}/{:2}/{:4}", timedate.day, timedate.month,
+ timedate.year);
+ else
+ value = emptyString;
+ }
+ break;
+ case INPUT_TIME:
+ {
+ if (!defaultt.empty() && defaultt.size() == 5)
+ {
+ const std::string& sDefault = defaultt;
+ timedate.hour = atoi(sDefault.substr(0, 2).c_str());
+ timedate.minute = atoi(sDefault.substr(3, 2).c_str());
+ }
+ if (CGUIDialogNumeric::ShowAndGetTime(timedate, heading))
+ value = StringUtils::Format("{:2}:{:02}", timedate.hour, timedate.minute);
+ else
+ value = emptyString;
+ }
+ break;
+ case INPUT_IPADDRESS:
+ {
+ if (!CGUIDialogNumeric::ShowAndGetIPAddress(value, heading))
+ value = emptyString;
+ }
+ break;
+ case INPUT_PASSWORD:
+ {
+ bool bResult = false;
+
+ if (option & PASSWORD_VERIFY)
+ bResult = CGUIKeyboardFactory::ShowAndVerifyPassword(value, heading, 0, autoclose) == 0 ? true : false;
+ else
+ bResult = CGUIKeyboardFactory::ShowAndVerifyNewPassword(value, heading, true, autoclose);
+
+ if (!bResult)
+ value = emptyString;
+ }
+ break;
+ default:
+ value = emptyString;
+ break;
+ }
+
+ return value;
+ }
+
+ String Dialog::colorpicker(const String& heading,
+ const String& selectedcolor,
+ const String& colorfile,
+ const std::vector<const ListItem*>& colorlist)
+ {
+ DelayedCallGuard dcguard(languageHook);
+ std::string value = emptyString;
+ CGUIDialogColorPicker* pDialog =
+ CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogColorPicker>(
+ WINDOW_DIALOG_COLOR_PICKER);
+ if (pDialog == nullptr)
+ throw WindowException("Error: Window is NULL, this is not possible :-)");
+
+ pDialog->Reset();
+ if (!heading.empty())
+ pDialog->SetHeading(CVariant{heading});
+
+ if (!colorlist.empty())
+ {
+ CFileItemList items;
+ for (const auto& coloritem : colorlist)
+ {
+ items.Add(coloritem->item);
+ }
+ pDialog->SetItems(items);
+ }
+ else if (!colorfile.empty())
+ pDialog->LoadColors(colorfile);
+ else
+ pDialog->LoadColors();
+
+ if (!selectedcolor.empty())
+ pDialog->SetSelectedColor(selectedcolor);
+
+ pDialog->Open();
+
+ if (pDialog->IsConfirmed())
+ value = pDialog->GetSelectedColor();
+ return value;
+ }
+
+ DialogProgress::~DialogProgress() { XBMC_TRACE; deallocating(); }
+
+ void DialogProgress::deallocating()
+ {
+ XBMC_TRACE;
+
+ if (dlg && open)
+ {
+ DelayedCallGuard dg;
+ dlg->Close();
+ }
+ }
+
+ void DialogProgress::create(const String& heading, const String& message)
+ {
+ DelayedCallGuard dcguard(languageHook);
+ CGUIDialogProgress* pDialog= CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogProgress>(WINDOW_DIALOG_PROGRESS);
+
+ if (pDialog == NULL)
+ throw WindowException("Error: Window is NULL, this is not possible :-)");
+
+ dlg = pDialog;
+ open = true;
+
+ pDialog->SetHeading(CVariant{heading});
+
+ if (!message.empty())
+ pDialog->SetText(CVariant{message});
+
+ pDialog->Open();
+ }
+
+ void DialogProgress::update(int percent, const String& message)
+ {
+ DelayedCallGuard dcguard(languageHook);
+ CGUIDialogProgress* pDialog = dlg;
+
+ if (pDialog == NULL)
+ throw WindowException("Dialog not created.");
+
+ if (percent >= 0 && percent <= 100)
+ {
+ pDialog->SetPercentage(percent);
+ pDialog->ShowProgressBar(true);
+ }
+ else
+ {
+ pDialog->ShowProgressBar(false);
+ }
+
+ if (!message.empty())
+ pDialog->SetText(CVariant{message});
+ }
+
+ void DialogProgress::close()
+ {
+ DelayedCallGuard dcguard(languageHook);
+ if (dlg == NULL)
+ throw WindowException("Dialog not created.");
+ dlg->Close();
+ open = false;
+ }
+
+ bool DialogProgress::iscanceled()
+ {
+ if (dlg == NULL)
+ throw WindowException("Dialog not created.");
+ return dlg->IsCanceled();
+ }
+
+ DialogProgressBG::~DialogProgressBG() { XBMC_TRACE; deallocating(); }
+
+ void DialogProgressBG::deallocating()
+ {
+ XBMC_TRACE;
+
+ if (dlg && open)
+ {
+ DelayedCallGuard dg;
+ dlg->Close();
+ }
+ }
+
+ void DialogProgressBG::create(const String& heading, const String& message)
+ {
+ DelayedCallGuard dcguard(languageHook);
+ CGUIDialogExtendedProgressBar* pDialog =
+ CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogExtendedProgressBar>(WINDOW_DIALOG_EXT_PROGRESS);
+
+ if (pDialog == NULL)
+ throw WindowException("Error: Window is NULL, this is not possible :-)");
+
+ CGUIDialogProgressBarHandle* pHandle = pDialog->GetHandle(heading);
+
+ dlg = pDialog;
+ handle = pHandle;
+ open = true;
+
+ pHandle->SetTitle(heading);
+ if (!message.empty())
+ pHandle->SetText(message);
+ }
+
+ void DialogProgressBG::update(int percent, const String& heading, const String& message)
+ {
+ DelayedCallGuard dcguard(languageHook);
+ CGUIDialogProgressBarHandle* pHandle = handle;
+
+ if (pHandle == NULL)
+ throw WindowException("Dialog not created.");
+
+ if (percent >= 0 && percent <= 100)
+ pHandle->SetPercentage((float)percent);
+ if (!heading.empty())
+ pHandle->SetTitle(heading);
+ if (!message.empty())
+ pHandle->SetText(message);
+ }
+
+ void DialogProgressBG::close()
+ {
+ DelayedCallGuard dcguard(languageHook);
+ if (handle == NULL)
+ throw WindowException("Dialog not created.");
+ handle->MarkFinished();
+ open = false;
+ }
+
+ bool DialogProgressBG::isFinished()
+ {
+ if (handle == NULL)
+ throw WindowException("Dialog not created.");
+ return handle->IsFinished();
+ }
+
+ }
+}