Skip to content
Browse files

Merge pull request #1079 from Montellese/xsp_ext_ors

[GSoC] smartplaylist: support multiple OR'ed conditions in a single rule
  • Loading branch information...
2 parents 1da97bf + 171e25a commit 12f9cb7dcb1bb0fea61d1898cf32d43101d85179 @Montellese committed Jul 1, 2012
View
62 xbmc/dialogs/GUIDialogSelect.cpp
@@ -56,6 +56,7 @@ bool CGUIDialogSelect::OnMessage(CGUIMessage& message)
{
CGUIDialog::OnMessage(message);
m_viewControl.Reset();
+
m_bButtonEnabled = false;
m_useDetails = false;
m_multiSelection = false;
@@ -83,6 +84,7 @@ bool CGUIDialogSelect::OnMessage(CGUIMessage& message)
case GUI_MSG_WINDOW_INIT:
{
m_bButtonPressed = false;
+ m_bConfirmed = false;
CGUIDialog::OnMessage(message);
return true;
}
@@ -108,6 +110,7 @@ bool CGUIDialogSelect::OnMessage(CGUIMessage& message)
for (int i = 0 ; i < m_vecList->Size() ; i++)
m_vecList->Get(i)->Select(false);
item->Select(true);
+ m_bConfirmed = true;
Close();
}
}
@@ -117,6 +120,8 @@ bool CGUIDialogSelect::OnMessage(CGUIMessage& message)
{
m_iSelected = -1;
m_bButtonPressed = true;
+ if (m_multiSelection)
+ m_bConfirmed = true;
Close();
}
}
@@ -138,6 +143,8 @@ bool CGUIDialogSelect::OnMessage(CGUIMessage& message)
bool CGUIDialogSelect::OnBack(int actionID)
{
m_iSelected = -1;
+ m_selectedItems->Clear();
+ m_bConfirmed = false;
return CGUIDialog::OnBack(actionID);
}
@@ -218,15 +225,63 @@ void CGUIDialogSelect::Sort(bool bSortOrder /*=true*/)
void CGUIDialogSelect::SetSelected(int iSelected)
{
- if (iSelected < 0 || iSelected >= (int)m_vecList->Size()) return;
- m_iSelected = iSelected;
+ if (iSelected < 0 || iSelected >= (int)m_vecList->Size() ||
+ m_vecList->Get(iSelected).get() == NULL)
+ return;
+
+ // only set m_iSelected if there is no multi-select
+ // or if it doesn't have a valid value yet
+ // or if the current value is bigger than the new one
+ // so that we always focus the item nearest to the beginning of the list
+ if (!m_multiSelection || m_iSelected < 0 || m_iSelected > iSelected)
+ m_iSelected = iSelected;
+ m_vecList->Get(iSelected)->Select(true);
+ m_selectedItems->Add(m_vecList->Get(iSelected));
+}
+
+void CGUIDialogSelect::SetSelected(const CStdString &strSelectedLabel)
+{
+ if (strSelectedLabel.empty())
+ return;
+
+ for (int index = 0; index < m_vecList->Size(); index++)
+ {
+ if (strSelectedLabel.Equals(m_vecList->Get(index)->GetLabel()))
+ {
+ SetSelected(index);
+ return;
+ }
+ }
+}
+
+void CGUIDialogSelect::SetSelected(std::vector<int> selectedIndexes)
+{
+ if (selectedIndexes.empty())
+ return;
+
+ for (std::vector<int>::const_iterator it = selectedIndexes.begin(); it != selectedIndexes.end(); it++)
+ SetSelected(*it);
+}
+
+void CGUIDialogSelect::SetSelected(const std::vector<CStdString> &selectedLabels)
+{
+ if (selectedLabels.empty())
+ return;
+
+ for (std::vector<CStdString>::const_iterator it = selectedLabels.begin(); it != selectedLabels.end(); it++)
+ SetSelected(*it);
}
void CGUIDialogSelect::SetUseDetails(bool useDetails)
{
m_useDetails = useDetails;
}
+void CGUIDialogSelect::SetMultiSelection(bool multiSelection)
+{
+ m_multiSelection = multiSelection;
+}
+
CGUIControl *CGUIDialogSelect::GetFirstFocusableControl(int id)
{
if (m_viewControl.HasControl(id))
@@ -263,6 +318,9 @@ void CGUIDialogSelect::OnInitWindow()
CStdString items;
items.Format("%i %s", m_vecList->Size(), g_localizeStrings.Get(127).c_str());
SET_CONTROL_LABEL(CONTROL_NUMBEROFFILES, items);
+
+ if (m_multiSelection)
+ EnableButton(true, 186);
if (m_bButtonEnabled)
{
View
5 xbmc/dialogs/GUIDialogSelect.h
@@ -50,8 +50,11 @@ class CGUIDialogSelect :
bool IsButtonPressed();
void Sort(bool bSortOrder = true);
void SetSelected(int iSelected);
+ void SetSelected(const CStdString &strSelectedLabel);
+ void SetSelected(std::vector<int> selectedIndexes);
+ void SetSelected(const std::vector<CStdString> &selectedLabels);
void SetUseDetails(bool useDetails);
- void SetMultiSelection(bool multiSelection) { m_multiSelection = multiSelection; };
+ void SetMultiSelection(bool multiSelection);
protected:
virtual CGUIControl *GetFirstFocusableControl(int id);
virtual void OnWindowLoaded();
View
2 xbmc/dialogs/GUIDialogSmartPlaylistEditor.cpp
@@ -274,7 +274,7 @@ void CGUIDialogSmartPlaylistEditor::UpdateButtons()
if (m_playlist.m_playlistRules[i].m_field == FieldNone)
item->SetLabel(g_localizeStrings.Get(21423));
else
- item->SetLabel(m_playlist.m_playlistRules[i].GetLocalizedRule());
+ item->SetLabel(m_playlist.m_playlistRules[i].GetLocalizedRule(m_playlist.GetType()));
m_ruleLabels->Add(item);
}
CGUIMessage msg(GUI_MSG_LABEL_BIND, GetID(), CONTROL_RULE_LIST, 0, 0, m_ruleLabels);
View
32 xbmc/dialogs/GUIDialogSmartPlaylistRule.cpp
@@ -68,8 +68,15 @@ bool CGUIDialogSmartPlaylistRule::OnMessage(CGUIMessage& message)
OnOK();
else if (iControl == CONTROL_CANCEL)
OnCancel();
- else if (iControl == CONTROL_VALUE)
- OnEditChanged(iControl, m_rule.m_parameter);
+ else if (iControl == CONTROL_VALUE && CSmartPlaylistRule::GetFieldType(m_rule.m_field) != CSmartPlaylistRule::BROWSEABLE_FIELD)
+ {
+ CStdString parameter;
+ OnEditChanged(iControl, parameter);
+ m_rule.m_parameter.clear();
+
+ if (!parameter.empty())
+ m_rule.m_parameter.push_back(parameter);
+ }
else if (iControl == CONTROL_OPERATOR)
OnOperator();
else if (iControl == CONTROL_FIELD)
@@ -218,7 +225,7 @@ void CGUIDialogSmartPlaylistRule::OnBrowse()
}
g_mediaManager.GetLocalDrives(sources);
- CGUIDialogFileBrowser::ShowAndGetDirectory(sources,g_localizeStrings.Get(657),m_rule.m_parameter,false);
+ CGUIDialogFileBrowser::ShowAndGetDirectory(sources,g_localizeStrings.Get(657),m_rule.GetLocalizedParameter(m_type),false);
UpdateButtons();
return;
}
@@ -241,10 +248,19 @@ void CGUIDialogSmartPlaylistRule::OnBrowse()
CStdString strHeading;
strHeading.Format(g_localizeStrings.Get(13401),g_localizeStrings.Get(iLabel));
pDialog->SetHeading(strHeading);
+ pDialog->SetMultiSelection(true);
+
+ if (!m_rule.m_parameter.empty())
+ pDialog->SetSelected(m_rule.m_parameter);
+
pDialog->DoModal();
- if (pDialog->GetSelectedLabel() > -1)
+ if (pDialog->IsConfirmed())
{
- m_rule.m_parameter = pDialog->GetSelectedLabelText();
+ const CFileItemList &items = pDialog->GetSelectedItems();
+ m_rule.m_parameter.clear();
+ for (int index = 0; index < items.Size(); index++)
+ m_rule.m_parameter.push_back(items[index]->GetLabel());
+
UpdateButtons();
}
pDialog->Reset();
@@ -344,13 +360,15 @@ void CGUIDialogSmartPlaylistRule::UpdateButtons()
m_rule.m_operator = (CSmartPlaylistRule::SEARCH_OPERATOR)selected.GetParam1();
// update the parameter edit control appropriately
- SET_CONTROL_LABEL2(CONTROL_VALUE, m_rule.m_parameter);
+ SET_CONTROL_LABEL2(CONTROL_VALUE, m_rule.GetLocalizedParameter(m_type));
CGUIEditControl::INPUT_TYPE type = CGUIEditControl::INPUT_TYPE_TEXT;
CSmartPlaylistRule::FIELD_TYPE fieldType = CSmartPlaylistRule::GetFieldType(m_rule.m_field);
switch (fieldType)
{
- case CSmartPlaylistRule::TEXT_FIELD:
case CSmartPlaylistRule::BROWSEABLE_FIELD:
+ type = CGUIEditControl::INPUT_TYPE_READONLY;
+ break;
+ case CSmartPlaylistRule::TEXT_FIELD:
case CSmartPlaylistRule::PLAYLIST_FIELD:
case CSmartPlaylistRule::TEXTIN_FIELD:
case CSmartPlaylistRule::NUMERIC_FIELD:
View
210 xbmc/guilib/GUIEditControl.cpp
@@ -101,138 +101,141 @@ bool CGUIEditControl::OnAction(const CAction &action)
{
ValidateCursor();
- if (action.GetID() == ACTION_BACKSPACE)
+ if (m_inputType != INPUT_TYPE_READONLY)
{
- // backspace
- if (m_cursorPos)
+ if (action.GetID() == ACTION_BACKSPACE)
{
- if (!ClearMD5())
- m_text2.erase(--m_cursorPos, 1);
- UpdateText();
- }
- return true;
- }
- else if (action.GetID() == ACTION_MOVE_LEFT)
- {
- if (m_cursorPos > 0)
- {
- m_cursorPos--;
- UpdateText(false);
- return true;
- }
- }
- else if (action.GetID() == ACTION_MOVE_RIGHT)
- {
- if ((unsigned int) m_cursorPos < m_text2.size())
- {
- m_cursorPos++;
- UpdateText(false);
- return true;
- }
- }
- else if (action.GetID() == ACTION_PASTE)
- {
- ClearMD5();
- OnPasteClipboard();
- }
- else if (action.GetID() >= KEY_VKEY && action.GetID() < KEY_ASCII)
- {
- // input from the keyboard (vkey, not ascii)
- BYTE b = action.GetID() & 0xFF;
- if (b == XBMCVK_HOME)
- {
- m_cursorPos = 0;
- UpdateText(false);
+ // backspace
+ if (m_cursorPos)
+ {
+ if (!ClearMD5())
+ m_text2.erase(--m_cursorPos, 1);
+ UpdateText();
+ }
return true;
}
- else if (b == XBMCVK_END)
+ else if (action.GetID() == ACTION_MOVE_LEFT)
{
- m_cursorPos = m_text2.length();
- UpdateText(false);
- return true;
+ if (m_cursorPos > 0)
+ {
+ m_cursorPos--;
+ UpdateText(false);
+ return true;
+ }
}
- if (b == XBMCVK_LEFT && m_cursorPos > 0)
+ else if (action.GetID() == ACTION_MOVE_RIGHT)
{
- m_cursorPos--;
- UpdateText(false);
- return true;
+ if ((unsigned int) m_cursorPos < m_text2.size())
+ {
+ m_cursorPos++;
+ UpdateText(false);
+ return true;
+ }
}
- if (b == XBMCVK_RIGHT && m_cursorPos < m_text2.length())
+ else if (action.GetID() == ACTION_PASTE)
{
- m_cursorPos++;
- UpdateText(false);
- return true;
+ ClearMD5();
+ OnPasteClipboard();
}
- if (b == XBMCVK_DELETE)
+ else if (action.GetID() >= KEY_VKEY && action.GetID() < KEY_ASCII)
{
- if (m_cursorPos < m_text2.length())
+ // input from the keyboard (vkey, not ascii)
+ BYTE b = action.GetID() & 0xFF;
+ if (b == XBMCVK_HOME)
{
- if (!ClearMD5())
- m_text2.erase(m_cursorPos, 1);
- UpdateText();
+ m_cursorPos = 0;
+ UpdateText(false);
return true;
}
- }
- if (b == XBMCVK_BACK)
- {
- if (m_cursorPos > 0)
+ else if (b == XBMCVK_END)
{
- if (!ClearMD5())
- m_text2.erase(--m_cursorPos, 1);
- UpdateText();
+ m_cursorPos = m_text2.length();
+ UpdateText(false);
+ return true;
}
- return true;
- }
- }
- else if (action.GetID() >= KEY_ASCII)
- {
- // input from the keyboard
- switch (action.GetUnicode())
- {
- case '\t':
- break;
- case 10:
- case 13:
+ if (b == XBMCVK_LEFT && m_cursorPos > 0)
{
- // enter - send click message, but otherwise ignore
- SEND_CLICK_MESSAGE(GetID(), GetParentID(), 1);
+ m_cursorPos--;
+ UpdateText(false);
return true;
}
- case 27:
- { // escape - fallthrough to default action
- return CGUIButtonControl::OnAction(action);
+ if (b == XBMCVK_RIGHT && m_cursorPos < m_text2.length())
+ {
+ m_cursorPos++;
+ UpdateText(false);
+ return true;
}
- case 8:
+ if (b == XBMCVK_DELETE)
{
- // backspace
- if (m_cursorPos)
+ if (m_cursorPos < m_text2.length())
+ {
+ if (!ClearMD5())
+ m_text2.erase(m_cursorPos, 1);
+ UpdateText();
+ return true;
+ }
+ }
+ if (b == XBMCVK_BACK)
+ {
+ if (m_cursorPos > 0)
{
if (!ClearMD5())
m_text2.erase(--m_cursorPos, 1);
+ UpdateText();
}
- break;
+ return true;
}
- default:
+ }
+ else if (action.GetID() >= KEY_ASCII)
+ {
+ // input from the keyboard
+ switch (action.GetUnicode())
{
- ClearMD5();
- m_text2.insert(m_text2.begin() + m_cursorPos++, (WCHAR)action.GetUnicode());
+ case '\t':
break;
+ case 10:
+ case 13:
+ {
+ // enter - send click message, but otherwise ignore
+ SEND_CLICK_MESSAGE(GetID(), GetParentID(), 1);
+ return true;
+ }
+ case 27:
+ { // escape - fallthrough to default action
+ return CGUIButtonControl::OnAction(action);
+ }
+ case 8:
+ {
+ // backspace
+ if (m_cursorPos)
+ {
+ if (!ClearMD5())
+ m_text2.erase(--m_cursorPos, 1);
+ }
+ break;
+ }
+ default:
+ {
+ ClearMD5();
+ m_text2.insert(m_text2.begin() + m_cursorPos++, (WCHAR)action.GetUnicode());
+ break;
+ }
}
- }
- UpdateText();
- return true;
- }
- else if (action.GetID() >= REMOTE_0 && action.GetID() <= REMOTE_9)
- { // input from the remote
- ClearMD5();
- if (m_inputType == INPUT_TYPE_FILTER)
- { // filtering - use single number presses
- m_text2.insert(m_text2.begin() + m_cursorPos++, L'0' + (action.GetID() - REMOTE_0));
UpdateText();
+ return true;
+ }
+ else if (action.GetID() >= REMOTE_0 && action.GetID() <= REMOTE_9)
+ { // input from the remote
+ ClearMD5();
+ if (m_inputType == INPUT_TYPE_FILTER)
+ { // filtering - use single number presses
+ m_text2.insert(m_text2.begin() + m_cursorPos++, L'0' + (action.GetID() - REMOTE_0));
+ UpdateText();
+ }
+ else
+ OnSMSCharacter(action.GetID() - REMOTE_0);
+ return true;
}
- else
- OnSMSCharacter(action.GetID() - REMOTE_0);
- return true;
}
return CGUIButtonControl::OnAction(action);
}
@@ -250,6 +253,9 @@ void CGUIEditControl::OnClick()
CStdString heading = g_localizeStrings.Get(m_inputHeading ? m_inputHeading : 16028);
switch (m_inputType)
{
+ case INPUT_TYPE_READONLY:
+ textChanged = false;
+ break;
case INPUT_TYPE_NUMBER:
textChanged = CGUIDialogNumeric::ShowAndGetNumber(utf8, heading);
break;
@@ -404,7 +410,7 @@ void CGUIEditControl::ProcessText(unsigned int currentTime)
}
CStdStringW text = GetDisplayedText();
// add the cursor if we're focused
- if (HasFocus())
+ if (HasFocus() && m_inputType != INPUT_TYPE_READONLY)
{
CStdStringW col;
if ((m_focusCounter % 64) > 32)
View
1 xbmc/guilib/GUIEditControl.h
@@ -41,6 +41,7 @@ class CGUIEditControl : public CGUIButtonControl
{
public:
enum INPUT_TYPE {
+ INPUT_TYPE_READONLY = -1,
INPUT_TYPE_TEXT = 0,
INPUT_TYPE_NUMBER,
INPUT_TYPE_SECONDS,
View
445 xbmc/playlists/SmartPlayList.cpp
@@ -132,24 +132,84 @@ CSmartPlaylistRule::CSmartPlaylistRule()
{
m_field = FieldNone;
m_operator = OPERATOR_CONTAINS;
- m_parameter = "";
+ m_parameter.clear();
}
-void CSmartPlaylistRule::TranslateStrings(const char *field, const char *oper, const char *parameter)
+bool CSmartPlaylistRule::Load(TiXmlElement *element, const CStdString &encoding /* = "UTF-8" */)
{
+ if (element == NULL)
+ return false;
+
+ // format is:
+ // <rule field="Genre" operator="contains">parameter</rule>
+ // where parameter can either be a string or a list of
+ // <value> tags containing a string
+ const char *field = element->Attribute("field");
+ const char *oper = element->Attribute("operator");
+ TiXmlNode *parameter = element->FirstChild();
+ if (field == NULL || oper == NULL || parameter == NULL)
+ return false;
+
+ if (parameter->Type() == TiXmlNode::TINYXML_TEXT)
+ {
+ CStdString utf8Parameter;
+ if (encoding.IsEmpty()) // utf8
+ utf8Parameter = parameter->ValueStr();
+ else
+ g_charsetConverter.stringCharsetToUtf8(encoding, parameter->ValueStr(), utf8Parameter);
+
+ if (!utf8Parameter.empty())
+ m_parameter.push_back(utf8Parameter);
+ }
+ else if (parameter->Type() == TiXmlNode::TINYXML_ELEMENT)
+ {
+ TiXmlElement *valueElem = element->FirstChildElement("value");
+ while (valueElem != NULL)
+ {
+ TiXmlNode *value = valueElem->FirstChild();
+ if (value != NULL && value->Type() == TiXmlNode::TINYXML_TEXT)
+ {
+ CStdString utf8Parameter;
+ if (encoding.IsEmpty()) // utf8
+ utf8Parameter = value->ValueStr();
+ else
+ g_charsetConverter.stringCharsetToUtf8(encoding, value->ValueStr(), utf8Parameter);
+
+ if (!utf8Parameter.empty())
+ m_parameter.push_back(utf8Parameter);
+ }
+
+ valueElem = valueElem->NextSiblingElement("value");
+ }
+ }
+ else
+ return false;
+
m_field = TranslateField(field);
m_operator = TranslateOperator(oper);
- m_parameter = parameter;
+ return true;
}
-TiXmlElement CSmartPlaylistRule::GetAsElement() const
+bool CSmartPlaylistRule::Save(TiXmlNode *parent) const
{
+ if (parent == NULL || m_parameter.empty())
+ return false;
+
TiXmlElement rule("rule");
- TiXmlText parameter(m_parameter.c_str());
- rule.InsertEndChild(parameter);
rule.SetAttribute("field", TranslateField(m_field).c_str());
rule.SetAttribute("operator", TranslateOperator(m_operator).c_str());
- return rule;
+
+ for (vector<CStdString>::const_iterator it = m_parameter.begin(); it != m_parameter.end(); it++)
+ {
+ TiXmlElement value("value");
+ TiXmlText text(it->c_str());
+ value.InsertEndChild(text);
+ rule.InsertEndChild(value);
+ }
+
+ parent->InsertEndChild(rule);
+
+ return true;
}
Field CSmartPlaylistRule::TranslateField(const char *field)
@@ -469,17 +529,22 @@ CStdString CSmartPlaylistRule::GetLocalizedOperator(SEARCH_OPERATOR oper)
return g_localizeStrings.Get(16018);
}
-CStdString CSmartPlaylistRule::GetLocalizedRule() const
+CStdString CSmartPlaylistRule::GetLocalizedRule(const CStdString &type) const
{
CStdString rule;
- rule.Format("%s %s %s", GetLocalizedField(m_field).c_str(), GetLocalizedOperator(m_operator).c_str(), m_parameter.c_str());
+ rule.Format("%s %s %s", GetLocalizedField(m_field).c_str(), GetLocalizedOperator(m_operator).c_str(), GetLocalizedParameter(type).c_str());
return rule;
}
-CStdString CSmartPlaylistRule::GetVideoResolutionQuery(void) const
+CStdString CSmartPlaylistRule::GetLocalizedParameter(const CStdString &type) const
+{
+ return StringUtils::JoinString(m_parameter, " / ");
+}
+
+CStdString CSmartPlaylistRule::GetVideoResolutionQuery(const CStdString &parameter) const
{
CStdString retVal(" in (select distinct idFile from streamdetails where iVideoWidth ");
- int iRes = atoi(m_parameter.c_str());
+ int iRes = (int)strtol(parameter.c_str(), NULL, 10);
int min, max;
if (iRes >= 1080) { min = 1281; max = INT_MAX; }
@@ -519,19 +584,10 @@ CStdString CSmartPlaylistRule::GetWhereClause(CDatabase &db, const CStdString& s
else if (op == OPERATOR_DOES_NOT_EQUAL)
op = OPERATOR_DOES_NOT_CONTAIN;
}
+
CStdString operatorString, negate;
- CStdString parameter;
if (GetFieldType(m_field) == TEXTIN_FIELD)
{
- CStdStringArray split;
- StringUtils::SplitString(m_parameter, ",", split);
- for (CStdStringArray::iterator it=split.begin(); it!=split.end(); ++it)
- {
- if (!parameter.IsEmpty())
- parameter += ",";
- parameter += db.PrepareSQL("'%s'", (*it).Trim().c_str());
- }
- parameter = " IN (" + parameter + ")";
if (op == OPERATOR_DOES_NOT_EQUAL)
negate = " NOT";
}
@@ -567,151 +623,178 @@ CStdString CSmartPlaylistRule::GetWhereClause(CDatabase &db, const CStdString& s
default:
break;
}
-
- parameter = db.PrepareSQL(operatorString.c_str(), m_parameter.c_str());
}
- if (GetFieldType(m_field) == DATE_FIELD)
- {
- if (m_operator == OPERATOR_IN_THE_LAST || m_operator == OPERATOR_NOT_IN_THE_LAST)
- { // translate time period
- CDateTime date=CDateTime::GetCurrentDateTime();
- CDateTimeSpan span;
- span.SetFromPeriod(m_parameter);
- date-=span;
- parameter = db.PrepareSQL(operatorString.c_str(), date.GetAsDBDate().c_str());
- }
- }
- else if (m_field == FieldTime)
- { // translate time to seconds
- CStdString seconds; seconds.Format("%i", StringUtils::TimeStringToSeconds(m_parameter));
- parameter = db.PrepareSQL(operatorString.c_str(), seconds.c_str());
- }
+ // FieldInProgress does not have any values in m_parameter, it works on the operator
+ if (m_field == FieldInProgress && (strType == "movies" || strType == "episodes"))
+ return "idFile " + negate + " in (select idFile from bookmark where type = 1)";
// now the query parameter
- CStdString query;
- if (strType == "songs")
- {
- if (m_field == FieldGenre)
- query = negate + " ((strGenre" + parameter + ") or idSong IN (select idSong from genre,exgenresong where exgenresong.idGenre = genre.idGenre and genre.strGenre" + parameter + "))";
- else if (m_field == FieldArtist)
- query = negate + " ((strArtist" + parameter + ") or idSong IN (select idSong from artist,exartistsong where exartistsong.idArtist = artist.idArtist and artist.strArtist" + parameter + "))";
- else if (m_field == FieldAlbumArtist)
- query = negate + " (idalbum in (select idalbum from artist,album where album.idArtist=artist.idArtist and artist.strArtist" + parameter + ") or idalbum in (select idalbum from artist,exartistalbum where exartistalbum.idArtist = artist.idArtist and artist.strArtist" + parameter + "))";
- else if (m_field == FieldLastPlayed && (m_operator == OPERATOR_LESS_THAN || m_operator == OPERATOR_BEFORE || m_operator == OPERATOR_NOT_IN_THE_LAST))
- query = "lastPlayed is NULL or lastPlayed" + parameter;
- }
- else if (strType == "albums")
- {
- if (m_field == FieldGenre)
- query = negate + " (idAlbum in (select song.idAlbum from song join genre on song.idGenre=genre.idGenre where genre.strGenre" + parameter + ") or "
- "idAlbum in (select song.idAlbum from song join exgenresong on song.idSong=exgenresong.idSong join genre on exgenresong.idGenre=genre.idGenre where genre.strGenre" + parameter + "))";
- else if (m_field == FieldArtist)
- query = negate + " (idAlbum in (select song.idAlbum from song join artist on song.idArtist=artist.idArtist where artist.strArtist" + parameter + ") or "
- "idAlbum in (select song.idAlbum from song join exartistsong on song.idSong=exartistsong.idSong join artist on exartistsong.idArtist=artist.idArtist where artist.strArtist" + parameter + "))";
- else if (m_field == FieldAlbumArtist)
- query = negate + " (idalbum in (select idalbum from artist,album where album.idArtist=artist.idArtist and artist.strArtist" + parameter + ") or idalbum in (select idalbum from artist,exartistalbum where exartistalbum.idArtist = artist.idArtist and artist.strArtist" + parameter + "))";
- }
- else if (strType == "movies")
- {
- if (m_field == FieldGenre)
- query = "idMovie" + negate + " in (select idMovie from genrelinkmovie join genre on genre.idGenre=genrelinkmovie.idGenre where genre.strGenre" + parameter + ")";
- else if (m_field == FieldDirector)
- query = "idMovie" + negate + " in (select idMovie from directorlinkmovie join actors on actors.idActor=directorlinkmovie.idDirector where actors.strActor" + parameter + ")";
- else if (m_field == FieldActor)
- query = "idMovie" + negate + " in (select idMovie from actorlinkmovie join actors on actors.idActor=actorlinkmovie.idActor where actors.strActor" + parameter + ")";
- else if (m_field == FieldWriter)
- query = "idMovie" + negate + " in (select idMovie from writerlinkmovie join actors on actors.idActor=writerlinkmovie.idWriter where actors.strActor" + parameter + ")";
- else if (m_field == FieldStudio)
- query = "idMovie" + negate + " in (select idMovie from studiolinkmovie join studio on studio.idStudio=studiolinkmovie.idStudio where studio.strStudio" + parameter + ")";
- else if (m_field == FieldCountry)
- query = "idMovie" + negate + " in (select idMovie from countrylinkmovie join country on country.idCountry=countrylinkmovie.idCountry where country.strCountry" + parameter + ")";
- else if (m_field == FieldTrailer)
- query = negate + GetField(m_field, strType) + "!= ''";
- else if ((m_field == FieldLastPlayed || m_field == FieldDateAdded) && (m_operator == OPERATOR_LESS_THAN || m_operator == OPERATOR_BEFORE || m_operator == OPERATOR_NOT_IN_THE_LAST))
- query = GetField(m_field, strType) + " is NULL or " + GetField(m_field, strType) + parameter;
- else if (m_field == FieldInProgress)
- query = "idFile " + negate + " in (select idFile from bookmark where type = 1)";
- else if (m_field == FieldSet)
- query = "idMovie" + negate + " in (select idMovie from setlinkmovie join sets on sets.idSet=setlinkmovie.idSet where sets.strSet" + parameter + ")";
- }
- else if (strType == "musicvideos")
- {
- if (m_field == FieldGenre)
- query = "idMVideo" + negate + " in (select idMVideo from genrelinkmusicvideo join genre on genre.idGenre=genrelinkmusicvideo.idGenre where genre.strGenre" + parameter + ")";
- else if (m_field == FieldArtist)
- query = "idMVideo" + negate + " in (select idMVideo from artistlinkmusicvideo join actors on actors.idActor=artistlinkmusicvideo.idArtist where actors.strActor" + parameter + ")";
- else if (m_field == FieldStudio)
- query = "idMVideo" + negate + " in (select idMVideo from studiolinkmusicvideo join studio on studio.idStudio=studiolinkmusicvideo.idStudio where studio.strStudio" + parameter + ")";
- else if (m_field == FieldDirector)
- query = "idMVideo" + negate + " in (select idMVideo from directorlinkmusicvideo join actors on actors.idActor=directorlinkmusicvideo.idDirector where actors.strActor" + parameter + ")";
- else if ((m_field == FieldLastPlayed || m_field == FieldDateAdded) && (m_operator == OPERATOR_LESS_THAN || m_operator == OPERATOR_BEFORE || m_operator == OPERATOR_NOT_IN_THE_LAST))
- query = GetField(m_field, strType) + " is NULL or " + GetField(m_field, strType) + parameter;
- }
- else if (strType == "tvshows")
- {
- if (m_field == FieldGenre)
- query = "idShow" + negate + " in (select idShow from genrelinktvshow join genre on genre.idGenre=genrelinktvshow.idGenre where genre.strGenre" + parameter + ")";
- else if (m_field == FieldDirector)
- query = "idShow" + negate + " in (select idShow from directorlinktvshow join actors on actors.idActor=directorlinktvshow.idDirector where actors.strActor" + parameter + ")";
- else if (m_field == FieldActor)
- query = "idShow" + negate + " in (select idShow from actorlinktvshow join actors on actors.idActor=actorlinktvshow.idActor where actors.strActor" + parameter + ")";
- else if (m_field == FieldStudio)
- query = "idShow" + negate + " IN (SELECT idShow FROM tvshowview WHERE " + GetField(m_field, strType) + parameter + ")";
- else if (m_field == FieldMPAA)
- query = "idShow" + negate + " IN (SELECT idShow FROM tvshowview WHERE " + GetField(m_field, strType) + parameter + ")";
- else if (m_field == FieldDateAdded && (m_operator == OPERATOR_LESS_THAN || m_operator == OPERATOR_BEFORE || m_operator == OPERATOR_NOT_IN_THE_LAST))
- query = "dateAdded is NULL or dateAdded" + parameter;
- }
- else if (strType == "episodes")
+ CStdString wholeQuery;
+ for (vector<CStdString>::const_iterator it = m_parameter.begin(); it != m_parameter.end(); /* it++ is done further down */)
{
- if (m_field == FieldGenre)
- query = "idShow" + negate + " in (select idShow from genrelinktvshow join genre on genre.idGenre=genrelinktvshow.idGenre where genre.strGenre" + parameter + ")";
- else if (m_field == FieldDirector)
- query = "idEpisode" + negate + " in (select idEpisode from directorlinkepisode join actors on actors.idActor=directorlinkepisode.idDirector where actors.strActor" + parameter + ")";
- else if (m_field == FieldActor)
- query = "idEpisode" + negate + " in (select idEpisode from actorlinkepisode join actors on actors.idActor=actorlinkepisode.idActor where actors.strActor" + parameter + ")";
- else if (m_field == FieldWriter)
- query = "idEpisode" + negate + " in (select idEpisode from writerlinkepisode join actors on actors.idActor=writerlinkepisode.idWriter where actors.strActor" + parameter + ")";
- else if ((m_field == FieldLastPlayed || m_field == FieldDateAdded) && (m_operator == OPERATOR_LESS_THAN || m_operator == OPERATOR_BEFORE || m_operator == OPERATOR_NOT_IN_THE_LAST))
- query = GetField(m_field, strType) + " is NULL or " + GetField(m_field, strType) + parameter;
- else if (m_field == FieldInProgress)
- query = "idFile " + negate + " in (select idFile from bookmark where type = 1)";
- else if (m_field == FieldStudio)
- query = "idEpisode" + negate + " IN (SELECT idEpisode FROM episodeview WHERE strStudio" + parameter + ")";
- else if (m_field == FieldMPAA)
- query = "idEpisode" + negate + " IN (SELECT idEpisode FROM episodeview WHERE mpaa" + parameter + ")";
- }
- if (m_field == FieldVideoResolution)
- query = "idFile" + negate + GetVideoResolutionQuery();
- else if (m_field == FieldAudioChannels)
- query = "idFile" + negate + " in (select distinct idFile from streamdetails where iAudioChannels " + parameter + ")";
- else if (m_field == FieldVideoCodec)
- query = "idFile" + negate + " in (select distinct idFile from streamdetails where strVideoCodec " + parameter + ")";
- else if (m_field == FieldAudioCodec)
- query = "idFile" + negate + " in (select distinct idFile from streamdetails where strAudioCodec " + parameter + ")";
- else if (m_field == FieldAudioLanguage)
- query = "idFile" + negate + " in (select distinct idFile from streamdetails where strAudioLanguage " + parameter + ")";
- else if (m_field == FieldSubtitleLanguage)
- query = "idFile" + negate + " in (select distinct idFile from streamdetails where strSubtitleLanguage " + parameter + ")";
- else if (m_field == FieldVideoAspectRatio)
- query = "idFile" + negate + " in (select distinct idFile from streamdetails where fVideoAspect " + parameter + ")";
- if (m_field == FieldPlaycount && strType != "songs" && strType != "albums")
- { // playcount is stored as NULL or number in video db
- if ((m_operator == OPERATOR_EQUALS && m_parameter == "0") ||
- (m_operator == OPERATOR_DOES_NOT_EQUAL && m_parameter != "0") ||
- (m_operator == OPERATOR_LESS_THAN))
+ CStdString parameter;
+ if (GetFieldType(m_field) == TEXTIN_FIELD)
+ {
+ CStdStringArray split;
+ StringUtils::SplitString(*it, ",", split);
+ for (CStdStringArray::iterator itIn = split.begin(); itIn != split.end(); ++itIn)
+ {
+ if (!parameter.IsEmpty())
+ parameter += ",";
+ parameter += db.PrepareSQL("'%s'", (*itIn).Trim().c_str());
+ }
+ parameter = " IN (" + parameter + ")";
+ }
+ else
+ parameter = db.PrepareSQL(operatorString.c_str(), it->c_str());
+
+ if (GetFieldType(m_field) == DATE_FIELD)
+ {
+ if (m_operator == OPERATOR_IN_THE_LAST || m_operator == OPERATOR_NOT_IN_THE_LAST)
+ { // translate time period
+ CDateTime date=CDateTime::GetCurrentDateTime();
+ CDateTimeSpan span;
+ span.SetFromPeriod(*it);
+ date-=span;
+ parameter = db.PrepareSQL(operatorString.c_str(), date.GetAsDBDate().c_str());
+ }
+ }
+ else if (m_field == FieldTime)
+ { // translate time to seconds
+ CStdString seconds; seconds.Format("%i", StringUtils::TimeStringToSeconds(*it));
+ parameter = db.PrepareSQL(operatorString.c_str(), seconds.c_str());
+ }
+
+ CStdString query;
+ if (strType == "songs")
+ {
+ if (m_field == FieldGenre)
+ query = negate + " ((strGenre" + parameter + ") or idSong IN (select idSong from genre,exgenresong where exgenresong.idGenre = genre.idGenre and genre.strGenre" + parameter + "))";
+ else if (m_field == FieldArtist)
+ query = negate + " ((strArtist" + parameter + ") or idSong IN (select idSong from artist,exartistsong where exartistsong.idArtist = artist.idArtist and artist.strArtist" + parameter + "))";
+ else if (m_field == FieldAlbumArtist)
+ query = negate + " (idalbum in (select idalbum from artist,album where album.idArtist=artist.idArtist and artist.strArtist" + parameter + ") or idalbum in (select idalbum from artist,exartistalbum where exartistalbum.idArtist = artist.idArtist and artist.strArtist" + parameter + "))";
+ else if (m_field == FieldLastPlayed && (m_operator == OPERATOR_LESS_THAN || m_operator == OPERATOR_BEFORE || m_operator == OPERATOR_NOT_IN_THE_LAST))
+ query = "lastPlayed is NULL or lastPlayed" + parameter;
+ }
+ else if (strType == "albums")
+ {
+ if (m_field == FieldGenre)
+ query = negate + " (idAlbum in (select song.idAlbum from song join genre on song.idGenre=genre.idGenre where genre.strGenre" + parameter + ") or "
+ "idAlbum in (select song.idAlbum from song join exgenresong on song.idSong=exgenresong.idSong join genre on exgenresong.idGenre=genre.idGenre where genre.strGenre" + parameter + "))";
+ else if (m_field == FieldArtist)
+ query = negate + " (idAlbum in (select song.idAlbum from song join artist on song.idArtist=artist.idArtist where artist.strArtist" + parameter + ") or "
+ "idAlbum in (select song.idAlbum from song join exartistsong on song.idSong=exartistsong.idSong join artist on exartistsong.idArtist=artist.idArtist where artist.strArtist" + parameter + "))";
+ else if (m_field == FieldAlbumArtist)
+ query = negate + " (idalbum in (select idalbum from artist,album where album.idArtist=artist.idArtist and artist.strArtist" + parameter + ") or idalbum in (select idalbum from artist,exartistalbum where exartistalbum.idArtist = artist.idArtist and artist.strArtist" + parameter + "))";
+ }
+ else if (strType == "movies")
+ {
+ if (m_field == FieldGenre)
+ query = "idMovie" + negate + " in (select idMovie from genrelinkmovie join genre on genre.idGenre=genrelinkmovie.idGenre where genre.strGenre" + parameter + ")";
+ else if (m_field == FieldDirector)
+ query = "idMovie" + negate + " in (select idMovie from directorlinkmovie join actors on actors.idActor=directorlinkmovie.idDirector where actors.strActor" + parameter + ")";
+ else if (m_field == FieldActor)
+ query = "idMovie" + negate + " in (select idMovie from actorlinkmovie join actors on actors.idActor=actorlinkmovie.idActor where actors.strActor" + parameter + ")";
+ else if (m_field == FieldWriter)
+ query = "idMovie" + negate + " in (select idMovie from writerlinkmovie join actors on actors.idActor=writerlinkmovie.idWriter where actors.strActor" + parameter + ")";
+ else if (m_field == FieldStudio)
+ query = "idMovie" + negate + " in (select idMovie from studiolinkmovie join studio on studio.idStudio=studiolinkmovie.idStudio where studio.strStudio" + parameter + ")";
+ else if (m_field == FieldCountry)
+ query = "idMovie" + negate + " in (select idMovie from countrylinkmovie join country on country.idCountry=countrylinkmovie.idCountry where country.strCountry" + parameter + ")";
+ else if (m_field == FieldTrailer)
+ query = negate + GetField(m_field, strType) + "!= ''";
+ else if ((m_field == FieldLastPlayed || m_field == FieldDateAdded) && (m_operator == OPERATOR_LESS_THAN || m_operator == OPERATOR_BEFORE || m_operator == OPERATOR_NOT_IN_THE_LAST))
+ query = GetField(m_field, strType) + " is NULL or " + GetField(m_field, strType) + parameter;
+ else if (m_field == FieldSet)
+ query = "idMovie" + negate + " in (select idMovie from setlinkmovie join sets on sets.idSet=setlinkmovie.idSet where sets.strSet" + parameter + ")";
+ }
+ else if (strType == "musicvideos")
+ {
+ if (m_field == FieldGenre)
+ query = "idMVideo" + negate + " in (select idMVideo from genrelinkmusicvideo join genre on genre.idGenre=genrelinkmusicvideo.idGenre where genre.strGenre" + parameter + ")";
+ else if (m_field == FieldArtist)
+ query = "idMVideo" + negate + " in (select idMVideo from artistlinkmusicvideo join actors on actors.idActor=artistlinkmusicvideo.idArtist where actors.strActor" + parameter + ")";
+ else if (m_field == FieldStudio)
+ query = "idMVideo" + negate + " in (select idMVideo from studiolinkmusicvideo join studio on studio.idStudio=studiolinkmusicvideo.idStudio where studio.strStudio" + parameter + ")";
+ else if (m_field == FieldDirector)
+ query = "idMVideo" + negate + " in (select idMVideo from directorlinkmusicvideo join actors on actors.idActor=directorlinkmusicvideo.idDirector where actors.strActor" + parameter + ")";
+ else if ((m_field == FieldLastPlayed || m_field == FieldDateAdded) && (m_operator == OPERATOR_LESS_THAN || m_operator == OPERATOR_BEFORE || m_operator == OPERATOR_NOT_IN_THE_LAST))
+ query = GetField(m_field, strType) + " is NULL or " + GetField(m_field, strType) + parameter;
+ }
+ else if (strType == "tvshows")
+ {
+ if (m_field == FieldGenre)
+ query = "idShow" + negate + " in (select idShow from genrelinktvshow join genre on genre.idGenre=genrelinktvshow.idGenre where genre.strGenre" + parameter + ")";
+ else if (m_field == FieldDirector)
+ query = "idShow" + negate + " in (select idShow from directorlinktvshow join actors on actors.idActor=directorlinktvshow.idDirector where actors.strActor" + parameter + ")";
+ else if (m_field == FieldActor)
+ query = "idShow" + negate + " in (select idShow from actorlinktvshow join actors on actors.idActor=actorlinktvshow.idActor where actors.strActor" + parameter + ")";
+ else if (m_field == FieldStudio)
+ query = "idShow" + negate + " IN (SELECT idShow FROM tvshowview WHERE " + GetField(m_field, strType) + parameter + ")";
+ else if (m_field == FieldMPAA)
+ query = "idShow" + negate + " IN (SELECT idShow FROM tvshowview WHERE " + GetField(m_field, strType) + parameter + ")";
+ else if (m_field == FieldDateAdded && (m_operator == OPERATOR_LESS_THAN || m_operator == OPERATOR_BEFORE || m_operator == OPERATOR_NOT_IN_THE_LAST))
+ query = "dateAdded is NULL or dateAdded" + parameter;
+ }
+ else if (strType == "episodes")
{
- CStdString field = GetField(FieldPlaycount, strType);
- query = field + " is NULL or " + field + parameter;
+ if (m_field == FieldGenre)
+ query = "idShow" + negate + " in (select idShow from genrelinktvshow join genre on genre.idGenre=genrelinktvshow.idGenre where genre.strGenre" + parameter + ")";
+ else if (m_field == FieldDirector)
+ query = "idEpisode" + negate + " in (select idEpisode from directorlinkepisode join actors on actors.idActor=directorlinkepisode.idDirector where actors.strActor" + parameter + ")";
+ else if (m_field == FieldActor)
+ query = "idEpisode" + negate + " in (select idEpisode from actorlinkepisode join actors on actors.idActor=actorlinkepisode.idActor where actors.strActor" + parameter + ")";
+ else if (m_field == FieldWriter)
+ query = "idEpisode" + negate + " in (select idEpisode from writerlinkepisode join actors on actors.idActor=writerlinkepisode.idWriter where actors.strActor" + parameter + ")";
+ else if ((m_field == FieldLastPlayed || m_field == FieldDateAdded) && (m_operator == OPERATOR_LESS_THAN || m_operator == OPERATOR_BEFORE || m_operator == OPERATOR_NOT_IN_THE_LAST))
+ query = GetField(m_field, strType) + " is NULL or " + GetField(m_field, strType) + parameter;
+ else if (m_field == FieldStudio)
+ query = "idEpisode" + negate + " IN (SELECT idEpisode FROM episodeview WHERE strStudio" + parameter + ")";
+ else if (m_field == FieldMPAA)
+ query = "idEpisode" + negate + " IN (SELECT idEpisode FROM episodeview WHERE mpaa" + parameter + ")";
}
+ if (m_field == FieldVideoResolution)
+ query = "idFile" + negate + GetVideoResolutionQuery(*it);
+ else if (m_field == FieldAudioChannels)
+ query = "idFile" + negate + " in (select distinct idFile from streamdetails where iAudioChannels " + parameter + ")";
+ else if (m_field == FieldVideoCodec)
+ query = "idFile" + negate + " in (select distinct idFile from streamdetails where strVideoCodec " + parameter + ")";
+ else if (m_field == FieldAudioCodec)
+ query = "idFile" + negate + " in (select distinct idFile from streamdetails where strAudioCodec " + parameter + ")";
+ else if (m_field == FieldAudioLanguage)
+ query = "idFile" + negate + " in (select distinct idFile from streamdetails where strAudioLanguage " + parameter + ")";
+ else if (m_field == FieldSubtitleLanguage)
+ query = "idFile" + negate + " in (select distinct idFile from streamdetails where strSubtitleLanguage " + parameter + ")";
+ else if (m_field == FieldVideoAspectRatio)
+ query = "idFile" + negate + " in (select distinct idFile from streamdetails where fVideoAspect " + parameter + ")";
+ if (m_field == FieldPlaycount && strType != "songs" && strType != "albums")
+ { // playcount is stored as NULL or number in video db
+ if ((m_operator == OPERATOR_EQUALS && it->Equals("0")) ||
+ (m_operator == OPERATOR_DOES_NOT_EQUAL && !it->Equals("0")) ||
+ (m_operator == OPERATOR_LESS_THAN))
+ {
+ CStdString field = GetField(FieldPlaycount, strType);
+ query = field + " is NULL or " + field + parameter;
+ }
+ }
+
+ if (query.IsEmpty() && m_field != FieldNone)
+ query = GetField(m_field,strType) + negate + parameter;
+
+ it++;
+ if (query.Equals(negate + parameter))
+ query = "1";
+
+ query = "(" + query + ")";
+ if (it != m_parameter.end())
+ query += " OR ";
+
+ wholeQuery += query;
}
- if (query.IsEmpty() && m_field != FieldNone)
- query = GetField(m_field,strType) + negate + parameter;
- // if we fail to get a dbfield, we empty query so it doesn't fail
- if (query.Equals(negate + parameter))
- query = "";
- return query;
+
+ return wholeQuery;
}
CStdString CSmartPlaylistRule::GetField(Field field, const CStdString& type)
@@ -797,36 +880,24 @@ bool CSmartPlaylist::LoadFromXML(TiXmlElement *root, const CStdString &encoding)
TiXmlHandle match = ((TiXmlHandle)root->FirstChild("match")).FirstChild();
if (match.Node())
m_matchAllRules = strcmpi(match.Node()->Value(), "all") == 0;
+
// now the rules
- TiXmlElement *rule = root->FirstChildElement("rule");
- while (rule)
+ TiXmlElement *ruleElement = root->FirstChildElement("rule");
+ while (ruleElement)
{
- // format is:
- // <rule field="Genre" operator="contains">parameter</rule>
- const char *field = rule->Attribute("field");
- const char *oper = rule->Attribute("operator");
- TiXmlNode *parameter = rule->FirstChild();
- if (field && oper)
- { // valid rule
- CStdString utf8Parameter;
- if (parameter)
- {
- if (encoding.IsEmpty()) // utf8
- utf8Parameter = parameter->Value();
- else
- g_charsetConverter.stringCharsetToUtf8(encoding, parameter->Value(), utf8Parameter);
- }
- CSmartPlaylistRule rule;
- rule.TranslateStrings(field, oper, utf8Parameter.c_str());
- m_playlistRules.push_back(rule);
- }
- rule = rule->NextSiblingElement("rule");
+ CSmartPlaylistRule rule;
+ rule.Load(ruleElement, encoding);
+ m_playlistRules.push_back(rule);
+
+ ruleElement = ruleElement->NextSiblingElement("rule");
}
+
// now any limits
// format is <limit>25</limit>
TiXmlHandle limit = ((TiXmlHandle)root->FirstChild("limit")).FirstChild();
if (limit.Node())
m_limit = atoi(limit.Node()->Value());
+
// and order
// format is <order direction="ascending">field</order>
TiXmlElement *order = root->FirstChildElement("order");
@@ -849,22 +920,25 @@ bool CSmartPlaylist::Save(const CStdString &path)
TiXmlElement xmlRootElement("smartplaylist");
xmlRootElement.SetAttribute("type",m_playlistType.c_str());
TiXmlNode *pRoot = doc.InsertEndChild(xmlRootElement);
- if (!pRoot) return false;
+ if (!pRoot)
+ return false;
+
// add the <name> tag
TiXmlText name(m_playlistName.c_str());
TiXmlElement nodeName("name");
nodeName.InsertEndChild(name);
pRoot->InsertEndChild(nodeName);
+
// add the <match> tag
TiXmlText match(m_matchAllRules ? "all" : "one");
TiXmlElement nodeMatch("match");
nodeMatch.InsertEndChild(match);
pRoot->InsertEndChild(nodeMatch);
+
// add <rule> tags
for (vector<CSmartPlaylistRule>::iterator it = m_playlistRules.begin(); it != m_playlistRules.end(); ++it)
- {
- pRoot->InsertEndChild((*it).GetAsElement());
- }
+ it->Save(pRoot);
+
// add <limit> tag
if (m_limit)
{
@@ -875,6 +949,7 @@ bool CSmartPlaylist::Save(const CStdString &path)
nodeLimit.InsertEndChild(limit);
pRoot->InsertEndChild(nodeLimit);
}
+
// add <order> tag
if (m_orderField != SortByNone)
{
@@ -913,7 +988,7 @@ CStdString CSmartPlaylist::GetWhereClause(CDatabase &db, set<CStdString> &refere
CStdString currentRule;
if (it->m_field == FieldPlaylist)
{
- CStdString playlistFile = CSmartPlaylistDirectory::GetPlaylistByName(it->m_parameter, GetType());
+ CStdString playlistFile = CSmartPlaylistDirectory::GetPlaylistByName(it->m_parameter.at(0), GetType());
if (!playlistFile.IsEmpty() && referencedPlaylists.find(playlistFile) == referencedPlaylists.end())
{
referencedPlaylists.insert(playlistFile);
View
14 xbmc/playlists/SmartPlayList.h
@@ -62,9 +62,10 @@ class CSmartPlaylistRule
TEXTIN_FIELD
};
- CStdString GetWhereClause(CDatabase &db, const CStdString& strType) const;
- void TranslateStrings(const char *field, const char *oper, const char *parameter);
+ bool Load(TiXmlElement *element, const CStdString &encoding = "UTF-8");
+ bool Save(TiXmlNode *parent) const;
+ CStdString GetWhereClause(CDatabase &db, const CStdString& strType) const;
static Field TranslateField(const char *field);
static CStdString TranslateField(Field field);
static SortBy TranslateOrder(const char *order);
@@ -79,17 +80,16 @@ class CSmartPlaylistRule
static std::vector<SortBy> GetOrders(const CStdString &type);
static FIELD_TYPE GetFieldType(Field field);
- CStdString GetLocalizedRule() const;
-
- TiXmlElement GetAsElement() const;
+ CStdString GetLocalizedRule(const CStdString &type) const;
+ CStdString GetLocalizedParameter(const CStdString &type) const;
Field m_field;
SEARCH_OPERATOR m_operator;
- CStdString m_parameter;
+ std::vector<CStdString> m_parameter;
private:
static SEARCH_OPERATOR TranslateOperator(const char *oper);
- CStdString GetVideoResolutionQuery(void) const;
+ CStdString GetVideoResolutionQuery(const CStdString &parameter) const;
};
class CSmartPlaylist

0 comments on commit 12f9cb7

Please sign in to comment.
Something went wrong with that request. Please try again.