xref: /haiku/src/apps/icon-o-matic/shape/commands/MoveShapesCommand.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 "MoveShapesCommand.h"
10 
11 #include <new>
12 #include <stdio.h>
13 
14 #include "ShapeContainer.h"
15 #include "Shape.h"
16 
17 using std::nothrow;
18 
19 // constructor
20 MoveShapesCommand::MoveShapesCommand(ShapeContainer* container,
21 									 Shape** shapes,
22 									 int32 count,
23 									 int32 toIndex)
24 	: Command(),
25 	  fContainer(container),
26 	  fShapes(shapes),
27 	  fIndices(count > 0 ? new (nothrow) int32[count] : NULL),
28 	  fToIndex(toIndex),
29 	  fCount(count)
30 {
31 	if (!fContainer || !fShapes || !fIndices)
32 		return;
33 
34 	// init original shape indices and
35 	// adjust toIndex compensating for items that
36 	// are removed before that index
37 	int32 itemsBeforeIndex = 0;
38 	for (int32 i = 0; i < fCount; i++) {
39 		fIndices[i] = fContainer->IndexOf(fShapes[i]);
40 		if (fIndices[i] >= 0 && fIndices[i] < fToIndex)
41 			itemsBeforeIndex++;
42 	}
43 	fToIndex -= itemsBeforeIndex;
44 }
45 
46 // destructor
47 MoveShapesCommand::~MoveShapesCommand()
48 {
49 	delete[] fShapes;
50 	delete[] fIndices;
51 }
52 
53 // InitCheck
54 status_t
55 MoveShapesCommand::InitCheck()
56 {
57 	if (!fContainer || !fShapes || !fIndices)
58 		return B_NO_INIT;
59 
60 	// analyse the move, don't return B_OK in case
61 	// the container state does not change...
62 
63 	int32 index = fIndices[0];
64 		// NOTE: fIndices == NULL if fCount < 1
65 
66 	if (index != fToIndex) {
67 		// a change is guaranteed
68 		return B_OK;
69 	}
70 
71 	// the insertion index is the same as the index of the first
72 	// moved item, a change only occures if the indices of the
73 	// moved items is not contiguous
74 	bool isContiguous = true;
75 	for (int32 i = 1; i < fCount; i++) {
76 		if (fIndices[i] != index + 1) {
77 			isContiguous = false;
78 			break;
79 		}
80 		index = fIndices[i];
81 	}
82 	if (isContiguous) {
83 		// the container state will not change because of the move
84 		return B_ERROR;
85 	}
86 
87 	return B_OK;
88 }
89 
90 // Perform
91 status_t
92 MoveShapesCommand::Perform()
93 {
94 	status_t ret = B_OK;
95 
96 	// remove shapes from container
97 	for (int32 i = 0; i < fCount; i++) {
98 		if (fShapes[i] && !fContainer->RemoveShape(fShapes[i])) {
99 			ret = B_ERROR;
100 			break;
101 		}
102 	}
103 	if (ret < B_OK)
104 		return ret;
105 
106 	// add shapes to container at the insertion index
107 	int32 index = fToIndex;
108 	for (int32 i = 0; i < fCount; i++) {
109 		if (fShapes[i] && !fContainer->AddShape(fShapes[i], index++)) {
110 			ret = B_ERROR;
111 			break;
112 		}
113 	}
114 
115 	return ret;
116 }
117 
118 // Undo
119 status_t
120 MoveShapesCommand::Undo()
121 {
122 	status_t ret = B_OK;
123 
124 	// remove shapes from container
125 	for (int32 i = 0; i < fCount; i++) {
126 		if (fShapes[i] && !fContainer->RemoveShape(fShapes[i])) {
127 			ret = B_ERROR;
128 			break;
129 		}
130 	}
131 	if (ret < B_OK)
132 		return ret;
133 
134 	// add shapes to container at remembered indices
135 	for (int32 i = 0; i < fCount; i++) {
136 		if (fShapes[i] && !fContainer->AddShape(fShapes[i], fIndices[i])) {
137 			ret = B_ERROR;
138 			break;
139 		}
140 	}
141 
142 	return ret;
143 }
144 
145 // GetName
146 void
147 MoveShapesCommand::GetName(BString& name)
148 {
149 //	if (fCount > 1)
150 //		name << _GetString(MOVE_MODIFIERS, "Move Shapes");
151 //	else
152 //		name << _GetString(MOVE_MODIFIER, "Move Shape");
153 	if (fCount > 1)
154 		name << "Move Shapes";
155 	else
156 		name << "Move Shape";
157 }
158