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 "StyleContainer.h" 18 #include "Shape.h" 19 #include "Style.h" 20 21 22 #undef B_TRANSLATE_CONTEXT 23 #define B_TRANSLATE_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 Shape* shape = dynamic_cast<Shape*>(styles[i]->ObserverAtFast(j)); 48 if (shape) 49 fInfos[i].shapes.AddItem((void*)shape); 50 } 51 } 52 } 53 } 54 55 // destructor 56 RemoveStylesCommand::~RemoveStylesCommand() 57 { 58 if (fStylesRemoved && fInfos) { 59 for (int32 i = 0; i < fCount; i++) { 60 if (fInfos[i].style) 61 fInfos[i].style->Release(); 62 } 63 } 64 delete[] fInfos; 65 } 66 67 // InitCheck 68 status_t 69 RemoveStylesCommand::InitCheck() 70 { 71 return fContainer && fInfos ? B_OK : B_NO_INIT; 72 } 73 74 // Perform 75 status_t 76 RemoveStylesCommand::Perform() 77 { 78 // remove styles from container 79 for (int32 i = 0; i < fCount; i++) { 80 if (!fInfos[i].style) 81 continue; 82 fContainer->RemoveStyle(fInfos[i].style); 83 } 84 85 // remove styles from shapes that reference them 86 for (int32 i = 0; i < fCount; i++) { 87 if (!fInfos[i].style) 88 continue; 89 int32 shapeCount = fInfos[i].shapes.CountItems(); 90 for (int32 j = 0; j < shapeCount; j++) { 91 Shape* shape = (Shape*)fInfos[i].shapes.ItemAtFast(j); 92 shape->SetStyle(fContainer->StyleAt(0)); 93 } 94 } 95 96 fStylesRemoved = true; 97 98 return B_OK; 99 } 100 101 // Undo 102 status_t 103 RemoveStylesCommand::Undo() 104 { 105 status_t ret = B_OK; 106 107 // add styles to container and shapes which previously referenced them 108 for (int32 i = 0; i < fCount; i++) { 109 if (!fInfos[i].style) 110 continue; 111 if (!fContainer->AddStyle(fInfos[i].style, fInfos[i].index)) { 112 // roll back 113 ret = B_ERROR; 114 for (int32 j = i - 1; j >= 0; j--) { 115 fContainer->RemoveStyle(fInfos[j].style); 116 } 117 for (int32 j = i - 1; j >= 0; j--) { 118 int32 shapeCount = fInfos[j].shapes.CountItems(); 119 for (int32 k = 0; k < shapeCount; k++) { 120 Shape* shape = (Shape*)fInfos[j].shapes.ItemAtFast(k); 121 shape->SetStyle(fContainer->StyleAt(0)); 122 } 123 } 124 break; 125 } 126 int32 shapeCount = fInfos[i].shapes.CountItems(); 127 for (int32 j = 0; j < shapeCount; j++) { 128 Shape* shape = (Shape*)fInfos[i].shapes.ItemAtFast(j); 129 shape->SetStyle(fInfos[i].style); 130 } 131 } 132 133 fStylesRemoved = false; 134 135 return ret; 136 } 137 138 // GetName 139 void 140 RemoveStylesCommand::GetName(BString& name) 141 { 142 if (fCount > 1) 143 name << B_TRANSLATE("Remove Styles"); 144 else 145 name << B_TRANSLATE("Remove Style"); 146 } 147