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