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