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 "InsertPointCommand.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-InsertPointCmd" 22 23 24 using std::nothrow; 25 26 // constructor 27 InsertPointCommand::InsertPointCommand(VectorPath* path, 28 int32 index, 29 const int32* selected, 30 int32 count) 31 : PathCommand(path), 32 fIndex(index), 33 fOldSelection(NULL), 34 fOldSelectionCount(count) 35 { 36 if (fPath && (!fPath->GetPointsAt(fIndex, fPoint, fPointIn, fPointOut) 37 || !fPath->GetPointOutAt(fIndex - 1, fPreviousOut) 38 || !fPath->GetPointInAt(fIndex + 1, fNextIn))) { 39 fPath = NULL; 40 } 41 if (fOldSelectionCount > 0 && selected) { 42 fOldSelection = new (nothrow) int32[count]; 43 memcpy(fOldSelection, selected, count * sizeof(int32)); 44 } 45 } 46 47 // destructor 48 InsertPointCommand::~InsertPointCommand() 49 { 50 delete[] fOldSelection; 51 } 52 53 // Perform 54 status_t 55 InsertPointCommand::Perform() 56 { 57 status_t status = InitCheck(); 58 if (status < B_OK) 59 return status; 60 61 // path point is already added 62 // but in/out points might still have changed 63 fPath->GetPointInAt(fIndex, fPointIn); 64 fPath->GetPointOutAt(fIndex, fPointOut); 65 66 return status; 67 } 68 69 // Undo 70 status_t 71 InsertPointCommand::Undo() 72 { 73 status_t status = InitCheck(); 74 if (status < B_OK) 75 return status; 76 77 AutoNotificationSuspender _(fPath); 78 79 // remove the inserted point 80 if (fPath->RemovePoint(fIndex)) { 81 // remember current previous "out" and restore it 82 BPoint previousOut = fPreviousOut; 83 fPath->GetPointOutAt(fIndex - 1, fPreviousOut); 84 fPath->SetPointOut(fIndex - 1, previousOut); 85 // remember current next "in" and restore it 86 BPoint nextIn = fNextIn; 87 fPath->GetPointInAt(fIndex, fNextIn); 88 fPath->SetPointIn(fIndex, nextIn); 89 // restore previous selection 90 _Select(fOldSelection, fOldSelectionCount); 91 } else { 92 status = B_ERROR; 93 } 94 95 return status; 96 } 97 98 // Redo 99 status_t 100 InsertPointCommand::Redo() 101 { 102 status_t status = InitCheck(); 103 if (status < B_OK) 104 return status; 105 106 107 AutoNotificationSuspender _(fPath); 108 109 // insert point again 110 if (fPath->AddPoint(fPoint, fIndex)) { 111 fPath->SetPoint(fIndex, fPoint, fPointIn, fPointOut, true); 112 // remember current previous "out" and restore it 113 BPoint previousOut = fPreviousOut; 114 fPath->GetPointOutAt(fIndex - 1, fPreviousOut); 115 fPath->SetPointOut(fIndex - 1, previousOut); 116 // remember current next "in" and restore it 117 BPoint nextIn = fNextIn; 118 fPath->GetPointInAt(fIndex + 1, fNextIn); 119 fPath->SetPointIn(fIndex + 1, nextIn); 120 // select inserted point 121 _Select(&fIndex, 1); 122 } else { 123 status = B_ERROR; 124 } 125 126 return status; 127 } 128 129 // GetName 130 void 131 InsertPointCommand::GetName(BString& name) 132 { 133 name << B_TRANSLATE("Insert vertex"); 134 } 135 136