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 "RemovePathsCommand.h" 10 11 #include <new> 12 #include <stdio.h> 13 14 #include "PathContainer.h" 15 #include "Shape.h" 16 #include "VectorPath.h" 17 18 using std::nothrow; 19 20 // constructor 21 RemovePathsCommand::RemovePathsCommand(PathContainer* container, 22 VectorPath** const paths, 23 int32 count) 24 : Command(), 25 fContainer(container), 26 fInfos(paths && count > 0 ? new (nothrow) PathInfo[count] : NULL), 27 fCount(count), 28 fPathsRemoved(false) 29 { 30 if (!fContainer || !fInfos) 31 return; 32 33 for (int32 i = 0; i < fCount; i++) { 34 fInfos[i].path = paths[i]; 35 fInfos[i].index = fContainer->IndexOf(paths[i]); 36 if (paths[i]) { 37 int32 listenerCount = paths[i]->CountListeners(); 38 for (int32 j = 0; j < listenerCount; j++) { 39 Shape* shape = dynamic_cast<Shape*>(paths[i]->ListenerAtFast(j)); 40 if (shape) 41 fInfos[i].shapes.AddItem((void*)shape); 42 } 43 } 44 } 45 } 46 47 // destructor 48 RemovePathsCommand::~RemovePathsCommand() 49 { 50 if (fPathsRemoved && fInfos) { 51 for (int32 i = 0; i < fCount; i++) { 52 if (fInfos[i].path) 53 fInfos[i].path->Release(); 54 } 55 } 56 delete[] fInfos; 57 } 58 59 // InitCheck 60 status_t 61 RemovePathsCommand::InitCheck() 62 { 63 return fContainer && fInfos ? B_OK : B_NO_INIT; 64 } 65 66 // Perform 67 status_t 68 RemovePathsCommand::Perform() 69 { 70 // remove paths from container and shapes that reference them 71 for (int32 i = 0; i < fCount; i++) { 72 if (!fInfos[i].path) 73 continue; 74 fContainer->RemovePath(fInfos[i].path); 75 int32 shapeCount = fInfos[i].shapes.CountItems(); 76 for (int32 j = 0; j < shapeCount; j++) { 77 Shape* shape = (Shape*)fInfos[i].shapes.ItemAtFast(j); 78 shape->Paths()->RemovePath(fInfos[i].path); 79 } 80 } 81 fPathsRemoved = true; 82 83 return B_OK; 84 } 85 86 // Undo 87 status_t 88 RemovePathsCommand::Undo() 89 { 90 status_t ret = B_OK; 91 92 // add paths to container and shapes which previously referenced them 93 for (int32 i = 0; i < fCount; i++) { 94 if (!fInfos[i].path) 95 continue; 96 if (!fContainer->AddPath(fInfos[i].path, fInfos[i].index)) { 97 // roll back 98 ret = B_ERROR; 99 for (int32 j = i - 1; j >= 0; j--) { 100 fContainer->RemovePath(fInfos[j].path); 101 int32 shapeCount = fInfos[j].shapes.CountItems(); 102 for (int32 k = 0; k < shapeCount; k++) { 103 Shape* shape = (Shape*)fInfos[j].shapes.ItemAtFast(k); 104 shape->Paths()->RemovePath(fInfos[j].path); 105 } 106 } 107 break; 108 } 109 int32 shapeCount = fInfos[i].shapes.CountItems(); 110 for (int32 j = 0; j < shapeCount; j++) { 111 Shape* shape = (Shape*)fInfos[i].shapes.ItemAtFast(j); 112 shape->Paths()->AddPath(fInfos[i].path); 113 } 114 } 115 fPathsRemoved = false; 116 117 return ret; 118 } 119 120 // GetName 121 void 122 RemovePathsCommand::GetName(BString& name) 123 { 124 if (fCount > 1) 125 name << "Remove Paths"; 126 else 127 name << "Remove Path"; 128 } 129