<commit_before>#include "xchainer/gradient_check.h"

#include <algorithm>
#include <memory>
#include <tuple>
#include <unordered_map>
#include <vector>

#include <gtest/gtest-spi.h>
#include <gtest/gtest.h>
#include <gsl/gsl>

#include "xchainer/array.h"
#include "xchainer/check_backward.h"
#include "xchainer/op_node.h"
#include "xchainer/shape.h"

namespace xchainer {
namespace {

using Arrays = std::vector<Array>;
using Fprop = std::function<std::vector<Array>(const std::vector<Array>&)>;

Arrays IncorrectBackwardUnaryFunc(const Arrays& inputs) {
    const Array& in = inputs[0];
    Array out = Array::EmptyLike(in);

    auto backward_function = [](const Array& gout, const std::vector<GraphId>&) { return gout * gout; };
    internal::SetUpOpNodes("incorrect_unary", {in}, out, {backward_function});

    VisitDtype(in.dtype(), [&](auto pt) {
        using T = typename decltype(pt)::type;
        int64_t total_size = in.total_size();
        auto* ldata = static_cast<const T*>(in.data().get());
        auto* odata = static_cast<T*>(out.data().get());
        for (int64_t i = 0; i < total_size; i++) {
            odata[i] = ldata[i];
        }
    });

    return {out};
}

Arrays IncorrectBackwardBinaryFunc(const Arrays& inputs) {
    const Array& lhs = inputs[0];
    const Array& rhs = inputs[1];
    CheckEqual(lhs.dtype(), rhs.dtype());
    CheckEqual(lhs.shape(), rhs.shape());
    Array out = Array::EmptyLike(lhs);

    auto lhs_backward_function = [other = rhs](const Array& gout, const std::vector<GraphId>& graph_ids_to_stop_gradient)->Array {
        return gout + other.AsConstant(graph_ids_to_stop_gradient);
    };
    auto rhs_backward_function = lhs_backward_function;
    internal::SetUpOpNodes("incorrect_binary", {lhs, rhs}, out, {lhs_backward_function, rhs_backward_function});

    VisitDtype(lhs.dtype(), [&](auto pt) {
        using T = typename decltype(pt)::type;
        int64_t total_size = lhs.total_size();
        auto* ldata = static_cast<const T*>(lhs.data().get());
        auto* rdata = static_cast<const T*>(rhs.data().get());
        auto* odata = static_cast<T*>(out.data().get());
        for (int64_t i = 0; i < total_size; i++) {
            odata[i] = ldata[i] * rdata[i];
        }
    });

    return {out};
}

class CheckBackwardBaseTest : public ::testing::Test {
protected:
    template <typename T>
    Array MakeArray(const Shape& shape, const T* data) const {
        int64_t size = shape.total_size();
        auto a = std::make_unique<T[]>(size);
        std::copy(data, data + size, a.get());
        return Array::FromBuffer(shape, TypeToDtype<T>, std::move(a));
    }

    void CheckBackwardBaseComputation(bool expect_correct, Fprop fprop, Arrays& inputs, const Arrays& grad_outputs, const Arrays& eps,
                                      double atol, double rtol, const GraphId& graph_id) {
        bool is_none_of_grad_required =
            std::none_of(inputs.begin(), inputs.end(), [graph_id](const Array& input) { return input.IsGradRequired(graph_id); });
        if (expect_correct || is_none_of_grad_required) {
            // We cannot expect any failures in case none of the input std::vector<Array> require gradients
            CheckBackwardComputation(fprop, inputs, grad_outputs, eps, atol, rtol, graph_id);
        } else {
            // Catch the gtest failure expected to be generated by CheckBackwardComputation but without failing this test
            EXPECT_NONFATAL_FAILURE(CheckBackwardComputation(fprop, inputs, grad_outputs, eps, atol, rtol, graph_id),
                                    "Backward check failure");
        }
    }
};

class CheckBackwardUnaryTest : public CheckBackwardBaseTest, public ::testing::WithParamInterface<bool> {
protected:
    void SetUp() override { requires_grad = GetParam(); }

    template <typename T>
    void CheckBackwardUnaryComputation(bool expect_correct, Fprop fprop, const Shape& shape, const T* input_data, const T* grad_output_data,
                                       const T* eps_data, double atol, double rtol, const GraphId& graph_id) {
        Arrays inputs{MakeArray(shape, input_data)};
        if (requires_grad) {
            inputs[0].RequireGrad(graph_id);
        }

        Arrays grad_outputs{MakeArray(shape, grad_output_data)};
        Arrays eps{MakeArray(shape, eps_data)};
        CheckBackwardBaseComputation(expect_correct, fprop, inputs, grad_outputs, eps, atol, rtol, graph_id);
    }

private:
    bool requires_grad;
};

class CheckBackwardBinaryTest : public CheckBackwardBaseTest, public ::testing::WithParamInterface<std::tuple<bool, bool>> {
protected:
    void SetUp() override { requires_grads = {std::get<0>(GetParam()), std::get<1>(GetParam())}; }

    template <typename T>
    void CheckBackwardBinaryComputation(bool expect_correct, Fprop fprop, const Shape& shape, const T* input_data1, const T* input_data2,
                                        const T* grad_output_data, const T* eps_data1, const T* eps_data2, double atol, double rtol,
                                        const GraphId& graph_id) {
        Arrays inputs{MakeArray(shape, input_data1), MakeArray(shape, input_data2)};
        if (requires_grads[0]) {
            inputs[0].RequireGrad(graph_id);
        }
        if (requires_grads[1]) {
            inputs[1].RequireGrad(graph_id);
        }

        Arrays grad_outputs{MakeArray(shape, grad_output_data)};
        Arrays eps{MakeArray(shape, eps_data1), MakeArray(shape, eps_data2)};
        CheckBackwardBaseComputation(expect_correct, fprop, inputs, grad_outputs, eps, atol, rtol, graph_id);
    }

private:
    std::vector<bool> requires_grads;
};

TEST_P(CheckBackwardUnaryTest, CorrectBackward) {
    float input_data[]{1.f, 2.f, 1.f};
    float grad_output_data[]{0.f, -2.f, 1.f};
    float eps_data[]{1e-3f, 1e-3f, 1e-3f};
    Fprop fprop = [](const Arrays& inputs) -> Arrays { return {inputs[0] * inputs[0]}; };
    CheckBackwardUnaryComputation(true, fprop, {1, 3}, input_data, grad_output_data, eps_data, 1e-5, 1e-4, "graph_1");
}

TEST_P(CheckBackwardUnaryTest, IncorrectBackward) {
    float input_data[]{-2.f, 3.f, 1.f};
    float grad_output_data[]{0.f, -2.f, 1.f};
    float eps_data[]{1e-3f, 1e-3f, 1e-3f};
    CheckBackwardUnaryComputation(false, &IncorrectBackwardUnaryFunc, {1, 3}, input_data, grad_output_data, eps_data, 1e-5, 1e-4,
                                  "graph_1");
}

TEST_P(CheckBackwardBinaryTest, CorrectBackward) {
    float input_data1[]{1.f, 2.f, 1.f};
    float input_data2[]{0.f, 1.f, 2.f};
    float eps_data1[]{1e-3f, 1e-3f, 1e-3f};
    float eps_data2[]{1e-3f, 1e-3f, 1e-3f};
    float grad_output_data[]{1.f, -2.f, 3.f};
    Fprop fprop = [](const Arrays& inputs) -> Arrays { return {inputs[0] * inputs[1]}; };
    CheckBackwardBinaryComputation(true, fprop, {1, 3}, input_data1, input_data2, grad_output_data, eps_data1, eps_data2, 1e-5, 1e-4,
                                   "graph_1");
}

TEST_P(CheckBackwardBinaryTest, IncorrectBackward) {
    float input_data1[]{1.f, -2.f, 1.f};
    float input_data2[]{0.f, 1.4f, 2.f};
    float eps_data1[]{1e-3f, 1e-3f, 1e-3f};
    float eps_data2[]{1e-3f, 1e-3f, 1e-3f};
    float grad_output_data[]{4.f, -2.f, 3.f};
    CheckBackwardBinaryComputation(false, &IncorrectBackwardBinaryFunc, {1, 3}, input_data1, input_data2, grad_output_data, eps_data1,
                                   eps_data2, 1e-5, 1e-4, "graph_1");
}

INSTANTIATE_TEST_CASE_P(ForEachSingleSetRequiresGrad, CheckBackwardUnaryTest, ::testing::Bool());
INSTANTIATE_TEST_CASE_P(ForEachCombinedSetRequiresGrad, CheckBackwardBinaryTest, ::testing::Combine(::testing::Bool(), ::testing::Bool()));

}  // namespace
}  // namespace xchainer
<commit_msg>fix check_backward_test.cc to pass<commit_after>#include "xchainer/gradient_check.h"

#include <algorithm>
#include <memory>
#include <tuple>
#include <unordered_map>
#include <vector>

#include <gtest/gtest-spi.h>
#include <gtest/gtest.h>
#include <gsl/gsl>

#include "xchainer/array.h"
#include "xchainer/check_backward.h"
#include "xchainer/native_backend.h"
#include "xchainer/op_node.h"
#include "xchainer/shape.h"

namespace xchainer {
namespace {

using Arrays = std::vector<Array>;
using Fprop = std::function<std::vector<Array>(const std::vector<Array>&)>;

Arrays IncorrectBackwardUnaryFunc(const Arrays& inputs) {
    const Array& in = inputs[0];
    Array out = Array::EmptyLike(in);

    auto backward_function = [](const Array& gout, const std::vector<GraphId>&) { return gout * gout; };
    internal::SetUpOpNodes("incorrect_unary", {in}, out, {backward_function});

    VisitDtype(in.dtype(), [&](auto pt) {
        using T = typename decltype(pt)::type;
        int64_t total_size = in.total_size();
        auto* ldata = static_cast<const T*>(in.data().get());
        auto* odata = static_cast<T*>(out.data().get());
        for (int64_t i = 0; i < total_size; i++) {
            odata[i] = ldata[i];
        }
    });

    return {out};
}

Arrays IncorrectBackwardBinaryFunc(const Arrays& inputs) {
    const Array& lhs = inputs[0];
    const Array& rhs = inputs[1];
    CheckEqual(lhs.dtype(), rhs.dtype());
    CheckEqual(lhs.shape(), rhs.shape());
    Array out = Array::EmptyLike(lhs);

    auto lhs_backward_function = [other = rhs](const Array& gout, const std::vector<GraphId>& graph_ids_to_stop_gradient)->Array {
        return gout + other.AsConstant(graph_ids_to_stop_gradient);
    };
    auto rhs_backward_function = lhs_backward_function;
    internal::SetUpOpNodes("incorrect_binary", {lhs, rhs}, out, {lhs_backward_function, rhs_backward_function});

    VisitDtype(lhs.dtype(), [&](auto pt) {
        using T = typename decltype(pt)::type;
        int64_t total_size = lhs.total_size();
        auto* ldata = static_cast<const T*>(lhs.data().get());
        auto* rdata = static_cast<const T*>(rhs.data().get());
        auto* odata = static_cast<T*>(out.data().get());
        for (int64_t i = 0; i < total_size; i++) {
            odata[i] = ldata[i] * rdata[i];
        }
    });

    return {out};
}

class CheckBackwardBaseTest : public ::testing::Test {
protected:
    virtual void SetUp() {
        backend_ = std::make_unique<NativeBackend>();
        device_scope_ = std::make_unique<DeviceScope>("cpu", backend_.get());
    }

    virtual void TearDown() {
        device_scope_.reset();
        backend_.reset();
    }

protected:
    template <typename T>
    Array MakeArray(const Shape& shape, const T* data) const {
        int64_t size = shape.total_size();
        auto a = std::make_unique<T[]>(size);
        std::copy(data, data + size, a.get());
        return Array::FromBuffer(shape, TypeToDtype<T>, std::move(a));
    }

