xref: /haiku/src/apps/icon-o-matic/shape/commands/InsertPointCommand.cpp (revision e1c4049fed1047bdb957b0529e1921e97ef94770)
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 "InsertPointCommand.h"
10 
11 #include <new>
12 #include <stdio.h>
13 
14 #include <Catalog.h>
15 #include <Locale.h>
16 
17 #include "VectorPath.h"
18 
19 
20 #undef B_TRANSLATION_CONTEXT
21 #define B_TRANSLATION_CONTEXT "Icon-O-Matic-InsertPointCmd"
22 
23 
24 using std::nothrow;
25 
26 // constructor
27 InsertPointCommand::InsertPointCommand(VectorPath* path,
28 									  int32 index,
29 									  const int32* selected,
30 									  int32 count)
31 	: PathCommand(path),
32 	  fIndex(index),
33 	  fOldSelection(NULL),
34 	  fOldSelectionCount(count)
35 {
36 	if (fPath && (!fPath->GetPointsAt(fIndex, fPoint, fPointIn, fPointOut)
37 				  || !fPath->GetPointOutAt(fIndex - 1, fPreviousOut)
38 				  || !fPath->GetPointInAt(fIndex + 1, fNextIn))) {
39 		fPath = NULL;
40 	}
41 	if (fOldSelectionCount > 0 && selected) {
42 		fOldSelection = new (nothrow) int32[count];
43 		memcpy(fOldSelection, selected, count * sizeof(int32));
44 	}
45 }
46 
47 // destructor
48 InsertPointCommand::~InsertPointCommand()
49 {
50 	delete[] fOldSelection;
51 }
52 
53 // Perform
54 status_t
55 InsertPointCommand::Perform()
56 {
57 	status_t status = InitCheck();
58 	if (status < B_OK)
59 		return status;
60 
61 	// path point is already added
62 	// but in/out points might still have changed
63 	fPath->GetPointInAt(fIndex, fPointIn);
64 	fPath->GetPointOutAt(fIndex, fPointOut);
65 
66 	return status;
67 }
68 
69 // Undo
70 status_t
71 InsertPointCommand::Undo()
72 {
73 	status_t status = InitCheck();
74 	if (status < B_OK)
75 		return status;
76 
77 	AutoNotificationSuspender _(fPath);
78 
79 	// remove the inserted point
80 	if (fPath->RemovePoint(fIndex)) {
81 		// remember current previous "out" and restore it
82 		BPoint previousOut = fPreviousOut;
83 		fPath->GetPointOutAt(fIndex - 1, fPreviousOut);
84 		fPath->SetPointOut(fIndex - 1, previousOut);
85 		// remember current next "in" and restore it
86 		BPoint nextIn = fNextIn;
87 		fPath->GetPointInAt(fIndex, fNextIn);
88 		fPath->SetPointIn(fIndex, nextIn);
89 		// restore previous selection
90 		_Select(fOldSelection, fOldSelectionCount);
91 	} else {
92 		status = B_ERROR;
93 	}
94 
95 	return status;
96 }
97 
98 // Redo
99 status_t
100 InsertPointCommand::Redo()
101 {
102 	status_t status = InitCheck();
103 	if (status < B_OK)
104 		return status;
105 
106 
107 	AutoNotificationSuspender _(fPath);
108 
109 	// insert point again
110 	if (fPath->AddPoint(fPoint, fIndex)) {
111 		fPath->SetPoint(fIndex, fPoint, fPointIn, fPointOut, true);
112 		// remember current previous "out" and restore it
113 		BPoint previousOut = fPreviousOut;
114 		fPath->GetPointOutAt(fIndex - 1, fPreviousOut);
115 		fPath->SetPointOut(fIndex - 1, previousOut);
116 		// remember current next "in" and restore it
117 		BPoint nextIn = fNextIn;
118 		fPath->GetPointInAt(fIndex + 1, fNextIn);
119 		fPath->SetPointIn(fIndex + 1, nextIn);
120 		// select inserted point
121 		_Select(&fIndex, 1);
122 	} else {
123 		status = B_ERROR;
124 	}
125 
126 	return status;
127 }
128 
129 // GetName
130 void
131 InsertPointCommand::GetName(BString& name)
132 {
133 	name << B_TRANSLATE("Insert vertex");
134 }
135 
136