xref: /haiku/src/apps/icon-o-matic/generic/command/RemoveCommand.h (revision e1c4049fed1047bdb957b0529e1921e97ef94770)
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 
27 using 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 */
36 template <class Type>
37 class 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 
61 template <class Type>
62 RemoveCommand<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 
80 template <class Type>
81 RemoveCommand<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 
94 template <class Type>
95 status_t
96 RemoveCommand<Type>::InitCheck()
97 {
98 	return fContainer && fItems && fIndices ? B_OK : B_NO_INIT;
99 }
100 
101 
102 template <class Type>
103 status_t
104 RemoveCommand<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 
121 template <class Type>
122 status_t
123 RemoveCommand<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 
140 template <class Type>
141 void
142 RemoveCommand<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