    void CheckBackwardBaseComputation(bool expect_correct, Fprop fprop, Arrays& inputs, const Arrays& grad_outputs, const Arrays& eps,
                                      double atol, double rtol, const GraphId& graph_id) {
        bool is_none_of_grad_required =
            std::none_of(inputs.begin(), inputs.end(), [graph_id](const Array& input) { return input.IsGradRequired(graph_id); });
        if (expect_correct || is_none_of_grad_required) {
            // We cannot expect any failures in case none of the input std::vector<Array> require gradients
            CheckBackwardComputation(fprop, inputs, grad_outputs, eps, atol, rtol, graph_id);
        } else {
            // Catch the gtest failure expected to be generated by CheckBackwardComputation but without failing this test
            EXPECT_NONFATAL_FAILURE(CheckBackwardComputation(fprop, inputs, grad_outputs, eps, atol, rtol, graph_id),
                                    "Backward check failure");
        }
    }

private:
    std::unique_ptr<Backend> backend_;
    std::unique_ptr<DeviceScope> device_scope_;
};

class CheckBackwardUnaryTest : public CheckBackwardBaseTest, public ::testing::WithParamInterface<bool> {
protected:
    void SetUp() override {
        CheckBackwardBaseTest::SetUp();
        requires_grad = GetParam();
    }

    template <typename T>
    void CheckBackwardUnaryComputation(bool expect_correct, Fprop fprop, const Shape& shape, const T* input_data, const T* grad_output_data,
                                       const T* eps_data, double atol, double rtol, const GraphId& graph_id) {
        Arrays inputs{MakeArray(shape, input_data)};
        if (requires_grad) {
            inputs[0].RequireGrad(graph_id);
        }

        Arrays grad_outputs{MakeArray(shape, grad_output_data)};
        Arrays eps{MakeArray(shape, eps_data)};
        CheckBackwardBaseComputation(expect_correct, fprop, inputs, grad_outputs, eps, atol, rtol, graph_id);
    }

private:
    bool requires_grad;
};

class CheckBackwardBinaryTest : public CheckBackwardBaseTest, public ::testing::WithParamInterface<std::tuple<bool, bool>> {
protected:
    void SetUp() override {
        CheckBackwardBaseTest::SetUp();
        requires_grads = {std::get<0>(GetParam()), std::get<1>(GetParam())};
    }

    template <typename T>
    void CheckBackwardBinaryComputation(bool expect_correct, Fprop fprop, const Shape& shape, const T* input_data1, const T* input_data2,
                                        const T* grad_output_data, const T* eps_data1, const T* eps_data2, double atol, double rtol,
                                        const GraphId& graph_id) {
        Arrays inputs{MakeArray(shape, input_data1), MakeArray(shape, input_data2)};
        if (requires_grads[0]) {
            inputs[0].RequireGrad(graph_id);
        }
        if (requires_grads[1]) {
            inputs[1].RequireGrad(graph_id);
        }

        Arrays grad_outputs{MakeArray(shape, grad_output_data)};
        Arrays eps{MakeArray(shape, eps_data1), MakeArray(shape, eps_data2)};
        CheckBackwardBaseComputation(expect_correct, fprop, inputs, grad_outputs, eps, atol, rtol, graph_id);
    }

private:
    std::vector<bool> requires_grads;
};

TEST_P(CheckBackwardUnaryTest, CorrectBackward) {
    float input_data[]{1.f, 2.f, 1.f};
    float grad_output_data[]{0.f, -2.f, 1.f};
    float eps_data[]{1e-3f, 1e-3f, 1e-3f};
    Fprop fprop = [](const Arrays& inputs) -> Arrays { return {inputs[0] * inputs[0]}; };
    CheckBackwardUnaryComputation(true, fprop, {1, 3}, input_data, grad_output_data, eps_data, 1e-5, 1e-4, "graph_1");
}

TEST_P(CheckBackwardUnaryTest, IncorrectBackward) {
    float input_data[]{-2.f, 3.f, 1.f};
    float grad_output_data[]{0.f, -2.f, 1.f};
    float eps_data[]{1e-3f, 1e-3f, 1e-3f};
    CheckBackwardUnaryComputation(false, &IncorrectBackwardUnaryFunc, {1, 3}, input_data, grad_output_data, eps_data, 1e-5, 1e-4,
                                  "graph_1");
}

TEST_P(CheckBackwardBinaryTest, CorrectBackward) {
    float input_data1[]{1.f, 2.f, 1.f};
    float input_data2[]{0.f, 1.f, 2.f};
    float eps_data1[]{1e-3f, 1e-3f, 1e-3f};
    float eps_data2[]{1e-3f, 1e-3f, 1e-3f};
    float grad_output_data[]{1.f, -2.f, 3.f};
    Fprop fprop = [](const Arrays& inputs) -> Arrays { return {inputs[0] * inputs[1]}; };
    CheckBackwardBinaryComputation(true, fprop, {1, 3}, input_data1, input_data2, grad_output_data, eps_data1, eps_data2, 1e-5, 1e-4,
                                   "graph_1");
}

TEST_P(CheckBackwardBinaryTest, IncorrectBackward) {
    float input_data1[]{1.f, -2.f, 1.f};
    float input_data2[]{0.f, 1.4f, 2.f};
    float eps_data1[]{1e-3f, 1e-3f, 1e-3f};
    float eps_data2[]{1e-3f, 1e-3f, 1e-3f};
    float grad_output_data[]{4.f, -2.f, 3.f};
    CheckBackwardBinaryComputation(false, &IncorrectBackwardBinaryFunc, {1, 3}, input_data1, input_data2, grad_output_data, eps_data1,
                                   eps_data2, 1e-5, 1e-4, "graph_1");
}

INSTANTIATE_TEST_CASE_P(ForEachSingleSetRequiresGrad, CheckBackwardUnaryTest, ::testing::Bool());
INSTANTIATE_TEST_CASE_P(ForEachCombinedSetRequiresGrad, CheckBackwardBinaryTest, ::testing::Combine(::testing::Bool(), ::testing::Bool()));

}  // namespace
}  // namespace xchainer
<|endoftext|>


<commit_before>#include "xchainer/gradient_check.h"

#include <algorithm>
#include <memory>
#include <vector>

#include <gtest/gtest-spi.h>
#include <gtest/gtest.h>
#include <gsl/gsl>

#include "xchainer/array.h"
#include "xchainer/check_backward.h"
#include "xchainer/op_node.h"
#include "xchainer/shape.h"

namespace xchainer {
namespace {

using Arrays = std::vector<Array>;
using Fprop = std::function<std::vector<Array>(const std::vector<Array>&)>;

Arrays IncorrectBackwardUnaryFunc(const Arrays& inputs) {
    const Array& lhs = inputs[0];

    Array out = Array::EmptyLike(lhs);
    out.set_requires_grad(lhs.requires_grad());

    if (out.requires_grad()) {
        std::shared_ptr<ArrayNode> lhs_node = lhs.mutable_node();
        std::shared_ptr<ArrayNode> out_node = out.RenewNode();
        int64_t out_rank = lhs_node->rank();
        auto next_nodes = std::vector<std::shared_ptr<ArrayNode>>{lhs_node};
        std::function<Array(const Array&)> empty_func;
        auto lhs_func = lhs.requires_grad() ? [](const Array& gout) { return gout * gout; } : empty_func;
        auto backward_functions = std::vector<std::function<Array(const Array&)>>{lhs_func};
        std::shared_ptr<OpNode> op_node = std::make_shared<OpNode>("incorrect_unary", out_rank, next_nodes, backward_functions);
        out_node->set_next_node(op_node);
        out_node->set_rank(out_rank + 1);
    }

    VisitDtype(lhs.dtype(), [&](auto pt) {
        using T = typename decltype(pt)::type;

        int64_t total_size = lhs.total_size();
        auto* ldata = static_cast<const T*>(lhs.data().get());
        auto* odata = static_cast<T*>(out.data().get());

        for (int64_t i = 0; i < total_size; i++) {
            odata[i] = ldata[i];
        }
    });

    return {out};
}

Arrays IncorrectBackwardBinaryFunc(const Arrays& inputs) {
    const Array& lhs = inputs[0];
    const Array& rhs = inputs[1];

    CheckEqual(lhs.dtype(), rhs.dtype());
    CheckEqual(lhs.shape(), rhs.shape());

    Array out = Array::EmptyLike(lhs);
    out.set_requires_grad(lhs.requires_grad() || rhs.requires_grad());

    if (out.requires_grad()) {
        std::shared_ptr<ArrayNode> lhs_node = lhs.mutable_node();
        std::shared_ptr<ArrayNode> rhs_node = rhs.mutable_node();
        std::shared_ptr<ArrayNode> out_node = out.RenewNode();
        int64_t out_rank = std::max(lhs_node->rank(), rhs_node->rank());
        auto next_nodes = std::vector<std::shared_ptr<ArrayNode>>{lhs_node, rhs_node};
        std::function<Array(const Array&)> empty_func;
        auto lhs_func = lhs.requires_grad() ? [rhs](const Array& gout) { return gout + rhs; } : empty_func;
        auto rhs_func = rhs.requires_grad() ? [lhs](const Array& gout) { return gout + lhs; } : empty_func;
        auto backward_functions = std::vector<std::function<Array(const Array&)>>{lhs_func, rhs_func};
        std::shared_ptr<OpNode> op_node = std::make_shared<OpNode>("incorrect_binary", out_rank, next_nodes, backward_functions);
        out_node->set_next_node(op_node);
        out_node->set_rank(out_rank + 1);
    }

    VisitDtype(lhs.dtype(), [&](auto pt) {
        using T = typename decltype(pt)::type;

        int64_t total_size = lhs.total_size();
        auto* ldata = static_cast<const T*>(lhs.data().get());
        auto* rdata = static_cast<const T*>(rhs.data().get());
        auto* odata = static_cast<T*>(out.data().get());

        for (int64_t i = 0; i < total_size; i++) {
            odata[i] = ldata[i] * rdata[i];
        }
    });

    return {out};
}

class CheckBackwardBaseTest : public ::testing::Test {
public:
    template <typename T>
    Array MakeArray(const Shape& shape, const T* data) const {
        int64_t size = shape.total_size();
        auto a = std::make_unique<T[]>(size);
        std::copy(data, data + size, a.get());
        return Array::FromBuffer(shape, TypeToDtype<T>, std::move(a));
    }

protected:
    void CheckBaseBackwardComputation(bool expect_correct, const Fprop fprop, const Arrays& inputs, const Arrays& grad_outputs,
                                      const Arrays& eps, double atol, double rtol) {
        if (!expect_correct && std::any_of(inputs.begin(), inputs.end(), [](const Array& input) { return input.requires_grad(); })) {
            // Catch the gtest failure expected to be generated by CheckBackwardComputation but without failing this test
            EXPECT_NONFATAL_FAILURE(CheckBackwardComputation(fprop, inputs, grad_outputs, eps, atol, rtol), "Backward check failure");
        } else {
            // We cannot expect any failures in case none of the input std::vector<Array> require gradients
            CheckBackwardComputation(fprop, inputs, grad_outputs, eps, atol, rtol);
        }
    }
};

class CheckBackwardUnaryTest : public CheckBackwardBaseTest, public ::testing::WithParamInterface<bool> {
public:
    template <typename T>
    void CheckBackwardComputation(bool expect_correct, const Fprop fprop, const Shape& shape, const T* input_data,
                                  const T* grad_output_data, const T* eps_data, double atol, double rtol) {
        Arrays inputs{MakeArray(shape, input_data)};
        Arrays grad_outputs{MakeArray(shape, grad_output_data)};
        Arrays eps{MakeArray(shape, eps_data)};
        inputs[0].set_requires_grad(requires_grad);  // parameterized by test
        CheckBaseBackwardComputation(expect_correct, fprop, inputs, grad_outputs, eps, atol, rtol);
    }

protected:
    void SetUp() override { requires_grad = GetParam(); }

private:
    bool requires_grad;
};

class CheckBackwardBinaryTest : public CheckBackwardBaseTest, public ::testing::WithParamInterface<::testing::tuple<bool, bool>> {
public:
    template <typename T>
    void CheckBackwardComputation(bool expect_correct, const Fprop fprop, const Shape& shape, const T* input_data1, const T* input_data2,
                                  const T* grad_output_data, const T* eps_data1, const T* eps_data2, double atol, double rtol) {
        Arrays inputs{MakeArray(shape, input_data1), MakeArray(shape, input_data2)};
        Arrays grad_outputs{MakeArray(shape, grad_output_data)};
        Arrays eps{MakeArray(shape, eps_data1), MakeArray(shape, eps_data2)};
        inputs[0].set_requires_grad(requires_grads[0]);  // parameterized by test
        inputs[1].set_requires_grad(requires_grads[1]);
        CheckBaseBackwardComputation(expect_correct, fprop, inputs, grad_outputs, eps, atol, rtol);
    }

protected:
    void SetUp() override { requires_grads = {::testing::get<0>(GetParam()), ::testing::get<1>(GetParam())}; }

private:
    std::vector<bool> requires_grads;
};

TEST_P(CheckBackwardUnaryTest, CorrectBackward) {
    float input_data[]{1.f, 2.f, 3.f, 4.f, -1.f, 3.f};
    float grad_output_data[]{1.f, -2.f, 3.f, 0.f, 5.2f, -1.f};
    float eps_data[]{1.f, 2.f, 3.f, 4.f, 5.f, 6.f};
    const Fprop fprop = [](const Arrays& inputs) -> Arrays { return {inputs[0]}; };
    CheckBackwardComputation(true, fprop, {2, 3}, input_data, grad_output_data, eps_data, 1e-5, 1e-4);
}

TEST_P(CheckBackwardUnaryTest, IncorrectBackward) {
    float input_data[]{-2.f, 3.f, 1.f, 6.f, 2.f, -1.f};
    float grad_output_data[]{1.f, -2.f, 1.f, 0.f, 1.2f, 2.f};
    float eps_data[]{1.f, 2.f, 3.f, 4.f, 5.f, 6.f};
    CheckBackwardComputation(false, &IncorrectBackwardUnaryFunc, {2, 3}, input_data, grad_output_data, eps_data, 1e-5, 1e-4);
}

TEST_P(CheckBackwardBinaryTest, CorrectBackward) {
    float input_data1[]{1.f, 2.f, 3.f, 4.f, 5.f, 6.f};
    float input_data2[]{0.f, 1.f, 2.f, 3.f, 4.f, 5.f};
    float eps_data1[]{1.f, 2.f, 3.f, 4.f, 5.f, 6.f};
    float eps_data2[]{3.f, -2.f, 3.f, -4.f, 3.2f, 0.9f};
    float grad_output_data[]{1.f, -2.f, 3.f, 0.f, 5.2f, 6.f};
    const Fprop fprop = [](const Arrays& inputs) -> Arrays { return {inputs[0] * inputs[1]}; };
    CheckBackwardComputation(true, fprop, {2, 3}, input_data1, input_data2, grad_output_data, eps_data1, eps_data2, 1e-5, 1e-4);
}

TEST_P(CheckBackwardBinaryTest, IncorrectBackward) {
    float input_data1[]{3.f, -2.f, 1.f, 2.f, -5.f, 9.f};
    float input_data2[]{0.f, 1.4f, 2.f, -3.f, 4.f, 3.f};
    float eps_data1[]{1.f, 2.f, 3.8f, -4.f, 5.f, 1.f};
    float eps_data2[]{3.f, -2.f, -3.f, -1.f, 3.2f, 0.9f};
    float grad_output_data[]{4.f, -2.f, 3.f, 0.f, -2.6f, 1.f};
    CheckBackwardComputation(false, &IncorrectBackwardBinaryFunc, {2, 3}, input_data1, input_data2, grad_output_data, eps_data1, eps_data2,
                             1e-5, 1e-4);
}

INSTANTIATE_TEST_CASE_P(ForEachSingleSetRequiresGrad, CheckBackwardUnaryTest, ::testing::Bool());
INSTANTIATE_TEST_CASE_P(ForEachCombinedSetRequiresGrad, CheckBackwardBinaryTest, ::testing::Combine(::testing::Bool(), ::testing::Bool()));

}  // namespace
}  // namespace xchainer
<commit_msg>Change public methods to protected<commit_after>#include "xchainer/gradient_check.h"

