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