root/src/apps/icon-o-matic/style/SetGradientCommand.cpp
/*
 * Copyright 2006, Haiku.
 * Distributed under the terms of the MIT License.
 *
 * Authors:
 *              Stephan Aßmus <superstippi@gmx.de>
 */

#include "SetGradientCommand.h"

#include <new>
#include <stdio.h>

#include <Catalog.h>
#include <Locale.h>

#include "GradientTransformable.h"
#include "Style.h"


#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "Icon-O-Matic-SetGradientCmd"


using std::nothrow;

// constructor
SetGradientCommand::SetGradientCommand(Style* style,
                                                                           const Gradient* gradient)
        : Command(),
          fStyle(style),
          fGradient(gradient ? new (nothrow) Gradient(*gradient) : NULL)
{
}

// destructor
SetGradientCommand::~SetGradientCommand()
{
        if (fGradient != NULL)
                fGradient->ReleaseReference();
}

// InitCheck
status_t
SetGradientCommand::InitCheck()
{
        if (!fStyle)
                return B_NO_INIT;
        if (fGradient && fStyle->Gradient()) {
                if (*fGradient == *fStyle->Gradient()) {
                        printf("SetGradientCommand::InitCheck() - same gradients\n");
                        return B_ERROR;
                }
        }
        return B_OK;
}

// Perform
status_t
SetGradientCommand::Perform()
{
        // clone the new gradient for handling over to the style
        Gradient* clone = NULL;
        if (fGradient) {
                clone = new (nothrow) Gradient(*fGradient);
                if (!clone)
                        return B_NO_MEMORY;
        }

        if (fStyle->Gradient()) {
                // remember the current gradient of the style
                if (fGradient)
                        *fGradient = *fStyle->Gradient();
                else {
                        fGradient = new (nothrow) Gradient(*fStyle->Gradient());
                        if (!fGradient) {
                                delete clone;
                                return B_NO_MEMORY;
                        }
                }
        } else if (fGradient != NULL) {
                // the style didn't have a gradient set
                fGradient->ReleaseReference();
                fGradient = NULL;
        }

        // remove the gradient or set the new one
        fStyle->SetGradient(clone);
        delete clone;

        return B_OK;
}

// Undo
status_t
SetGradientCommand::Undo()
{
        return Perform();
}

// GetName
void
SetGradientCommand::GetName(BString& name)
{
        name << B_TRANSLATE("Edit gradient");
}

// CombineWithNext
bool
SetGradientCommand::CombineWithNext(const Command* command)
{
        const SetGradientCommand* next
                = dynamic_cast<const SetGradientCommand*>(command);

        if (next && next->fTimeStamp - fTimeStamp < 1000000) {
                fTimeStamp = next->fTimeStamp;
                // NOTE: next was already performed, but
                // when undoing, we want to use our
                // remembered gradient
                return true;
        }
        return false;
}