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
6
7#include "ImportPLItemsCommand.h"
8
9#include <new>
10#include <stdio.h>
11
12#include <Autolock.h>
13#include <Catalog.h>
14#include <Locale.h>
15
16#include "Playlist.h"
17#include "PlaylistItem.h"
18
19
20#undef B_TRANSLATION_CONTEXT
21#define B_TRANSLATION_CONTEXT "MediaPlayer-ImportPLItemsCmd"
22
23
24using std::nothrow;
25
26
27ImportPLItemsCommand::ImportPLItemsCommand(Playlist* playlist,
28		const BMessage* refsMessage, int32 toIndex, bool sortItems)
29	:
30	PLItemsCommand(),
31	fPlaylist(playlist),
32
33	fOldItems(NULL),
34	fOldCount(0),
35
36	fNewItems(NULL),
37	fNewCount(0),
38
39	fToIndex(toIndex),
40	fPlaylingIndex(0),
41
42	fItemsAdded(false)
43{
44	if (!fPlaylist)
45		return;
46
47	Playlist temp;
48	temp.AppendItems(refsMessage, APPEND_INDEX_REPLACE_PLAYLIST, sortItems);
49
50	fNewCount = temp.CountItems();
51	if (fNewCount <= 0)
52		return;
53
54	fNewItems = new (nothrow) PlaylistItem*[fNewCount];
55	if (!fNewItems)
56		return;
57	memset(fNewItems, 0, fNewCount * sizeof(PlaylistItem*));
58
59	// init new entries
60	int32 added = 0;
61	for (int32 i = 0; i < fNewCount; i++) {
62		if (!Playlist::ExtraMediaExists(playlist, temp.ItemAtFast(i))) {
63			fNewItems[added] = temp.ItemAtFast(i)->Clone();
64			if (fNewItems[added] == NULL) {
65				// indicate bad object init
66				_CleanUp(fNewItems, fNewCount, true);
67				return;
68			}
69			added++;
70		}
71	}
72	fNewCount = added;
73
74	fPlaylingIndex = fPlaylist->CurrentItemIndex();
75
76	if (fToIndex == APPEND_INDEX_REPLACE_PLAYLIST) {
77		fOldCount = fPlaylist->CountItems();
78		if (fOldCount > 0) {
79			fOldItems = new (nothrow) PlaylistItem*[fOldCount];
80			if (!fOldItems) {
81				// indicate bad object init
82				_CleanUp(fNewItems, fNewCount, true);
83			} else
84				memset(fOldItems, 0, fOldCount * sizeof(PlaylistItem*));
85		}
86	}
87
88	for (int32 i = 0; i < fOldCount; i++) {
89		fOldItems[i] = fPlaylist->ItemAtFast(i)->Clone();
90		if (fOldItems[i] == NULL) {
91			// indicate bad object init
92			_CleanUp(fNewItems, fNewCount, true);
93			return;
94		}
95	}
96}
97
98
99ImportPLItemsCommand::~ImportPLItemsCommand()
100{
101	_CleanUp(fOldItems, fOldCount, fItemsAdded);
102	_CleanUp(fNewItems, fNewCount, !fItemsAdded);
103}
104
105
106status_t
107ImportPLItemsCommand::InitCheck()
108{
109	if (!fPlaylist || !fNewItems)
110		return B_NO_INIT;
111	return B_OK;
112}
113
114
115status_t
116ImportPLItemsCommand::Perform()
117{
118	BAutolock _(fPlaylist);
119
120	fItemsAdded = true;
121
122	if (fToIndex == APPEND_INDEX_APPEND_LAST)
123		fToIndex = fPlaylist->CountItems();
124
125	int32 index = fToIndex;
126	if (fToIndex == APPEND_INDEX_REPLACE_PLAYLIST) {
127		fPlaylist->MakeEmpty(false);
128		index = 0;
129	}
130
131	bool startPlaying = fPlaylist->CountItems() == 0;
132
133	// add refs to playlist at the insertion index
134	for (int32 i = 0; i < fNewCount; i++) {
135		if (!fPlaylist->AddItem(fNewItems[i], index++))
136			return B_NO_MEMORY;
137	}
138
139	if (startPlaying) {
140		// open first file
141		fPlaylist->SetCurrentItemIndex(0);
142	}
143
144	return B_OK;
145}
146
147
148status_t
149ImportPLItemsCommand::Undo()
150{
151	BAutolock _(fPlaylist);
152
153	fItemsAdded = false;
154
155	if (fToIndex == APPEND_INDEX_REPLACE_PLAYLIST) {
156		// remove new items from playlist and restore old refs
157		fPlaylist->MakeEmpty(false);
158		for (int32 i = 0; i < fOldCount; i++) {
159			if (!fPlaylist->AddItem(fOldItems[i], i))
160				return B_NO_MEMORY;
161		}
162		// Restore previously playing item
163		if (fPlaylingIndex >= 0)
164			fPlaylist->SetCurrentItemIndex(fPlaylingIndex, false);
165	} else {
166		// remove new items from playlist
167		for (int32 i = 0; i < fNewCount; i++) {
168			fPlaylist->RemoveItem(fToIndex);
169		}
170	}
171
172	return B_OK;
173}
174
175
176void
177ImportPLItemsCommand::GetName(BString& name)
178{
179	if (fNewCount > 1)
180		name << B_TRANSLATE("Import Entries");
181	else
182		name << B_TRANSLATE("Import Entry");
183}
184
185