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 24using 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 29SplitPointsCommand::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 66SplitPointsCommand::~SplitPointsCommand() 67{ 68 delete[] fIndex; 69 delete[] fPoint; 70 delete[] fPointIn; 71 delete[] fPointOut; 72 delete[] fConnected; 73} 74 75// InitCheck 76status_t 77SplitPointsCommand::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 88status_t 89SplitPointsCommand::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 122status_t 123SplitPointsCommand::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 154void 155SplitPointsCommand::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