summaryrefslogtreecommitdiffstats
path: root/xbmc/pvr/guilib/PVRGUIActionsDatabase.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'xbmc/pvr/guilib/PVRGUIActionsDatabase.cpp')
-rw-r--r--xbmc/pvr/guilib/PVRGUIActionsDatabase.cpp341
1 files changed, 341 insertions, 0 deletions
diff --git a/xbmc/pvr/guilib/PVRGUIActionsDatabase.cpp b/xbmc/pvr/guilib/PVRGUIActionsDatabase.cpp
new file mode 100644
index 0000000..53bbf81
--- /dev/null
+++ b/xbmc/pvr/guilib/PVRGUIActionsDatabase.cpp
@@ -0,0 +1,341 @@
+/*
+ * Copyright (C) 2016-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 "PVRGUIActionsDatabase.h"
+
+#include "FileItem.h"
+#include "ServiceBroker.h"
+#include "dialogs/GUIDialogProgress.h"
+#include "dialogs/GUIDialogSelect.h"
+#include "dialogs/GUIDialogYesNo.h"
+#include "guilib/GUIComponent.h"
+#include "guilib/GUIWindowManager.h"
+#include "guilib/LocalizeStrings.h"
+#include "guilib/WindowIDs.h"
+#include "messaging/ApplicationMessenger.h"
+#include "pvr/PVRDatabase.h"
+#include "pvr/PVRManager.h"
+#include "pvr/PVRPlaybackState.h"
+#include "pvr/epg/EpgContainer.h"
+#include "pvr/epg/EpgDatabase.h"
+#include "pvr/guilib/PVRGUIActionsParentalControl.h"
+#include "pvr/recordings/PVRRecordings.h"
+#include "pvr/recordings/PVRRecordingsPath.h"
+#include "utils/StringUtils.h"
+#include "utils/Variant.h"
+#include "utils/log.h"
+#include "video/VideoDatabase.h"
+
+#include <memory>
+#include <string>
+
+using namespace PVR;
+
+namespace
+{
+class CPVRGUIDatabaseResetComponentsSelector
+{
+public:
+ CPVRGUIDatabaseResetComponentsSelector() = default;
+ virtual ~CPVRGUIDatabaseResetComponentsSelector() = default;
+
+ bool Select()
+ {
+ CGUIDialogSelect* pDlgSelect =
+ CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogSelect>(
+ WINDOW_DIALOG_SELECT);
+ if (!pDlgSelect)
+ {
+ CLog::LogF(LOGERROR, "Unable to get WINDOW_DIALOG_SELECT!");
+ return false;
+ }
+
+ CFileItemList options;
+
+ const std::shared_ptr<CFileItem> itemAll =
+ std::make_shared<CFileItem>(StringUtils::Format(g_localizeStrings.Get(593))); // All
+ itemAll->SetPath("all");
+ options.Add(itemAll);
+
+ // if channels are cleared, groups, EPG data and providers must also be cleared
+ const std::shared_ptr<CFileItem> itemChannels =
+ std::make_shared<CFileItem>(StringUtils::Format("{}, {}, {}, {}",
+ g_localizeStrings.Get(19019), // Channels
+ g_localizeStrings.Get(19146), // Groups
+ g_localizeStrings.Get(19069), // Guide
+ g_localizeStrings.Get(19334))); // Providers
+ itemChannels->SetPath("channels");
+ itemChannels->Select(true); // preselect this item in dialog
+ options.Add(itemChannels);
+
+ const std::shared_ptr<CFileItem> itemGroups =
+ std::make_shared<CFileItem>(g_localizeStrings.Get(19146)); // Groups
+ itemGroups->SetPath("groups");
+ options.Add(itemGroups);
+
+ const std::shared_ptr<CFileItem> itemGuide =
+ std::make_shared<CFileItem>(g_localizeStrings.Get(19069)); // Guide
+ itemGuide->SetPath("guide");
+ options.Add(itemGuide);
+
+ const std::shared_ptr<CFileItem> itemProviders =
+ std::make_shared<CFileItem>(g_localizeStrings.Get(19334)); // Providers
+ itemProviders->SetPath("providers");
+ options.Add(itemProviders);
+
+ const std::shared_ptr<CFileItem> itemReminders =
+ std::make_shared<CFileItem>(g_localizeStrings.Get(19215)); // Reminders
+ itemReminders->SetPath("reminders");
+ options.Add(itemReminders);
+
+ const std::shared_ptr<CFileItem> itemRecordings =
+ std::make_shared<CFileItem>(g_localizeStrings.Get(19017)); // Recordings
+ itemRecordings->SetPath("recordings");
+ options.Add(itemRecordings);
+
+ const std::shared_ptr<CFileItem> itemClients =
+ std::make_shared<CFileItem>(g_localizeStrings.Get(24019)); // PVR clients
+ itemClients->SetPath("clients");
+ options.Add(itemClients);
+
+ pDlgSelect->Reset();
+ pDlgSelect->SetHeading(CVariant{g_localizeStrings.Get(19185)}); // "Clear data"
+ pDlgSelect->SetItems(options);
+ pDlgSelect->SetMultiSelection(true);
+ pDlgSelect->Open();
+
+ if (!pDlgSelect->IsConfirmed())
+ return false;
+
+ for (int i : pDlgSelect->GetSelectedItems())
+ {
+ const std::string path = options.Get(i)->GetPath();
+
+ m_bResetChannels |= (path == "channels" || path == "all");
+ m_bResetGroups |= (path == "groups" || path == "all");
+ m_bResetGuide |= (path == "guide" || path == "all");
+ m_bResetProviders |= (path == "providers" || path == "all");
+ m_bResetReminders |= (path == "reminders" || path == "all");
+ m_bResetRecordings |= (path == "recordings" || path == "all");
+ m_bResetClients |= (path == "clients" || path == "all");
+ }
+
+ m_bResetGroups |= m_bResetChannels;
+ m_bResetGuide |= m_bResetChannels;
+ m_bResetProviders |= m_bResetChannels;
+
+ return (m_bResetChannels || m_bResetGroups || m_bResetGuide || m_bResetProviders ||
+ m_bResetReminders || m_bResetRecordings || m_bResetClients);
+ }
+
+ bool IsResetChannelsSelected() const { return m_bResetChannels; }
+ bool IsResetGroupsSelected() const { return m_bResetGroups; }
+ bool IsResetGuideSelected() const { return m_bResetGuide; }
+ bool IsResetProvidersSelected() const { return m_bResetProviders; }
+ bool IsResetRemindersSelected() const { return m_bResetReminders; }
+ bool IsResetRecordingsSelected() const { return m_bResetRecordings; }
+ bool IsResetClientsSelected() const { return m_bResetClients; }
+
+private:
+ bool m_bResetChannels = false;
+ bool m_bResetGroups = false;
+ bool m_bResetGuide = false;
+ bool m_bResetProviders = false;
+ bool m_bResetReminders = false;
+ bool m_bResetRecordings = false;
+ bool m_bResetClients = false;
+};
+
+} // unnamed namespace
+
+bool CPVRGUIActionsDatabase::ResetDatabase(bool bResetEPGOnly)
+{
+ CGUIDialogProgress* pDlgProgress =
+ CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogProgress>(
+ WINDOW_DIALOG_PROGRESS);
+ if (!pDlgProgress)
+ {
+ CLog::LogF(LOGERROR, "Unable to get WINDOW_DIALOG_PROGRESS!");
+ return false;
+ }
+
+ bool bResetChannels = false;
+ bool bResetGroups = false;
+ bool bResetGuide = false;
+ bool bResetProviders = false;
+ bool bResetReminders = false;
+ bool bResetRecordings = false;
+ bool bResetClients = false;
+
+ if (bResetEPGOnly)
+ {
+ if (!CGUIDialogYesNo::ShowAndGetInput(
+ CVariant{19098}, // "Warning!"
+ CVariant{19188})) // "All guide data will be cleared. Are you sure?"
+ return false;
+
+ bResetGuide = true;
+ }
+ else
+ {
+ if (CServiceBroker::GetPVRManager().Get<PVR::GUI::Parental>().CheckParentalPIN() !=
+ ParentalCheckResult::SUCCESS)
+ return false;
+
+ CPVRGUIDatabaseResetComponentsSelector selector;
+ if (!selector.Select())
+ return false;
+
+ if (!CGUIDialogYesNo::ShowAndGetInput(
+ CVariant{19098}, // "Warning!"
+ CVariant{19186})) // "All selected data will be cleared. ... Are you sure?"
+ return false;
+
+ bResetChannels = selector.IsResetChannelsSelected();
+ bResetGroups = selector.IsResetGroupsSelected();
+ bResetGuide = selector.IsResetGuideSelected();
+ bResetProviders = selector.IsResetProvidersSelected();
+ bResetReminders = selector.IsResetRemindersSelected();
+ bResetRecordings = selector.IsResetRecordingsSelected();
+ bResetClients = selector.IsResetClientsSelected();
+ }
+
+ CDateTime::ResetTimezoneBias();
+
+ CLog::LogFC(LOGDEBUG, LOGPVR, "PVR clearing {} database", bResetEPGOnly ? "EPG" : "PVR and EPG");
+
+ pDlgProgress->SetHeading(CVariant{313}); // "Cleaning database"
+ pDlgProgress->SetLine(0, CVariant{g_localizeStrings.Get(19187)}); // "Clearing all related data."
+ pDlgProgress->SetLine(1, CVariant{""});
+ pDlgProgress->SetLine(2, CVariant{""});
+
+ pDlgProgress->Open();
+ pDlgProgress->Progress();
+
+ if (CServiceBroker::GetPVRManager().PlaybackState()->IsPlaying())
+ {
+ CLog::Log(LOGINFO, "PVR is stopping playback for {} database reset",
+ bResetEPGOnly ? "EPG" : "PVR and EPG");
+ CServiceBroker::GetAppMessenger()->SendMsg(TMSG_MEDIA_STOP);
+ }
+
+ const std::shared_ptr<CPVRDatabase> pvrDatabase(CServiceBroker::GetPVRManager().GetTVDatabase());
+ const std::shared_ptr<CPVREpgDatabase> epgDatabase(
+ CServiceBroker::GetPVRManager().EpgContainer().GetEpgDatabase());
+
+ // increase db open refcounts, so they don't get closed during following pvr manager shutdown
+ pvrDatabase->Open();
+ epgDatabase->Open();
+
+ // stop pvr manager; close both pvr and epg databases
+ CServiceBroker::GetPVRManager().Stop();
+
+ const int iProgressStepPercentage =
+ 100 / ((2 * bResetChannels) + bResetGroups + bResetGuide + bResetProviders + bResetReminders +
+ bResetRecordings + bResetClients + 1);
+ int iProgressStepsDone = 0;
+
+ if (bResetProviders)
+ {
+ pDlgProgress->SetPercentage(iProgressStepPercentage * ++iProgressStepsDone);
+ pDlgProgress->Progress();
+
+ // delete all providers
+ pvrDatabase->DeleteProviders();
+ }
+
+ if (bResetGuide)
+ {
+ pDlgProgress->SetPercentage(iProgressStepPercentage * ++iProgressStepsDone);
+ pDlgProgress->Progress();
+
+ // reset channel's EPG pointers
+ pvrDatabase->ResetEPG();
+
+ // delete all entries from the EPG database
+ epgDatabase->DeleteEpg();
+ }
+
+ if (bResetGroups)
+ {
+ pDlgProgress->SetPercentage(iProgressStepPercentage * ++iProgressStepsDone);
+ pDlgProgress->Progress();
+
+ // delete all channel groups (including data only available locally, like user defined groups)
+ pvrDatabase->DeleteChannelGroups();
+ }
+
+ if (bResetChannels)
+ {
+ pDlgProgress->SetPercentage(iProgressStepPercentage * ++iProgressStepsDone);
+ pDlgProgress->Progress();
+
+ // delete all channels (including data only available locally, like user set icons)
+ pvrDatabase->DeleteChannels();
+ }
+
+ if (bResetReminders)
+ {
+ pDlgProgress->SetPercentage(iProgressStepPercentage * ++iProgressStepsDone);
+ pDlgProgress->Progress();
+
+ // delete all timers data (e.g. all reminders, which are only stored locally)
+ pvrDatabase->DeleteTimers();
+ }
+
+ if (bResetClients)
+ {
+ pDlgProgress->SetPercentage(iProgressStepPercentage * ++iProgressStepsDone);
+ pDlgProgress->Progress();
+
+ // delete all clients data (e.g priorities, which are only stored locally)
+ pvrDatabase->DeleteClients();
+ }
+
+ if (bResetChannels || bResetRecordings)
+ {
+ CVideoDatabase videoDatabase;
+
+ if (videoDatabase.Open())
+ {
+ if (bResetChannels)
+ {
+ pDlgProgress->SetPercentage(iProgressStepPercentage * ++iProgressStepsDone);
+ pDlgProgress->Progress();
+
+ // delete all channel's entries (e.g. settings, bookmarks, stream details)
+ videoDatabase.EraseAllForPath("pvr://channels/");
+ }
+
+ if (bResetRecordings)
+ {
+ pDlgProgress->SetPercentage(iProgressStepPercentage * ++iProgressStepsDone);
+ pDlgProgress->Progress();
+
+ // delete all recording's entries (e.g. settings, bookmarks, stream details)
+ videoDatabase.EraseAllForPath(CPVRRecordingsPath::PATH_RECORDINGS);
+ }
+
+ videoDatabase.Close();
+ }
+ }
+
+ // decrease db open refcounts; this actually closes dbs because refcounts drops to zero
+ pvrDatabase->Close();
+ epgDatabase->Close();
+
+ CLog::LogFC(LOGDEBUG, LOGPVR, "{} database cleared", bResetEPGOnly ? "EPG" : "PVR and EPG");
+
+ CLog::Log(LOGINFO, "Restarting the PVR Manager after {} database reset",
+ bResetEPGOnly ? "EPG" : "PVR and EPG");
+ CServiceBroker::GetPVRManager().Start();
+
+ pDlgProgress->SetPercentage(100);
+ pDlgProgress->Close();
+ return true;
+}