1 /* 2 * Copyright 2006-2007, 2023, Haiku. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Stephan Aßmus <superstippi@gmx.de> 7 * Zardshard 8 */ 9 #ifndef REMOVE_COMMAND_H 10 #define REMOVE_COMMAND_H 11 12 13 #include <new> 14 #include <string.h> 15 16 #include <Catalog.h> 17 #include <Locale.h> 18 #include <StringFormat.h> 19 20 #include "Command.h" 21 #include "Container.h" 22 #include "IconBuild.h" 23 24 #undef B_TRANSLATION_CONTEXT 25 #define B_TRANSLATION_CONTEXT "Icon-O-Matic-RemoveItemsCmd" 26 27 using std::nothrow; 28 29 _USING_ICON_NAMESPACE 30 31 32 /*! Removes items located at certain \c indices from a \c Container. 33 34 \note This class should be subclassed and the \c GetName member overridden. 35 */ 36 template <class Type> 37 class RemoveCommand : public Command { 38 public: 39 RemoveCommand( 40 Container<Type>* container, 41 const int32* indices, 42 int32 count); 43 virtual ~RemoveCommand(); 44 45 virtual status_t InitCheck(); 46 47 virtual status_t Perform(); 48 virtual status_t Undo(); 49 50 virtual void GetName(BString& name); 51 52 protected: 53 Container<Type>* fContainer; 54 Type** fItems; 55 int32* fIndices; 56 int32 fCount; 57 bool fItemsRemoved; 58 }; 59 60 61 template <class Type> 62 RemoveCommand<Type>::RemoveCommand( 63 Container<Type>* container, const int32* indices, int32 count) 64 : Command(), 65 fContainer(container), 66 fItems(count > 0 ? new (nothrow) Type*[count] : NULL), 67 fIndices(count > 0 ? new (nothrow) int32[count] : NULL), 68 fCount(count), 69 fItemsRemoved(false) 70 { 71 if (!fContainer || !fItems || !fIndices) 72 return; 73 74 memcpy(fIndices, indices, sizeof(int32) * fCount); 75 for (int32 i = 0; i < fCount; i++) 76 fItems[i] = fContainer->ItemAt(fIndices[i]); 77 } 78 79 80 template <class Type> 81 RemoveCommand<Type>::~RemoveCommand() 82 { 83 if (fItemsRemoved && fItems) { 84 for (int32 i = 0; i < fCount; i++) { 85 if (fItems[i]) 86 fItems[i]->ReleaseReference(); 87 } 88 } 89 delete[] fItems; 90 delete[] fIndices; 91 } 92 93 94 template <class Type> 95 status_t 96 RemoveCommand<Type>::InitCheck() 97 { 98 return fContainer && fItems && fIndices ? B_OK : B_NO_INIT; 99 } 100 101 102 template <class Type> 103 status_t 104 RemoveCommand<Type>::Perform() 105 { 106 status_t ret = B_OK; 107 108 // remove shapes from container 109 for (int32 i = 0; i < fCount; i++) { 110 if (fItems[i] && !fContainer->RemoveItem(fItems[i])) { 111 ret = B_ERROR; 112 break; 113 } 114 } 115 fItemsRemoved = true; 116 117 return ret; 118 } 119 120 121 template <class Type> 122 status_t 123 RemoveCommand<Type>::Undo() 124 { 125 status_t ret = B_OK; 126 127 // add shapes to container at remembered indices 128 for (int32 i = 0; i < fCount; i++) { 129 if (fItems[i] && !fContainer->AddItem(fItems[i], fIndices[i])) { 130 ret = B_ERROR; 131 break; 132 } 133 } 134 fItemsRemoved = false; 135 136 return ret; 137 } 138 139 140 template <class Type> 141 void 142 RemoveCommand<Type>::GetName(BString& name) 143 { 144 static BStringFormat format(B_TRANSLATE("Remove {0, plural, " 145 "one{item} other{items}}")); 146 format.Format(name, fCount); 147 } 148 #endif // REMOVE_COMMAND_H 149