xref: /haiku/src/apps/mediaplayer/playlist/ImportPLItemsCommand.cpp (revision 516510a226827b32bc1c2b12f96f8c74bd21ee1f)
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 
24 using std::nothrow;
25 
26 
ImportPLItemsCommand(Playlist * playlist,const BMessage * refsMessage,int32 toIndex,bool sortItems)27 ImportPLItemsCommand::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 
~ImportPLItemsCommand()99 ImportPLItemsCommand::~ImportPLItemsCommand()
100 {
101 	_CleanUp(fOldItems, fOldCount, fItemsAdded);
102 	_CleanUp(fNewItems, fNewCount, !fItemsAdded);
103 }
104 
105 
106 status_t
InitCheck()107 ImportPLItemsCommand::InitCheck()
108 {
109 	if (!fPlaylist || !fNewItems)
110 		return B_NO_INIT;
111 	return B_OK;
112 }
113 
114 
115 status_t
Perform()116 ImportPLItemsCommand::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 
148 status_t
Undo()149 ImportPLItemsCommand::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 
176 void
GetName(BString & name)177 ImportPLItemsCommand::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