#include <algorithm>
#include <memory>
#include <vector>

#include <gtest/gtest-spi.h>
#include <gtest/gtest.h>
#include <gsl/gsl>

#include "xchainer/array.h"
#include "xchainer/check_backward.h"
#include "xchainer/op_node.h"
#include "xchainer/shape.h"

namespace xchainer {
namespace {

using Arrays = std::vector<Array>;
using Fprop = std::function<std::vector<Array>(const std::vector<Array>&)>;

Arrays IncorrectBackwardUnaryFunc(const Arrays& inputs) {
    const Array& lhs = inputs[0];

    Array out = Array::EmptyLike(lhs);
    out.set_requires_grad(lhs.requires_grad());

    if (out.requires_grad()) {
        std::shared_ptr<ArrayNode> lhs_node = lhs.mutable_node();
        std::shared_ptr<ArrayNode> out_node = out.RenewNode();
        int64_t out_rank = lhs_node->rank();
        auto next_nodes = std::vector<std::shared_ptr<ArrayNode>>{lhs_node};
        std::function<Array(const Array&)> empty_func;
        auto lhs_func = lhs.requires_grad() ? [](const Array& gout) { return gout * gout; } : empty_func;
        auto backward_functions = std::vector<std::function<Array(const Array&)>>{lhs_func};
        std::shared_ptr<OpNode> op_node = std::make_shared<OpNode>("incorrect_unary", out_rank, next_nodes, backward_functions);
        out_node->set_next_node(op_node);
        out_node->set_rank(out_rank + 1);
    }

    VisitDtype(lhs.dtype(), [&](auto pt) {
        using T = typename decltype(pt)::type;

        int64_t total_size = lhs.total_size();
        auto* ldata = static_cast<const T*>(lhs.data().get());
        auto* odata = static_cast<T*>(out.data().get());

        for (int64_t i = 0; i < total_size; i++) {
            odata[i] = ldata[i];
        }
    });

    return {out};
}

Arrays IncorrectBackwardBinaryFunc(const Arrays& inputs) {
    const Array& lhs = inputs[0];
    const Array& rhs = inputs[1];

    CheckEqual(lhs.dtype(), rhs.dtype());
    CheckEqual(lhs.shape(), rhs.shape());

    Array out = Array::EmptyLike(lhs);
    out.set_requires_grad(lhs.requires_grad() || rhs.requires_grad());

    if (out.requires_grad()) {
        std::shared_ptr<ArrayNode> lhs_node = lhs.mutable_node();
        std::shared_ptr<ArrayNode> rhs_node = rhs.mutable_node();
        std::shared_ptr<ArrayNode> out_node = out.RenewNode();
        int64_t out_rank = std::max(lhs_node->rank(), rhs_node->rank());
        auto next_nodes = std::vector<std::shared_ptr<ArrayNode>>{lhs_node, rhs_node};
        std::function<Array(const Array&)> empty_func;
        auto lhs_func = lhs.requires_grad() ? [rhs](const Array& gout) { return gout + rhs; } : empty_func;
        auto rhs_func = rhs.requires_grad() ? [lhs](const Array& gout) { return gout + lhs; } : empty_func;
        auto backward_functions = std::vector<std::function<Array(const Array&)>>{lhs_func, rhs_func};
        std::shared_ptr<OpNode> op_node = std::make_shared<OpNode>("incorrect_binary", out_rank, next_nodes, backward_functions);
        out_node->set_next_node(op_node);
        out_node->set_rank(out_rank + 1);
    }

    VisitDtype(lhs.dtype(), [&](auto pt) {
        using T = typename decltype(pt)::type;

        int64_t total_size = lhs.total_size();
        auto* ldata = static_cast<const T*>(lhs.data().get());
        auto* rdata = static_cast<const T*>(rhs.data().get());
        auto* odata = static_cast<T*>(out.data().get());

        for (int64_t i = 0; i < total_size; i++) {
            odata[i] = ldata[i] * rdata[i];
        }
    });

    return {out};
}

class CheckBackwardBaseTest : public ::testing::Test {
protected:
    template <typename T>
    Array MakeArray(const Shape& shape, const T* data) const {
        int64_t size = shape.total_size();
        auto a = std::make_unique<T[]>(size);
        std::copy(data, data + size, a.get());
        return Array::FromBuffer(shape, TypeToDtype<T>, std::move(a));
    }

protected:
    void CheckBaseBackwardComputation(bool expect_correct, const Fprop fprop, const Arrays& inputs, const Arrays& grad_outputs,
                                      const Arrays& eps, double atol, double rtol) {
        if (!expect_correct && std::any_of(inputs.begin(), inputs.end(), [](const Array& input) { return input.requires_grad(); })) {
            // Catch the gtest failure expected to be generated by CheckBackwardComputation but without failing this test
            EXPECT_NONFATAL_FAILURE(CheckBackwardComputation(fprop, inputs, grad_outputs, eps, atol, rtol), "Backward check failure");
        } else {
            // We cannot expect any failures in case none of the input std::vector<Array> require gradients
            CheckBackwardComputation(fprop, inputs, grad_outputs, eps, atol, rtol);
        }
    }
};

class CheckBackwardUnaryTest : public CheckBackwardBaseTest, public ::testing::WithParamInterface<bool> {
protected:
    void SetUp() override { requires_grad = GetParam(); }

    template <typename T>
    void CheckBackwardComputation(bool expect_correct, const Fprop fprop, const Shape& shape, const T* input_data,
                                  const T* grad_output_data, const T* eps_data, double atol, double rtol) {
        Arrays inputs{MakeArray(shape, input_data)};
        Arrays grad_outputs{MakeArray(shape, grad_output_data)};
        Arrays eps{MakeArray(shape, eps_data)};
        inputs[0].set_requires_grad(requires_grad);  // parameterized by test
        CheckBaseBackwardComputation(expect_correct, fprop, inputs, grad_outputs, eps, atol, rtol);
    }

private:
    bool requires_grad;
};

class CheckBackwardBinaryTest : public CheckBackwardBaseTest, public ::testing::WithParamInterface<::testing::tuple<bool, bool>> {
protected:
    void SetUp() override { requires_grads = {::testing::get<0>(GetParam()), ::testing::get<1>(GetParam())}; }

    template <typename T>
    void CheckBackwardComputation(bool expect_correct, const Fprop fprop, const Shape& shape, const T* input_data1, const T* input_data2,
                                  const T* grad_output_data, const T* eps_data1, const T* eps_data2, double atol, double rtol) {
        Arrays inputs{MakeArray(shape, input_data1), MakeArray(shape, input_data2)};
        Arrays grad_outputs{MakeArray(shape, grad_output_data)};
        Arrays eps{MakeArray(shape, eps_data1), MakeArray(shape, eps_data2)};
        inputs[0].set_requires_grad(requires_grads[0]);  // parameterized by test
        inputs[1].set_requires_grad(requires_grads[1]);
        CheckBaseBackwardComputation(expect_correct, fprop, inputs, grad_outputs, eps, atol, rtol);
    }

private:
    std::vector<bool> requires_grads;
};

TEST_P(CheckBackwardUnaryTest, CorrectBackward) {
    float input_data[]{1.f, 2.f, 3.f, 4.f, -1.f, 3.f};
    float grad_output_data[]{1.f, -2.f, 3.f, 0.f, 5.2f, -1.f};
    float eps_data[]{1.f, 2.f, 3.f, 4.f, 5.f, 6.f};
    const Fprop fprop = [](const Arrays& inputs) -> Arrays { return {inputs[0]}; };
    CheckBackwardComputation(true, fprop, {2, 3}, input_data, grad_output_data, eps_data, 1e-5, 1e-4);
}

TEST_P(CheckBackwardUnaryTest, IncorrectBackward) {
    float input_data[]{-2.f, 3.f, 1.f, 6.f, 2.f, -1.f};
    float grad_output_data[]{1.f, -2.f, 1.f, 0.f, 1.2f, 2.f};
    float eps_data[]{1.f, 2.f, 3.f, 4.f, 5.f, 6.f};
    CheckBackwardComputation(false, &IncorrectBackwardUnaryFunc, {2, 3}, input_data, grad_output_data, eps_data, 1e-5, 1e-4);
}

TEST_P(CheckBackwardBinaryTest, CorrectBackward) {
    float input_data1[]{1.f, 2.f, 3.f, 4.f, 5.f, 6.f};
    float input_data2[]{0.f, 1.f, 2.f, 3.f, 4.f, 5.f};
    float eps_data1[]{1.f, 2.f, 3.f, 4.f, 5.f, 6.f};
    float eps_data2[]{3.f, -2.f, 3.f, -4.f, 3.2f, 0.9f};
    float grad_output_data[]{1.f, -2.f, 3.f, 0.f, 5.2f, 6.f};
    const Fprop fprop = [](const Arrays& inputs) -> Arrays { return {inputs[0] * inputs[1]}; };
    CheckBackwardComputation(true, fprop, {2, 3}, input_data1, input_data2, grad_output_data, eps_data1, eps_data2, 1e-5, 1e-4);
}

TEST_P(CheckBackwardBinaryTest, IncorrectBackward) {
    float input_data1[]{3.f, -2.f, 1.f, 2.f, -5.f, 9.f};
    float input_data2[]{0.f, 1.4f, 2.f, -3.f, 4.f, 3.f};
    float eps_data1[]{1.f, 2.f, 3.8f, -4.f, 5.f, 1.f};
    float eps_data2[]{3.f, -2.f, -3.f, -1.f, 3.2f, 0.9f};
    float grad_output_data[]{4.f, -2.f, 3.f, 0.f, -2.6f, 1.f};
    CheckBackwardComputation(false, &IncorrectBackwardBinaryFunc, {2, 3}, input_data1, input_data2, grad_output_data, eps_data1, eps_data2,
                             1e-5, 1e-4);
}

INSTANTIATE_TEST_CASE_P(ForEachSingleSetRequiresGrad, CheckBackwardUnaryTest, ::testing::Bool());
INSTANTIATE_TEST_CASE_P(ForEachCombinedSetRequiresGrad, CheckBackwardBinaryTest, ::testing::Combine(::testing::Bool(), ::testing::Bool()));

}  // namespace
}  // namespace xchainer
<|endoftext|>


