xref: /haiku/src/apps/mediaplayer/playlist/ImportPLItemsCommand.cpp (revision 820dca4df6c7bf955c46e8f6521b9408f50b2900)
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 
27 ImportPLItemsCommand::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 
100 ImportPLItemsCommand::~ImportPLItemsCommand()
101 {
102 	_CleanUp(fOldItems, fOldCount, fItemsAdded);
103 	_CleanUp(fNewItems, fNewCount, !fItemsAdded);
104 }
105 
106 
107 status_t
108 ImportPLItemsCommand::InitCheck()
109 {
110 	if (!fPlaylist || !fNewItems)
111 		return B_NO_INIT;
112 	return B_OK;
113 }
114 
115 
116 status_t
117 ImportPLItemsCommand::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 
149 status_t
150 ImportPLItemsCommand::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 
177 void
178 ImportPLItemsCommand::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