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)
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.AppendRefs(refsMessage);
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		FilePlaylistItem* fileItem = dynamic_cast<FilePlaylistItem*>(temp.ItemAtFast(i));
63		if (fileItem && !Playlist::ExtraMediaExists(playlist, fileItem->Ref())) {
64			fNewItems[added] = temp.ItemAtFast(i)->Clone();
65			if (fNewItems[added] == NULL) {
66				// indicate bad object init
67				_CleanUp(fNewItems, fNewCount, true);
68				return;
69			}
70			added++;
71		}
72	}
73	fNewCount = added;
74
75	fPlaylingIndex = fPlaylist->CurrentItemIndex();
76
77	if (fToIndex == APPEND_INDEX_REPLACE_PLAYLIST) {
78		fOldCount = fPlaylist->CountItems();
79		if (fOldCount > 0) {
80			fOldItems = new (nothrow) PlaylistItem*[fOldCount];
81			if (!fOldItems) {
82				// indicate bad object init
83				_CleanUp(fNewItems, fNewCount, true);
84			} else
85				memset(fOldItems, 0, fOldCount * sizeof(PlaylistItem*));
86		}
87	}
88
89	for (int32 i = 0; i < fOldCount; i++) {
90		fOldItems[i] = fPlaylist->ItemAtFast(i)->Clone();
91		if (fOldItems[i] == NULL) {
92			// indicate bad object init
93			_CleanUp(fNewItems, fNewCount, true);
94			return;
95		}
96	}
97}
98
99
100ImportPLItemsCommand::~ImportPLItemsCommand()
101{
102	_CleanUp(fOldItems, fOldCount, fItemsAdded);
103	_CleanUp(fNewItems, fNewCount, !fItemsAdded);
104}
105
106
107status_t
108ImportPLItemsCommand::InitCheck()
109{
110	if (!fPlaylist || !fNewItems)
111		return B_NO_INIT;
112	return B_OK;
113}
114
115
116status_t
117ImportPLItemsCommand::Perform()
118{
119	BAutolock _(fPlaylist);
120
121	fItemsAdded = true;
122
123	if (fToIndex == APPEND_INDEX_APPEND_LAST)
124		fToIndex = fPlaylist->CountItems();
125
126	int32 index = fToIndex;
127	if (fToIndex == APPEND_INDEX_REPLACE_PLAYLIST) {
128		fPlaylist->MakeEmpty(false);
129		index = 0;
130	}
131
132	bool startPlaying = fPlaylist->CountItems() == 0;
133
134	// add refs to playlist at the insertion index
135	for (int32 i = 0; i < fNewCount; i++) {
136		if (!fPlaylist->AddItem(fNewItems[i], index++))
137			return B_NO_MEMORY;
138	}
139
140	if (startPlaying) {
141		// open first file
142		fPlaylist->SetCurrentItemIndex(0);
143	}
144
145	return B_OK;
146}
147
148
149status_t
150ImportPLItemsCommand::Undo()
151{
152	BAutolock _(fPlaylist);
153
154	fItemsAdded = false;
155
156	if (fToIndex == APPEND_INDEX_REPLACE_PLAYLIST) {
157		// remove new items from playlist and restore old refs
158		fPlaylist->MakeEmpty(false);
159		for (int32 i = 0; i < fOldCount; i++) {
160			if (!fPlaylist->AddItem(fOldItems[i], i))
161				return B_NO_MEMORY;
162		}
163		// Restore previously playing item
164		if (fPlaylingIndex >= 0)
165			fPlaylist->SetCurrentItemIndex(fPlaylingIndex, false);
166	} else {
167		// remove new items from playlist
168		for (int32 i = 0; i < fNewCount; i++) {
169			fPlaylist->RemoveItem(fToIndex);
170		}
171	}
172
173	return B_OK;
174}
175
176
177void
178ImportPLItemsCommand::GetName(BString& name)
179{
180	if (fNewCount > 1)
181		name << B_TRANSLATE("Import Entries");
182	else
183		name << B_TRANSLATE("Import Entry");
184}
185
186