xref: /haiku/src/apps/icon-o-matic/shape/commands/RemovePointsCommand.cpp (revision 1e60bdeab63fa7a57bc9a55b032052e95a18bd2c)
1 /*
2  * Copyright 2006, Haiku.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Stephan Aßmus <superstippi@gmx.de>
7  */
8 
9 #include "RemovePointsCommand.h"
10 
11 #include <new>
12 #include <stdio.h>
13 
14 #include <Catalog.h>
15 #include <Locale.h>
16 
17 #include "VectorPath.h"
18 
19 
20 #undef B_TRANSLATION_CONTEXT
21 #define B_TRANSLATION_CONTEXT "Icon-O-Matic-RemovePointsCmd"
22 
23 
24 using std::nothrow;
25 
26 // constructor
27 // * when clicking a point in Remove mode, with other points selected
28 RemovePointsCommand::RemovePointsCommand(VectorPath* path,
29 										 int32 index,
30 										 const int32* selected,
31 										 int32 count)
32 	: PathCommand(path),
33 	  fIndex(NULL),
34 	  fPoint(NULL),
35 	  fPointIn(NULL),
36 	  fPointOut(NULL),
37 	  fConnected(NULL),
38 	  fCount(0),
39 	  fOldSelection(NULL),
40 	  fOldSelectionCount(count)
41 {
42 	_Init(&index, 1, selected, count);
43 }
44 
45 // constructor
46 // * when hitting the Delete key, so the selected points are the
47 // same as the ones to be removed
48 RemovePointsCommand::RemovePointsCommand(VectorPath* path,
49 										 const int32* selected,
50 										 int32 count)
51 	: PathCommand(path),
52 	  fIndex(NULL),
53 	  fPoint(NULL),
54 	  fPointIn(NULL),
55 	  fPointOut(NULL),
56 	  fConnected(NULL),
57 	  fCount(0),
58 	  fOldSelection(NULL),
59 	  fOldSelectionCount(count)
60 {
61 	_Init(selected, count, selected, count);
62 }
63 
64 // destructor
65 RemovePointsCommand::~RemovePointsCommand()
66 {
67 	delete[] fIndex;
68 	delete[] fPoint;
69 	delete[] fPointIn;
70 	delete[] fPointOut;
71 	delete[] fConnected;
72 	delete[] fOldSelection;
73 }
74 
75 // InitCheck
76 status_t
77 RemovePointsCommand::InitCheck()
78 {
79 	status_t status = PathCommand::InitCheck();
80 	if (status < B_OK)
81 		return status;
82 	if (!fIndex || !fPoint || !fPointIn || !fPointOut || !fConnected)
83 		status = B_NO_MEMORY;
84 	return status;
85 }
86 
87 // Perform
88 status_t
89 RemovePointsCommand::Perform()
90 {
91 	// path points are already removed
92 	return InitCheck();
93 }
94 
95 // Undo
96 status_t
97 RemovePointsCommand::Undo()
98 {
99 	status_t status = InitCheck();
100 	if (status < B_OK)
101 		return status;
102 
103 	AutoNotificationSuspender _(fPath);
104 
105 	// add points again at their respective index
106 	for (int32 i = 0; i < fCount; i++) {
107 		if (fPath->AddPoint(fPoint[i], fIndex[i])) {
108 			fPath->SetPoint(fIndex[i],
109 							fPoint[i],
110 							fPointIn[i],
111 							fPointOut[i],
112 							fConnected[i]);
113 		} else {
114 			status = B_ERROR;
115 			break;
116 		}
117 	}
118 
119 	fPath->SetClosed(fWasClosed);
120 
121 	if (status >= B_OK) {
122 		// select the added points
123 		_Select(fIndex, fCount);
124 	}
125 
126 	return status;
127 }
128 
129 // Redo
130 status_t
131 RemovePointsCommand::Redo()
132 {
133 	status_t status = InitCheck();
134 	if (status < B_OK)
135 		return status;
136 
137 	AutoNotificationSuspender _(fPath);
138 
139 	// remove points
140 	// the loop assumes the indices in the collection
141 	// are increasing (removal at "index[i] - i" to account
142 	// for items already removed)
143 	for (int32 i = 0; i < fCount; i++) {
144 		if (!fPath->RemovePoint(fIndex[i] - i)) {
145 			status = B_ERROR;
146 			break;
147 		}
148 	}
149 
150 	fPath->SetClosed(fWasClosed && fPath->CountPoints() > 1);
151 
152 	if (status >= B_OK) {
153 		// restore selection
154 		_Select(fOldSelection, fOldSelectionCount);
155 	}
156 
157 	return status;
158 }
159 
160 // GetName
161 void
162 RemovePointsCommand::GetName(BString& name)
163 {
164 //	if (fCount > 1)
165 //		name << _GetString(REMOVE_CONTROL_POINTS, "Remove Control Points");
166 //	else
167 //		name << _GetString(REMOVE_CONTROL_POINT, "Remove Control Point");
168 	if (fCount > 1)
169 		name << B_TRANSLATE("Remove Control Points");
170 	else
171 		name << B_TRANSLATE("Remove Control Point");
172 }
173 
174 // _Init
175 void
176 RemovePointsCommand::_Init(const int32* indices, int32 count,
177 						 const int32* selection, int32 selectionCount)
178 {
179 	if (indices && count > 0) {
180 		fIndex = new (nothrow) int32[count];
181 		fPoint = new (nothrow) BPoint[count];
182 		fPointIn = new (nothrow) BPoint[count];
183 		fPointOut = new (nothrow) BPoint[count];
184 		fConnected = new (nothrow) bool[count];
185 		fCount = count;
186 	}
187 
188 	if (InitCheck() < B_OK)
189 		return;
190 
191 	memcpy(fIndex, indices, count * sizeof(int32));
192 	for (int32 i = 0; i < count; i++) {
193 		if (!fPath->GetPointsAt(fIndex[i],
194 								fPoint[i],
195 								fPointIn[i],
196 								fPointOut[i],
197 								&fConnected[i])) {
198 			fPath = NULL;
199 			break;
200 		}
201 	}
202 
203 	if (fPath)
204 		fWasClosed = fPath->IsClosed();
205 
206 	if (selectionCount > 0 && selection) {
207 		fOldSelectionCount = selectionCount;
208 		fOldSelection = new (nothrow) int32[selectionCount];
209 		memcpy(fOldSelection, selection, selectionCount * sizeof(int32));
210 	}
211 }
212