Skip to content

Commit

Permalink
[video] refactor select first unwatched season/episode item
Browse files Browse the repository at this point in the history
Undo previous changes made to add selection of first unplayed item.

Add settings videolibrary.tvshowselectfirstunwatcheditem (renamed from videolibrary.jumptofirstunplayeditem) and videolibrary.tvshowsincludeallseasonsandspecials

Add unwatched item selection to CGUIWindowVideoNav.
  • Loading branch information
Carcharius committed Mar 3, 2015
1 parent b7d1690 commit 8c7f35d
Show file tree
Hide file tree
Showing 9 changed files with 204 additions and 68 deletions.
51 changes: 46 additions & 5 deletions language/English/strings.po
Original file line number Diff line number Diff line change
Expand Up @@ -11338,7 +11338,7 @@ msgstr ""

#: system/settings/settings.xml
msgctxt "#21416"
msgid "Jump to first unwatched TV show season/episode"
msgid "Select the first unwatched TV show season/episode"
msgstr ""

#: system/settings/settings.xml
Expand Down Expand Up @@ -11562,10 +11562,10 @@ msgctxt "#21465"
msgid "Above video"
msgstr ""

#. Description of setting "Videos -> Library -> Jump to first unwatched TV show season/episode" with label #21416
#. Description of setting "Videos -> Library -> Select first unwatched TV show season/episode" with label #21416
#: system/settings/settings.xml
msgctxt "#21466"
msgid "When entering a TV show season or episode view automatically jump to the first unwatched season or episode."
msgid "When entering a TV show season or episode view automatically select the first unwatched season or episode. [On first entry] the first unwatched item will be selected only when a view is entered for the first time. [Always] the first unwatched item will be selected every time a view is entered."
msgstr ""

#. Filter (media data) from float value to float value
Expand Down Expand Up @@ -11593,7 +11593,48 @@ msgctxt "#21470"
msgid "%s [%d]"
msgstr ""

#empty strings from id 21471 to 21601
#. One of the values valid for "Videos -> Library -> Select first unwatched TV show season/episode" with label #21416
#: system/settings/settings.xml
msgctxt "#21471"
msgid "On first entry"
msgstr ""

#: system/settings/settings.xml
msgctxt "#21472"
msgid "Include All Seasons and Specials"
msgstr ""

#. Description of setting "Videos -> Library -> Include All Seasons and Specials" with label #21472
#: system/settings/settings.xml
msgctxt "#21473"
msgid "Whether or not to consider All Seasons and Special items in the unwatched item selection."
msgstr ""

#. One of the values valid for "Videos -> Library -> Include All Seasons and Specials" with label #21472
#: system/settings/settings.xml
msgctxt "#21474"
msgid "Neither"
msgstr ""

#. One of the values valid for "Videos -> Library -> Include All Seasons and Specials" with label #21472
#: system/settings/settings.xml
msgctxt "#21475"
msgid "Both"
msgstr ""

#. One of the values valid for "Videos -> Library -> Include All Seasons and Specials" with label #21472
#: system/settings/settings.xml
msgctxt "#21476"
msgid "Just All Seasons"
msgstr ""

#. One of the values valid for "Videos -> Library -> Include All Seasons and Specials" with label #21472
#: system/settings/settings.xml
msgctxt "#21477"
msgid "Just Specials"
msgstr ""

#empty strings from id 21478 to 21601

