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