1/*
2 * Copyright �� 2007-2009 Stephan A��mus <superstippi@gmx.de>.
3 * All rights reserved. Distributed under the terms of the MIT License.
4 */
5#include "CopyPLItemsCommand.h"
6
7#include <new>
8#include <stdio.h>
9
10#include <Autolock.h>
11#include <Catalog.h>
12#include <Locale.h>
13
14#include "Playlist.h"
15
16
17#undef B_TRANSLATION_CONTEXT
18#define B_TRANSLATION_CONTEXT "MediaPlayer-CopyPLItemsCmd"
19
20
21using std::nothrow;
22
23
24CopyPLItemsCommand::CopyPLItemsCommand(Playlist* playlist,
25		 BList indices, int32 toIndex)
26	:
27	PLItemsCommand(),
28	fPlaylist(playlist),
29	fCount(indices.CountItems()),
30	fItems(fCount > 0 ? new (nothrow) PlaylistItem*[fCount] : NULL),
31	fToIndex(toIndex),
32	fItemsCopied(false)
33{
34	if (indices.IsEmpty() || !fPlaylist || !fItems) {
35		// indicate a bad object state
36		delete[] fItems;
37		fItems = NULL;
38		return;
39	}
40
41	memset(fItems, 0, sizeof(PlaylistItem*) * fCount);
42
43	// init original entries and
44	for (int32 i = 0; i < fCount; i++) {
45		PlaylistItem* item =
46			fPlaylist->ItemAt((int32)(addr_t)indices.ItemAt(i));
47		if (item != NULL)
48			fItems[i] = item->Clone();
49		if (fItems[i] == NULL) {
50			// indicate a bad object state
51			_CleanUp(fItems, fCount, true);
52			return;
53		}
54	}
55}
56
57
58CopyPLItemsCommand::~CopyPLItemsCommand()
59{
60	_CleanUp(fItems, fCount, !fItemsCopied);
61}
62
63
64status_t
65CopyPLItemsCommand::InitCheck()
66{
67	if (!fPlaylist || !fItems)
68		return B_NO_INIT;
69	return B_OK;
70}
71
72
73status_t
74CopyPLItemsCommand::Perform()
75{
76	BAutolock _(fPlaylist);
77
78	status_t ret = B_OK;
79
80	fItemsCopied = true;
81
82	// add refs to playlist at the insertion index
83	int32 index = fToIndex;
84	for (int32 i = 0; i < fCount; i++) {
85		if (!fPlaylist->AddItem(fItems[i], index++)) {
86			ret = B_NO_MEMORY;
87			break;
88		}
89	}
90	return ret;
91}
92
93
94status_t
95CopyPLItemsCommand::Undo()
96{
97	BAutolock _(fPlaylist);
98
99	fItemsCopied = false;
100	// remember currently playling item in case we copy items over it
101	PlaylistItem* current = fPlaylist->ItemAt(fPlaylist->CurrentItemIndex());
102
103	// remove refs from playlist
104	int32 index = fToIndex;
105	for (int32 i = 0; i < fCount; i++) {
106		fPlaylist->RemoveItem(index++, false);
107	}
108
109	// take care about currently played item
110	if (current != NULL)
111		fPlaylist->SetCurrentItemIndex(fPlaylist->IndexOf(current), false);
112
113	return B_OK;
114}
115
116
117void
118CopyPLItemsCommand::GetName(BString& name)
119{
120	if (fCount > 1)
121		name << B_TRANSLATE("Copy Entries");
122	else
123		name << B_TRANSLATE("Copy Entry");
124}
125