#: xbmc/Util.cpp
msgctxt "#21602"
Expand Down Expand Up @@ -16346,4 +16387,4 @@ msgstr ""
#: system/settings/settings.xml
msgctxt "#38012"
msgid "Hide "All Items" entry in directory (for example All Albums or All Seasons)"
msgstr ""
msgstr ""
29 changes: 26 additions & 3 deletions system/settings/settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -349,10 +349,33 @@
</constraints>
<control type="list" format="string" />
</setting>
<setting id="videolibrary.jumptofirstunplayeditem" type="boolean" label="21416" help="21466">
<setting id="videolibrary.tvshowsselectfirstunwatcheditem" type="integer" label="21416" help="21466">
<level>1</level>
<default>false</default>
<control type="toggle" />
<default>0</default> <!-- Never -->
<constraints>
<options>
<option label="20420">0</option> <!-- Never -->
<option label="21471">1</option> <!-- On first entry -->
<option label="20422">2</option> <!-- Always -->
</options>
</constraints>
<control type="spinner" format="string" />
</setting>
<setting id="videolibrary.tvshowsincludeallseasonsandspecials" type="integer" parent="videolibrary.tvshowsselectfirstunwatcheditem" label="21472" help="21473">
<level>2</level>
<default>0</default> <!-- Neither -->
<constraints>
<options>
<option label="21474">0</option> <!-- Neither -->
<option label="21475">1</option> <!-- Both -->
<option label="21476">2</option> <!-- Just All Seasons -->
<option label="21477">3</option> <!-- Just Specials -->
</options>
</constraints>
<dependencies>
<dependency type="enable" setting="videolibrary.tvshowsselectfirstunwatcheditem" operator="!is">0</dependency> <!-- Never -->
</dependencies>
<control type="spinner" format="string" />
</setting>
<setting id="videolibrary.hideallitems" type="boolean" label="38011" help="38012">
<level>2</level>
Expand Down
25 changes: 0 additions & 25 deletions xbmc/video/GUIViewStateVideo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -436,31 +436,6 @@ bool CGUIViewStateWindowVideoNav::AutoPlayNextItem()
return CSettings::Get().GetBool("videoplayer.autoplaynextitem");
}

bool CGUIViewStateWindowVideoNav::JumpToFirstUnplayedItem()
{
if (m_items.IsVideoDb())
{
NODE_TYPE NodeType = CVideoDatabaseDirectory::GetDirectoryChildType(m_items.GetPath());
switch (NodeType)
{
case NODE_TYPE_EPISODES:
if (GetSortMethod().sortBy == SortBy::SortByEpisodeNumber)
return CSettings::Get().GetBool("videolibrary.jumptofirstunplayeditem");
else
return false;

case NODE_TYPE_SEASONS:
return CSettings::Get().GetBool("videolibrary.jumptofirstunplayeditem");

default:
return false;
break;
}
}

return CGUIViewStateWindowVideo::JumpToFirstUnplayedItem();
}

CGUIViewStateWindowVideoPlaylist::CGUIViewStateWindowVideoPlaylist(const CFileItemList& items) : CGUIViewStateWindowVideo(items)
{
AddSortMethod(SortByNone, 551, LABEL_MASKS("%L", "", "%L", "")); // Label, empty | Label, empty
Expand Down
1 change: 0 additions & 1 deletion xbmc/video/GUIViewStateVideo.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ class CGUIViewStateWindowVideoNav : public CGUIViewStateWindowVideo
public:
CGUIViewStateWindowVideoNav(const CFileItemList& items);
virtual bool AutoPlayNextItem();
virtual bool JumpToFirstUnplayedItem();

protected:
virtual void SaveViewState();
Expand Down
108 changes: 108 additions & 0 deletions xbmc/video/windows/GUIWindowVideoNav.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,114 @@ std::string CGUIWindowVideoNav::GetQuickpathName(const std::string& strPath) con
}
}

SelectFirstUnwatchedItem CGUIWindowVideoNav::GetSettingSelectFirstUnwatchedItem()
{
if (m_vecItems->IsVideoDb())
{
NODE_TYPE nodeType = CVideoDatabaseDirectory::GetDirectoryChildType(m_vecItems->GetPath());

if (nodeType == NODE_TYPE_SEASONS || nodeType == NODE_TYPE_EPISODES)
{
int iValue = CSettings::Get().GetInt("videolibrary.tvshowsselectfirstunwatcheditem");
if (iValue >= SelectFirstUnwatchedItem::NEVER && iValue <= SelectFirstUnwatchedItem::ALWAYS)
return (SelectFirstUnwatchedItem)iValue;
}
}

return SelectFirstUnwatchedItem::NEVER;
}

