xref: /haiku/src/apps/icon-o-matic/style/RemoveStylesCommand.cpp (revision 1c09002cbee8e797a0f8bbfc5678dfadd39ee1a7)
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 "RemoveStylesCommand.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 "Shape.h"
19 #include "Style.h"
20 
21 
22 #undef B_TRANSLATE_CONTEXT
23 #define B_TRANSLATE_CONTEXT "Icon-O-Matic-RemoveStylesCmd"
24 
25 
26 using std::nothrow;
27 
28 // constructor
29 RemoveStylesCommand::RemoveStylesCommand(StyleContainer* container,
30 										 Style** const styles,
31 										 int32 count)
32 	: Command(),
33 	  fContainer(container),
34 	  fInfos(styles && count > 0 ? new (nothrow) StyleInfo[count] : NULL),
35 	  fCount(count),
36 	  fStylesRemoved(false)
37 {
38 	if (!fContainer || !fInfos)
39 		return;
40 
41 	for (int32 i = 0; i < fCount; i++) {
42 		fInfos[i].style = styles[i];
43 		fInfos[i].index = fContainer->IndexOf(styles[i]);
44 		if (styles[i]) {
45 			int32 listenerCount = styles[i]->CountObservers();
46 			for (int32 j = 0; j < listenerCount; j++) {
47 				Shape* shape = dynamic_cast<Shape*>(styles[i]->ObserverAtFast(j));
48 				if (shape)
49 					fInfos[i].shapes.AddItem((void*)shape);
50 			}
51 		}
52 	}
53 }
54 
55 // destructor
56 RemoveStylesCommand::~RemoveStylesCommand()
57 {
58 	if (fStylesRemoved && fInfos) {
59 		for (int32 i = 0; i < fCount; i++) {
60 			if (fInfos[i].style)
61 				fInfos[i].style->Release();
62 		}
63 	}
64 	delete[] fInfos;
65 }
66 
67 // InitCheck
68 status_t
69 RemoveStylesCommand::InitCheck()
70 {
71 	return fContainer && fInfos ? B_OK : B_NO_INIT;
72 }
73 
74 // Perform
75 status_t
76 RemoveStylesCommand::Perform()
77 {
78 	// remove styles from container
79 	for (int32 i = 0; i < fCount; i++) {
80 		if (!fInfos[i].style)
81 			continue;
82 		fContainer->RemoveStyle(fInfos[i].style);
83 	}
84 
85 	// remove styles from shapes that reference them
86 	for (int32 i = 0; i < fCount; i++) {
87 		if (!fInfos[i].style)
88 			continue;
89 		int32 shapeCount = fInfos[i].shapes.CountItems();
90 		for (int32 j = 0; j < shapeCount; j++) {
91 			Shape* shape = (Shape*)fInfos[i].shapes.ItemAtFast(j);
92 			shape->SetStyle(fContainer->StyleAt(0));
93 		}
94 	}
95 
96 	fStylesRemoved = true;
97 
98 	return B_OK;
99 }
100 
101 // Undo
102 status_t
103 RemoveStylesCommand::Undo()
104 {
105 	status_t ret = B_OK;
106 
107 	// add styles to container and shapes which previously referenced them
108 	for (int32 i = 0; i < fCount; i++) {
109 		if (!fInfos[i].style)
110 			continue;
111 		if (!fContainer->AddStyle(fInfos[i].style, fInfos[i].index)) {
112 			// roll back
113 			ret = B_ERROR;
114 			for (int32 j = i - 1; j >= 0; j--) {
115 				fContainer->RemoveStyle(fInfos[j].style);
116 			}
117 			for (int32 j = i - 1; j >= 0; j--) {
118 				int32 shapeCount = fInfos[j].shapes.CountItems();
119 				for (int32 k = 0; k < shapeCount; k++) {
120 					Shape* shape = (Shape*)fInfos[j].shapes.ItemAtFast(k);
121 					shape->SetStyle(fContainer->StyleAt(0));
122 				}
123 			}
124 			break;
125 		}
126 		int32 shapeCount = fInfos[i].shapes.CountItems();
127 		for (int32 j = 0; j < shapeCount; j++) {
128 			Shape* shape = (Shape*)fInfos[i].shapes.ItemAtFast(j);
129 			shape->SetStyle(fInfos[i].style);
130 		}
131 	}
132 
133 	fStylesRemoved = false;
134 
135 	return ret;
136 }
137 
138 // GetName
139 void
140 RemoveStylesCommand::GetName(BString& name)
141 {
142 	if (fCount > 1)
143 		name << B_TRANSLATE("Remove Styles");
144 	else
145 		name << B_TRANSLATE("Remove Style");
146 }
147