Skip to content

Commit

Permalink
Moved filters into a dialog and get them working!
Browse files Browse the repository at this point in the history
Fixes xbmc#356
Fixes xbmc#341
  • Loading branch information
Tobias Hieta committed Jan 10, 2013
1 parent 7738125 commit e894b98
Show file tree
Hide file tree
Showing 9 changed files with 366 additions and 159 deletions.
2 changes: 1 addition & 1 deletion addons/skin.plex
2 changes: 0 additions & 2 deletions plex/FileSystem/PlexDirectory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -495,8 +495,6 @@ bool CPlexDirectory::ReallyGetDirectory(const CStdString& strPath, CFileItemList
if (pVal && *pVal != 0)
items.SetProperty("offset", atoi(pVal));

dprintf("totalSize for %s is %d", items.GetPath().c_str(), items.GetProperty("totalSize").asInteger());

return true;
}

Expand Down
97 changes: 97 additions & 0 deletions plex/GUI/GUIDialogFilterSort.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
//
// GUIDialogFilterSort.cpp
// Plex
//
// Created by Tobias Hieta <tobias@plexapp.com> on 2012-11-26.
// Copyright 2012 Plex Inc. All rights reserved.
//

#include "GUIDialogFilterSort.h"
#include "plex/PlexTypes.h"
#include "guilib/GUIControlGroupList.h"
#include "guilib/GUILabelControl.h"
#include "GUIWindowManager.h"

CGUIDialogFilterSort::CGUIDialogFilterSort()
: CGUIDialog(WINDOW_DIALOG_FILTER_SORT, "DialogFilters.xml")
{
m_loadType = LOAD_ON_GUI_INIT;
}

void CGUIDialogFilterSort::SetFilter(CPlexFilterPtr filter)
{
m_filter = filter;
m_filterIdMap.clear();
m_itemIdMap.clear();

CFileItemList sublist;
if (!filter->GetSublist(sublist))
return;

CGUIControlGroupList* list = (CGUIControlGroupList*)GetControl(FILTER_SUBLIST);
if (!list)
return;

list->ClearAll();

CGUIRadioButtonControl* radioButton = (CGUIRadioButtonControl*)GetControl(FILTER_SUBLIST_BUTTON);
if (!radioButton)
return;
radioButton->SetVisible(false);

CGUILabelControl* headerLabel = (CGUILabelControl*)GetControl(FILTER_SUBLIST_LABEL);
if (headerLabel)
headerLabel->SetLabel(filter->GetFilterString());

for (int i = 0; i < sublist.Size(); i++)
{
CFileItemPtr item = sublist.Get(i);
CGUIRadioButtonControl* sublistItem = new CGUIRadioButtonControl(*radioButton);
sublistItem->SetLabel(item->GetLabel());
sublistItem->SetVisible(true);
sublistItem->AllocResources();
sublistItem->SetID(FILTER_SUBLIST_BUTTONS_START + i);

if (filter->HasCurrentValue(item->GetProperty("unprocessedKey").asString()))
sublistItem->SetSelected(true);

m_filterIdMap[FILTER_SUBLIST_BUTTONS_START + i] = sublistItem;
m_itemIdMap[FILTER_SUBLIST_BUTTONS_START + i] = item;
list->AddControl(sublistItem);
}

}

bool CGUIDialogFilterSort::OnMessage(CGUIMessage &message)
{
switch (message.GetMessage())
{
case GUI_MSG_CLICKED:
{
int senderId = message.GetSenderId();
if (m_filterIdMap.find(senderId) != m_filterIdMap.end())
{
CGUIRadioButtonControl *filterCtrl = m_filterIdMap[senderId];
CFileItemPtr item = m_itemIdMap[senderId];
if (filterCtrl->IsSelected())
{
m_filter->AddCurrentValue(item->GetProperty("unprocessedKey").asString());
}
else
{
m_filter->RemoveCurrentValue(item->GetProperty("unprocessedKey").asString());
}

CGUIMessage msg(GUI_MSG_UPDATE_FILTERS, GetID(), WINDOW_VIDEO_NAV);
g_windowManager.SendThreadMessage(msg);
}
}

}
return CGUIDialog::OnMessage(message);
}