IncludeAllSeasonsAndSpecials CGUIWindowVideoNav::GetSettingIncludeAllSeasonsAndSpecials()
{
int iValue = CSettings::Get().GetInt("videolibrary.tvshowsincludeallseasonsandspecials");
if (iValue >= IncludeAllSeasonsAndSpecials::NEITHER && iValue <= IncludeAllSeasonsAndSpecials::SPECIALS)
return (IncludeAllSeasonsAndSpecials)iValue;

return IncludeAllSeasonsAndSpecials::NEITHER;
}

int CGUIWindowVideoNav::GetFirstUnwatchedItemIndex(bool includeAllSeasons, bool includeSpecials)
{
int iIndex = 0;
int iUnwatchedSeason = INT_MAX;

// Run through the list of items and find the season number of the first season with unwatched episodes
for (int i = 0; i < m_vecItems->Size(); ++i)
{
CFileItemPtr pItem = m_vecItems->Get(i);
if (pItem->IsParentFolder() || !pItem->HasVideoInfoTag())
continue;

CVideoInfoTag *pTag = pItem->GetVideoInfoTag();

if ((!includeAllSeasons && pTag->m_iSeason < 0) || (!includeSpecials && pTag->m_iSeason == 0))
continue;

// Is the season unwatched, and is its season number lower than the currently identified
// first unwatched season
if (pTag->m_playCount == 0 && pTag->m_iSeason < iUnwatchedSeason)
{
iUnwatchedSeason = pTag->m_iSeason;
iIndex = i;
}
}

NODE_TYPE nodeType = CVideoDatabaseDirectory::GetDirectoryChildType(m_vecItems->GetPath());
if (nodeType == NODE_TYPE::NODE_TYPE_EPISODES)
{
iIndex = 0;
int iUnwatchedEpisode = INT_MAX;

// Now run through the list of items and check episodes from the season identified above
// to find the first (lowest episode number) unwatched epsisode.
for (int i = 0; i < m_vecItems->Size(); ++i)
{
CFileItemPtr pItem = m_vecItems->Get(i);
if (pItem->IsParentFolder() || !pItem->HasVideoInfoTag())
continue;

CVideoInfoTag *pTag = pItem->GetVideoInfoTag();

// Does the episode belong to the unwatched season and Is the episode unwatched, and is its epsiode number
// lower than the currently identified first unwatched episode
if (pTag->m_iSeason == iUnwatchedSeason && pTag->m_playCount == 0 && pTag->m_iEpisode < iUnwatchedEpisode)
{
iUnwatchedEpisode = pTag->m_iEpisode;
iIndex = i;
}
}
}

return iIndex;
}

bool CGUIWindowVideoNav::Update(const std::string &strDirectory, bool updateFilterPath /* = true */)
{
if (!CGUIWindowVideoBase::Update(strDirectory, updateFilterPath))
return false;

// Check if we should select the first unwatched item
SelectFirstUnwatchedItem selectFirstUnwatched = GetSettingSelectFirstUnwatchedItem();
if (selectFirstUnwatched != SelectFirstUnwatchedItem::NEVER)
{
bool bIsItemSelected = (m_viewControl.GetSelectedItem() > 0);

if (selectFirstUnwatched == SelectFirstUnwatchedItem::ALWAYS ||
(selectFirstUnwatched == SelectFirstUnwatchedItem::ON_FIRST_ENTRY && !bIsItemSelected))
{
IncludeAllSeasonsAndSpecials incAllSeasonsSpecials = GetSettingIncludeAllSeasonsAndSpecials();

bool bIncludeAllSeasons = (incAllSeasonsSpecials == IncludeAllSeasonsAndSpecials::BOTH || incAllSeasonsSpecials == IncludeAllSeasonsAndSpecials::ALL_SEASONS);
bool bIncludeSpecials = (incAllSeasonsSpecials == IncludeAllSeasonsAndSpecials::BOTH || incAllSeasonsSpecials == IncludeAllSeasonsAndSpecials::SPECIALS);

int iIndex = GetFirstUnwatchedItemIndex(bIncludeAllSeasons, bIncludeSpecials);
m_viewControl.SetSelectedItem(iIndex);
}
}

return true;
}

