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