<commit_before>/*
	This file is part of solidity.

	solidity is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	solidity is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with solidity.  If not, see <http://www.gnu.org/licenses/>.
*/
/**
 * Executable for use with AFL <http://lcamtuf.coredump.cx/afl>.
 */

#include <libevmasm/Assembly.h>
#include <libevmasm/ConstantOptimiser.h>

#include <json/json.h>

#include <boost/program_options.hpp>

#include <string>
#include <iostream>

using namespace std;
using namespace dev;
using namespace dev::eth;
namespace po = boost::program_options;

extern "C"
{
extern char const* compileJSON(char const* _input, bool _optimize);
}

bool quiet = false;

string contains(string const& _haystack, vector<string> const& _needles)
{
	for (string const& needle: _needles)
		if (_haystack.find(needle) != string::npos)
			return needle;
	return "";
}

void testConstantOptimizer()
{
	if (!quiet)
		cout << "Testing constant optimizer" << endl;
	vector<u256> numbers;
	while (!cin.eof())
	{
		h256 data;
		cin.read(reinterpret_cast<char*>(data.data()), 32);
		numbers.push_back(u256(data));
	}
	if (!quiet)
		cout << "Got " << numbers.size() << " inputs:" << endl;

	Assembly assembly;
	for (u256 const& n: numbers)
	{
		if (!quiet)
			cout << n << endl;
		assembly.append(n);
	}
	for (bool isCreation: {false, true})
	{
		for (unsigned runs: {1, 2, 3, 20, 40, 100, 200, 400, 1000})
		{
			ConstantOptimisationMethod::optimiseConstants(
				isCreation,
				runs,
				assembly,
				const_cast<AssemblyItems&>(assembly.items())
			);
		}
	}
}

void testCompiler()
{
	if (!quiet)
		cout << "Testing compiler." << endl;
	string input;
	while (!cin.eof())
	{
		string s;
		getline(cin, s);
		input += s + '\n';
	}

	bool optimize = true;
	string outputString(compileJSON(input.c_str(), optimize));
	Json::Value outputJson;
	if (!Json::Reader().parse(outputString, outputJson))
	{
		cout << "Compiler produced invalid JSON output." << endl;
		abort();
	}
	if (outputJson.isMember("errors"))
	{
		if (!outputJson["errors"].isArray())
		{
			cout << "Output JSON has \"errors\" but it is not an array." << endl;
			abort();
		}
		for (Json::Value const& error: outputJson["errors"])
		{
			string invalid = contains(error.asString(), vector<string>{
				"Internal compiler error",
				"Exception during compilation",
				"Unknown exception during compilation",
				"Unknown exception while generating contract data output",
				"Unknown exception while generating formal method output",
				"Unknown exception while generating source name output",
				"Unknown error while generating JSON"
			});
			if (!invalid.empty())
			{
				cout << "Invalid error: \"" << error.asString() << "\"" << endl;
				abort();
			}
		}
	}
	else if (!outputJson.isMember("contracts"))
	{
		cout << "Output JSON has neither \"errors\" nor \"contracts\"." << endl;
		abort();
	}
}

int main(int argc, char** argv)
{
	po::options_description options(
		R"(solfuzzer, fuzz-testing binary for use with AFL.
Usage: solfuzzer [Options] < input
Reads a single source from stdin, compiles it and signals a failure for internal errors.

Allowed options)",
		po::options_description::m_default_line_length,
		po::options_description::m_default_line_length - 23);
	options.add_options()
		("help", "Show this help screen.")
		("quiet", "Only output errors.")
		(
			"const-opt",
			"Run the constant optimizer instead of compiling. "
			"Expects a binary string of up to 32 bytes on stdin."
		);

	po::variables_map arguments;
	try
	{
		po::command_line_parser cmdLineParser(argc, argv);
		cmdLineParser.options(options);
		po::store(cmdLineParser.run(), arguments);
	}
	catch (po::error const& _exception)
	{
		cerr << _exception.what() << endl;
		return false;
	}

	if (arguments.count("quiet"))
		quiet = true;

	if (arguments.count("help"))
		cout << options;
	else if (arguments.count("const-opt"))
		testConstantOptimizer();
	else
		testCompiler();

	return 0;
}
<commit_msg>Add --standard-json option to solfuzzer<commit_after>/*
	This file is part of solidity.

	solidity is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	solidity is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with solidity.  If not, see <http://www.gnu.org/licenses/>.
*/
/**
 * Executable for use with AFL <http://lcamtuf.coredump.cx/afl>.
 */

#include <libevmasm/Assembly.h>
#include <libevmasm/ConstantOptimiser.h>

#include <json/json.h>

#include <boost/program_options.hpp>

#include <string>
#include <iostream>

using namespace std;
using namespace dev;
using namespace dev::eth;
namespace po = boost::program_options;

extern "C"
{
extern char const* compileJSON(char const* _input, bool _optimize);
typedef void (*CStyleReadFileCallback)(char const* _path, char** o_contents, char** o_error);
extern char const* compileStandard(char const* _input, CStyleReadFileCallback _readCallback);
}

bool quiet = false;

string contains(string const& _haystack, vector<string> const& _needles)
{
	for (string const& needle: _needles)
		if (_haystack.find(needle) != string::npos)
			return needle;
	return "";
}

void testConstantOptimizer()
{
	if (!quiet)
		cout << "Testing constant optimizer" << endl;
	vector<u256> numbers;
	while (!cin.eof())
	{
		h256 data;
		cin.read(reinterpret_cast<char*>(data.data()), 32);
		numbers.push_back(u256(data));
	}
	if (!quiet)
		cout << "Got " << numbers.size() << " inputs:" << endl;

	Assembly assembly;
	for (u256 const& n: numbers)
	{
		if (!quiet)
			cout << n << endl;
		assembly.append(n);
	}
	for (bool isCreation: {false, true})
	{
		for (unsigned runs: {1, 2, 3, 20, 40, 100, 200, 400, 1000})
		{
			ConstantOptimisationMethod::optimiseConstants(
				isCreation,
				runs,
				assembly,
				const_cast<AssemblyItems&>(assembly.items())
			);
		}
	}
}

string readInput()
{
	string input;
	while (!cin.eof())
	{
		string s;
		getline(cin, s);
		input += s + '\n';
	}
	return input;
}

void testStandardCompiler()
{
	if (!quiet)
		cout << "Testing compiler via JSON interface." << endl;
	string input = readInput();
	string outputString(compileStandard(input.c_str(), NULL));
	Json::Value output;
	if (!Json::Reader().parse(outputString, output))
	{
		cout << "Compiler produced invalid JSON output." << endl;
		abort();
	}
	if (output.isMember("errors"))
		for (auto const& error: output["errors"])
		{
			string invalid = contains(error["type"].asString(), vector<string>{
				"Exception",
				"InternalCompilerError"
			});
			if (!invalid.empty())
			{
				cout << "Invalid error: \"" << error["type"].asString() << "\"" << endl;
				abort();
			}
		}
}

void testCompiler()
{
	if (!quiet)
		cout << "Testing compiler." << endl;
	string input = readInput();

	bool optimize = true;
	string outputString(compileJSON(input.c_str(), optimize));
	Json::Value outputJson;
	if (!Json::Reader().parse(outputString, outputJson))
	{
		cout << "Compiler produced invalid JSON output." << endl;
		abort();
	}
	if (outputJson.isMember("errors"))
	{
		if (!outputJson["errors"].isArray())
		{
			cout << "Output JSON has \"errors\" but it is not an array." << endl;
			abort();
		}
		for (Json::Value const& error: outputJson["errors"])
		{
			string invalid = contains(error.asString(), vector<string>{
				"Internal compiler error",
				"Exception during compilation",
				"Unknown exception during compilation",
				"Unknown exception while generating contract data output",
				"Unknown exception while generating formal method output",
				"Unknown exception while generating source name output",
				"Unknown error while generating JSON"
			});
			if (!invalid.empty())
			{
				cout << "Invalid error: \"" << error.asString() << "\"" << endl;
				abort();
			}
		}
	}
	else if (!outputJson.isMember("contracts"))
	{
		cout << "Output JSON has neither \"errors\" nor \"contracts\"." << endl;
		abort();
	}
}

int main(int argc, char** argv)
{
	po::options_description options(
		R"(solfuzzer, fuzz-testing binary for use with AFL.
Usage: solfuzzer [Options] < input
Reads a single source from stdin, compiles it and signals a failure for internal errors.

Allowed options)",
		po::options_description::m_default_line_length,
		po::options_description::m_default_line_length - 23);
	options.add_options()
		("help", "Show this help screen.")
		("quiet", "Only output errors.")
		(
			"standard-json",
			"Test via the standard-json interface, i.e. "
			"input is expected to be JSON-encoded instead of "
			"plain source file."
		)
		(
			"const-opt",
			"Run the constant optimizer instead of compiling. "
			"Expects a binary string of up to 32 bytes on stdin."
		);

	po::variables_map arguments;
	try
	{
		po::command_line_parser cmdLineParser(argc, argv);
		cmdLineParser.options(options);
		po::store(cmdLineParser.run(), arguments);
	}
	catch (po::error const& _exception)
	{
		cerr << _exception.what() << endl;
		return false;
	}

	if (arguments.count("quiet"))
		quiet = true;

	if (arguments.count("help"))
		cout << options;
	else if (arguments.count("const-opt"))
		testConstantOptimizer();
	else if (arguments.count("standard-json"))
		testStandardCompiler();
	else
		testCompiler();

	return 0;
}
<|endoftext|>


<commit_before>#include "fancylineedit.h"

#include <QToolButton>
#include <QStyle>
#include <QInputDialog>
#include <QDir>

FancyLineEdit::FancyLineEdit(QWidget *parent) : QLineEdit(parent)
{
    clearButton = new QToolButton(this);
    clearButton->resize(24, 18);
    clearButton->setText("x");
    clearButton->setCursor(Qt::ArrowCursor);

    editButton = new QToolButton(this);
    editButton->resize(24, 18);
    editButton->setText("...");
    editButton->setCursor(Qt::ArrowCursor);

    fileDropDialog = new FileDropDialog(this);
    fileDropDialog->hide();
    setAcceptDrops(true);

    connect(clearButton, &QAbstractButton::clicked, this, &QLineEdit::clear);
    connect(editButton, &QAbstractButton::clicked,this, &FancyLineEdit::on_editButton_Clicked);
}

FancyLineEdit::~FancyLineEdit(){}

void FancyLineEdit::hideEditButton()
{
    editButton->hide();
}

void FancyLineEdit::hideClearButton()
{
    clearButton->hide();
}

void FancyLineEdit::showEditButton()
{
    editButton->show();
}

void FancyLineEdit::showClearButton()
{
    clearButton->show();
}

void FancyLineEdit::resizeEvent(QResizeEvent *)
{
    // put the Clear button on the far-right of the Line Edit, and position 2 pixels down from Line Edit;
    clearButton->move(QPoint(this->width()-clearButton->sizeHint().width(), 2));
    clearButton->resize(QSize(clearButton->sizeHint().width() - 2, this->height() - 4));

    // put the Edit button to the left of the Clear button, and position 2 pixels down from Line Edit;
    editButton->move(QPoint(this->width() - 2 * editButton->sizeHint().width() + 3, 2));
    editButton->resize(QSize(editButton->sizeHint().width() - 2, this->height() - 4));
}

void FancyLineEdit::dragEnterEvent(QDragEnterEvent *e)
{
    if(e->mimeData()->hasText()) {
        e->acceptProposedAction();
    }
}

