/* * Copyright 2006-2007, 2023, Haiku. * Distributed under the terms of the MIT License. * * Authors: * Stephan Aßmus * Zardshard */ #ifndef ADD_COMMAND_H #define ADD_COMMAND_H #include #include #include #include #include #include #include #include "Command.h" #include "Container.h" #include "IconBuild.h" #undef B_TRANSLATION_CONTEXT #define B_TRANSLATION_CONTEXT "Icon-O-Matic-AddItemsCmd" using std::nothrow; _BEGIN_ICON_NAMESPACE class BReferenceable; _END_ICON_NAMESPACE _USING_ICON_NAMESPACE /*! Adds items to a \c Container. \note This class should be subclassed and the \c GetName member overridden. */ template class AddCommand : public Command { public: AddCommand( Container* container, const Type* const* items, int32 count, bool ownsItems, int32 index); virtual ~AddCommand(); virtual status_t InitCheck(); virtual status_t Perform(); virtual status_t Undo(); virtual void GetName(BString& name); protected: Container* fContainer; Type** fItems; int32 fCount; bool fOwnsItems; int32 fIndex; bool fItemsAdded; }; template AddCommand::AddCommand(Container* container, const Type* const* items, int32 count, bool ownsItems, int32 index) : Command(), fContainer(container), fItems(items && count > 0 ? new (nothrow) Type*[count] : NULL), fCount(count), fOwnsItems(ownsItems), fIndex(index), fItemsAdded(false) { if (!fContainer || !fItems) return; memcpy(fItems, items, sizeof(Type*) * fCount); if (!fOwnsItems) { // Add references to items for (int32 i = 0; i < fCount; i++) { if (fItems[i] != NULL) fItems[i]->AcquireReference(); } } } template AddCommand::~AddCommand() { if (!fItemsAdded && fItems) { for (int32 i = 0; i < fCount; i++) { if (fItems[i] != NULL) fItems[i]->ReleaseReference(); } } delete[] fItems; } template status_t AddCommand::InitCheck() { return fContainer && fItems ? B_OK : B_NO_INIT; } template status_t AddCommand::Perform() { // add items to container for (int32 i = 0; i < fCount; i++) { if (fItems[i] && !fContainer->AddItem(fItems[i], fIndex + i)) { // roll back for (int32 j = i - 1; j >= 0; j--) fContainer->RemoveItem(fItems[j]); return B_ERROR; } } fItemsAdded = true; return B_OK; } template status_t AddCommand::Undo() { // remove items from container for (int32 i = 0; i < fCount; i++) { fContainer->RemoveItem(fItems[i]); } fItemsAdded = false; return B_OK; } template void AddCommand::GetName(BString& name) { static BStringFormat format(B_TRANSLATE("Add {0, plural, " "one{item} other{items}}")); format.Format(name, fCount); } #endif // ADD_COMMAND_H