xref: /haiku/src/apps/icon-o-matic/style/MoveStylesCommand.cpp (revision 3cb015b1ee509d69c643506e8ff573808c86dcfc)
1 /*
2  * Copyright 2006, Haiku. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Stephan Aßmus <superstippi@gmx.de>
7  */
8 
9 #include "MoveStylesCommand.h"
10 
11 #include <new>
12 #include <stdio.h>
13 
14 #include "StyleContainer.h"
15 #include "Style.h"
16 
17 using std::nothrow;
18 
19 // constructor
20 MoveStylesCommand::MoveStylesCommand(StyleContainer* container,
21 									 Style** styles,
22 									 int32 count,
23 									 int32 toIndex)
24 	: Command(),
25 	  fContainer(container),
26 	  fStyles(styles),
27 	  fIndices(count > 0 ? new (nothrow) int32[count] : NULL),
28 	  fToIndex(toIndex),
29 	  fCount(count)
30 {
31 	if (!fContainer || !fStyles || !fIndices)
32 		return;
33 
34 	// init original style 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(fStyles[i]);
40 		if (fIndices[i] >= 0 && fIndices[i] < fToIndex)
41 			itemsBeforeIndex++;
42 	}
43 	fToIndex -= itemsBeforeIndex;
44 }
45 
46 // destructor
47 MoveStylesCommand::~MoveStylesCommand()
48 {
49 	delete[] fStyles;
50 	delete[] fIndices;
51 }
52 
53 // InitCheck
54 status_t
55 MoveStylesCommand::InitCheck()
56 {
57 	if (!fContainer || !fStyles || !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 MoveStylesCommand::Perform()
93 {
94 	status_t ret = B_OK;
95 
96 	// remove styles from container
97 	for (int32 i = 0; i < fCount; i++) {
98 		if (fStyles[i] && !fContainer->RemoveStyle(fStyles[i])) {
99 			ret = B_ERROR;
100 			break;
101 		}
102 	}
103 	if (ret < B_OK)
104 		return ret;
105 
106 	// add styles to container at the insertion index
107 	int32 index = fToIndex;
108 	for (int32 i = 0; i < fCount; i++) {
109 		if (fStyles[i] && !fContainer->AddStyle(fStyles[i], index++)) {
110 			ret = B_ERROR;
111 			break;
112 		}
113 	}
114 
115 	return ret;
116 }
117 
118 // Undo
119 status_t
120 MoveStylesCommand::Undo()
121 {
122 	status_t ret = B_OK;
123 
124 	// remove styles from container
125 	for (int32 i = 0; i < fCount; i++) {
126 		if (fStyles[i] && !fContainer->RemoveStyle(fStyles[i])) {
127 			ret = B_ERROR;
128 			break;
129 		}
130 	}
131 	if (ret < B_OK)
132 		return ret;
133 
134 	// add styles to container at remembered indices
135 	for (int32 i = 0; i < fCount; i++) {
136 		if (fStyles[i] && !fContainer->AddStyle(fStyles[i], fIndices[i])) {
137 			ret = B_ERROR;
138 			break;
139 		}
140 	}
141 
142 	return ret;
143 }
144 
145 // GetName
146 void
147 MoveStylesCommand::GetName(BString& name)
148 {
149 	if (fCount > 1)
150 		name << "Move Styles";
151 	else
152 		name << "Move Style";
153 }
154