void FancyLineEdit::dropEvent(QDropEvent *e)
{
    QStringList urlStrings = e->mimeData()->text().split("\n");
    QUrl url;
    QStringList paths;
    for(const auto& urlString : urlStrings) {
        if(urlString.isEmpty())
            continue;
        url = urlString;
        QString path = QDir::toNativeSeparators(url.path());

#ifdef Q_OS_WIN
        if(path.startsWith('\\')) {
            path.remove(0, 1);
        }
#endif
        // if path is a directory, append a wilcard(*) to it.
        QFileInfo x(path);
        if(x.isDir()) {
            path.append("/*");
        }

        paths.append(QDir::toNativeSeparators(path));

    }

    if(!paths.isEmpty())
        setText(paths.join("\n"));
}

void FancyLineEdit::on_editButton_Clicked()
{
    fileDropDialog->setText(tr("Edit multiple filenames"), tr("Edit filenames below, and click 'OK' when done."), this->text());
    fileDropDialog->show();

    connect(fileDropDialog, &FileDropDialog::accepted, this, [this]{
        setText(fileDropDialog->getText());
        fileDropDialog->hide();
    });

    connect(fileDropDialog, &FileDropDialog::rejected, this, [this]{
        fileDropDialog->close();
    });
}
<commit_msg>minor refactoring<commit_after>#include "fancylineedit.h"

#include <QToolButton>
#include <QStyle>
#include <QInputDialog>
#include <QDir>

FancyLineEdit::FancyLineEdit(QWidget *parent) : QLineEdit(parent)
{
    clearButton = new QToolButton(this);
    editButton = new QToolButton(this);
    fileDropDialog = new FileDropDialog(this);

    clearButton->resize(24, 18);
    clearButton->setText("x");
    clearButton->setCursor(Qt::ArrowCursor);

    editButton->resize(24, 18);
    editButton->setText("...");
    editButton->setCursor(Qt::ArrowCursor);

    fileDropDialog->hide();
    setAcceptDrops(true);

    connect(clearButton, &QAbstractButton::clicked, this, &QLineEdit::clear);
    connect(editButton, &QAbstractButton::clicked,this, &FancyLineEdit::on_editButton_Clicked);
}

FancyLineEdit::~FancyLineEdit(){}

void FancyLineEdit::hideEditButton()
{
    editButton->hide();
}

void FancyLineEdit::hideClearButton()
{
    clearButton->hide();
}

void FancyLineEdit::showEditButton()
{
    editButton->show();
}

void FancyLineEdit::showClearButton()
{
    clearButton->show();
}

void FancyLineEdit::resizeEvent(QResizeEvent *)
{
    // put the Clear button on the far-right of the Line Edit, and position 2 pixels down from Line Edit;
    clearButton->move(QPoint(this->width()-clearButton->sizeHint().width(), 2));
    clearButton->resize(QSize(clearButton->sizeHint().width() - 2, this->height() - 4));

    // put the Edit button to the left of the Clear button, and position 2 pixels down from Line Edit;
    editButton->move(QPoint(this->width() - 2 * editButton->sizeHint().width() + 3, 2));
    editButton->resize(QSize(editButton->sizeHint().width() - 2, this->height() - 4));
}

void FancyLineEdit::dragEnterEvent(QDragEnterEvent *e)
{
    if(e->mimeData()->hasText()) {
        e->acceptProposedAction();
    }
}

void FancyLineEdit::dropEvent(QDropEvent *e)
{
    QStringList urlStrings = e->mimeData()->text().split("\n");
    QUrl url;
    QStringList paths;
    for(const auto& urlString : urlStrings) {
        if(urlString.isEmpty())
            continue;
        url = urlString;
        QString path = QDir::toNativeSeparators(url.path());

#ifdef Q_OS_WIN
        if(path.startsWith('\\')) {
            path.remove(0, 1);
        }
#endif
        // if path is a directory, append a wilcard(*) to it.
        QFileInfo x(path);
        if(x.isDir()) {
            path.append("/*");
        }

        paths.append(QDir::toNativeSeparators(path));

    }

    if(!paths.isEmpty())
        setText(paths.join("\n"));
}

void FancyLineEdit::on_editButton_Clicked()
{
    fileDropDialog->setText(tr("Edit multiple filenames"), tr("Edit filenames below, and click 'OK' when done."), this->text());
    fileDropDialog->show();

    connect(fileDropDialog, &FileDropDialog::accepted, this, [this]{
        setText(fileDropDialog->getText());
        fileDropDialog->hide();
    });

    connect(fileDropDialog, &FileDropDialog::rejected, this, [this]{
        fileDropDialog->close();
    });
}
<|endoftext|>


<commit_before>#include "message.hpp"
#include "server.hpp"
#include "Cereal.hpp"
#include <vector>
#include <iostream>

using namespace std;

MqttFixedHeader::MqttFixedHeader():
    type(), dup(), qos(), retain(), remaining() {
}

MqttFixedHeader::MqttFixedHeader(MqttType t, bool d, ubyte q, bool rt, uint re):
    type(t), dup(d), qos(q), retain(rt), remaining(re) {
}

void MqttFixedHeader::cerealise(Cereal& cereal) {
    cereal.grainBits(type, 4);
    cereal.grainBits(dup, 1);
    cereal.grainBits(qos, 2);
    cereal.grainBits(retain, 1);

    switch(cereal.getType()) {
    case Cereal::Type::Write:
        setRemainingSize(cereal);
        break;

    case Cereal::Type::Read:
        remaining = getRemainingSize(cereal);
        break;
    }
}

uint MqttFixedHeader::getRemainingSize(Cereal& cereal) {
    //algorithm straight from the MQTT spec
    int multiplier = 1;
    uint value = 0;
    ubyte digit;
    do {
        cereal.grain(digit);
        value += (digit & 127) * multiplier;
        multiplier *= 128;
    } while((digit & 128) != 0);

    return value;
}

void MqttFixedHeader::setRemainingSize(Cereal& cereal) const {
    //algorithm straight from the MQTT spec
    vector<ubyte> digits;
    uint x = remaining;
    do {
        ubyte digit = x % 128;
        x /= 128;
        if(x > 0) {
            digit = digit | 0x80;
        }
        digits.push_back(digit);
    } while(x > 0);

    for(auto b: digits) cereal.grain(b);
}

void MqttMessage::handle(MqttServer& server, MqttConnection& connection) const {
    (void)server;
    (void)connection;
}

MqttConnect::MqttConnect(MqttFixedHeader h):header(h) { }

void MqttConnect::cerealise(Cereal& cereal) {
    cereal.grain(header);
    cereal.grain(protoName);
    cereal.grain(protoVersion);

    cereal.grainBits(hasUserName, 1);
    cereal.grainBits(hasPassword, 1);
    cereal.grainBits(hasWillRetain, 1);
    cereal.grainBits(willQos, 2);
    cereal.grainBits(hasWill, 1);
    cereal.grainBits(hasClear, 1);
    cereal.grainBits(reserved, 1);

    cereal.grain(keepAlive);
    cereal.grain(clientId);

    if(hasWill) cereal.grain(willTopic);
    if(hasWill) cereal.grain(willMessage);
    if(hasUserName) cereal.grain(userName);
    if(hasPassword) cereal.grain(password);
}

MqttConnack::MqttConnack():
    header(MqttType::CONNACK, false, 0, false, 2) {
}

MqttConnack::MqttConnack(Code c):
    MqttConnack() {
    code = c;
}

void MqttConnack::cerealise(Cereal& cereal) {
    cereal.grain(header);
    cereal.grain(reserved);
    cereal.grain(reinterpret_cast<ubyte&>(code));
}

MqttPublish::MqttPublish(MqttFixedHeader h):header(h) {

}

MqttPublish::MqttPublish(string topic, std::vector<ubyte> payload, ushort msgId):
    MqttPublish(false, 0, false, topic, payload, msgId) {
}

MqttPublish::MqttPublish(bool dup, ubyte qos, bool retain, string t, std::vector<ubyte> p, ushort mid) {
    const auto topicLen = t.length() + 2; //2 for length
    auto remaining = qos ? topicLen + 2 /*msgId*/ : topicLen;
    remaining += p.size();

    header = MqttFixedHeader(MqttType::PUBLISH, dup, qos, retain, remaining);
    topic = t;
    payload = std::move(p);
    msgId = mid;
}

void MqttPublish::cerealise(Cereal& cereal) {
    cereal.grain(header);
    cereal.grain(topic);

    auto payloadLen = header.remaining - (topic.length() + MqttFixedHeader::SIZE);
    if(header.qos) {
        if(header.remaining < 7 && cereal.getType() == Cereal::Type::Read) {
            cerr << "Error: PUBLISH message with QOS but no message ID" << endl;
        } else {
            cereal.grain(msgId);
            payloadLen -= 2;
        }
    }
    if(cereal.getType() == Cereal::Type::Read) payload.resize(payloadLen);
    for(auto& b: payload) cereal.grain(b);
}

void MqttPublish::handle(MqttServer& server, MqttConnection& connection) const {
    (void)connection;
    server.publish(topic, payload);
}

MqttSubscribe::MqttSubscribe(MqttFixedHeader h):header(h) {

}

void MqttSubscribe::handle(MqttServer& server, MqttConnection& connection) const {
    server.subscribe(connection, msgId, topics);
}

void MqttSubscribe::Topic::cerealise(Cereal& cereal) {
    cereal.grain(topic);
    cereal.grain(qos);
}

void MqttSubscribe::cerealise(Cereal& cereal) {
    cereal.grain(header);
    cereal.grain(msgId);
    ushort size;
    cereal.grain(size);
    if(topics.size() != size) topics.resize(size);
    for(auto& t: topics) cereal.grain(t);
}

MqttSuback::MqttSuback(MqttFixedHeader h):header(h) {

}

MqttSuback::MqttSuback(ushort m, std::vector<ubyte> q):
    header(MqttType::SUBACK, false, 0, false, qos.size() + 2),
    msgId(m),
    qos(std::move(q)) {
}

void MqttSuback::cerealise(Cereal& cereal) {
    cereal.grain(header);
    cereal.grain(msgId);
    ushort size;
    cereal.grain(size);
    if(qos.size() != size) qos.resize(size);
    for(auto& q: qos) cereal.grain(q);
}

MqttUnsubscribe::MqttUnsubscribe(MqttFixedHeader h):header(h) {

}

void MqttUnsubscribe::handle(MqttServer& server, MqttConnection& connection) const {
    server.unsubscribe(connection, msgId, topics);
}

void MqttUnsubscribe::cerealise(Cereal& cereal) {
    cereal.grain(header);
    cereal.grain(msgId);
    ushort size;
    cereal.grain(size);
    if(topics.size() != size) topics.resize(size);
    for(auto& t: topics) cereal.grain(t);
}

MqttUnsuback::MqttUnsuback(ushort m):
    header(MqttType::UNSUBACK, false, 0, false, 2),
    msgId(m)
{
}

MqttUnsuback::MqttUnsuback(MqttFixedHeader h):header(h), msgId() {

}

void MqttUnsuback::cerealise(Cereal& cereal) {
    cereal.grain(header);
    cereal.grain(msgId);
}

void MqttDisconnect::handle(MqttServer& server, MqttConnection& connection) const {
    server.unsubscribe(connection);
    connection.disconnect();
}

void MqttPingReq::handle(MqttServer& server, MqttConnection& connection) const {
    server.ping(connection);
}

std::vector<ubyte> MqttPingResp::encode() const {
    return std::vector<ubyte>{0xd0, 0x00};
}
<commit_msg>Fixed the failing unit test in message<commit_after>#include "message.hpp"
#include "server.hpp"
#include "Cereal.hpp"
#include <vector>
#include <iostream>

using namespace std;

MqttFixedHeader::MqttFixedHeader():
    type(), dup(), qos(), retain(), remaining() {
}

MqttFixedHeader::MqttFixedHeader(MqttType t, bool d, ubyte q, bool rt, uint re):
    type(t), dup(d), qos(q), retain(rt), remaining(re) {
}

void MqttFixedHeader::cerealise(Cereal& cereal) {
    cereal.grainBits(type, 4);
    cereal.grainBits(dup, 1);
    cereal.grainBits(qos, 2);
    cereal.grainBits(retain, 1);

    switch(cereal.getType()) {
    case Cereal::Type::Write:
        setRemainingSize(cereal);
        break;

    case Cereal::Type::Read:
        remaining = getRemainingSize(cereal);
        break;
    }
}

uint MqttFixedHeader::getRemainingSize(Cereal& cereal) {
    //algorithm straight from the MQTT spec
    int multiplier = 1;
    uint value = 0;
    ubyte digit;
    do {
        cereal.grain(digit);
        value += (digit & 127) * multiplier;
        multiplier *= 128;
    } while((digit & 128) != 0);

    return value;
}

