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 "RemovePointsCommand.h" 10 11 #include <new> 12 #include <stdio.h> 13 14 #include "VectorPath.h" 15 16 using std::nothrow; 17 18 // constructor 19 // * when clicking a point in Remove mode, with other points selected 20 RemovePointsCommand::RemovePointsCommand(VectorPath* path, 21 int32 index, 22 const int32* selected, 23 int32 count) 24 : PathCommand(path), 25 fIndex(NULL), 26 fPoint(NULL), 27 fPointIn(NULL), 28 fPointOut(NULL), 29 fConnected(NULL), 30 fCount(0), 31 fOldSelection(NULL), 32 fOldSelectionCount(count) 33 { 34 _Init(&index, 1, selected, count); 35 } 36 37 // constructor 38 // * when hitting the Delete key, so the selected points are the 39 // same as the ones to be removed 40 RemovePointsCommand::RemovePointsCommand(VectorPath* path, 41 const int32* selected, 42 int32 count) 43 : PathCommand(path), 44 fIndex(NULL), 45 fPoint(NULL), 46 fPointIn(NULL), 47 fPointOut(NULL), 48 fConnected(NULL), 49 fCount(0), 50 fOldSelection(NULL), 51 fOldSelectionCount(count) 52 { 53 _Init(selected, count, selected, count); 54 } 55 56 // destructor 57 RemovePointsCommand::~RemovePointsCommand() 58 { 59 delete[] fIndex; 60 delete[] fPoint; 61 delete[] fPointIn; 62 delete[] fPointOut; 63 delete[] fConnected; 64 delete[] fOldSelection; 65 } 66 67 // InitCheck 68 status_t 69 RemovePointsCommand::InitCheck() 70 { 71 status_t status = PathCommand::InitCheck(); 72 if (status < B_OK) 73 return status; 74 if (!fIndex || !fPoint || !fPointIn || !fPointOut || !fConnected) 75 status = B_NO_MEMORY; 76 return status; 77 } 78 79 // Perform 80 status_t 81 RemovePointsCommand::Perform() 82 { 83 // path points are already removed 84 return InitCheck(); 85 } 86 87 // Undo 88 status_t 89 RemovePointsCommand::Undo() 90 { 91 status_t status = InitCheck(); 92 if (status < B_OK) 93 return status; 94 95 AutoNotificationSuspender _(fPath); 96 97 // add points again at their respective index 98 for (int32 i = 0; i < fCount; i++) { 99 if (fPath->AddPoint(fPoint[i], fIndex[i])) { 100 fPath->SetPoint(fIndex[i], 101 fPoint[i], 102 fPointIn[i], 103 fPointOut[i], 104 fConnected[i]); 105 } else { 106 status = B_ERROR; 107 break; 108 } 109 } 110 111 fPath->SetClosed(fWasClosed); 112 113 if (status >= B_OK) { 114 // select the added points 115 _Select(fIndex, fCount); 116 } 117 118 return status; 119 } 120 121 // Redo 122 status_t 123 RemovePointsCommand::Redo() 124 { 125 status_t status = InitCheck(); 126 if (status < B_OK) 127 return status; 128 129 AutoNotificationSuspender _(fPath); 130 131 // remove points 132 // the loop assumes the indices in the collection 133 // are increasing (removal at "index[i] - i" to account 134 // for items already removed) 135 for (int32 i = 0; i < fCount; i++) { 136 if (!fPath->RemovePoint(fIndex[i] - i)) { 137 status = B_ERROR; 138 break; 139 } 140 } 141 142 fPath->SetClosed(fWasClosed && fPath->CountPoints() > 1); 143 144 if (status >= B_OK) { 145 // restore selection 146 _Select(fOldSelection, fOldSelectionCount); 147 } 148 149 return status; 150 } 151 152 // GetName 153 void 154 RemovePointsCommand::GetName(BString& name) 155 { 156 // if (fCount > 1) 157 // name << _GetString(REMOVE_CONTROL_POINTS, "Remove Control Points"); 158 // else 159 // name << _GetString(REMOVE_CONTROL_POINT, "Remove Control Point"); 160 if (fCount > 1) 161 name << "Remove Control Points"; 162 else 163 name << "Remove Control Point"; 164 } 165 166 // _Init 167 void 168 RemovePointsCommand::_Init(const int32* indices, int32 count, 169 const int32* selection, int32 selectionCount) 170 { 171 if (indices && count > 0) { 172 fIndex = new (nothrow) int32[count]; 173 fPoint = new (nothrow) BPoint[count]; 174 fPointIn = new (nothrow) BPoint[count]; 175 fPointOut = new (nothrow) BPoint[count]; 176 fConnected = new (nothrow) bool[count]; 177 fCount = count; 178 } 179 180 if (InitCheck() < B_OK) 181 return; 182 183 memcpy(fIndex, indices, count * sizeof(int32)); 184 for (int32 i = 0; i < count; i++) { 185 if (!fPath->GetPointsAt(fIndex[i], 186 fPoint[i], 187 fPointIn[i], 188 fPointOut[i], 189 &fConnected[i])) { 190 fPath = NULL; 191 break; 192 } 193 } 194 195 if (fPath) 196 fWasClosed = fPath->IsClosed(); 197 198 if (selectionCount > 0 && selection) { 199 fOldSelectionCount = selectionCount; 200 fOldSelection = new (nothrow) int32[selectionCount]; 201 memcpy(fOldSelection, selection, selectionCount * sizeof(int32)); 202 } 203 } 204