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