diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 18:07:22 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 18:07:22 +0000 |
commit | c04dcc2e7d834218ef2d4194331e383402495ae1 (patch) | |
tree | 7333e38d10d75386e60f336b80c2443c1166031d /xbmc/interfaces/legacy/Dialog.cpp | |
parent | Initial commit. (diff) | |
download | kodi-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.cpp | 622 |
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(); + } + + } +} |