void CGUIDialogFilterSort::DoModal(int iWindowID, const CStdString &param)
{
CGUIDialog::DoModal(iWindowID, param);
}
37 changes: 37 additions & 0 deletions plex/GUI/GUIDialogFilterSort.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//
// GUIDialogFilterSort.h
// Plex
//
// Created by Tobias Hieta <tobias@plexapp.com> on 2012-11-26.
// Copyright 2012 Plex Inc. All rights reserved.
//

#ifndef GUIDIALOGFILTERSORT_H
#define GUIDIALOGFILTERSORT_H

#define FILTER_SUBLIST 19020
#define FILTER_SUBLIST_BUTTON 19021
#define FILTER_SUBLIST_LABEL 19029
#define FILTER_SUBLIST_BUTTONS_START -300

#include "guilib/GUIDialog.h"
#include "GUI/PlexFilter.h"
#include "FileItem.h"
#include <map>

class CGUIDialogFilterSort : public CGUIDialog
{
public:
CGUIDialogFilterSort();

void SetFilter(CPlexFilterPtr filter);
void DoModal(int iWindowID = WINDOW_INVALID, const CStdString &param = "");
bool OnMessage(CGUIMessage &message);

private:
CPlexFilterPtr m_filter;
std::map<int, CGUIRadioButtonControl*> m_filterIdMap;
std::map<int, CFileItemPtr> m_itemIdMap;
};

#endif // GUIDIALOGFILTERSORT_H
121 changes: 65 additions & 56 deletions plex/GUI/GUIWindowMediaFilterView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
#include "GUIUserMessages.h"
#include "AdvancedSettings.h"
#include "guilib/GUILabelControl.h"
#include "GUI/GUIDialogFilterSort.h"
#include "GUIWindowManager.h"

bool CGUIWindowMediaFilterView::FetchFilterSortList(const CStdString& url, const CStdString& filterSort, int type, CFileItemList& list)
{
Expand Down Expand Up @@ -103,48 +105,6 @@ void CGUIWindowMediaFilterView::BuildFilters(const CStdString& baseUrl, int type

}

void CGUIWindowMediaFilterView::PopulateSublist(CPlexFilterPtr filter)
{
CFileItemList sublist;
if (!filter->GetSublist(sublist))
return;

CGUIControlGroupList* list = (CGUIControlGroupList*)GetControl(FILTER_SUBLIST);
if (!list)
return;

list->ClearAll();

CGUIRadioButtonControl* radioButton = (CGUIRadioButtonControl*)GetControl(FILTER_SUBLIST_BUTTON);
if (!radioButton)
return;
radioButton->SetVisible(false);

CGUILabelControl* headerLabel = (CGUILabelControl*)GetControl(FILTER_SUBLIST_LABEL);
if (headerLabel)
headerLabel->SetLabel(filter->GetFilterString());

for (int i = 0; i < sublist.Size(); i++)
{
CFileItemPtr item = sublist.Get(i);
CGUIRadioButtonControl* sublistItem = new CGUIRadioButtonControl(*radioButton);
sublistItem->SetLabel(item->GetLabel());
sublistItem->SetVisible(true);
sublistItem->AllocResources();
sublistItem->SetID(FILTER_SUBLIST_BUTTONS_START + i);

list->AddControl(sublistItem);
}

SET_CONTROL_VISIBLE(FILTER_SUBLIST);
}

void CGUIWindowMediaFilterView::OnInitWindow()
{
CGUIWindowVideoNav::OnInitWindow();
SET_CONTROL_HIDDEN(FILTER_SUBLIST);
}

typedef pair<CStdString, CPlexFilterPtr> name_filter_pair;

bool CGUIWindowMediaFilterView::OnMessage(CGUIMessage &message)
Expand Down Expand Up @@ -179,7 +139,14 @@ bool CGUIWindowMediaFilterView::OnMessage(CGUIMessage &message)
}
else
{
PopulateSublist(pr.second);
CGUIDialogFilterSort *dialog = (CGUIDialogFilterSort *)g_windowManager.GetWindow(WINDOW_DIALOG_FILTER_SORT);
if (!dialog)
break;
dialog->SetFilter(pr.second);
m_openFilter = pr.second;
dialog->DoModal();

break;
}
}
}
Expand All @@ -202,6 +169,8 @@ bool CGUIWindowMediaFilterView::OnMessage(CGUIMessage &message)
if (update)
Update(m_baseUrl, true, false);
}
break;

