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