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