1/*
2 * Copyright 2006-2007, 2023, Haiku.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Stephan A��mus <superstippi@gmx.de>
7 *		Zardshard
8 */
9#ifndef REMOVE_COMMAND_H
10#define REMOVE_COMMAND_H
11
12
13#include <new>
14#include <string.h>
15
16#include <Catalog.h>
17#include <Locale.h>
18#include <StringFormat.h>
19
20#include "Command.h"
21#include "Container.h"
22#include "IconBuild.h"
23
24#undef B_TRANSLATION_CONTEXT
25#define B_TRANSLATION_CONTEXT "Icon-O-Matic-RemoveItemsCmd"
26
27using std::nothrow;
28
29_USING_ICON_NAMESPACE
30
31
32/*! Removes items located at certain \c indices from a \c Container.
33
34	\note This class should be subclassed and the \c GetName member overridden.
35*/
36template <class Type>
37class RemoveCommand : public Command {
38 public:
39								RemoveCommand(
40									Container<Type>* container,
41									const int32* indices,
42									int32 count);
43	virtual						~RemoveCommand();
44
45	virtual	status_t			InitCheck();
46
47	virtual	status_t			Perform();
48	virtual status_t			Undo();
49
50	virtual void				GetName(BString& name);
51
52 protected:
53			Container<Type>*	fContainer;
54			Type**				fItems;
55			int32*				fIndices;
56			int32				fCount;
57			bool				fItemsRemoved;
58};
59
60
61template <class Type>
62RemoveCommand<Type>::RemoveCommand(
63		Container<Type>* container, const int32* indices, int32 count)
64	: Command(),
65	  fContainer(container),
66	  fItems(count > 0 ? new (nothrow) Type*[count] : NULL),
67	  fIndices(count > 0 ? new (nothrow) int32[count] : NULL),
68	  fCount(count),
69	  fItemsRemoved(false)
70{
71	if (!fContainer || !fItems || !fIndices)
72		return;
73
74	memcpy(fIndices, indices, sizeof(int32) * fCount);
75	for (int32 i = 0; i < fCount; i++)
76		fItems[i] = fContainer->ItemAt(fIndices[i]);
77}
78
79
80template <class Type>
81RemoveCommand<Type>::~RemoveCommand()
82{
83	if (fItemsRemoved && fItems) {
84		for (int32 i = 0; i < fCount; i++) {
85			if (fItems[i])
86				fItems[i]->ReleaseReference();
87		}
88	}
89	delete[] fItems;
90	delete[] fIndices;
91}
92
93
94template <class Type>
95status_t
96RemoveCommand<Type>::InitCheck()
97{
98	return fContainer && fItems && fIndices ? B_OK : B_NO_INIT;
99}
100
101
102template <class Type>
103status_t
104RemoveCommand<Type>::Perform()
105{
106	status_t ret = B_OK;
107
108	// remove shapes from container
109	for (int32 i = 0; i < fCount; i++) {
110		if (fItems[i] && !fContainer->RemoveItem(fItems[i])) {
111			ret = B_ERROR;
112			break;
113		}
114	}
115	fItemsRemoved = true;
116
117	return ret;
118}
119
120
121template <class Type>
122status_t
123RemoveCommand<Type>::Undo()
124{
125	status_t ret = B_OK;
126
127	// add shapes to container at remembered indices
128	for (int32 i = 0; i < fCount; i++) {
129		if (fItems[i] && !fContainer->AddItem(fItems[i], fIndices[i])) {
130			ret = B_ERROR;
131			break;
132		}
133	}
134	fItemsRemoved = false;
135
136	return ret;
137}
138
139
140template <class Type>
141void
142RemoveCommand<Type>::GetName(BString& name)
143{
144	static BStringFormat format(B_TRANSLATE("Remove {0, plural, "
145		"one{item} other{items}}"));
146	format.Format(name, fCount);
147}
148#endif // REMOVE_COMMAND_H
149