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