case GUI_MSG_LOAD_SKIN:
{
/* This is called BEFORE the skin is reloaded, so let's save this event to be handled
Expand All @@ -210,6 +179,7 @@ bool CGUIWindowMediaFilterView::OnMessage(CGUIMessage &message)
m_returningFromSkinLoad = true;
}
break;

case GUI_MSG_WINDOW_INIT:
{
/* If this is a reload event we must make sure to get the filters back */
Expand All @@ -218,6 +188,28 @@ bool CGUIWindowMediaFilterView::OnMessage(CGUIMessage &message)
m_returningFromSkinLoad = false;
}
break;

case GUI_MSG_UPDATE_FILTERS:
{
if (m_openFilter)
{
if (m_appliedFilters.find(m_openFilter->GetFilterName()) != m_appliedFilters.end())
m_appliedFilters.erase(m_openFilter->GetFilterName());

if (!m_openFilter->GetFilterValue().empty())
m_appliedFilters[m_openFilter->GetFilterName()] = m_openFilter->GetFilterValue();
}
if (!m_appliedFilters.empty())
{
/* This sucks, but "ok" */
BOOST_FOREACH(name_filter_pair p, m_filters)
{
p.second->SetFilterUrl(GetFilterUrl(p.second->GetFilterName()));
}
}
Update(m_baseUrl, true, false);
}
break;
}

return ret;
Expand All @@ -228,6 +220,25 @@ bool CGUIWindowMediaFilterView::Update(const CStdString &strDirectory, bool upda
return Update(strDirectory, updateFilterPath, true);
}

CStdString CGUIWindowMediaFilterView::GetFilterUrl(const CStdString exclude) const
{
CStdString url;
if (m_appliedFilters.size() > 0)
{
vector<string> filterValues;
pair<CStdString, string> stpair;
BOOST_FOREACH(stpair, m_appliedFilters)
{
if (!stpair.first.Equals(exclude))
filterValues.push_back(stpair.second);
}

CStdString optionList = StringUtils::Join(filterValues, "&");
url = "?" + optionList;
}
return url;
}

bool CGUIWindowMediaFilterView::Update(const CStdString &strDirectory, bool updateFilterPath, bool updateFilters)
{
bool ret;
Expand All @@ -239,25 +250,24 @@ bool CGUIWindowMediaFilterView::Update(const CStdString &strDirectory, bool upda
containerUrl+="?X-Plex-Container-Start=0&X-Plex-Container-Size=1";
tmpItems.SetPath(containerUrl);

/* Ok this is kind of wastefull */
/* A bit stupidity here, but we need to request the container twice. Fortunately it's really fast
* to do it with the offset stuff above */
if (dir.GetDirectory(containerUrl, tmpItems))
{
if (tmpItems.IsPlexMediaServer() && tmpItems.GetContent() == "secondary")
{
CStdString url;
url = PlexUtils::AppendPathToURL(strDirectory, "all");

if (m_appliedFilters.size() > 0)
if (!m_baseUrl.Equals(strDirectory))
{
vector<string> filterValues;
pair<CStdString, string> stpair;
BOOST_FOREACH(stpair, m_appliedFilters)
filterValues.push_back(stpair.second);

CStdString optionList = StringUtils::Join(filterValues, "&");
url += "?" + optionList;
m_baseUrl = strDirectory;
m_appliedFilters.clear();
m_filters.clear();
m_sorts.clear();
}

CStdString url;
url = PlexUtils::AppendPathToURL(strDirectory, "all");
url += GetFilterUrl();

if (!m_appliedSort.empty())
{
CStdString sortStr;
Expand All @@ -269,7 +279,6 @@ bool CGUIWindowMediaFilterView::Update(const CStdString &strDirectory, bool upda
url += "?" + sortStr;
}

m_baseUrl = strDirectory;

ret = CGUIWindowVideoNav::Update(url, updateFilterPath);

Expand Down
Loading

0 comments on commit e894b98

Please sign in to comment.