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.
9 #include "GUIDialogSmartPlaylistEditor.h"
12 #include "FileItemList.h"
13 #include "GUIDialogContextMenu.h"
14 #include "GUIDialogSelect.h"
15 #include "GUIDialogSmartPlaylistRule.h"
16 #include "ServiceBroker.h"
18 #include "filesystem/File.h"
19 #include "guilib/GUIComponent.h"
20 #include "guilib/GUIKeyboardFactory.h"
21 #include "guilib/GUIWindowManager.h"
22 #include "guilib/LocalizeStrings.h"
23 #include "input/actions/ActionIDs.h"
24 #include "profiles/ProfileManager.h"
25 #include "settings/Settings.h"
26 #include "settings/SettingsComponent.h"
27 #include "utils/SortUtils.h"
28 #include "utils/StringUtils.h"
29 #include "utils/URIUtils.h"
30 #include "utils/Variant.h"
36 #define CONTROL_HEADING 2
37 #define CONTROL_RULE_LIST 10
38 #define CONTROL_NAME 12
39 #define CONTROL_RULE_ADD 13
40 #define CONTROL_RULE_REMOVE 14
41 #define CONTROL_RULE_EDIT 15
42 #define CONTROL_MATCH 16
43 #define CONTROL_LIMIT 17
44 #define CONTROL_ORDER_FIELD 18
45 #define CONTROL_ORDER_DIRECTION 19
46 #define CONTROL_GROUP_BY 23
47 #define CONTROL_GROUP_MIXED 24
50 #define CONTROL_CANCEL 21
51 #define CONTROL_TYPE 22
55 CGUIDialogSmartPlaylistEditor::PLAYLIST_TYPE type
;
60 static const translateType types
[] = { { CGUIDialogSmartPlaylistEditor::TYPE_SONGS
, "songs", 134 },
61 { CGUIDialogSmartPlaylistEditor::TYPE_ALBUMS
, "albums", 132 },
62 { CGUIDialogSmartPlaylistEditor::TYPE_ARTISTS
, "artists", 133 },
63 { CGUIDialogSmartPlaylistEditor::TYPE_MIXED
, "mixed", 20395 },
64 { CGUIDialogSmartPlaylistEditor::TYPE_MUSICVIDEOS
, "musicvideos", 20389 },
65 { CGUIDialogSmartPlaylistEditor::TYPE_MOVIES
, "movies", 20342 },
66 { CGUIDialogSmartPlaylistEditor::TYPE_TVSHOWS
, "tvshows", 20343 },
67 { CGUIDialogSmartPlaylistEditor::TYPE_EPISODES
, "episodes", 20360 }
70 CGUIDialogSmartPlaylistEditor::CGUIDialogSmartPlaylistEditor(void)
71 : CGUIDialog(WINDOW_DIALOG_SMART_PLAYLIST_EDITOR
, "SmartPlaylistEditor.xml")
74 m_ruleLabels
= new CFileItemList
;
75 m_loadType
= KEEP_IN_MEMORY
;
78 CGUIDialogSmartPlaylistEditor::~CGUIDialogSmartPlaylistEditor()
83 bool CGUIDialogSmartPlaylistEditor::OnBack(int actionID
)
86 return CGUIDialog::OnBack(actionID
);
89 bool CGUIDialogSmartPlaylistEditor::OnMessage(CGUIMessage
& message
)
91 switch ( message
.GetMessage() )
95 int iControl
= message
.GetSenderId();
96 int iAction
= message
.GetParam1();
97 if (iControl
== CONTROL_RULE_LIST
&& (iAction
== ACTION_SELECT_ITEM
|| iAction
== ACTION_MOUSE_LEFT_CLICK
))
98 OnRuleList(GetSelectedItem());
99 else if (iControl
== CONTROL_RULE_ADD
)
101 else if (iControl
== CONTROL_RULE_EDIT
)
102 OnRuleList(GetSelectedItem());
103 else if (iControl
== CONTROL_RULE_REMOVE
)
104 OnRuleRemove(GetSelectedItem());
105 else if (iControl
== CONTROL_NAME
)
107 else if (iControl
== CONTROL_OK
)
109 else if (iControl
== CONTROL_CANCEL
)
111 else if (iControl
== CONTROL_MATCH
)
113 else if (iControl
== CONTROL_LIMIT
)
115 else if (iControl
== CONTROL_ORDER_FIELD
)
117 else if (iControl
== CONTROL_ORDER_DIRECTION
)
119 else if (iControl
== CONTROL_TYPE
)
121 else if (iControl
== CONTROL_GROUP_BY
)
123 else if (iControl
== CONTROL_GROUP_MIXED
)
125 else if (iControl
== CONTROL_RULE_LIST
&& (iAction
== ACTION_CONTEXT_MENU
|| iAction
== ACTION_MOUSE_RIGHT_CLICK
))
126 OnPopupMenu(GetSelectedItem());
128 return CGUIDialog::OnMessage(message
);
132 case GUI_MSG_FOCUSED
:
133 if (message
.GetControlId() == CONTROL_RULE_REMOVE
||
134 message
.GetControlId() == CONTROL_RULE_EDIT
)
135 HighlightItem(GetSelectedItem());
138 if (message
.GetControlId() == CONTROL_RULE_LIST
)
139 UpdateRuleControlButtons();
144 case GUI_MSG_WINDOW_INIT
:
146 const std::string
& startupList
= message
.GetStringParam(0);
147 if (!startupList
.empty())
150 if (URIUtils::PathEquals(startupList
, CServiceBroker::GetSettingsComponent()->GetProfileManager()->GetUserDataItem("PartyMode.xsp")))
152 else if (URIUtils::PathEquals(startupList
, CServiceBroker::GetSettingsComponent()->GetProfileManager()->GetUserDataItem("PartyMode-Video.xsp")))
155 if ((party
&& !XFILE::CFile::Exists(startupList
)) ||
156 m_playlist
.Load(startupList
))
158 m_path
= startupList
;
161 m_mode
= "partymusic";
163 m_mode
= "partyvideo";
166 PLAYLIST_TYPE type
= ConvertType(m_playlist
.GetType());
167 if (type
== TYPE_SONGS
|| type
== TYPE_ALBUMS
|| type
== TYPE_ARTISTS
)
178 case GUI_MSG_WINDOW_DEINIT
:
184 return CGUIDialog::OnMessage(message
);
187 void CGUIDialogSmartPlaylistEditor::OnPopupMenu(int item
)
189 if (item
< 0 || static_cast<size_t>(item
) >= m_playlist
.m_ruleCombination
.m_rules
.size())
191 // highlight the item
192 m_ruleLabels
->Get(item
)->Select(true);
194 CContextButtons choices
;
195 choices
.Add(1, 15015);
197 int button
= CGUIDialogContextMenu::ShowAndGetChoice(choices
);
199 // unhighlight the item
200 m_ruleLabels
->Get(item
)->Select(false);
206 void CGUIDialogSmartPlaylistEditor::OnRuleList(int item
)
208 if (item
< 0 || item
> static_cast<int>(m_playlist
.m_ruleCombination
.m_rules
.size()))
210 if (item
== static_cast<int>(m_playlist
.m_ruleCombination
.m_rules
.size()))
214 auto rule
= *std::static_pointer_cast
<PLAYLIST::CSmartPlaylistRule
>(
215 m_playlist
.m_ruleCombination
.m_rules
[item
]);
216 if (CGUIDialogSmartPlaylistRule::EditRule(rule
, m_playlist
.GetType()))
217 *m_playlist
.m_ruleCombination
.m_rules
[item
] = rule
;
222 void CGUIDialogSmartPlaylistEditor::OnOK()
224 std::string systemPlaylistsPath
= CServiceBroker::GetSettingsComponent()->GetSettings()->GetString(CSettings::SETTING_SYSTEM_PLAYLISTSPATH
);
228 std::string
filename(CUtil::MakeLegalFileName(m_playlist
.m_playlistName
));
230 if (CGUIKeyboardFactory::ShowAndGetInput(filename
, CVariant
{g_localizeStrings
.Get(16013)}, false))
232 path
= URIUtils::AddFileToFolder(systemPlaylistsPath
, m_playlist
.GetSaveLocation(),
233 CUtil::MakeLegalFileName(std::move(filename
)));
237 if (!URIUtils::HasExtension(path
, ".xsp"))
240 // should we check whether we should overwrite?
245 // check if we need to actually change the save location for this playlist
246 // this occurs if the user switches from music video <> songs <> mixed
247 if (StringUtils::StartsWith(m_path
, systemPlaylistsPath
))
249 std::string filename
= URIUtils::GetFileName(m_path
);
250 std::string strFolder
= m_path
.substr(systemPlaylistsPath
.size(), m_path
.size() - filename
.size() - systemPlaylistsPath
.size() - 1);
251 if (strFolder
!= m_playlist
.GetSaveLocation())
252 { // move to the correct folder
253 XFILE::CFile::Delete(m_path
);
254 m_path
= URIUtils::AddFileToFolder(systemPlaylistsPath
, m_playlist
.GetSaveLocation(), filename
);
259 m_playlist
.Save(m_path
);
265 void CGUIDialogSmartPlaylistEditor::OnCancel()
271 void CGUIDialogSmartPlaylistEditor::OnMatch()
273 // toggle between AND and OR setting
274 if (m_playlist
.m_ruleCombination
.GetType() ==
275 PLAYLIST::CSmartPlaylistRuleCombination::CombinationOr
)
276 m_playlist
.m_ruleCombination
.SetType(PLAYLIST::CSmartPlaylistRuleCombination::CombinationAnd
);
278 m_playlist
.m_ruleCombination
.SetType(PLAYLIST::CSmartPlaylistRuleCombination::CombinationOr
);
282 void CGUIDialogSmartPlaylistEditor::OnName()
284 std::string name
= m_playlist
.m_playlistName
;
285 if (CGUIKeyboardFactory::ShowAndGetInput(name
, CVariant
{16012}, false))
287 m_playlist
.m_playlistName
= name
;
292 void CGUIDialogSmartPlaylistEditor::OnLimit()
294 std::vector
<int> limits
= {0, 10, 25, 50, 100, 250, 500, 1000};
295 CGUIDialogSelect
* dialog
= CServiceBroker::GetGUI()->GetWindowManager().GetWindow
<CGUIDialogSelect
>(WINDOW_DIALOG_SELECT
);
298 for (auto limit
= limits
.begin(); limit
!= limits
.end(); limit
++)
300 if (*limit
== static_cast<int>(m_playlist
.m_limit
))
301 selected
= std::distance(limits
.begin(), limit
);
303 dialog
->Add(g_localizeStrings
.Get(21428));
305 dialog
->Add(StringUtils::Format(g_localizeStrings
.Get(21436), *limit
));
307 dialog
->SetHeading(CVariant
{ 21427 });
308 dialog
->SetSelected(selected
);
310 int newSelected
= dialog
->GetSelectedItem();
311 if (!dialog
->IsConfirmed() || newSelected
< 0 || limits
[newSelected
] == static_cast<int>(m_playlist
.m_limit
))
313 m_playlist
.m_limit
= limits
[newSelected
];
317 void CGUIDialogSmartPlaylistEditor::OnType()
319 std::vector
<PLAYLIST_TYPE
> allowedTypes
= GetAllowedTypes(m_mode
);
320 CGUIDialogSelect
* dialog
= CServiceBroker::GetGUI()->GetWindowManager().GetWindow
<CGUIDialogSelect
>(WINDOW_DIALOG_SELECT
);
322 for (auto allowedType
: allowedTypes
)
323 dialog
->Add(GetLocalizedType(allowedType
));
324 dialog
->SetHeading(CVariant
{ 564 });
325 dialog
->SetSelected(GetLocalizedType(ConvertType(m_playlist
.GetType())));
327 int newSelected
= dialog
->GetSelectedItem();
328 if (!dialog
->IsConfirmed() || newSelected
< 0 || allowedTypes
[newSelected
] == ConvertType(m_playlist
.GetType()))
331 m_playlist
.SetType(ConvertType(allowedTypes
[newSelected
]));
333 // Remove any invalid grouping left over when changing the type
334 Field currentGroup
= PLAYLIST::CSmartPlaylistRule::TranslateGroup(m_playlist
.GetGroup().c_str());
335 if (currentGroup
!= FieldNone
&& currentGroup
!= FieldUnknown
)
337 std::vector
<Field
> groups
= PLAYLIST::CSmartPlaylistRule::GetGroups(m_playlist
.GetType());
338 if (std::find(groups
.begin(), groups
.end(), currentGroup
) == groups
.end())
339 m_playlist
.SetGroup(PLAYLIST::CSmartPlaylistRule::TranslateGroup(FieldUnknown
));
345 void CGUIDialogSmartPlaylistEditor::OnOrder()
347 std::vector
<SortBy
> orders
= PLAYLIST::CSmartPlaylistRule::GetOrders(m_playlist
.GetType());
348 CGUIDialogSelect
* dialog
= CServiceBroker::GetGUI()->GetWindowManager().GetWindow
<CGUIDialogSelect
>(WINDOW_DIALOG_SELECT
);
350 for (auto order
: orders
)
351 dialog
->Add(g_localizeStrings
.Get(SortUtils::GetSortLabel(order
)));
352 dialog
->SetHeading(CVariant
{ 21429 });
353 dialog
->SetSelected(g_localizeStrings
.Get(SortUtils::GetSortLabel(m_playlist
.m_orderField
)));
355 int newSelected
= dialog
->GetSelectedItem();
356 if (!dialog
->IsConfirmed() || newSelected
< 0 || orders
[newSelected
] == m_playlist
.m_orderField
)
358 m_playlist
.m_orderField
= orders
[newSelected
];
362 void CGUIDialogSmartPlaylistEditor::OnOrderDirection()
364 if (m_playlist
.m_orderDirection
== SortOrderDescending
)
365 m_playlist
.m_orderDirection
= SortOrderAscending
;
367 m_playlist
.m_orderDirection
= SortOrderDescending
;
371 void CGUIDialogSmartPlaylistEditor::OnGroupBy()
373 std::vector
<Field
> groups
= PLAYLIST::CSmartPlaylistRule::GetGroups(m_playlist
.GetType());
374 Field currentGroup
= PLAYLIST::CSmartPlaylistRule::TranslateGroup(m_playlist
.GetGroup().c_str());
375 CGUIDialogSelect
* dialog
= CServiceBroker::GetGUI()->GetWindowManager().GetWindow
<CGUIDialogSelect
>(WINDOW_DIALOG_SELECT
);
377 for (auto group
: groups
)
378 dialog
->Add(PLAYLIST::CSmartPlaylistRule::GetLocalizedGroup(group
));
379 dialog
->SetHeading(CVariant
{ 21458 });
380 dialog
->SetSelected(PLAYLIST::CSmartPlaylistRule::GetLocalizedGroup(currentGroup
));
382 int newSelected
= dialog
->GetSelectedItem();
383 // check if selection has changed
384 if (!dialog
->IsConfirmed() || newSelected
< 0 || groups
[newSelected
] == currentGroup
)
386 m_playlist
.SetGroup(PLAYLIST::CSmartPlaylistRule::TranslateGroup(groups
[newSelected
]));
388 if (m_playlist
.IsGroupMixed() && !PLAYLIST::CSmartPlaylistRule::CanGroupMix(currentGroup
))
389 m_playlist
.SetGroupMixed(false);
394 void CGUIDialogSmartPlaylistEditor::OnGroupMixed()
396 m_playlist
.SetGroupMixed(!m_playlist
.IsGroupMixed());
400 void CGUIDialogSmartPlaylistEditor::UpdateButtons()
402 CONTROL_ENABLE(CONTROL_OK
); // always enabled since we can have no rules -> match everything (as we do with default partymode playlists)
404 if (m_mode
== "partyvideo" || m_mode
== "partymusic")
406 SET_CONTROL_LABEL2(CONTROL_NAME
, g_localizeStrings
.Get(16035));
407 CONTROL_DISABLE(CONTROL_NAME
);
410 SET_CONTROL_LABEL2(CONTROL_NAME
, m_playlist
.m_playlistName
);
412 UpdateRuleControlButtons();
414 if (m_playlist
.m_ruleCombination
.GetType() ==
415 PLAYLIST::CSmartPlaylistRuleCombination::CombinationOr
)
416 SET_CONTROL_LABEL2(CONTROL_MATCH
, g_localizeStrings
.Get(21426)); // one or more of the rules
418 SET_CONTROL_LABEL2(CONTROL_MATCH
, g_localizeStrings
.Get(21425)); // all of the rules
419 CONTROL_ENABLE_ON_CONDITION(CONTROL_MATCH
, m_playlist
.m_ruleCombination
.m_rules
.size() > 1);
420 if (m_playlist
.m_limit
== 0)
421 SET_CONTROL_LABEL2(CONTROL_LIMIT
, g_localizeStrings
.Get(21428)); // no limit
423 SET_CONTROL_LABEL2(CONTROL_LIMIT
,
424 StringUtils::Format(g_localizeStrings
.Get(21436), m_playlist
.m_limit
));
425 int currentItem
= GetSelectedItem();
426 CGUIMessage
msgReset(GUI_MSG_LABEL_RESET
, GetID(), CONTROL_RULE_LIST
);
428 m_ruleLabels
->Clear();
429 for (const auto& rule
: m_playlist
.m_ruleCombination
.m_rules
)
431 CFileItemPtr
item(new CFileItem("", false));
433 std::static_pointer_cast
<PLAYLIST::CSmartPlaylistRule
>(rule
)->GetLocalizedRule());
434 m_ruleLabels
->Add(item
);
436 CFileItemPtr
item(new CFileItem("", false));
437 item
->SetLabel(g_localizeStrings
.Get(21423));
438 m_ruleLabels
->Add(item
);
439 CGUIMessage
msg(GUI_MSG_LABEL_BIND
, GetID(), CONTROL_RULE_LIST
, 0, 0, m_ruleLabels
);
441 SendMessage(GUI_MSG_ITEM_SELECT
, GetID(), CONTROL_RULE_LIST
, currentItem
);
443 if (m_playlist
.m_orderDirection
!= SortOrderDescending
)
445 SET_CONTROL_LABEL2(CONTROL_ORDER_DIRECTION
, g_localizeStrings
.Get(21430));
449 SET_CONTROL_LABEL2(CONTROL_ORDER_DIRECTION
, g_localizeStrings
.Get(21431));
452 SET_CONTROL_LABEL2(CONTROL_ORDER_FIELD
, g_localizeStrings
.Get(SortUtils::GetSortLabel(m_playlist
.m_orderField
)));
453 SET_CONTROL_LABEL2(CONTROL_TYPE
, GetLocalizedType(ConvertType(m_playlist
.GetType())));
456 std::vector
<Field
> groups
= PLAYLIST::CSmartPlaylistRule::GetGroups(m_playlist
.GetType());
457 Field currentGroup
= PLAYLIST::CSmartPlaylistRule::TranslateGroup(m_playlist
.GetGroup().c_str());
458 SET_CONTROL_LABEL2(CONTROL_GROUP_BY
,
459 PLAYLIST::CSmartPlaylistRule::GetLocalizedGroup(currentGroup
));
460 if (m_playlist
.IsGroupMixed())
461 CONTROL_SELECT(CONTROL_GROUP_MIXED
);
463 CONTROL_DESELECT(CONTROL_GROUP_MIXED
);
465 // disable the group controls if there's no group
466 // or only one group which can't be mixed
467 if (groups
.empty() ||
468 (groups
.size() == 1 && !PLAYLIST::CSmartPlaylistRule::CanGroupMix(groups
[0])))
470 CONTROL_DISABLE(CONTROL_GROUP_BY
);
471 CONTROL_DISABLE(CONTROL_GROUP_MIXED
);
475 CONTROL_ENABLE(CONTROL_GROUP_BY
);
476 CONTROL_ENABLE_ON_CONDITION(CONTROL_GROUP_MIXED
,
477 PLAYLIST::CSmartPlaylistRule::CanGroupMix(currentGroup
));
481 void CGUIDialogSmartPlaylistEditor::UpdateRuleControlButtons()
483 int iSize
= m_playlist
.m_ruleCombination
.m_rules
.size();
484 int iItem
= GetSelectedItem();
485 // only enable the remove control if ...
486 CONTROL_ENABLE_ON_CONDITION(CONTROL_RULE_REMOVE
,
487 iSize
> 0 && // there is at least one item
488 iItem
>= 0 && iItem
< iSize
&& // and a valid item is selected
489 m_playlist
.m_ruleCombination
.m_rules
[iItem
]->m_field
!= FieldNone
); // and it is not be empty
492 void CGUIDialogSmartPlaylistEditor::OnInitWindow()
496 std::vector
<PLAYLIST_TYPE
> allowedTypes
= GetAllowedTypes(m_mode
);
497 // check if our playlist type is allowed
498 PLAYLIST_TYPE type
= ConvertType(m_playlist
.GetType());
499 bool allowed
= false;
500 for (auto allowedType
: allowedTypes
)
502 if (type
== allowedType
)
505 if (!allowed
&& allowedTypes
.size())
506 m_playlist
.SetType(ConvertType(allowedTypes
[0]));
510 SET_CONTROL_LABEL(CONTROL_HEADING
, 21432);
512 CGUIDialog::OnInitWindow();
515 void CGUIDialogSmartPlaylistEditor::OnDeinitWindow(int nextWindowID
)
517 CGUIDialog::OnDeinitWindow(nextWindowID
);
518 SendMessage(GUI_MSG_LABEL_RESET
, CONTROL_RULE_LIST
);
519 SendMessage(GUI_MSG_LABEL_RESET
, CONTROL_TYPE
);
520 m_ruleLabels
->Clear();
523 CGUIDialogSmartPlaylistEditor::PLAYLIST_TYPE
CGUIDialogSmartPlaylistEditor::ConvertType(const std::string
&type
)
525 for (const translateType
& t
: types
)
526 if (type
== t
.string
)
532 std::string
CGUIDialogSmartPlaylistEditor::GetLocalizedType(PLAYLIST_TYPE type
)
534 for (const translateType
& t
: types
)
536 return g_localizeStrings
.Get(t
.localizedString
);
541 std::string
CGUIDialogSmartPlaylistEditor::ConvertType(PLAYLIST_TYPE type
)
543 for (const translateType
& t
: types
)
550 int CGUIDialogSmartPlaylistEditor::GetSelectedItem()
552 CGUIMessage
message(GUI_MSG_ITEM_SELECTED
, GetID(), CONTROL_RULE_LIST
);
554 return message
.GetParam1();
557 void CGUIDialogSmartPlaylistEditor::HighlightItem(int item
)
559 for (int i
= 0; i
< m_ruleLabels
->Size(); i
++)
560 (*m_ruleLabels
)[i
]->Select(false);
561 if (item
>= 0 && item
< m_ruleLabels
->Size())
562 (*m_ruleLabels
)[item
]->Select(true);
563 CGUIMessage
msg(GUI_MSG_ITEM_SELECT
, GetID(), CONTROL_RULE_LIST
, item
);
567 std::vector
<CGUIDialogSmartPlaylistEditor::PLAYLIST_TYPE
> CGUIDialogSmartPlaylistEditor::GetAllowedTypes(const std::string
& mode
)
569 std::vector
<PLAYLIST_TYPE
> allowedTypes
;
570 if (mode
== "partymusic")
572 allowedTypes
.push_back(TYPE_SONGS
);
573 allowedTypes
.push_back(TYPE_MIXED
);
575 else if (mode
== "partyvideo")
577 allowedTypes
.push_back(TYPE_MUSICVIDEOS
);
578 allowedTypes
.push_back(TYPE_MIXED
);
580 else if (mode
== "music")
581 { // music types + mixed
582 allowedTypes
.push_back(TYPE_SONGS
);
583 allowedTypes
.push_back(TYPE_ALBUMS
);
584 allowedTypes
.push_back(TYPE_ARTISTS
);
585 allowedTypes
.push_back(TYPE_MIXED
);
587 else if (mode
== "video")
588 { // general category for videos
589 allowedTypes
.push_back(TYPE_MOVIES
);
590 allowedTypes
.push_back(TYPE_TVSHOWS
);
591 allowedTypes
.push_back(TYPE_EPISODES
);
592 allowedTypes
.push_back(TYPE_MUSICVIDEOS
);
593 allowedTypes
.push_back(TYPE_MIXED
);
598 void CGUIDialogSmartPlaylistEditor::OnRuleRemove(int item
)
600 if (item
< 0 || item
>= (int)m_playlist
.m_ruleCombination
.m_rules
.size()) return;
601 m_playlist
.m_ruleCombination
.m_rules
.erase(m_playlist
.m_ruleCombination
.m_rules
.begin() + item
);
604 if (item
>= m_ruleLabels
->Size())
605 HighlightItem(m_ruleLabels
->Size() - 1);
610 void CGUIDialogSmartPlaylistEditor::OnRuleAdd()
612 PLAYLIST::CSmartPlaylistRule rule
;
613 if (CGUIDialogSmartPlaylistRule::EditRule(rule
,m_playlist
.GetType()))
614 m_playlist
.m_ruleCombination
.AddRule(rule
);
618 bool CGUIDialogSmartPlaylistEditor::NewPlaylist(const std::string
&type
)
620 CGUIDialogSmartPlaylistEditor
*editor
= CServiceBroker::GetGUI()->GetWindowManager().GetWindow
<CGUIDialogSmartPlaylistEditor
>(WINDOW_DIALOG_SMART_PLAYLIST_EDITOR
);
621 if (!editor
) return false;
624 editor
->m_playlist
= PLAYLIST::CSmartPlaylist();
625 editor
->m_mode
= type
;
626 editor
->Initialize();
628 return !editor
->m_cancelled
;
631 bool CGUIDialogSmartPlaylistEditor::EditPlaylist(const std::string
&path
, const std::string
&type
)
633 CGUIDialogSmartPlaylistEditor
*editor
= CServiceBroker::GetGUI()->GetWindowManager().GetWindow
<CGUIDialogSmartPlaylistEditor
>(WINDOW_DIALOG_SMART_PLAYLIST_EDITOR
);
634 if (!editor
) return false;
636 editor
->m_mode
= type
;
637 if (URIUtils::PathEquals(path
, CServiceBroker::GetSettingsComponent()->GetProfileManager()->GetUserDataItem("PartyMode.xsp")))
638 editor
->m_mode
= "partymusic";
639 if (URIUtils::PathEquals(path
, CServiceBroker::GetSettingsComponent()->GetProfileManager()->GetUserDataItem("PartyMode-Video.xsp")))
640 editor
->m_mode
= "partyvideo";
642 PLAYLIST::CSmartPlaylist playlist
;
643 bool loaded(playlist
.Load(path
));
646 if (!StringUtils::StartsWithNoCase(editor
->m_mode
, "party"))
647 return false; // only edit normal playlists that exist
648 // party mode playlists can be edited even if they don't exist
649 playlist
.SetType(editor
->m_mode
== "partymusic" ? "songs" : "musicvideos");
652 editor
->m_playlist
= playlist
;
653 editor
->m_path
= path
;
654 editor
->Initialize();
656 return !editor
->m_cancelled
;