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