Skip to content

Commit

Permalink
Merge pull request xbmc#25755 from ksooo/pvr-epg-search-copy
Browse files Browse the repository at this point in the history
[PVR] Add possibility to make copies of EPG saved searches (e.g. to use an existing search as a template for a new search).
  • Loading branch information
ksooo authored Sep 24, 2024
2 parents 00784cb + d67b074 commit ce88eca
Show file tree
Hide file tree
Showing 9 changed files with 190 additions and 132 deletions.
14 changes: 13 additions & 1 deletion addons/resource.language.en_gb/resources/strings.po
Original file line number Diff line number Diff line change
Expand Up @@ -11855,7 +11855,19 @@ msgctxt "#19354"
msgid "Play only this programme"
msgstr ""

#empty strings from id 19355 to 19498
#. Label of a context menu entry to create a copy of an EPG saved saerch
#: xbmc/pvr/PVRContextMenus.cpp
msgctxt "#19355"
msgid "Duplicate"
msgstr ""

#. Initial title of a duplicated EPG saved search.
#: xbmc/pvr/PVRContextMenus.cpp
msgctxt "#19356"
msgid "Copy of '{0:s}'"
msgstr ""

#empty strings from id 19357 to 19498

#. label for epg genre value
#: xbmc/pvr/epg/Epg.cpp
Expand Down
15 changes: 15 additions & 0 deletions xbmc/pvr/PVRContextMenus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ DECL_STATICCONTEXTMENUITEM(ExecuteSearch);
DECL_STATICCONTEXTMENUITEM(EditSearch);
DECL_STATICCONTEXTMENUITEM(RenameSearch);
DECL_STATICCONTEXTMENUITEM(ChooseIconForSearch);
DECL_STATICCONTEXTMENUITEM(DuplicateSearch);
DECL_STATICCONTEXTMENUITEM(DeleteSearch);

class PVRClientMenuHook : public IContextMenuItem
Expand Down Expand Up @@ -748,6 +749,19 @@ bool ChooseIconForSearch::Execute(const std::shared_ptr<CFileItem>& item) const
return CServiceBroker::GetPVRManager().Get<PVR::GUI::EPG>().ChooseIconForSavedSearch(*item);
}

///////////////////////////////////////////////////////////////////////////////
// Duplicate a saved search

bool DuplicateSearch::IsVisible(const CFileItem& item) const
{
return item.HasEPGSearchFilter();
}

bool DuplicateSearch::Execute(const std::shared_ptr<CFileItem>& item) const
{
return CServiceBroker::GetPVRManager().Get<PVR::GUI::EPG>().DuplicateSavedSearch(*item);
}

///////////////////////////////////////////////////////////////////////////////
// Delete saved search