void MqttFixedHeader::setRemainingSize(Cereal& cereal) const {
    //algorithm straight from the MQTT spec
    vector<ubyte> digits;
    uint x = remaining;
    do {
        ubyte digit = x % 128;
        x /= 128;
        if(x > 0) {
            digit = digit | 0x80;
        }
        digits.push_back(digit);
    } while(x > 0);

    for(auto b: digits) cereal.grain(b);
}

void MqttMessage::handle(MqttServer& server, MqttConnection& connection) const {
    (void)server;
    (void)connection;
}

MqttConnect::MqttConnect(MqttFixedHeader h):header(h) { }

void MqttConnect::cerealise(Cereal& cereal) {
    cereal.grain(header);
    cereal.grain(protoName);
    cereal.grain(protoVersion);

    cereal.grainBits(hasUserName, 1);
    cereal.grainBits(hasPassword, 1);
    cereal.grainBits(hasWillRetain, 1);
    cereal.grainBits(willQos, 2);
    cereal.grainBits(hasWill, 1);
    cereal.grainBits(hasClear, 1);
    cereal.grainBits(reserved, 1);

    cereal.grain(keepAlive);
    cereal.grain(clientId);

    if(hasWill) cereal.grain(willTopic);
    if(hasWill) cereal.grain(willMessage);
    if(hasUserName) cereal.grain(userName);
    if(hasPassword) cereal.grain(password);
}

MqttConnack::MqttConnack():
    header(MqttType::CONNACK, false, 0, false, 2) {
}

MqttConnack::MqttConnack(Code c):
    MqttConnack() {
    code = c;
}

void MqttConnack::cerealise(Cereal& cereal) {
    cereal.grain(header);
    cereal.grain(reserved);
    cereal.grain(reinterpret_cast<ubyte&>(code));
}

MqttPublish::MqttPublish(MqttFixedHeader h):header(h) {

}

MqttPublish::MqttPublish(string topic, std::vector<ubyte> payload, ushort msgId):
    MqttPublish(false, 0, false, topic, payload, msgId) {
}

MqttPublish::MqttPublish(bool dup, ubyte qos, bool retain, string t, std::vector<ubyte> p, ushort mid) {
    const auto topicLen = t.length() + 2; //2 for length
    auto remaining = qos ? topicLen + 2 /*msgId*/ : topicLen;
    remaining += p.size();

    header = MqttFixedHeader(MqttType::PUBLISH, dup, qos, retain, remaining);
    topic = t;
    payload = std::move(p);
    msgId = mid;
}

void MqttPublish::cerealise(Cereal& cereal) {
    cereal.grain(header);
    cereal.grain(topic);

    auto payloadLen = header.remaining - (topic.length() + MqttFixedHeader::SIZE);
    if(header.qos) {
        if(header.remaining < 7 && cereal.getType() == Cereal::Type::Read) {
            cerr << "Error: PUBLISH message with QOS but no message ID" << endl;
        } else {
            cereal.grain(msgId);
            payloadLen -= 2;
        }
    }
    if(cereal.getType() == Cereal::Type::Read) payload.resize(payloadLen);
    for(auto& b: payload) cereal.grain(b);
}

void MqttPublish::handle(MqttServer& server, MqttConnection& connection) const {
    (void)connection;
    server.publish(topic, payload);
}

MqttSubscribe::MqttSubscribe(MqttFixedHeader h):header(h) {

}

void MqttSubscribe::handle(MqttServer& server, MqttConnection& connection) const {
    server.subscribe(connection, msgId, topics);
}

void MqttSubscribe::Topic::cerealise(Cereal& cereal) {
    cereal.grain(topic);
    cereal.grain(qos);
}

void MqttSubscribe::cerealise(Cereal& cereal) {
    cereal.grain(header);
    cereal.grain(msgId);
    cereal.grainRawArray(topics);
}

MqttSuback::MqttSuback(MqttFixedHeader h):header(h) {

}

MqttSuback::MqttSuback(ushort m, std::vector<ubyte> q):
    header(MqttType::SUBACK, false, 0, false, q.size() + 2),
    msgId(m),
    qos(std::move(q)) {
}

void MqttSuback::cerealise(Cereal& cereal) {
    cereal.grain(header);
    cereal.grain(msgId);
    cereal.grainRawArray(qos);
}

MqttUnsubscribe::MqttUnsubscribe(MqttFixedHeader h):header(h) {

}

void MqttUnsubscribe::handle(MqttServer& server, MqttConnection& connection) const {
    server.unsubscribe(connection, msgId, topics);
}

void MqttUnsubscribe::cerealise(Cereal& cereal) {
    cereal.grain(header);
    cereal.grain(msgId);
    cereal.grainRawArray(topics);
}

MqttUnsuback::MqttUnsuback(ushort m):
    header(MqttType::UNSUBACK, false, 0, false, 2),
    msgId(m)
{
}

MqttUnsuback::MqttUnsuback(MqttFixedHeader h):header(h), msgId() {

}

void MqttUnsuback::cerealise(Cereal& cereal) {
    cereal.grain(header);
    cereal.grain(msgId);
}

void MqttDisconnect::handle(MqttServer& server, MqttConnection& connection) const {
    server.unsubscribe(connection);
    connection.disconnect();
}

void MqttPingReq::handle(MqttServer& server, MqttConnection& connection) const {
    server.ping(connection);
}

std::vector<ubyte> MqttPingResp::encode() const {
    return std::vector<ubyte>{0xd0, 0x00};
}
<|endoftext|>


