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 27using 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*/ 36template <class Type> 37class 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 61template <class Type> 62RemoveCommand<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 80template <class Type> 81RemoveCommand<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 94template <class Type> 95status_t 96RemoveCommand<Type>::InitCheck() 97{ 98 return fContainer && fItems && fIndices ? B_OK : B_NO_INIT; 99} 100 101 102template <class Type> 103status_t 104RemoveCommand<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 121template <class Type> 122status_t 123RemoveCommand<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 140template <class Type> 141void 142RemoveCommand<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