[ExecString] combine SplitParameters with identical function of CUtil
[xbmc.git] / xbmc / dialogs / GUIDialogSmartPlaylistEditor.cpp
blob98714d38dcddb3dcca6d02ee4f4604127e5ae1dd
1 /*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
9 #include "GUIDialogSmartPlaylistEditor.h"
11 #include "FileItem.h"
12 #include "GUIDialogContextMenu.h"
13 #include "GUIDialogSelect.h"
14 #include "GUIDialogSmartPlaylistRule.h"
15 #include "ServiceBroker.h"
16 #include "Util.h"
17 #include "filesystem/File.h"
18 #include "guilib/GUIComponent.h"
19 #include "guilib/GUIKeyboardFactory.h"
20 #include "guilib/GUIWindowManager.h"
21 #include "guilib/LocalizeStrings.h"
22 #include "input/actions/ActionIDs.h"
23 #include "profiles/ProfileManager.h"
24 #include "settings/Settings.h"
25 #include "settings/SettingsComponent.h"
26 #include "utils/SortUtils.h"
27 #include "utils/StringUtils.h"
28 #include "utils/URIUtils.h"
29 #include "utils/Variant.h"
31 #include <utility>
33 #define CONTROL_HEADING 2
34 #define CONTROL_RULE_LIST 10
35 #define CONTROL_NAME 12
36 #define CONTROL_RULE_ADD 13
37 #define CONTROL_RULE_REMOVE 14
38 #define CONTROL_RULE_EDIT 15
39 #define CONTROL_MATCH 16
40 #define CONTROL_LIMIT 17
41 #define CONTROL_ORDER_FIELD 18
42 #define CONTROL_ORDER_DIRECTION 19
43 #define CONTROL_GROUP_BY 23
44 #define CONTROL_GROUP_MIXED 24
46 #define CONTROL_OK 20
47 #define CONTROL_CANCEL 21
48 #define CONTROL_TYPE 22
50 typedef struct
52 CGUIDialogSmartPlaylistEditor::PLAYLIST_TYPE type;
53 char string[13];
54 int localizedString;
55 } translateType;
57 static const translateType types[] = { { CGUIDialogSmartPlaylistEditor::TYPE_SONGS, "songs", 134 },
58 { CGUIDialogSmartPlaylistEditor::TYPE_ALBUMS, "albums", 132 },
59 { CGUIDialogSmartPlaylistEditor::TYPE_ARTISTS, "artists", 133 },
60 { CGUIDialogSmartPlaylistEditor::TYPE_MIXED, "mixed", 20395 },
61 { CGUIDialogSmartPlaylistEditor::TYPE_MUSICVIDEOS, "musicvideos", 20389 },
62 { CGUIDialogSmartPlaylistEditor::TYPE_MOVIES, "movies", 20342 },
63 { CGUIDialogSmartPlaylistEditor::TYPE_TVSHOWS, "tvshows", 20343 },
64 { CGUIDialogSmartPlaylistEditor::TYPE_EPISODES, "episodes", 20360 }
67 CGUIDialogSmartPlaylistEditor::CGUIDialogSmartPlaylistEditor(void)
68 : CGUIDialog(WINDOW_DIALOG_SMART_PLAYLIST_EDITOR, "SmartPlaylistEditor.xml")
70 m_cancelled = false;
71 m_ruleLabels = new CFileItemList;
72 m_loadType = KEEP_IN_MEMORY;
75 CGUIDialogSmartPlaylistEditor::~CGUIDialogSmartPlaylistEditor()
77 delete m_ruleLabels;
80 bool CGUIDialogSmartPlaylistEditor::OnBack(int actionID)
82 m_cancelled = true;
83 return CGUIDialog::OnBack(actionID);
86 bool CGUIDialogSmartPlaylistEditor::OnMessage(CGUIMessage& message)
88 switch ( message.GetMessage() )
90 case GUI_MSG_CLICKED:
92 int iControl = message.GetSenderId();
93 int iAction = message.GetParam1();
94 if (iControl == CONTROL_RULE_LIST && (iAction == ACTION_SELECT_ITEM || iAction == ACTION_MOUSE_LEFT_CLICK))
95 OnRuleList(GetSelectedItem());
96 else if (iControl == CONTROL_RULE_ADD)
97 OnRuleAdd();
98 else if (iControl == CONTROL_RULE_EDIT)
99 OnRuleList(GetSelectedItem());
100 else if (iControl == CONTROL_RULE_REMOVE)
101 OnRuleRemove(GetSelectedItem());
102 else if (iControl == CONTROL_NAME)
103 OnName();
104 else if (iControl == CONTROL_OK)
105 OnOK();
106 else if (iControl == CONTROL_CANCEL)
107 OnCancel();
108 else if (iControl == CONTROL_MATCH)
109 OnMatch();
110 else if (iControl == CONTROL_LIMIT)
111 OnLimit();
112 else if (iControl == CONTROL_ORDER_FIELD)
113 OnOrder();
114 else if (iControl == CONTROL_ORDER_DIRECTION)
115 OnOrderDirection();
116 else if (iControl == CONTROL_TYPE)
117 OnType();
118 else if (iControl == CONTROL_GROUP_BY)
119 OnGroupBy();
120 else if (iControl == CONTROL_GROUP_MIXED)
121 OnGroupMixed();
122 else if (iControl == CONTROL_RULE_LIST && (iAction == ACTION_CONTEXT_MENU || iAction == ACTION_MOUSE_RIGHT_CLICK))
123 OnPopupMenu(GetSelectedItem());
124 else
125 return CGUIDialog::OnMessage(message);
126 return true;
128 break;
129 case GUI_MSG_FOCUSED:
130 if (message.GetControlId() == CONTROL_RULE_REMOVE ||
131 message.GetControlId() == CONTROL_RULE_EDIT)
132 HighlightItem(GetSelectedItem());
133 else
135 if (message.GetControlId() == CONTROL_RULE_LIST)
136 UpdateRuleControlButtons();
138 HighlightItem(-1);
140 break;
141 case GUI_MSG_WINDOW_INIT:
143 const std::string& startupList = message.GetStringParam(0);
144 if (!startupList.empty())
146 int party = 0;
147 if (URIUtils::PathEquals(startupList, CServiceBroker::GetSettingsComponent()->GetProfileManager()->GetUserDataItem("PartyMode.xsp")))
148 party = 1;
149 else if (URIUtils::PathEquals(startupList, CServiceBroker::GetSettingsComponent()->GetProfileManager()->GetUserDataItem("PartyMode-Video.xsp")))
150 party = 2;
152 if ((party && !XFILE::CFile::Exists(startupList)) ||
153 m_playlist.Load(startupList))
155 m_path = startupList;
157 if (party == 1)
158 m_mode = "partymusic";
159 else if (party == 2)
160 m_mode = "partyvideo";
161 else
163 PLAYLIST_TYPE type = ConvertType(m_playlist.GetType());
164 if (type == TYPE_SONGS || type == TYPE_ALBUMS || type == TYPE_ARTISTS)
165 m_mode = "music";
166 else
167 m_mode = "video";
170 else
171 return false;
174 break;
175 case GUI_MSG_WINDOW_DEINIT:
177 m_playlist.Reset();
179 break;
181 return CGUIDialog::OnMessage(message);
184 void CGUIDialogSmartPlaylistEditor::OnPopupMenu(int item)
186 if (item < 0 || static_cast<size_t>(item) >= m_playlist.m_ruleCombination.m_rules.size())
187 return;
188 // highlight the item
189 m_ruleLabels->Get(item)->Select(true);
191 CContextButtons choices;
192 choices.Add(1, 15015);
194 int button = CGUIDialogContextMenu::ShowAndGetChoice(choices);
196 // unhighlight the item
197 m_ruleLabels->Get(item)->Select(false);
199 if (button == 1)
200 OnRuleRemove(item);
203 void CGUIDialogSmartPlaylistEditor::OnRuleList(int item)
205 if (item < 0 || item > static_cast<int>(m_playlist.m_ruleCombination.m_rules.size()))
206 return;
207 if (item == static_cast<int>(m_playlist.m_ruleCombination.m_rules.size()))
208 OnRuleAdd();
209 else
211 CSmartPlaylistRule rule = *std::static_pointer_cast<CSmartPlaylistRule>(m_playlist.m_ruleCombination.m_rules[item]);
212 if (CGUIDialogSmartPlaylistRule::EditRule(rule, m_playlist.GetType()))
213 *m_playlist.m_ruleCombination.m_rules[item] = rule;
215 UpdateButtons();
218 void CGUIDialogSmartPlaylistEditor::OnOK()
220 std::string systemPlaylistsPath = CServiceBroker::GetSettingsComponent()->GetSettings()->GetString(CSettings::SETTING_SYSTEM_PLAYLISTSPATH);
221 // save our playlist
222 if (m_path.empty())
224 std::string filename(CUtil::MakeLegalFileName(m_playlist.m_playlistName));
225 std::string path;
226 if (CGUIKeyboardFactory::ShowAndGetInput(filename, CVariant{g_localizeStrings.Get(16013)}, false))
228 path = URIUtils::AddFileToFolder(systemPlaylistsPath, m_playlist.GetSaveLocation(),
229 CUtil::MakeLegalFileName(std::move(filename)));
231 else
232 return;
233 if (!URIUtils::HasExtension(path, ".xsp"))
234 path += ".xsp";
236 // should we check whether we should overwrite?
237 m_path = path;
239 else
241 // check if we need to actually change the save location for this playlist
242 // this occurs if the user switches from music video <> songs <> mixed
243 if (StringUtils::StartsWith(m_path, systemPlaylistsPath))
245 std::string filename = URIUtils::GetFileName(m_path);
246 std::string strFolder = m_path.substr(systemPlaylistsPath.size(), m_path.size() - filename.size() - systemPlaylistsPath.size() - 1);
247 if (strFolder != m_playlist.GetSaveLocation())
248 { // move to the correct folder
249 XFILE::CFile::Delete(m_path);
250 m_path = URIUtils::AddFileToFolder(systemPlaylistsPath, m_playlist.GetSaveLocation(), filename);
255 m_playlist.Save(m_path);
257 m_cancelled = false;
258 Close();
261 void CGUIDialogSmartPlaylistEditor::OnCancel()
263 m_cancelled = true;
264 Close();
267 void CGUIDialogSmartPlaylistEditor::OnMatch()
269 // toggle between AND and OR setting
270 if (m_playlist.m_ruleCombination.GetType() == CSmartPlaylistRuleCombination::CombinationOr)
271 m_playlist.m_ruleCombination.SetType(CSmartPlaylistRuleCombination::CombinationAnd);
272 else
273 m_playlist.m_ruleCombination.SetType(CSmartPlaylistRuleCombination::CombinationOr);
274 UpdateButtons();
277 void CGUIDialogSmartPlaylistEditor::OnName()
279 std::string name = m_playlist.m_playlistName;
280 if (CGUIKeyboardFactory::ShowAndGetInput(name, CVariant{16012}, false))
282 m_playlist.m_playlistName = name;
283 UpdateButtons();
287 void CGUIDialogSmartPlaylistEditor::OnLimit()
289 std::vector<int> limits = {0, 10, 25, 50, 100, 250, 500, 1000};
290 CGUIDialogSelect* dialog = CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogSelect>(WINDOW_DIALOG_SELECT);
291 dialog->Reset();
292 int selected = -1;
293 for (auto limit = limits.begin(); limit != limits.end(); limit++)
295 if (*limit == static_cast<int>(m_playlist.m_limit))
296 selected = std::distance(limits.begin(), limit);
297 if (*limit == 0)
298 dialog->Add(g_localizeStrings.Get(21428));
299 else
300 dialog->Add(StringUtils::Format(g_localizeStrings.Get(21436), *limit));
302 dialog->SetHeading(CVariant{ 21427 });
303 dialog->SetSelected(selected);
304 dialog->Open();
305 int newSelected = dialog->GetSelectedItem();
306 if (!dialog->IsConfirmed() || newSelected < 0 || limits[newSelected] == static_cast<int>(m_playlist.m_limit))
307 return;
308 m_playlist.m_limit = limits[newSelected];
309 UpdateButtons();
312 void CGUIDialogSmartPlaylistEditor::OnType()
314 std::vector<PLAYLIST_TYPE> allowedTypes = GetAllowedTypes(m_mode);
315 CGUIDialogSelect* dialog = CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogSelect>(WINDOW_DIALOG_SELECT);
316 dialog->Reset();
317 for (auto allowedType: allowedTypes)
318 dialog->Add(GetLocalizedType(allowedType));
319 dialog->SetHeading(CVariant{ 564 });
320 dialog->SetSelected(GetLocalizedType(ConvertType(m_playlist.GetType())));
321 dialog->Open();
322 int newSelected = dialog->GetSelectedItem();
323 if (!dialog->IsConfirmed() || newSelected < 0 || allowedTypes[newSelected] == ConvertType(m_playlist.GetType()))
324 return;
326 m_playlist.SetType(ConvertType(allowedTypes[newSelected]));
328 // Remove any invalid grouping left over when changing the type
329 Field currentGroup = CSmartPlaylistRule::TranslateGroup(m_playlist.GetGroup().c_str());
330 if (currentGroup != FieldNone && currentGroup != FieldUnknown)
332 std::vector<Field> groups = CSmartPlaylistRule::GetGroups(m_playlist.GetType());
333 if (std::find(groups.begin(), groups.end(), currentGroup) == groups.end())
334 m_playlist.SetGroup(CSmartPlaylistRule::TranslateGroup(FieldUnknown));
337 UpdateButtons();
340 void CGUIDialogSmartPlaylistEditor::OnOrder()
342 std::vector<SortBy> orders = CSmartPlaylistRule::GetOrders(m_playlist.GetType());
343 CGUIDialogSelect* dialog = CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogSelect>(WINDOW_DIALOG_SELECT);
344 dialog->Reset();
345 for (auto order: orders)
346 dialog->Add(g_localizeStrings.Get(SortUtils::GetSortLabel(order)));
347 dialog->SetHeading(CVariant{ 21429 });
348 dialog->SetSelected(g_localizeStrings.Get(SortUtils::GetSortLabel(m_playlist.m_orderField)));
349 dialog->Open();
350 int newSelected = dialog->GetSelectedItem();
351 if (!dialog->IsConfirmed() || newSelected < 0 || orders[newSelected] == m_playlist.m_orderField)
352 return;
353 m_playlist.m_orderField = orders[newSelected];
354 UpdateButtons();
357 void CGUIDialogSmartPlaylistEditor::OnOrderDirection()
359 if (m_playlist.m_orderDirection == SortOrderDescending)
360 m_playlist.m_orderDirection = SortOrderAscending;
361 else
362 m_playlist.m_orderDirection = SortOrderDescending;
363 UpdateButtons();
366 void CGUIDialogSmartPlaylistEditor::OnGroupBy()
368 std::vector<Field> groups = CSmartPlaylistRule::GetGroups(m_playlist.GetType());
369 Field currentGroup = CSmartPlaylistRule::TranslateGroup(m_playlist.GetGroup().c_str());
370 CGUIDialogSelect* dialog = CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogSelect>(WINDOW_DIALOG_SELECT);
371 dialog->Reset();
372 for (auto group : groups)
373 dialog->Add(CSmartPlaylistRule::GetLocalizedGroup(group));
374 dialog->SetHeading(CVariant{ 21458 });
375 dialog->SetSelected(CSmartPlaylistRule::GetLocalizedGroup(currentGroup));
376 dialog->Open();
377 int newSelected = dialog->GetSelectedItem();
378 // check if selection has changed
379 if (!dialog->IsConfirmed() || newSelected < 0 || groups[newSelected] == currentGroup)
380 return;
381 m_playlist.SetGroup(CSmartPlaylistRule::TranslateGroup(groups[newSelected]));
383 if (m_playlist.IsGroupMixed() && !CSmartPlaylistRule::CanGroupMix(currentGroup))
384 m_playlist.SetGroupMixed(false);
386 UpdateButtons();
389 void CGUIDialogSmartPlaylistEditor::OnGroupMixed()
391 m_playlist.SetGroupMixed(!m_playlist.IsGroupMixed());
392 UpdateButtons();
395 void CGUIDialogSmartPlaylistEditor::UpdateButtons()
397 CONTROL_ENABLE(CONTROL_OK); // always enabled since we can have no rules -> match everything (as we do with default partymode playlists)
399 if (m_mode == "partyvideo" || m_mode == "partymusic")
401 SET_CONTROL_LABEL2(CONTROL_NAME, g_localizeStrings.Get(16035));
402 CONTROL_DISABLE(CONTROL_NAME);
404 else
405 SET_CONTROL_LABEL2(CONTROL_NAME, m_playlist.m_playlistName);
407 UpdateRuleControlButtons();
409 if (m_playlist.m_ruleCombination.GetType() == CSmartPlaylistRuleCombination::CombinationOr)
410 SET_CONTROL_LABEL2(CONTROL_MATCH, g_localizeStrings.Get(21426)); // one or more of the rules
411 else
412 SET_CONTROL_LABEL2(CONTROL_MATCH, g_localizeStrings.Get(21425)); // all of the rules
413 CONTROL_ENABLE_ON_CONDITION(CONTROL_MATCH, m_playlist.m_ruleCombination.m_rules.size() > 1);
414 if (m_playlist.m_limit == 0)
415 SET_CONTROL_LABEL2(CONTROL_LIMIT, g_localizeStrings.Get(21428)); // no limit
416 else
417 SET_CONTROL_LABEL2(CONTROL_LIMIT,
418 StringUtils::Format(g_localizeStrings.Get(21436), m_playlist.m_limit));
419 int currentItem = GetSelectedItem();
420 CGUIMessage msgReset(GUI_MSG_LABEL_RESET, GetID(), CONTROL_RULE_LIST);
421 OnMessage(msgReset);
422 m_ruleLabels->Clear();
423 for (const auto& rule: m_playlist.m_ruleCombination.m_rules)
425 CFileItemPtr item(new CFileItem("", false));
426 item->SetLabel(std::static_pointer_cast<CSmartPlaylistRule>(rule)->GetLocalizedRule());
427 m_ruleLabels->Add(item);
429 CFileItemPtr item(new CFileItem("", false));
430 item->SetLabel(g_localizeStrings.Get(21423));
431 m_ruleLabels->Add(item);
432 CGUIMessage msg(GUI_MSG_LABEL_BIND, GetID(), CONTROL_RULE_LIST, 0, 0, m_ruleLabels);
433 OnMessage(msg);
434 SendMessage(GUI_MSG_ITEM_SELECT, GetID(), CONTROL_RULE_LIST, currentItem);
436 if (m_playlist.m_orderDirection != SortOrderDescending)
438 SET_CONTROL_LABEL2(CONTROL_ORDER_DIRECTION, g_localizeStrings.Get(21430));
440 else
442 SET_CONTROL_LABEL2(CONTROL_ORDER_DIRECTION, g_localizeStrings.Get(21431));
445 SET_CONTROL_LABEL2(CONTROL_ORDER_FIELD, g_localizeStrings.Get(SortUtils::GetSortLabel(m_playlist.m_orderField)));
446 SET_CONTROL_LABEL2(CONTROL_TYPE, GetLocalizedType(ConvertType(m_playlist.GetType())));
448 // setup groups
449 std::vector<Field> groups = CSmartPlaylistRule::GetGroups(m_playlist.GetType());
450 Field currentGroup = CSmartPlaylistRule::TranslateGroup(m_playlist.GetGroup().c_str());
451 SET_CONTROL_LABEL2(CONTROL_GROUP_BY, CSmartPlaylistRule::GetLocalizedGroup(currentGroup));
452 if (m_playlist.IsGroupMixed())
453 CONTROL_SELECT(CONTROL_GROUP_MIXED);
454 else
455 CONTROL_DESELECT(CONTROL_GROUP_MIXED);
457 // disable the group controls if there's no group
458 // or only one group which can't be mixed
459 if (groups.empty() ||
460 (groups.size() == 1 && !CSmartPlaylistRule::CanGroupMix(groups[0])))
462 CONTROL_DISABLE(CONTROL_GROUP_BY);
463 CONTROL_DISABLE(CONTROL_GROUP_MIXED);
465 else
467 CONTROL_ENABLE(CONTROL_GROUP_BY);
468 CONTROL_ENABLE_ON_CONDITION(CONTROL_GROUP_MIXED, CSmartPlaylistRule::CanGroupMix(currentGroup));
472 void CGUIDialogSmartPlaylistEditor::UpdateRuleControlButtons()
474 int iSize = m_playlist.m_ruleCombination.m_rules.size();
475 int iItem = GetSelectedItem();
476 // only enable the remove control if ...
477 CONTROL_ENABLE_ON_CONDITION(CONTROL_RULE_REMOVE,
478 iSize > 0 && // there is at least one item
479 iItem >= 0 && iItem < iSize && // and a valid item is selected
480 m_playlist.m_ruleCombination.m_rules[iItem]->m_field != FieldNone); // and it is not be empty
483 void CGUIDialogSmartPlaylistEditor::OnInitWindow()
485 m_cancelled = false;
487 std::vector<PLAYLIST_TYPE> allowedTypes = GetAllowedTypes(m_mode);
488 // check if our playlist type is allowed
489 PLAYLIST_TYPE type = ConvertType(m_playlist.GetType());
490 bool allowed = false;
491 for (auto allowedType: allowedTypes)
493 if (type == allowedType)
494 allowed = true;
496 if (!allowed && allowedTypes.size())
497 m_playlist.SetType(ConvertType(allowedTypes[0]));
499 UpdateButtons();
501 SET_CONTROL_LABEL(CONTROL_HEADING, 21432);
503 CGUIDialog::OnInitWindow();
506 void CGUIDialogSmartPlaylistEditor::OnDeinitWindow(int nextWindowID)
508 CGUIDialog::OnDeinitWindow(nextWindowID);
509 SendMessage(GUI_MSG_LABEL_RESET, CONTROL_RULE_LIST);
510 SendMessage(GUI_MSG_LABEL_RESET, CONTROL_TYPE);
511 m_ruleLabels->Clear();
514 CGUIDialogSmartPlaylistEditor::PLAYLIST_TYPE CGUIDialogSmartPlaylistEditor::ConvertType(const std::string &type)
516 for (const translateType& t : types)
517 if (type == t.string)
518 return t.type;
519 assert(false);
520 return TYPE_SONGS;
523 std::string CGUIDialogSmartPlaylistEditor::GetLocalizedType(PLAYLIST_TYPE type)
525 for (const translateType& t : types)
526 if (t.type == type)
527 return g_localizeStrings.Get(t.localizedString);
528 assert(false);
529 return "";
532 std::string CGUIDialogSmartPlaylistEditor::ConvertType(PLAYLIST_TYPE type)
534 for (const translateType& t : types)
535 if (t.type == type)
536 return t.string;
537 assert(false);
538 return "songs";
541 int CGUIDialogSmartPlaylistEditor::GetSelectedItem()
543 CGUIMessage message(GUI_MSG_ITEM_SELECTED, GetID(), CONTROL_RULE_LIST);
544 OnMessage(message);
545 return message.GetParam1();
548 void CGUIDialogSmartPlaylistEditor::HighlightItem(int item)
550 for (int i = 0; i < m_ruleLabels->Size(); i++)
551 (*m_ruleLabels)[i]->Select(false);
552 if (item >= 0 && item < m_ruleLabels->Size())
553 (*m_ruleLabels)[item]->Select(true);
554 CGUIMessage msg(GUI_MSG_ITEM_SELECT, GetID(), CONTROL_RULE_LIST, item);
555 OnMessage(msg);
558 std::vector<CGUIDialogSmartPlaylistEditor::PLAYLIST_TYPE> CGUIDialogSmartPlaylistEditor::GetAllowedTypes(const std::string& mode)
560 std::vector<PLAYLIST_TYPE> allowedTypes;
561 if (mode == "partymusic")
563 allowedTypes.push_back(TYPE_SONGS);
564 allowedTypes.push_back(TYPE_MIXED);
566 else if (mode == "partyvideo")
568 allowedTypes.push_back(TYPE_MUSICVIDEOS);
569 allowedTypes.push_back(TYPE_MIXED);
571 else if (mode == "music")
572 { // music types + mixed
573 allowedTypes.push_back(TYPE_SONGS);
574 allowedTypes.push_back(TYPE_ALBUMS);
575 allowedTypes.push_back(TYPE_ARTISTS);
576 allowedTypes.push_back(TYPE_MIXED);
578 else if (mode == "video")
579 { // general category for videos
580 allowedTypes.push_back(TYPE_MOVIES);
581 allowedTypes.push_back(TYPE_TVSHOWS);
582 allowedTypes.push_back(TYPE_EPISODES);
583 allowedTypes.push_back(TYPE_MUSICVIDEOS);
584 allowedTypes.push_back(TYPE_MIXED);
586 return allowedTypes;
589 void CGUIDialogSmartPlaylistEditor::OnRuleRemove(int item)
591 if (item < 0 || item >= (int)m_playlist.m_ruleCombination.m_rules.size()) return;
592 m_playlist.m_ruleCombination.m_rules.erase(m_playlist.m_ruleCombination.m_rules.begin() + item);
594 UpdateButtons();
595 if (item >= m_ruleLabels->Size())
596 HighlightItem(m_ruleLabels->Size() - 1);
597 else
598 HighlightItem(item);
601 void CGUIDialogSmartPlaylistEditor::OnRuleAdd()
603 CSmartPlaylistRule rule;
604 if (CGUIDialogSmartPlaylistRule::EditRule(rule,m_playlist.GetType()))
605 m_playlist.m_ruleCombination.AddRule(rule);
606 UpdateButtons();
609 bool CGUIDialogSmartPlaylistEditor::NewPlaylist(const std::string &type)
611 CGUIDialogSmartPlaylistEditor *editor = CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogSmartPlaylistEditor>(WINDOW_DIALOG_SMART_PLAYLIST_EDITOR);
612 if (!editor) return false;
614 editor->m_path = "";
615 editor->m_playlist = CSmartPlaylist();
616 editor->m_mode = type;
617 editor->Initialize();
618 editor->Open();
619 return !editor->m_cancelled;
622 bool CGUIDialogSmartPlaylistEditor::EditPlaylist(const std::string &path, const std::string &type)
624 CGUIDialogSmartPlaylistEditor *editor = CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogSmartPlaylistEditor>(WINDOW_DIALOG_SMART_PLAYLIST_EDITOR);
625 if (!editor) return false;
627 editor->m_mode = type;
628 if (URIUtils::PathEquals(path, CServiceBroker::GetSettingsComponent()->GetProfileManager()->GetUserDataItem("PartyMode.xsp")))
629 editor->m_mode = "partymusic";
630 if (URIUtils::PathEquals(path, CServiceBroker::GetSettingsComponent()->GetProfileManager()->GetUserDataItem("PartyMode-Video.xsp")))
631 editor->m_mode = "partyvideo";
633 CSmartPlaylist playlist;
634 bool loaded(playlist.Load(path));
635 if (!loaded)
636 { // failed to load
637 if (!StringUtils::StartsWithNoCase(editor->m_mode, "party"))
638 return false; // only edit normal playlists that exist
639 // party mode playlists can be edited even if they don't exist
640 playlist.SetType(editor->m_mode == "partymusic" ? "songs" : "musicvideos");
643 editor->m_playlist = playlist;
644 editor->m_path = path;
645 editor->Initialize();
646 editor->Open();
647 return !editor->m_cancelled;