<commit_before>/**
 * Copyright 2008 Matthew Graham
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "message.h"

message_arg_list_c::~message_arg_list_c()
{
	std::vector< message_arg_i * >::iterator it;
	for ( it=m_arg.begin(); it!=m_arg.end(); ++it ) {
		delete *it;
	}
	m_arg.clear();
}

std::string message_arg_list_c::argv( int i ) const
{
	std::string value;
	m_arg[i]->get_string( value );
	return value;
}

message_c::message_c()
: m_arg()
{}

message_c::message_c( const std::string &args )
: m_arg()
{
	parse_args( args );
}

message_c::~message_c()
{}

void message_c::add_arg( const std::string &arg )
{
	// m_arg.add_arg( arg );
}

std::string message_c::argv( int i ) const
{
	std::string arg;
	m_arg.argv( i, arg );
	return arg;
}

void message_c::get_argv( int i, std::string &value ) const
{
	m_arg.argv( i, value );
}

void message_c::parse_args( const std::string &args )
{
	std::istringstream in( args );
	std::string value;
	while ( in >> value ) {
		add_arg( value );
	}
}

<commit_msg>removed message.get_argv which is now implemented directly in the header<commit_after>/**
 * Copyright 2008 Matthew Graham
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "message.h"

message_arg_list_c::~message_arg_list_c()
{
	std::vector< message_arg_i * >::iterator it;
	for ( it=m_arg.begin(); it!=m_arg.end(); ++it ) {
		delete *it;
	}
	m_arg.clear();
}

std::string message_arg_list_c::argv( int i ) const
{
	std::string value;
	m_arg[i]->get_string( value );
	return value;
}

message_c::message_c()
: m_arg()
{}

message_c::message_c( const std::string &args )
: m_arg()
{
	parse_args( args );
}

message_c::~message_c()
{}

void message_c::add_arg( const std::string &arg )
{
	// m_arg.add_arg( arg );
}

std::string message_c::argv( int i ) const
{
	std::string arg;
	m_arg.argv( i, arg );
	return arg;
}

void message_c::parse_args( const std::string &args )
{
	std::istringstream in( args );
	std::string value;
	while ( in >> value ) {
		add_arg( value );
	}
}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: ximppage.cxx,v $
 *
 *  $Revision: 1.16 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-19 18:14:53 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

#ifndef _XMLOFF_NUMBERSTYLESIMPORT_HXX
#include "XMLNumberStylesImport.hxx"
#endif

#ifndef _XMLOFF_XMLSTYLE_HXX
#include "xmlstyle.hxx"
#endif

#ifndef _XMLOFF_XMLTOKEN_HXX
#include "xmltoken.hxx"
#endif

#ifndef _XMLOFF_XMLSTYLE_HXX
#include "xmlstyle.hxx"
#endif

#ifndef _XMLOFF_XMLNMSPE_HXX
#include "xmlnmspe.hxx"
#endif

#ifndef _XIMPPAGE_HXX
#include "ximppage.hxx"
#endif

#ifndef _XIMPSHAPE_HXX
#include "ximpshap.hxx"
#endif

#ifndef _XMLOFF_ANIMIMP_HXX
#include "animimp.hxx"
#endif

#ifndef _XMLOFF_FORMSIMP_HXX
#include "formsimp.hxx"
#endif

#ifndef _XMLOFF_XMLICTXT_HXX
#include "xmlictxt.hxx"
#endif

#ifndef _XIMPSTYLE_HXX
#include "ximpstyl.hxx"
#endif

#ifndef _XMLOFF_PRSTYLEI_HXX_
#include "prstylei.hxx"
#endif

#ifndef _XMLOFF_PROPERTYSETMERGER_HXX_
#include "PropertySetMerger.hxx"
#endif

using namespace ::rtl;
using namespace ::com::sun::star;
using namespace ::xmloff::token;

using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::makeAny;

//////////////////////////////////////////////////////////////////////////////

TYPEINIT1( SdXMLGenericPageContext, SvXMLImportContext );

SdXMLGenericPageContext::SdXMLGenericPageContext(
    SvXMLImport& rImport,
    USHORT nPrfx, const OUString& rLocalName,
    const Reference< xml::sax::XAttributeList>&,
    Reference< drawing::XShapes >& rShapes)
:   SvXMLImportContext( rImport, nPrfx, rLocalName ),
    mxShapes( rShapes )
{
}

//////////////////////////////////////////////////////////////////////////////

SdXMLGenericPageContext::~SdXMLGenericPageContext()
{
}

//////////////////////////////////////////////////////////////////////////////

void SdXMLGenericPageContext::StartElement( const Reference< ::com::sun::star::xml::sax::XAttributeList >& )
{
    GetImport().GetShapeImport()->pushGroupForSorting( mxShapes );

#ifndef SVX_LIGHT
    if( GetImport().IsFormsSupported() )
        GetImport().GetFormImport()->startPage( Reference< drawing::XDrawPage >::query( mxShapes ) );
#endif
}

//////////////////////////////////////////////////////////////////////////////

SvXMLImportContext* SdXMLGenericPageContext::CreateChildContext( USHORT nPrefix,
    const OUString& rLocalName,
    const Reference< xml::sax::XAttributeList>& xAttrList )
{
    SvXMLImportContext* pContext = 0L;

    if( nPrefix == XML_NAMESPACE_PRESENTATION && IsXMLToken( rLocalName, XML_ANIMATIONS ) )
    {
        pContext = new XMLAnimationsContext( GetImport(), nPrefix, rLocalName, xAttrList );
    }
    else if( nPrefix == XML_NAMESPACE_OFFICE && IsXMLToken( rLocalName, XML_FORMS ) )
    {
#ifndef SVX_LIGHT
        if( GetImport().IsFormsSupported() )
            pContext = GetImport().GetFormImport()->createOfficeFormsContext( GetImport(), nPrefix, rLocalName );
#endif
    }
    else
    {
        // call GroupChildContext function at common ShapeImport
        pContext = GetImport().GetShapeImport()->CreateGroupChildContext(
            GetImport(), nPrefix, rLocalName, xAttrList, mxShapes);
    }

    // call parent when no own context was created
    if(!pContext)
        pContext = SvXMLImportContext::CreateChildContext(nPrefix, rLocalName, xAttrList);

    return pContext;
}

//////////////////////////////////////////////////////////////////////////////

void SdXMLGenericPageContext::EndElement()
{
    GetImport().GetShapeImport()->popGroupAndSort();

    if( GetImport().IsFormsSupported() )
        GetImport().GetFormImport()->endPage();

    if( maUseHeaderDeclName.getLength() || maUseFooterDeclName.getLength() || maUseDateTimeDeclName.getLength() )
    {
        try
        {
            Reference <beans::XPropertySet> xSet(mxShapes, uno::UNO_QUERY_THROW );
            Reference< beans::XPropertySetInfo > xInfo( xSet->getPropertySetInfo() );

            if( maUseHeaderDeclName.getLength() )
            {
                const OUString aStrHeaderTextProp( RTL_CONSTASCII_USTRINGPARAM( "HeaderText" ) );
                if( xInfo->hasPropertyByName( aStrHeaderTextProp ) )
                    xSet->setPropertyValue( aStrHeaderTextProp,
                                            makeAny( GetSdImport().GetHeaderDecl( maUseHeaderDeclName ) ) );
            }

            if( maUseFooterDeclName.getLength() )
            {
                const OUString aStrFooterTextProp( RTL_CONSTASCII_USTRINGPARAM( "FooterText" ) );
                if( xInfo->hasPropertyByName( aStrFooterTextProp ) )
                    xSet->setPropertyValue( aStrFooterTextProp,
                                        makeAny( GetSdImport().GetFooterDecl( maUseFooterDeclName ) ) );
            }

            if( maUseDateTimeDeclName.getLength() )
            {
                const OUString aStrDateTimeTextProp( RTL_CONSTASCII_USTRINGPARAM( "DateTimeText" ) );
                if( xInfo->hasPropertyByName( aStrDateTimeTextProp ) )
                {
                    sal_Bool bFixed;
                    OUString aDateTimeFormat;
                    const OUString aText( GetSdImport().GetDateTimeDecl( maUseDateTimeDeclName, bFixed, aDateTimeFormat ) );

                    xSet->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM("IsDateTimeFixed") ),
                                        makeAny( bFixed ) );

                    if( bFixed )
                    {
                        xSet->setPropertyValue( aStrDateTimeTextProp, makeAny( aText ) );
                    }
                    else if( aDateTimeFormat.getLength() )
                    {
                        const SdXMLStylesContext* pStyles = dynamic_cast< const SdXMLStylesContext* >( GetSdImport().GetShapeImport()->GetStylesContext() );
                        if( pStyles )
                        {
                            const SdXMLNumberFormatImportContext* pSdNumStyle =
                                dynamic_cast< const SdXMLNumberFormatImportContext* >( pStyles->FindStyleChildContext( XML_STYLE_FAMILY_DATA_STYLE, aDateTimeFormat, sal_True ) );

                            if( pSdNumStyle )
                            {
                                xSet->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM("DateTimeFormat") ),
                                                                    makeAny( pSdNumStyle->GetDrawKey() ) );
                            }
                        }
                    }
                }
            }
        }
        catch( uno::Exception& e )
        {
            (void)e;
            DBG_ERROR("xmloff::SdXMLGenericPageContext::EndElement(), unexpected exception cought!");
        }
    }
}

void SdXMLGenericPageContext::SetStyle( rtl::OUString& rStyleName )
{
    // set PageProperties?
    if(rStyleName.getLength())
    {
        try
        {
            const SvXMLImportContext* pContext = GetSdImport().GetShapeImport()->GetAutoStylesContext();

            if( pContext && pContext->ISA( SvXMLStyleContext ) )
            {
                const SdXMLStylesContext* pStyles = (SdXMLStylesContext*)pContext;
                if(pStyles)
                {
                    const SvXMLStyleContext* pStyle = pStyles->FindStyleChildContext(
                        XML_STYLE_FAMILY_SD_DRAWINGPAGE_ID, rStyleName);

                    if(pStyle && pStyle->ISA(XMLPropStyleContext))
                    {
                        XMLPropStyleContext* pPropStyle = (XMLPropStyleContext*)pStyle;

                        Reference <beans::XPropertySet> xPropSet1(mxShapes, uno::UNO_QUERY);
                        if(xPropSet1.is())
                        {
                            Reference< beans::XPropertySet > xPropSet( xPropSet1 );
                            Reference< beans::XPropertySet > xBackgroundSet;

                            const OUString aBackground(RTL_CONSTASCII_USTRINGPARAM("Background"));
                            if( xPropSet1->getPropertySetInfo()->hasPropertyByName( aBackground ) )
                            {
                                Reference< beans::XPropertySetInfo > xInfo( xPropSet1->getPropertySetInfo() );
                                if( xInfo.is() && xInfo->hasPropertyByName( aBackground ) )
                                {
                                    Reference< lang::XMultiServiceFactory > xServiceFact(GetSdImport().GetModel(), uno::UNO_QUERY);
                                    if(xServiceFact.is())
                                    {
                                        xBackgroundSet = Reference< beans::XPropertySet >::query(
                                            xServiceFact->createInstance(
                                            OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.Background"))));
                                    }
                                }

                                if( xBackgroundSet.is() )
                                    xPropSet = PropertySetMerger_CreateInstance( xPropSet1, xBackgroundSet );
                            }

                            if(xPropSet.is())
                            {
                                pPropStyle->FillPropertySet(xPropSet);

                                if( xBackgroundSet.is() )
                                    xPropSet1->setPropertyValue( aBackground, uno::makeAny( xBackgroundSet ) );
                            }
                        }
                    }
                }
            }
        }
        catch( uno::Exception )
        {
            DBG_ERROR( "SdXMLGenericPageContext::SetStyle(): uno::Exception catched!" );
        }
    }
}

void SdXMLGenericPageContext::SetLayout()
{
    // set PresentationPageLayout?
    if(GetSdImport().IsImpress() && maPageLayoutName.getLength())
    {
        sal_Int32 nType = -1;

        const SvXMLImportContext* pContext = GetSdImport().GetShapeImport()->GetStylesContext();

        if( pContext && pContext->ISA( SvXMLStyleContext ) )
        {
            const SdXMLStylesContext* pStyles = (SdXMLStylesContext*)pContext;
            if(pStyles)
            {
                const SvXMLStyleContext* pStyle = pStyles->FindStyleChildContext( XML_STYLE_FAMILY_SD_PRESENTATIONPAGELAYOUT_ID, maPageLayoutName);

                if(pStyle && pStyle->ISA(SdXMLPresentationPageLayoutContext))
                {
                    SdXMLPresentationPageLayoutContext* pLayout = (SdXMLPresentationPageLayoutContext*)pStyle;
                    nType = pLayout->GetTypeId();
                }
            }

        }
        if( -1 == nType )
        {
            Reference< container::XNameAccess > xPageLayouts( GetSdImport().getPageLayouts() );
            if( xPageLayouts.is() )
            {
                if( xPageLayouts->hasByName( maPageLayoutName ) )
                    xPageLayouts->getByName( maPageLayoutName ) >>= nType;
            }

        }

        if( -1 != nType )
        {
            Reference <beans::XPropertySet> xPropSet(mxShapes, uno::UNO_QUERY);
            if(xPropSet.is())
            {
                OUString aPropName(RTL_CONSTASCII_USTRINGPARAM("Layout"));
                Reference< beans::XPropertySetInfo > xInfo( xPropSet->getPropertySetInfo() );
                if( xInfo.is() && xInfo->hasPropertyByName( aPropName ) )
                    xPropSet->setPropertyValue(aPropName, uno::makeAny( (sal_Int16)nType ) );
            }
        }
    }
}

void SdXMLGenericPageContext::DeleteAllShapes()
{
    // now delete all up-to-now contained shapes; they have been created
    // when setting the presentation page layout.
    while(mxShapes->getCount())
    {
        Reference< drawing::XShape > xShape;
        uno::Any aAny(mxShapes->getByIndex(0L));

        aAny >>= xShape;

        if(xShape.is())
        {
            mxShapes->remove(xShape);
        }
    }
}

void SdXMLGenericPageContext::SetPageMaster( OUString& rsPageMasterName )
{
    if( GetSdImport().GetShapeImport()->GetStylesContext() )
    {
        // look for PageMaster with this name

        // #80012# GetStylesContext() replaced with GetAutoStylesContext()
        const SvXMLStylesContext* pAutoStyles = GetSdImport().GetShapeImport()->GetAutoStylesContext();

        const SvXMLStyleContext* pStyle = pAutoStyles ? pAutoStyles->FindStyleChildContext(XML_STYLE_FAMILY_SD_PAGEMASTERCONEXT_ID, rsPageMasterName) : NULL;

        if(pStyle && pStyle->ISA(SdXMLPageMasterContext))
        {
            const SdXMLPageMasterContext* pPageMaster = (SdXMLPageMasterContext*)pStyle;
            const SdXMLPageMasterStyleContext* pPageMasterContext = pPageMaster->GetPageMasterStyle();

            if(pPageMasterContext)
            {
                Reference< drawing::XDrawPage > xMasterPage(GetLocalShapesContext(), uno::UNO_QUERY);
                if(xMasterPage.is())
                {
                    // set sizes for this masterpage
                    Reference <beans::XPropertySet> xPropSet(xMasterPage, uno::UNO_QUERY);
                    if(xPropSet.is())
                    {
                        uno::Any aAny;

                        aAny <<= pPageMasterContext->GetBorderBottom();
                        xPropSet->setPropertyValue(
                            OUString(RTL_CONSTASCII_USTRINGPARAM("BorderBottom")), aAny);

                        aAny <<= pPageMasterContext->GetBorderLeft();
                        xPropSet->setPropertyValue(
                            OUString(RTL_CONSTASCII_USTRINGPARAM("BorderLeft")), aAny);

                        aAny <<= pPageMasterContext->GetBorderRight();
                        xPropSet->setPropertyValue(
                            OUString(RTL_CONSTASCII_USTRINGPARAM("BorderRight")), aAny);

                        aAny <<= pPageMasterContext->GetBorderTop();
                        xPropSet->setPropertyValue(
                            OUString(RTL_CONSTASCII_USTRINGPARAM("BorderTop")), aAny);

                        aAny <<= pPageMasterContext->GetWidth();
                        xPropSet->setPropertyValue(
                            OUString(RTL_CONSTASCII_USTRINGPARAM("Width")), aAny);

                        aAny <<= pPageMasterContext->GetHeight();
                        xPropSet->setPropertyValue(
                            OUString(RTL_CONSTASCII_USTRINGPARAM("Height")), aAny);

                        aAny <<= pPageMasterContext->GetOrientation();
                        xPropSet->setPropertyValue(
                            OUString(RTL_CONSTASCII_USTRINGPARAM("Orientation")), aAny);
                    }
                }
            }
        }

    }
}
<commit_msg>INTEGRATION: CWS pchfix02 (1.16.34); FILE MERGED 2006/09/01 17:59:37 kaib 1.16.34.1: #i68856# Added header markers and pch files<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: ximppage.cxx,v $
 *
 *  $Revision: 1.17 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 10:32:00 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_xmloff.hxx"

#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

#ifndef _XMLOFF_NUMBERSTYLESIMPORT_HXX
#include "XMLNumberStylesImport.hxx"
#endif

#ifndef _XMLOFF_XMLSTYLE_HXX
#include "xmlstyle.hxx"
#endif

#ifndef _XMLOFF_XMLTOKEN_HXX
#include "xmltoken.hxx"
#endif

#ifndef _XMLOFF_XMLSTYLE_HXX
#include "xmlstyle.hxx"
#endif

#ifndef _XMLOFF_XMLNMSPE_HXX
#include "xmlnmspe.hxx"
#endif

#ifndef _XIMPPAGE_HXX
#include "ximppage.hxx"
#endif

#ifndef _XIMPSHAPE_HXX
#include "ximpshap.hxx"
#endif

#ifndef _XMLOFF_ANIMIMP_HXX
#include "animimp.hxx"
#endif

#ifndef _XMLOFF_FORMSIMP_HXX
#include "formsimp.hxx"
#endif

#ifndef _XMLOFF_XMLICTXT_HXX
#include "xmlictxt.hxx"
#endif

#ifndef _XIMPSTYLE_HXX
#include "ximpstyl.hxx"
#endif

#ifndef _XMLOFF_PRSTYLEI_HXX_
#include "prstylei.hxx"
#endif

#ifndef _XMLOFF_PROPERTYSETMERGER_HXX_
#include "PropertySetMerger.hxx"
#endif

using namespace ::rtl;
using namespace ::com::sun::star;
using namespace ::xmloff::token;

using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::makeAny;

//////////////////////////////////////////////////////////////////////////////

TYPEINIT1( SdXMLGenericPageContext, SvXMLImportContext );

SdXMLGenericPageContext::SdXMLGenericPageContext(
    SvXMLImport& rImport,
    USHORT nPrfx, const OUString& rLocalName,
    const Reference< xml::sax::XAttributeList>&,
    Reference< drawing::XShapes >& rShapes)
:   SvXMLImportContext( rImport, nPrfx, rLocalName ),
    mxShapes( rShapes )
{
}

//////////////////////////////////////////////////////////////////////////////

SdXMLGenericPageContext::~SdXMLGenericPageContext()
{
}

//////////////////////////////////////////////////////////////////////////////

void SdXMLGenericPageContext::StartElement( const Reference< ::com::sun::star::xml::sax::XAttributeList >& )
{
    GetImport().GetShapeImport()->pushGroupForSorting( mxShapes );

#ifndef SVX_LIGHT
    if( GetImport().IsFormsSupported() )
        GetImport().GetFormImport()->startPage( Reference< drawing::XDrawPage >::query( mxShapes ) );
#endif
}

//////////////////////////////////////////////////////////////////////////////

SvXMLImportContext* SdXMLGenericPageContext::CreateChildContext( USHORT nPrefix,
    const OUString& rLocalName,
    const Reference< xml::sax::XAttributeList>& xAttrList )
{
    SvXMLImportContext* pContext = 0L;

    if( nPrefix == XML_NAMESPACE_PRESENTATION && IsXMLToken( rLocalName, XML_ANIMATIONS ) )
    {
        pContext = new XMLAnimationsContext( GetImport(), nPrefix, rLocalName, xAttrList );
    }
    else if( nPrefix == XML_NAMESPACE_OFFICE && IsXMLToken( rLocalName, XML_FORMS ) )
    {
#ifndef SVX_LIGHT
        if( GetImport().IsFormsSupported() )
            pContext = GetImport().GetFormImport()->createOfficeFormsContext( GetImport(), nPrefix, rLocalName );
#endif
    }
    else
    {
        // call GroupChildContext function at common ShapeImport
        pContext = GetImport().GetShapeImport()->CreateGroupChildContext(
            GetImport(), nPrefix, rLocalName, xAttrList, mxShapes);
    }

    // call parent when no own context was created
    if(!pContext)
        pContext = SvXMLImportContext::CreateChildContext(nPrefix, rLocalName, xAttrList);

    return pContext;
}

//////////////////////////////////////////////////////////////////////////////

void SdXMLGenericPageContext::EndElement()
{
    GetImport().GetShapeImport()->popGroupAndSort();

    if( GetImport().IsFormsSupported() )
        GetImport().GetFormImport()->endPage();

    if( maUseHeaderDeclName.getLength() || maUseFooterDeclName.getLength() || maUseDateTimeDeclName.getLength() )
    {
        try
        {
            Reference <beans::XPropertySet> xSet(mxShapes, uno::UNO_QUERY_THROW );
            Reference< beans::XPropertySetInfo > xInfo( xSet->getPropertySetInfo() );

            if( maUseHeaderDeclName.getLength() )
            {
                const OUString aStrHeaderTextProp( RTL_CONSTASCII_USTRINGPARAM( "HeaderText" ) );
                if( xInfo->hasPropertyByName( aStrHeaderTextProp ) )
                    xSet->setPropertyValue( aStrHeaderTextProp,
                                            makeAny( GetSdImport().GetHeaderDecl( maUseHeaderDeclName ) ) );
            }

            if( maUseFooterDeclName.getLength() )
            {
                const OUString aStrFooterTextProp( RTL_CONSTASCII_USTRINGPARAM( "FooterText" ) );
                if( xInfo->hasPropertyByName( aStrFooterTextProp ) )
                    xSet->setPropertyValue( aStrFooterTextProp,
                                        makeAny( GetSdImport().GetFooterDecl( maUseFooterDeclName ) ) );
            }

            if( maUseDateTimeDeclName.getLength() )
            {
                const OUString aStrDateTimeTextProp( RTL_CONSTASCII_USTRINGPARAM( "DateTimeText" ) );
                if( xInfo->hasPropertyByName( aStrDateTimeTextProp ) )
                {
                    sal_Bool bFixed;
                    OUString aDateTimeFormat;
                    const OUString aText( GetSdImport().GetDateTimeDecl( maUseDateTimeDeclName, bFixed, aDateTimeFormat ) );

                    xSet->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM("IsDateTimeFixed") ),
                                        makeAny( bFixed ) );

                    if( bFixed )
                    {
                        xSet->setPropertyValue( aStrDateTimeTextProp, makeAny( aText ) );
                    }
                    else if( aDateTimeFormat.getLength() )
                    {
                        const SdXMLStylesContext* pStyles = dynamic_cast< const SdXMLStylesContext* >( GetSdImport().GetShapeImport()->GetStylesContext() );
                        if( pStyles )
                        {
                            const SdXMLNumberFormatImportContext* pSdNumStyle =
                                dynamic_cast< const SdXMLNumberFormatImportContext* >( pStyles->FindStyleChildContext( XML_STYLE_FAMILY_DATA_STYLE, aDateTimeFormat, sal_True ) );

                            if( pSdNumStyle )
                            {
                                xSet->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM("DateTimeFormat") ),
                                                                    makeAny( pSdNumStyle->GetDrawKey() ) );
                            }
                        }
                    }
                }
            }
        }
        catch( uno::Exception& e )
        {
            (void)e;
            DBG_ERROR("xmloff::SdXMLGenericPageContext::EndElement(), unexpected exception cought!");
        }
    }
}

void SdXMLGenericPageContext::SetStyle( rtl::OUString& rStyleName )
{
    // set PageProperties?
    if(rStyleName.getLength())
    {
        try
        {
            const SvXMLImportContext* pContext = GetSdImport().GetShapeImport()->GetAutoStylesContext();

            if( pContext && pContext->ISA( SvXMLStyleContext ) )
            {
                const SdXMLStylesContext* pStyles = (SdXMLStylesContext*)pContext;
                if(pStyles)
                {
                    const SvXMLStyleContext* pStyle = pStyles->FindStyleChildContext(
                        XML_STYLE_FAMILY_SD_DRAWINGPAGE_ID, rStyleName);

                    if(pStyle && pStyle->ISA(XMLPropStyleContext))
                    {
                        XMLPropStyleContext* pPropStyle = (XMLPropStyleContext*)pStyle;

                        Reference <beans::XPropertySet> xPropSet1(mxShapes, uno::UNO_QUERY);
                        if(xPropSet1.is())
                        {
                            Reference< beans::XPropertySet > xPropSet( xPropSet1 );
                            Reference< beans::XPropertySet > xBackgroundSet;

                            const OUString aBackground(RTL_CONSTASCII_USTRINGPARAM("Background"));
                            if( xPropSet1->getPropertySetInfo()->hasPropertyByName( aBackground ) )
                            {
                                Reference< beans::XPropertySetInfo > xInfo( xPropSet1->getPropertySetInfo() );
                                if( xInfo.is() && xInfo->hasPropertyByName( aBackground ) )
                                {
                                    Reference< lang::XMultiServiceFactory > xServiceFact(GetSdImport().GetModel(), uno::UNO_QUERY);
                                    if(xServiceFact.is())
                                    {
                                        xBackgroundSet = Reference< beans::XPropertySet >::query(
                                            xServiceFact->createInstance(
                                            OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.Background"))));
                                    }
                                }

                                if( xBackgroundSet.is() )
                                    xPropSet = PropertySetMerger_CreateInstance( xPropSet1, xBackgroundSet );
                            }

                            if(xPropSet.is())
                            {
                                pPropStyle->FillPropertySet(xPropSet);

                                if( xBackgroundSet.is() )
                                    xPropSet1->setPropertyValue( aBackground, uno::makeAny( xBackgroundSet ) );
                            }
                        }
                    }
                }
            }
        }
        catch( uno::Exception )
        {
            DBG_ERROR( "SdXMLGenericPageContext::SetStyle(): uno::Exception catched!" );
        }
    }
}

void SdXMLGenericPageContext::SetLayout()
{
    // set PresentationPageLayout?
    if(GetSdImport().IsImpress() && maPageLayoutName.getLength())
    {
        sal_Int32 nType = -1;

        const SvXMLImportContext* pContext = GetSdImport().GetShapeImport()->GetStylesContext();

        if( pContext && pContext->ISA( SvXMLStyleContext ) )
        {
            const SdXMLStylesContext* pStyles = (SdXMLStylesContext*)pContext;
            if(pStyles)
            {
                const SvXMLStyleContext* pStyle = pStyles->FindStyleChildContext( XML_STYLE_FAMILY_SD_PRESENTATIONPAGELAYOUT_ID, maPageLayoutName);

                if(pStyle && pStyle->ISA(SdXMLPresentationPageLayoutContext))
                {
                    SdXMLPresentationPageLayoutContext* pLayout = (SdXMLPresentationPageLayoutContext*)pStyle;
                    nType = pLayout->GetTypeId();
                }
            }

        }
        if( -1 == nType )
        {
            Reference< container::XNameAccess > xPageLayouts( GetSdImport().getPageLayouts() );
            if( xPageLayouts.is() )
            {
                if( xPageLayouts->hasByName( maPageLayoutName ) )
                    xPageLayouts->getByName( maPageLayoutName ) >>= nType;
            }

        }

        if( -1 != nType )
        {
            Reference <beans::XPropertySet> xPropSet(mxShapes, uno::UNO_QUERY);
            if(xPropSet.is())
            {
                OUString aPropName(RTL_CONSTASCII_USTRINGPARAM("Layout"));
                Reference< beans::XPropertySetInfo > xInfo( xPropSet->getPropertySetInfo() );
                if( xInfo.is() && xInfo->hasPropertyByName( aPropName ) )
                    xPropSet->setPropertyValue(aPropName, uno::makeAny( (sal_Int16)nType ) );
            }
        }
    }
}

void SdXMLGenericPageContext::DeleteAllShapes()
{
    // now delete all up-to-now contained shapes; they have been created
    // when setting the presentation page layout.
    while(mxShapes->getCount())
    {
        Reference< drawing::XShape > xShape;
        uno::Any aAny(mxShapes->getByIndex(0L));

        aAny >>= xShape;

        if(xShape.is())
        {
            mxShapes->remove(xShape);
        }
    }
}

void SdXMLGenericPageContext::SetPageMaster( OUString& rsPageMasterName )
{
    if( GetSdImport().GetShapeImport()->GetStylesContext() )
    {
        // look for PageMaster with this name

        // #80012# GetStylesContext() replaced with GetAutoStylesContext()
        const SvXMLStylesContext* pAutoStyles = GetSdImport().GetShapeImport()->GetAutoStylesContext();

        const SvXMLStyleContext* pStyle = pAutoStyles ? pAutoStyles->FindStyleChildContext(XML_STYLE_FAMILY_SD_PAGEMASTERCONEXT_ID, rsPageMasterName) : NULL;

        if(pStyle && pStyle->ISA(SdXMLPageMasterContext))
        {
            const SdXMLPageMasterContext* pPageMaster = (SdXMLPageMasterContext*)pStyle;
            const SdXMLPageMasterStyleContext* pPageMasterContext = pPageMaster->GetPageMasterStyle();

            if(pPageMasterContext)
            {
                Reference< drawing::XDrawPage > xMasterPage(GetLocalShapesContext(), uno::UNO_QUERY);
                if(xMasterPage.is())
                {
                    // set sizes for this masterpage
                    Reference <beans::XPropertySet> xPropSet(xMasterPage, uno::UNO_QUERY);
                    if(xPropSet.is())
                    {
                        uno::Any aAny;

                        aAny <<= pPageMasterContext->GetBorderBottom();
                        xPropSet->setPropertyValue(
                            OUString(RTL_CONSTASCII_USTRINGPARAM("BorderBottom")), aAny);

                        aAny <<= pPageMasterContext->GetBorderLeft();
                        xPropSet->setPropertyValue(
                            OUString(RTL_CONSTASCII_USTRINGPARAM("BorderLeft")), aAny);

                        aAny <<= pPageMasterContext->GetBorderRight();
                        xPropSet->setPropertyValue(
                            OUString(RTL_CONSTASCII_USTRINGPARAM("BorderRight")), aAny);

                        aAny <<= pPageMasterContext->GetBorderTop();
                        xPropSet->setPropertyValue(
                            OUString(RTL_CONSTASCII_USTRINGPARAM("BorderTop")), aAny);

                        aAny <<= pPageMasterContext->GetWidth();
                        xPropSet->setPropertyValue(
                            OUString(RTL_CONSTASCII_USTRINGPARAM("Width")), aAny);

                        aAny <<= pPageMasterContext->GetHeight();
                        xPropSet->setPropertyValue(
                            OUString(RTL_CONSTASCII_USTRINGPARAM("Height")), aAny);

                        aAny <<= pPageMasterContext->GetOrientation();
                        xPropSet->setPropertyValue(
                            OUString(RTL_CONSTASCII_USTRINGPARAM("Orientation")), aAny);
                    }
                }
            }
        }

    }
}
<|endoftext|>