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