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