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		 const int32* indices, int32 count, int32 toIndex)
26	:
27	PLItemsCommand(),
28	fPlaylist(playlist),
29	fItems(count > 0 ? new (nothrow) PlaylistItem*[count] : NULL),
30	fToIndex(toIndex),
31	fCount(count),
32	fItemsCopied(false)
33{
34	if (!indices || !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 = fPlaylist->ItemAt(indices[i]);
46		if (item != NULL)
47			fItems[i] = item->Clone();
48		if (fItems[i] == NULL) {
49			// indicate a bad object state
50			_CleanUp(fItems, fCount, true);
51			return;
52		}
53	}
54}
55
56
57CopyPLItemsCommand::~CopyPLItemsCommand()
58{
59	_CleanUp(fItems, fCount, !fItemsCopied);
60}
61
62
63status_t
64CopyPLItemsCommand::InitCheck()
65{
66	if (!fPlaylist || !fItems)
67		return B_NO_INIT;
68	return B_OK;
69}
70
71
72status_t
73CopyPLItemsCommand::Perform()
74{
75	BAutolock _(fPlaylist);
76
77	status_t ret = B_OK;
78
79	fItemsCopied = true;
80
81	// add refs to playlist at the insertion index
82	int32 index = fToIndex;
83	for (int32 i = 0; i < fCount; i++) {
84		if (!fPlaylist->AddItem(fItems[i], index++)) {
85			ret = B_NO_MEMORY;
86			break;
87		}
88	}
89	return ret;
90}
91
92
93status_t
94CopyPLItemsCommand::Undo()
95{
96	BAutolock _(fPlaylist);
97
98	fItemsCopied = false;
99	// remember currently playling item in case we copy items over it
100	PlaylistItem* current = fPlaylist->ItemAt(fPlaylist->CurrentItemIndex());
101
102	// remove refs from playlist
103	int32 index = fToIndex;
104	for (int32 i = 0; i < fCount; i++) {
105		fPlaylist->RemoveItem(index++, false);
106	}
107
108	// take care about currently played item
109	if (current != NULL)
110		fPlaylist->SetCurrentItemIndex(fPlaylist->IndexOf(current), false);
111
112	return B_OK;
113}
114
115
116void
117CopyPLItemsCommand::GetName(BString& name)
118{
119	if (fCount > 1)
120		name << B_TRANSLATE("Copy Entries");
121	else
122		name << B_TRANSLATE("Copy Entry");
123}
124