1 /* 2 * Copyright 2006, Haiku. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Stephan Aßmus <superstippi@gmx.de> 7 */ 8 9 #include "SplitPointsCommand.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-SplitPointsCmd" 23 24 25 using std::nothrow; 26 27 // constructor 28 // * when hitting the Delete key, so the selected points are the 29 // same as the ones to be removed 30 SplitPointsCommand::SplitPointsCommand(VectorPath* path, 31 const int32* indices, 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 { 41 if (indices && count > 0) { 42 fIndex = new (nothrow) int32[count]; 43 fPoint = new (nothrow) BPoint[count]; 44 fPointIn = new (nothrow) BPoint[count]; 45 fPointOut = new (nothrow) BPoint[count]; 46 fConnected = new (nothrow) bool[count]; 47 fCount = count; 48 } 49 50 if (InitCheck() < B_OK) 51 return; 52 53 memcpy(fIndex, indices, count * sizeof(int32)); 54 for (int32 i = 0; i < count; i++) { 55 if (!fPath->GetPointsAt(fIndex[i], 56 fPoint[i], 57 fPointIn[i], 58 fPointOut[i], 59 &fConnected[i])) { 60 fPath = NULL; 61 break; 62 } 63 } 64 } 65 66 // destructor 67 SplitPointsCommand::~SplitPointsCommand() 68 { 69 delete[] fIndex; 70 delete[] fPoint; 71 delete[] fPointIn; 72 delete[] fPointOut; 73 delete[] fConnected; 74 } 75 76 // InitCheck 77 status_t 78 SplitPointsCommand::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 SplitPointsCommand::Perform() 91 { 92 status_t status = B_OK; 93 94 AutoNotificationSuspender _(fPath); 95 96 // NOTE: fCount guaranteed > 0 97 // add points again at their respective index 98 for (int32 i = 0; i < fCount; i++) { 99 int32 index = fIndex[i] + 1 + i; 100 // "+ 1" to insert behind existing point 101 // "+ i" to adjust for already inserted points 102 if (fPath->AddPoint(fPoint[i], index)) { 103 fPath->SetPoint(index - 1, 104 fPoint[i], 105 fPointIn[i], 106 fPoint[i], 107 true); 108 fPath->SetPoint(index, 109 fPoint[i], 110 fPoint[i], 111 fPointOut[i], 112 true); 113 } else { 114 status = B_ERROR; 115 break; 116 } 117 } 118 119 return status; 120 } 121 122 // Undo 123 status_t 124 SplitPointsCommand::Undo() 125 { 126 status_t status = B_OK; 127 128 AutoNotificationSuspender _(fPath); 129 130 // remove inserted points and reset modified 131 // points to previous condition 132 for (int32 i = 0; i < fCount; i++) { 133 int32 index = fIndex[i] + 1; 134 if (fPath->RemovePoint(index)) { 135 fPath->SetPoint(index - 1, 136 fPoint[i], 137 fPointIn[i], 138 fPointOut[i], 139 fConnected[i]); 140 } else { 141 status = B_ERROR; 142 break; 143 } 144 } 145 146 if (status >= B_OK) { 147 // restore selection 148 _Select(fIndex, fCount); 149 } 150 151 return status; 152 } 153 154 // GetName 155 void 156 SplitPointsCommand::GetName(BString& name) 157 { 158 static BStringFormat format(B_TRANSLATE("Split {0, plural, " 159 "one{vertex} other{vertices}}")); 160 format.Format(name, fCount); 161 } 162 163