xref: /haiku/src/apps/mediaplayer/playlist/ImportPLItemsCommand.cpp (revision e7c8829c5d8e5d34a2a1e111f1c06aceff256013)
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 < 0) {
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 	int32 index = fToIndex;
116 	if (fToIndex < 0) {
117 		fPlaylist->MakeEmpty(false);
118 		index = 0;
119 	}
120 
121 	bool startPlaying = fPlaylist->CountItems() == 0;
122 
123 	// add refs to playlist at the insertion index
124 	for (int32 i = 0; i < fNewCount; i++) {
125 		if (!fPlaylist->AddItem(fNewItems[i], index++))
126 			return B_NO_MEMORY;
127 	}
128 
129 	if (startPlaying) {
130 		// open first file
131 		fPlaylist->SetCurrentItemIndex(0);
132 	}
133 
134 	return B_OK;
135 }
136 
137 
138 status_t
139 ImportPLItemsCommand::Undo()
140 {
141 	BAutolock _(fPlaylist);
142 
143 	fItemsAdded = false;
144 
145 	if (fToIndex < 0) {
146 		// remove new items from playlist and restore old refs
147 		fPlaylist->MakeEmpty(false);
148 		for (int32 i = 0; i < fOldCount; i++) {
149 			if (!fPlaylist->AddItem(fOldItems[i], i))
150 				return B_NO_MEMORY;
151 		}
152 		// Restore previously playing item
153 		if (fPlaylingIndex >= 0)
154 			fPlaylist->SetCurrentItemIndex(fPlaylingIndex);
155 	} else {
156 		// remove new items from playlist
157 		for (int32 i = 0; i < fNewCount; i++) {
158 			fPlaylist->RemoveItem(fToIndex);
159 		}
160 	}
161 
162 	return B_OK;
163 }
164 
165 
166 void
167 ImportPLItemsCommand::GetName(BString& name)
168 {
169 	if (fNewCount > 1)
170 		name << "Import Entries";
171 	else
172 		name << "Import Entry";
173 }
174 
175