repository_infos: Enable automatic updates on the main Haiku repostiory.
[haiku.git] / src / apps / mediaplayer / playlist / MovePLItemsCommand.cpp
blobc40127cb80c885d61625b7f2a499ec5f520cbcb8
1 /*
2 * Copyright 2007-2009 Stephan Aßmus <superstippi@gmx.de>.
3 * All rights reserved. Distributed under the terms of the MIT License.
4 */
6 #include "MovePLItemsCommand.h"
8 #include <new>
9 #include <stdio.h>
11 #include <Autolock.h>
12 #include <Catalog.h>
13 #include <Locale.h>
15 #include "Playlist.h"
18 #undef B_TRANSLATION_CONTEXT
19 #define B_TRANSLATION_CONTEXT "MediaPlayer-MovePLItemsCmd"
22 using std::nothrow;
25 MovePLItemsCommand::MovePLItemsCommand(Playlist* playlist,
26 const int32* indices, int32 count, int32 toIndex)
28 PLItemsCommand(),
29 fPlaylist(playlist),
30 fItems(count > 0 ? new (nothrow) PlaylistItem*[count] : NULL),
31 fIndices(count > 0 ? new (nothrow) int32[count] : NULL),
32 fToIndex(toIndex),
33 fCount(count)
35 if (!indices || !fPlaylist || !fItems || !fIndices) {
36 // indicate a bad object state
37 delete[] fItems;
38 fItems = NULL;
39 return;
42 memset(fItems, 0, sizeof(PlaylistItem*) * fCount);
43 memcpy(fIndices, indices, fCount * sizeof(int32));
45 // init original entry indices and
46 // adjust toIndex compensating for items that
47 // are removed before that index
48 int32 itemsBeforeIndex = 0;
49 for (int32 i = 0; i < fCount; i++) {
50 fItems[i] = fPlaylist->ItemAt(fIndices[i]);
51 if (fItems[i] == NULL) {
52 // indicate a bad object state
53 delete[] fItems;
54 fItems = NULL;
55 return;
57 if (fIndices[i] < fToIndex)
58 itemsBeforeIndex++;
60 fToIndex -= itemsBeforeIndex;
64 MovePLItemsCommand::~MovePLItemsCommand()
66 delete[] fItems;
67 delete[] fIndices;
71 status_t
72 MovePLItemsCommand::InitCheck()
74 if (!fItems)
75 return B_NO_INIT;
77 // analyse the move, don't return B_OK in case
78 // the container state does not change...
80 int32 index = fIndices[0];
81 // NOTE: fIndices == NULL if fCount < 1
83 if (index != fToIndex) {
84 // a change is guaranteed
85 return B_OK;
88 // the insertion index is the same as the index of the first
89 // moved item, a change only occures if the indices of the
90 // moved items is not contiguous
91 bool isContiguous = true;
92 for (int32 i = 1; i < fCount; i++) {
93 if (fIndices[i] != index + 1) {
94 isContiguous = false;
95 break;
97 index = fIndices[i];
99 if (isContiguous) {
100 // the container state will not change because of the move
101 return B_ERROR;
104 return B_OK;
108 status_t
109 MovePLItemsCommand::Perform()
111 BAutolock _(fPlaylist);
113 status_t ret = B_OK;
115 // remember currently playling item in case we move it
116 PlaylistItem* current = fPlaylist->ItemAt(fPlaylist->CurrentItemIndex());
118 // remove refs from playlist
119 for (int32 i = 0; i < fCount; i++) {
120 // "- i" to account for the items already removed
121 fPlaylist->RemoveItem(fIndices[i] - i, false);
124 // add refs to playlist at the insertion index
125 int32 index = fToIndex;
126 for (int32 i = 0; i < fCount; i++) {
127 if (!fPlaylist->AddItem(fItems[i], index++)) {
128 ret = B_NO_MEMORY;
129 break;
132 if (ret < B_OK)
133 return ret;
135 // take care about currently played item
136 if (current != NULL)
137 fPlaylist->SetCurrentItemIndex(fPlaylist->IndexOf(current), false);
139 return B_OK;
143 status_t
144 MovePLItemsCommand::Undo()
146 BAutolock _(fPlaylist);
148 status_t ret = B_OK;
150 // remember currently playling item in case we move it
151 PlaylistItem* current = fPlaylist->ItemAt(fPlaylist->CurrentItemIndex());
153 // remove refs from playlist
154 int32 index = fToIndex;
155 for (int32 i = 0; i < fCount; i++) {
156 fPlaylist->RemoveItem(index++, false);
159 // add ref to playlist at remembered indices
160 for (int32 i = 0; i < fCount; i++) {
161 if (!fPlaylist->AddItem(fItems[i], fIndices[i])) {
162 ret = B_NO_MEMORY;
163 break;
166 if (ret < B_OK)
167 return ret;
169 // take care about currently played item
170 if (current != NULL)
171 fPlaylist->SetCurrentItemIndex(fPlaylist->IndexOf(current), false);
173 return B_OK;
177 void
178 MovePLItemsCommand::GetName(BString& name)
180 if (fCount > 1)
181 name << B_TRANSLATE("Move Entries");
182 else
183 name << B_TRANSLATE("Move Entry");