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