Expand Down Expand Up @@ -794,6 +808,7 @@ CPVRContextMenuManager::CPVRContextMenuManager()
std::make_shared<CONTEXTMENUITEM::EditSearch>(21450), /* Edit */
std::make_shared<CONTEXTMENUITEM::RenameSearch>(118), /* Rename */
std::make_shared<CONTEXTMENUITEM::ChooseIconForSearch>(19284), /* Choose icon */
std::make_shared<CONTEXTMENUITEM::DuplicateSearch>(19355), /* Duplicate */
std::make_shared<CONTEXTMENUITEM::DeleteSearch>(117), /* Delete */
})
{
Expand Down
5 changes: 3 additions & 2 deletions xbmc/pvr/PVRDatabase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -590,7 +590,7 @@ int CPVRDatabase::GetClientID(const std::string& addonID, unsigned int instanceI
if (ExecuteQuery(sql))
return static_cast<int>(m_pDS->lastinsertid());

return -1;
return PVR_CLIENT_INVALID_UID;
}

/********** Channel provider methods **********/
Expand Down Expand Up @@ -1306,7 +1306,8 @@ std::vector<std::shared_ptr<CPVRTimerInfoTag>> CPVRDatabase::GetTimers(
newTag->m_iClientIndex = -m_pDS->fv("iClientIndex").get_asInt();
newTag->m_iParentClientIndex = m_pDS->fv("iParentClientIndex").get_asInt();
newTag->m_iClientId = m_pDS->fv("iClientId").get_asInt();
newTag->SetTimerType(CPVRTimerType::CreateFromIds(m_pDS->fv("iTimerType").get_asInt(), -1));
newTag->SetTimerType(CPVRTimerType::CreateFromIds(m_pDS->fv("iTimerType").get_asInt(),
PVR_CLIENT_INVALID_UID));
newTag->m_state = static_cast<PVR_TIMER_STATE>(m_pDS->fv("iState").get_asInt());
newTag->m_strTitle = m_pDS->fv("sTitle").get_asString().c_str();
newTag->m_iClientChannelUid = m_pDS->fv("iClientChannelUid").get_asInt();
Expand Down
8 changes: 4 additions & 4 deletions xbmc/pvr/epg/EpgDatabase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1442,7 +1442,7 @@ bool CPVREpgDatabase::Persist(CPVREpgSearchFilter& epgSearch)

// Insert a new entry if this is a new search, replace the existing otherwise
std::string strQuery;
if (epgSearch.GetDatabaseId() == -1)
if (epgSearch.GetDatabaseId() == PVR_EPG_SEARCH_INVALID_DATABASE_ID)
strQuery = PrepareSQL(
"INSERT INTO savedsearches "
"(sTitle, sLastExecutedDateTime, sSearchTerm, bSearchInDescription, bIsCaseSensitive, "
Expand Down Expand Up @@ -1510,7 +1510,7 @@ bool CPVREpgDatabase::Persist(CPVREpgSearchFilter& epgSearch)
if (bReturn)
{
// Set the database id for searches persisted for the first time
if (epgSearch.GetDatabaseId() == -1)
if (epgSearch.GetDatabaseId() == PVR_EPG_SEARCH_INVALID_DATABASE_ID)
epgSearch.SetDatabaseId(static_cast<int>(m_pDS->lastinsertid()));

epgSearch.SetChanged(false);
Expand All @@ -1521,7 +1521,7 @@ bool CPVREpgDatabase::Persist(CPVREpgSearchFilter& epgSearch)

bool CPVREpgDatabase::UpdateSavedSearchLastExecuted(const CPVREpgSearchFilter& epgSearch)
{
if (epgSearch.GetDatabaseId() == -1)
if (epgSearch.GetDatabaseId() == PVR_EPG_SEARCH_INVALID_DATABASE_ID)
return false;

std::unique_lock<CCriticalSection> lock(m_critSection);
Expand All @@ -1534,7 +1534,7 @@ bool CPVREpgDatabase::UpdateSavedSearchLastExecuted(const CPVREpgSearchFilter& e

bool CPVREpgDatabase::Delete(const CPVREpgSearchFilter& epgSearch)
{
if (epgSearch.GetDatabaseId() == -1)
if (epgSearch.GetDatabaseId() == PVR_EPG_SEARCH_INVALID_DATABASE_ID)
return false;

CLog::LogFC(LOGDEBUG, LOGEPG, "Deleting saved search '{}' from the database",
Expand Down
12 changes: 7 additions & 5 deletions xbmc/pvr/epg/EpgSearchFilter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@

using namespace PVR;

CPVREpgSearchFilter::CPVREpgSearchFilter(bool bRadio)
: m_bIsRadio(bRadio)
CPVREpgSearchFilter::CPVREpgSearchFilter(bool bRadio) : m_bIsRadio(bRadio)
{
Reset();
}
Expand Down Expand Up @@ -366,7 +365,8 @@ void CPVREpgSearchFilter::RemoveDuplicates(std::vector<std::shared_ptr<CPVREpgIn
for (auto it = results.begin(); it != results.end();)
{
it = results.erase(std::remove_if(results.begin(), results.end(),
[&it](const std::shared_ptr<const CPVREpgInfoTag>& entry) {
[&it](const std::shared_ptr<const CPVREpgInfoTag>& entry)
{
return *it != entry && (*it)->Title() == entry->Title() &&
(*it)->Plot() == entry->Plot() &&
(*it)->PlotOutline() == entry->PlotOutline();
Expand Down Expand Up @@ -414,10 +414,12 @@ bool CPVREpgSearchFilter::MatchFreeToAir(const std::shared_ptr<const CPVREpgInfo

bool CPVREpgSearchFilter::MatchTimers(const std::shared_ptr<const CPVREpgInfoTag>& tag) const
{
return (!m_bIgnorePresentTimers || !CServiceBroker::GetPVRManager().Timers()->GetTimerForEpgTag(tag));
return (!m_bIgnorePresentTimers ||
!CServiceBroker::GetPVRManager().Timers()->GetTimerForEpgTag(tag));
}

bool CPVREpgSearchFilter::MatchRecordings(const std::shared_ptr<const CPVREpgInfoTag>& tag) const
{
return (!m_bIgnorePresentRecordings || !CServiceBroker::GetPVRManager().Recordings()->GetRecordingForEpgTag(tag));
return (!m_bIgnorePresentRecordings ||
!CServiceBroker::GetPVRManager().Recordings()->GetRecordingForEpgTag(tag));
}
Loading

0 comments on commit ce88eca

Please sign in to comment.