aboutsummaryrefslogtreecommitdiff
path: root/xbmc/video/windows/VideoFileItemListModifier.cpp
blob: 2f5c222c62810ec3e7d53e64a195ddb5ddf0f6b8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/*
 *  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 "VideoFileItemListModifier.h"

#include "FileItem.h"
#include "FileItemList.h"
#include "ServiceBroker.h"
#include "filesystem/VideoDatabaseDirectory/DirectoryNode.h"
#include "guilib/LocalizeStrings.h"
#include "settings/AdvancedSettings.h"
#include "settings/Settings.h"
#include "settings/SettingsComponent.h"
#include "video/VideoDatabase.h"
#include "video/VideoDbUrl.h"
#include "video/VideoFileItemClassify.h"

#include <memory>

using namespace KODI::VIDEO;
using namespace XFILE::VIDEODATABASEDIRECTORY;

bool CVideoFileItemListModifier::CanModify(const CFileItemList &items) const
{
  if (IsVideoDb(items))
    return true;

  return false;
}

bool CVideoFileItemListModifier::Modify(CFileItemList &items) const
{
  AddQueuingFolder(items);
  return true;
}

//  Add an "* All ..." folder to the CFileItemList
//  depending on the child node
void CVideoFileItemListModifier::AddQueuingFolder(CFileItemList& items)
{
  if (!IsVideoDb(items))
    return;

  auto directoryNode = CDirectoryNode::ParseURL(items.GetPath());

  CFileItemPtr pItem;

  // always show "all" items by default
  if (!CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_VIDEOLIBRARY_SHOWALLITEMS))
    return;

  // no need for "all" item when only one item
  if (items.GetObjectCount() <= 1)
    return;

  CVideoDbUrl videoUrl;
  if (!videoUrl.FromString(directoryNode->BuildPath()))
    return;

  // hack - as the season node might return episodes
  std::unique_ptr<CDirectoryNode> pNode(directoryNode);

  switch (pNode->GetChildType())
  {
  case NODE_TYPE_SEASONS:
  {
    const std::string& strLabel = g_localizeStrings.Get(20366);
    pItem = std::make_shared<CFileItem>(strLabel); // "All Seasons"
    videoUrl.AppendPath("-1/");
    pItem->SetPath(videoUrl.ToString());
    // set the number of watched and unwatched items accordingly
    int watched = 0;
    int unwatched = 0;
    int inprogress = 0;
    for (int i = 0; i < items.Size(); i++)
    {
      CFileItemPtr item = items[i];
      watched += static_cast<int>(item->GetProperty("watchedepisodes").asInteger());
      unwatched += static_cast<int>(item->GetProperty("unwatchedepisodes").asInteger());
      inprogress += static_cast<int>(item->GetProperty("inprogressepisodes").asInteger());
    }
    const int totalEpisodes = watched + unwatched;
    pItem->SetProperty("totalepisodes", totalEpisodes);
    pItem->SetProperty("numepisodes",
                       totalEpisodes); // will be changed later to reflect watchmode setting
    pItem->SetProperty("watchedepisodes", watched);
    pItem->SetProperty("unwatchedepisodes", unwatched);
    pItem->SetProperty("inprogressepisodes", inprogress);
    pItem->SetProperty("watchedepisodepercent",
                       totalEpisodes > 0 ? watched * 100 / totalEpisodes : 0);

    // @note: The items list may contain additional items that do not belong to the show.
    // This is the case of the up directory (..) or movies linked to the tvshow.
    // Iterate through the list till the first season type is found and the infotag can safely be copied.

    if (items.Size() > 1)
    {
      for (int i = 1; i < items.Size(); i++)
      {
        if (items[i]->GetVideoInfoTag() && items[i]->GetVideoInfoTag()->m_type == MediaTypeSeason &&
            items[i]->GetVideoInfoTag()->m_iSeason > 0)
        {
          *pItem->GetVideoInfoTag() = *items[i]->GetVideoInfoTag();
          pItem->GetVideoInfoTag()->m_iSeason = -1;
          break;
        }
      }
    }

    pItem->GetVideoInfoTag()->m_strTitle = strLabel;
    pItem->GetVideoInfoTag()->m_iEpisode = watched + unwatched;
    pItem->GetVideoInfoTag()->SetPlayCount((unwatched == 0) ? 1 : 0);
    CVideoDatabase db;
    if (db.Open())
    {
      pItem->GetVideoInfoTag()->m_iDbId = db.GetSeasonId(pItem->GetVideoInfoTag()->m_iIdShow, -1);
      db.Close();
    }
    pItem->GetVideoInfoTag()->m_type = MediaTypeSeason;
  }
  break;
  case NODE_TYPE_MUSICVIDEOS_ALBUM:
    pItem = std::make_shared<CFileItem>("* " + g_localizeStrings.Get(16100)); // "* All Videos"
    videoUrl.AppendPath("-1/");
    pItem->SetPath(videoUrl.ToString());
    break;
  default:
    break;
  }

  if (pItem)
  {
    pItem->m_bIsFolder = true;
    pItem->SetSpecialSort(CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_bVideoLibraryAllItemsOnBottom ? SortSpecialOnBottom : SortSpecialOnTop);
    pItem->SetCanQueue(false);
    items.Add(pItem);
  }
}