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