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