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