bool CGUIWindowVideoNav::GetDirectory(const std::string &strDirectory, CFileItemList &items)
{
if (m_thumbLoader.IsLoading())
Expand Down
22 changes: 22 additions & 0 deletions xbmc/video/windows/GUIWindowVideoNav.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,21 @@

class CFileItemList;

enum SelectFirstUnwatchedItem
{
NEVER = 0,
ON_FIRST_ENTRY = 1,
ALWAYS = 2
};

enum IncludeAllSeasonsAndSpecials
{
NEITHER = 0,
BOTH = 1,
ALL_SEASONS = 2,
SPECIALS = 3
};

class CGUIWindowVideoNav : public CGUIWindowVideoBase
{
public:
Expand Down Expand Up @@ -55,7 +70,9 @@ class CGUIWindowVideoNav : public CGUIWindowVideoBase
virtual bool GetFilteredItems(const std::string &filter, CFileItemList &items);

virtual void OnItemLoaded(CFileItem* pItem) {};

// override base class methods
virtual bool Update(const std::string &strDirectory, bool updateFilterPath = true);
virtual bool GetDirectory(const std::string &strDirectory, CFileItemList &items);
virtual void UpdateButtons();
virtual void DoSearch(const std::string& strSearch, CFileItemList& items);
Expand All @@ -69,4 +86,9 @@ class CGUIWindowVideoNav : public CGUIWindowVideoBase
virtual std::string GetQuickpathName(const std::string& strPath) const;

VECSOURCES m_shares;

private:
virtual SelectFirstUnwatchedItem GetSettingSelectFirstUnwatchedItem();
virtual IncludeAllSeasonsAndSpecials GetSettingIncludeAllSeasonsAndSpecials();
virtual int GetFirstUnwatchedItemIndex(bool includeAllSeasons, bool includeSpecials);
};
5 changes: 0 additions & 5 deletions xbmc/view/GUIViewState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -395,11 +395,6 @@ bool CGUIViewState::AutoPlayNextItem()
return false;
}

bool CGUIViewState::JumpToFirstUnplayedItem()
{
return false;
}

std::string CGUIViewState::GetLockType()
{
return "";
Expand Down
1 change: 0 additions & 1 deletion xbmc/view/GUIViewState.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ class CGUIViewState
void SetPlaylistDirectory(const std::string& strDirectory);
bool IsCurrentPlaylistDirectory(const std::string& strDirectory);
virtual bool AutoPlayNextItem();
virtual bool JumpToFirstUnplayedItem();

virtual std::string GetLockType();
virtual std::string GetExtensions();
Expand Down
30 changes: 2 additions & 28 deletions xbmc/windows/GUIMediaWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -853,35 +853,9 @@ bool CGUIMediaWindow::Update(const std::string &strDirectory, bool updateFilterP
}
}

// if we haven't found the selected item, see if we should select the first unplayed item
// if yes, find the first unplayed item and select it
// if no, select the first item
// if we haven't found the selected item, select the first item
if (!bSelectedFound)
{
int iIndex = 0; // index of the item to select, default to the first item

// Check if we should select the first unplayed item
if (m_guiState.get()->JumpToFirstUnplayedItem())
{
// Find the index of the
for (int i = 0; i < m_vecItems->Size(); ++i)
{
CFileItemPtr pItem = m_vecItems->Get(i);
// We don't want to jump to the parent folder item or an All Seasons item
if (pItem->IsParentFolder() || !pItem->HasVideoInfoTag() ||
(pItem->GetVideoInfoTag()->m_type == MediaTypeSeason && pItem->GetVideoInfoTag()->m_iSeason < 0))
continue;

if (pItem->GetVideoInfoTag()->m_playCount == 0)
{
iIndex = i;
break;
}
}
}

m_viewControl.SetSelectedItem(iIndex);
}
m_viewControl.SetSelectedItem(0);

m_history.AddPath(m_vecItems->GetPath(), m_strFilterPath);

Expand Down

0 comments on commit 8c7f35d

Please sign in to comment.