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