xref: /haiku/src/apps/icon-o-matic/shape/commands/RemovePathsCommand.cpp (revision 098eaec6305ae804d3eb6c8e6c6aad790fb4cfb1)
1 /*
2  * Copyright 2006, Haiku.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Stephan Aßmus <superstippi@gmx.de>
7  */
8 
9 #include "RemovePathsCommand.h"
10 
11 #include <new>
12 #include <stdio.h>
13 
14 #include <Catalog.h>
15 #include <Locale.h>
16 
17 #include "PathContainer.h"
18 #include "PathSourceShape.h"
19 #include "Shape.h"
20 #include "VectorPath.h"
21 
22 
23 #undef B_TRANSLATION_CONTEXT
24 #define B_TRANSLATION_CONTEXT "Icon-O-Matic-RemovePathsCmd"
25 
26 
27 using std::nothrow;
28 
29 // constructor
30 RemovePathsCommand::RemovePathsCommand(PathContainer* container,
31 									   VectorPath** const paths,
32 									   int32 count)
33 	: Command(),
34 	  fContainer(container),
35 	  fInfos(paths && count > 0 ? new (nothrow) PathInfo[count] : NULL),
36 	  fCount(count),
37 	  fPathsRemoved(false)
38 {
39 	if (!fContainer || !fInfos)
40 		return;
41 
42 	for (int32 i = 0; i < fCount; i++) {
43 		fInfos[i].path = paths[i];
44 		fInfos[i].index = fContainer->IndexOf(paths[i]);
45 		if (paths[i]) {
46 			int32 listenerCount = paths[i]->CountListeners();
47 			for (int32 j = 0; j < listenerCount; j++) {
48 				PathSourceShape* shape
49 					= dynamic_cast<PathSourceShape*>(paths[i]->ListenerAtFast(j));
50 				if (shape)
51 					fInfos[i].shapes.AddItem((void*)shape);
52 			}
53 		}
54 	}
55 }
56 
57 // destructor
58 RemovePathsCommand::~RemovePathsCommand()
59 {
60 	if (fPathsRemoved && fInfos) {
61 		for (int32 i = 0; i < fCount; i++) {
62 			if (fInfos[i].path)
63 				fInfos[i].path->ReleaseReference();
64 		}
65 	}
66 	delete[] fInfos;
67 }
68 
69 // InitCheck
70 status_t
71 RemovePathsCommand::InitCheck()
72 {
73 	return fContainer && fInfos ? B_OK : B_NO_INIT;
74 }
75 
76 // Perform
77 status_t
78 RemovePathsCommand::Perform()
79 {
80 	// remove paths from container and shapes that reference them
81 	for (int32 i = 0; i < fCount; i++) {
82 		if (!fInfos[i].path)
83 			continue;
84 		fContainer->RemovePath(fInfos[i].path);
85 		int32 shapeCount = fInfos[i].shapes.CountItems();
86 		for (int32 j = 0; j < shapeCount; j++) {
87 			PathSourceShape* shape = (PathSourceShape*)fInfos[i].shapes.ItemAtFast(j);
88 			shape->Paths()->RemovePath(fInfos[i].path);
89 		}
90 	}
91 	fPathsRemoved = true;
92 
93 	return B_OK;
94 }
95 
96 // Undo
97 status_t
98 RemovePathsCommand::Undo()
99 {
100 	status_t ret = B_OK;
101 
102 	// add paths to container and shapes which previously referenced them
103 	for (int32 i = 0; i < fCount; i++) {
104 		if (!fInfos[i].path)
105 			continue;
106 		if (!fContainer->AddPath(fInfos[i].path, fInfos[i].index)) {
107 			// roll back
108 			ret = B_ERROR;
109 			for (int32 j = i - 1; j >= 0; j--) {
110 				fContainer->RemovePath(fInfos[j].path);
111 				int32 shapeCount = fInfos[j].shapes.CountItems();
112 				for (int32 k = 0; k < shapeCount; k++) {
113 					PathSourceShape* shape = (PathSourceShape*)fInfos[j].shapes.ItemAtFast(k);
114 					shape->Paths()->RemovePath(fInfos[j].path);
115 				}
116 			}
117 			break;
118 		}
119 		int32 shapeCount = fInfos[i].shapes.CountItems();
120 		for (int32 j = 0; j < shapeCount; j++) {
121 			PathSourceShape* shape = (PathSourceShape*)fInfos[i].shapes.ItemAtFast(j);
122 			shape->Paths()->AddPath(fInfos[i].path);
123 		}
124 	}
125 	fPathsRemoved = false;
126 
127 	return ret;
128 }
129 
130 // GetName
131 void
132 RemovePathsCommand::GetName(BString& name)
133 {
134 	if (fCount > 1)
135 		name << B_TRANSLATE("Remove Paths");
136 	else
137 		name << B_TRANSLATE("Remove Path");
138 }
139