<commit_before>#include <cassert>

#include "operators.h"

namespace ad {

static void AddBackprop(Var& val, Var* lhs, Var* rhs) {
    lhs->derivative() += val.derivative();
    rhs->derivative() += val.derivative();
}

Var operator+(const Var& v1, const Var& v2) {
    return v1.graph()->CreateNode(v1.value() + v2.value(), v1, v2, AddBackprop);
}

static void SubBackprop(Var& val, Var* lhs, Var* rhs) {
    lhs->derivative() += val.derivative();
    rhs->derivative() -= val.derivative();
}

Var operator-(const Var& v1, const Var& v2) {
    return v1.graph()->CreateNode(v1.value() - v2.value(), v1, v2, SubBackprop);
}

Var operator-(double a, const Var& v1) {
    Eigen::MatrixXd coeff(1, 1);
    coeff << a;
    Var coeff_var = v1.graph()->CreateParam(coeff);
    return v1.graph()->CreateNode(
            v1.value().array() - a, v1, coeff_var, SubBackprop);
}

Var operator-(const Var& v1, double a) {
    Eigen::MatrixXd coeff(1, 1);
    coeff << a;
    Var coeff_var = v1.graph()->CreateParam(coeff);
    return v1.graph()->CreateNode(
            a - v1.value().array(), v1, coeff_var, SubBackprop);
}

static void MulBackprop(Var& val, Var* lhs, Var* rhs) {
    lhs->derivative() +=  val.derivative() * rhs->value().transpose();
    rhs->derivative() +=  lhs->value().transpose() * val.derivative();
}

Var operator*(const Var& v1, const Var& v2) {
    return v1.graph()->CreateNode(v1.value() * v2.value(), v1, v2, MulBackprop);
}

static void CoeffMulBackprop(Var& val, Var* lhs, Var* rhs) {
    lhs->derivative() +=  val.derivative() * rhs->value()(0, 0);
}

Var operator*(double a, const Var& v1) {
    Eigen::MatrixXd coeff(1, 1);
    coeff << a;
    Var coeff_var = v1.graph()->CreateParam(coeff);
    return v1.graph()->CreateNode(v1.value() * a, v1, coeff_var, CoeffMulBackprop);
}

Var operator*(const Var& v1, double a) {
    Eigen::MatrixXd coeff(1, 1);
    coeff << a;
    Var coeff_var = v1.graph()->CreateParam(coeff);
    return v1.graph()->CreateNode(v1.value() * a, v1, coeff_var, CoeffMulBackprop);
}

static void ReluBackprop(Var& val, Var* lhs, Var*) {
    double* da = lhs->derivative().data();
    const double* a = lhs->value().data();
    double* db = val.derivative().data();
    for (int i = 0; i < lhs->derivative().size(); ++i) {
        da[i] += a[i] > 0 ? db[i] : 0;
    }
}

Var Relu(const Var& v1) {
    return v1.graph()->CreateNode(
            v1.value().array().max(0), v1, no_operand, ReluBackprop);
}

static void SquareBackprop(Var& val, Var* lhs, Var*) {
    lhs->derivative() += 2 * val.derivative() * lhs->value();
}

Var Square(const Var& v1) {
    return v1.graph()->CreateNode(
            v1.value() * v1.value(), v1, no_operand, SquareBackprop);
}

static void EltSquareBackprop(Var& val, Var* lhs, Var*) {
    lhs->derivative() += 2 * val.derivative().cwiseProduct(lhs->value());
}

Var EltSquare(const Var& v1) {
    return v1.graph()->CreateNode(
            v1.value().cwiseProduct(v1.value()), v1, no_operand, EltSquareBackprop);
}

static void EltwiseMulBackprop(Var& val, Var* lhs, Var* rhs) {
    lhs->derivative() += val.derivative().cwiseProduct(rhs->value());
    rhs->derivative() += val.derivative().cwiseProduct(lhs->value());
}

Var operator^(const Var& v1, const Var& v2) {
    return v1.graph()->CreateNode(
            v1.value().cwiseProduct(v2.value()), v1, v2, EltwiseMulBackprop);
}

static void LogBackprop(Var& val, Var* lhs, Var*) {
    double* da = lhs->derivative().data();
    double* dx = val.derivative().data();
    const double* a = lhs->value().data();
    for (int i = 0; i < val.value().size(); ++i) {
        da[i] += dx[i] / a[i];
    }
}

Var Log(const Var& x) {
    Eigen::MatrixXd res(x.value().rows(), x.value().cols());
    double* dst_ptr = res.data();
    const double* src_ptr = x.value().data();
    for (int i = 0; i < res.size(); ++i) {
        dst_ptr[i] = log(src_ptr[i]);
    }
    return x.graph()->CreateNode(res, x, no_operand, LogBackprop);
}

static void NLogBackprop(Var& val, Var* lhs, Var*) {
    double* da = lhs->derivative().data();
    double* dx = val.derivative().data();
    const double* a = lhs->value().data();
    for (int i = 0, size = val.value().size(); i < size; ++i) {
        da[i] += -dx[i] / (a[i]);
    }
}

Var NLog(const Var& x) {
    Eigen::MatrixXd res(x.value().rows(), x.value().cols());
    double* dst_ptr = res.data();
    const double* src_ptr = x.value().data();
    for (int i = 0; i < res.size(); ++i) {
        dst_ptr[i] = -log(src_ptr[i]);
    }
    return x.graph()->CreateNode(res, x, no_operand, NLogBackprop);
}

Var CrossEntropy(const Var& h, const Var& y) {
    return Sum(y ^ NLog(h));
}

static Eigen::MatrixXd Softmax(const Eigen::MatrixXd& x) {
    Eigen::MatrixXd res(x.rows(), x.cols());
    double* dst_ptr = res.data();
    const double* src_ptr = x.data();
    double total = 0;
    for (int i = 0; i < res.size(); ++i) {
        dst_ptr[i] = exp(src_ptr[i]);
        total += dst_ptr[i];
    }

    for (int i = 0; i < res.size(); ++i) {
        dst_ptr[i] /= total;
    }
    return res;
}

static void SoftmaxLossBackprop(Var& val, Var* lhs, Var* rhs) {
    lhs->derivative() += val.derivative().cwiseProduct(
            Softmax(lhs->value()) - rhs->value());
}

Var SoftmaxLoss(Var h, Var y) {
    auto res = Softmax(h.value());

    double* d = res.data();
    double* dy = y.value().data();
    for (size_t i = 0, len = res.size(); i < len; ++i) {
        if (dy[i] != 0.0) {
            d[i] = -dy[i] * log(d[i]);
        }
    }
    return h.graph()->CreateNode(res, h, y, SoftmaxLossBackprop);
}

static void ExpBackprop(Var& val, Var* lhs, Var*) {
    double* da = lhs->derivative().data();
    const double* dx = val.derivative().data();
    const double* a = lhs->value().data();
    for (int i = 0; i < val.value().size(); ++i) {
        da[i] += dx[i] * exp(a[i]);
    }
}

Var Exp(const Var& x) {
    Eigen::MatrixXd res(x.value().rows(), x.value().cols());
    double* dst_ptr = res.data();
    const double* src_ptr = x.value().data();
    for (int i = 0; i < res.size(); ++i) {
        dst_ptr[i] = exp(src_ptr[i]);
    }
    return x.graph()->CreateNode(res, x, no_operand, ExpBackprop);
}

static void SoftmaxBackprop(Var& val, Var* lhs, Var*) {
    double* da = lhs->derivative().data();
    const double* dx = val.derivative().data();
    const double* a = val.value().data();
    size_t len = val.value().size();
    for (size_t i = 0; i < len; ++i) {
        double d = 0;
        for (size_t j = 0; j < len; ++j) {
            d += a[i] * (((i == j) ? 1 : 0) - a[j]) * dx[j];
        }
        da[i] += d;
    }
}

Var Softmax(const Var& x) {
    return x.graph()->CreateNode(
            Softmax(x.value()), x, no_operand, SoftmaxBackprop);
}

static void SigmoidBackprop(Var& val, Var* lhs, Var*) {
    const Eigen::MatrixXd& a = val.value();
    lhs->derivative() += val.derivative()
        .cwiseProduct((a.array() * (1.0 - a.array())).matrix());
}

Var Sigmoid(const Var& x) {
    Eigen::MatrixXd res(x.value().rows(), x.value().cols());
    double* dst_ptr = res.data();
    const double* src_ptr = x.value().data();
    for (int i = 0; i < res.size(); ++i) {
        dst_ptr[i] = 1.0 / (1 + exp(-src_ptr[i]));
    }

    return x.graph()->CreateNode(res, x, no_operand, SigmoidBackprop);
}

static void SumBackprop(Var& val, Var* lhs, Var*) {
    lhs->derivative().array() += (double)val.derivative()(0, 0);
}

Var Sum(const Var& a) {
    Eigen::MatrixXd res(1, 1);
    res << a.value().sum();
    return a.graph()->CreateNode(res, a, no_operand, SumBackprop);
}

static void MeanBackprop(Var& val, Var* lhs, Var*) {
    lhs->derivative().array() +=
        (double)val.derivative()(0, 0) / val.value().size();
}

Var Mean(const Var& a) {
    Eigen::MatrixXd res(1, 1);
    res << a.value().sum() / a.value().size();
    return a.graph()->CreateNode(res, a, no_operand, MeanBackprop);
}

Var MSE(const Var& h, const Var& y) {
    return Mean(EltSquare(h - y));
}

Var SSE(const Var& h, const Var& y) {
    return Sum(EltSquare(h - y));
}

static void NthColBackprop(Var& val, Var* lhs, Var* rhs) {
    lhs->derivative().col(rhs->value()(0, 0)) += val.derivative();
}

Var NthCol(const Var& w, int n) {
    Eigen::MatrixXd n_mat(1, 1);
    n_mat << n;
    Var n_var = w.graph()->CreateParam(n_mat);
    return w.graph()->CreateNode(w.value().col(n), w, n_var, NthColBackprop);
}

static void TanhBackprop(Var& val, Var* lhs, Var*) {
    double* da = lhs->derivative().data();
    const double* dx = val.derivative().data();
    const double* a = lhs->value().data();
    for (int i = 0; i < val.value().size(); ++i) {
        double denom = std::cosh(2 * a[i]) + 1;
        denom = denom * denom;
        if (std::isfinite(denom)) {
            double num = std::cosh(a[i]);
            num = 4 * num * num;
            double res = num / denom;
            da[i] += dx[i] * res;
        }
    }
}

Var Tanh(const Var& x) {
    Eigen::MatrixXd res(x.value().rows(), x.value().cols());
    double* dst_ptr = res.data();
    const double* src_ptr = x.value().data();
    for (int i = 0; i < res.size(); ++i) {
        dst_ptr[i] = std::tanh(src_ptr[i]);
    }

    return x.graph()->CreateNode(res, x, no_operand, TanhBackprop);
}

static void ColAppendBackprop(Var& val, Var* lhs, Var* rhs) {
    lhs->derivative() += val.derivative().block(0, 0, lhs->derivative().rows(), 1);
    rhs->derivative() += val.derivative().block(
            lhs->derivative().rows(), 0, rhs->derivative().rows(), 1);
}

Var ColAppend(Var x, Var y) {
    if (x.value().cols() != 1 || y.value().cols() != 1) {
        throw std::runtime_error("cannot append not-a-column-vectors");
    }

    Eigen::MatrixXd cated(x.value().rows() + y.value().rows(), 1);
    cated << x.value(), y.value();
    return x.graph()->CreateNode(cated, x, y, ColAppendBackprop);
}

}
<commit_msg>fix litterals with operator-<commit_after>#include <cassert>

#include "operators.h"

namespace ad {

static void AddBackprop(Var& val, Var* lhs, Var* rhs) {
    lhs->derivative() += val.derivative();
    rhs->derivative() += val.derivative();
}

Var operator+(const Var& v1, const Var& v2) {
    return v1.graph()->CreateNode(v1.value() + v2.value(), v1, v2, AddBackprop);
}

static void SubBackprop(Var& val, Var* lhs, Var* rhs) {
    lhs->derivative() += val.derivative();
    rhs->derivative() -= val.derivative();
}

Var operator-(const Var& v1, const Var& v2) {
    return v1.graph()->CreateNode(v1.value() - v2.value(), v1, v2, SubBackprop);
}

Var operator-(double a, const Var& v1) {
    Eigen::MatrixXd coeff(v1.value().rows(), v1.value().cols());
    coeff.setConstant(a);
    Var coeff_var = v1.graph()->CreateParam(coeff);
    return v1.graph()->CreateNode(
            a - v1.value().array(), coeff_var, v1, SubBackprop);
}

Var operator-(const Var& v1, double a) {
    Eigen::MatrixXd coeff(v1.value().rows(), v1.value().cols());
    coeff.setConstant(a);
    Var coeff_var = v1.graph()->CreateParam(coeff);
    return v1.graph()->CreateNode(
            v1.value().array() - a, v1, coeff_var, SubBackprop);
}

static void MulBackprop(Var& val, Var* lhs, Var* rhs) {
    lhs->derivative() +=  val.derivative() * rhs->value().transpose();
    rhs->derivative() +=  lhs->value().transpose() * val.derivative();
}

Var operator*(const Var& v1, const Var& v2) {
    return v1.graph()->CreateNode(v1.value() * v2.value(), v1, v2, MulBackprop);
}

static void CoeffMulBackprop(Var& val, Var* lhs, Var* rhs) {
    lhs->derivative() +=  val.derivative() * rhs->value()(0, 0);
}

Var operator*(double a, const Var& v1) {
    Eigen::MatrixXd coeff(1, 1);
    coeff << a;
    Var coeff_var = v1.graph()->CreateParam(coeff);
    return v1.graph()->CreateNode(v1.value() * a, v1, coeff_var, CoeffMulBackprop);
}

Var operator*(const Var& v1, double a) {
    Eigen::MatrixXd coeff(1, 1);
    coeff << a;
    Var coeff_var = v1.graph()->CreateParam(coeff);
    return v1.graph()->CreateNode(v1.value() * a, v1, coeff_var, CoeffMulBackprop);
}

static void ReluBackprop(Var& val, Var* lhs, Var*) {
    double* da = lhs->derivative().data();
    const double* a = lhs->value().data();
    double* db = val.derivative().data();
    for (int i = 0; i < lhs->derivative().size(); ++i) {
        da[i] += a[i] > 0 ? db[i] : 0;
    }
}

Var Relu(const Var& v1) {
    return v1.graph()->CreateNode(
            v1.value().array().max(0), v1, no_operand, ReluBackprop);
}

static void SquareBackprop(Var& val, Var* lhs, Var*) {
    lhs->derivative() += 2 * val.derivative() * lhs->value();
}

Var Square(const Var& v1) {
    return v1.graph()->CreateNode(
            v1.value() * v1.value(), v1, no_operand, SquareBackprop);
}

static void EltSquareBackprop(Var& val, Var* lhs, Var*) {
    lhs->derivative() += 2 * val.derivative().cwiseProduct(lhs->value());
}

Var EltSquare(const Var& v1) {
    return v1.graph()->CreateNode(
            v1.value().cwiseProduct(v1.value()), v1, no_operand, EltSquareBackprop);
}

static void EltwiseMulBackprop(Var& val, Var* lhs, Var* rhs) {
    lhs->derivative() += val.derivative().cwiseProduct(rhs->value());
    rhs->derivative() += val.derivative().cwiseProduct(lhs->value());
}

Var operator^(const Var& v1, const Var& v2) {
    return v1.graph()->CreateNode(
            v1.value().cwiseProduct(v2.value()), v1, v2, EltwiseMulBackprop);
}

static void LogBackprop(Var& val, Var* lhs, Var*) {
    double* da = lhs->derivative().data();
    double* dx = val.derivative().data();
    const double* a = lhs->value().data();
    for (int i = 0; i < val.value().size(); ++i) {
        da[i] += dx[i] / a[i];
    }
}

Var Log(const Var& x) {
    Eigen::MatrixXd res(x.value().rows(), x.value().cols());
    double* dst_ptr = res.data();
    const double* src_ptr = x.value().data();
    for (int i = 0; i < res.size(); ++i) {
        dst_ptr[i] = log(src_ptr[i]);
    }
    return x.graph()->CreateNode(res, x, no_operand, LogBackprop);
}

static void NLogBackprop(Var& val, Var* lhs, Var*) {
    double* da = lhs->derivative().data();
    double* dx = val.derivative().data();
    const double* a = lhs->value().data();
    for (int i = 0, size = val.value().size(); i < size; ++i) {
        da[i] += -dx[i] / (a[i]);
    }
}

Var NLog(const Var& x) {
    Eigen::MatrixXd res(x.value().rows(), x.value().cols());
    double* dst_ptr = res.data();
    const double* src_ptr = x.value().data();
    for (int i = 0; i < res.size(); ++i) {
        dst_ptr[i] = -log(src_ptr[i]);
    }
    return x.graph()->CreateNode(res, x, no_operand, NLogBackprop);
}

Var CrossEntropy(const Var& h, const Var& y) {
    return Sum(y ^ NLog(h));
}

static Eigen::MatrixXd Softmax(const Eigen::MatrixXd& x) {
    Eigen::MatrixXd res(x.rows(), x.cols());
    double* dst_ptr = res.data();
    const double* src_ptr = x.data();
    double total = 0;
    for (int i = 0; i < res.size(); ++i) {
        dst_ptr[i] = exp(src_ptr[i]);
        total += dst_ptr[i];
    }

    for (int i = 0; i < res.size(); ++i) {
        dst_ptr[i] /= total;
    }
    return res;
}

static void SoftmaxLossBackprop(Var& val, Var* lhs, Var* rhs) {
    lhs->derivative() += val.derivative().cwiseProduct(
            Softmax(lhs->value()) - rhs->value());
}

Var SoftmaxLoss(Var h, Var y) {
    auto res = Softmax(h.value());

    double* d = res.data();
    double* dy = y.value().data();
    for (size_t i = 0, len = res.size(); i < len; ++i) {
        if (dy[i] != 0.0) {
            d[i] = -dy[i] * log(d[i]);
        }
    }
    return h.graph()->CreateNode(res, h, y, SoftmaxLossBackprop);
}

static void ExpBackprop(Var& val, Var* lhs, Var*) {
    double* da = lhs->derivative().data();
    const double* dx = val.derivative().data();
    const double* a = lhs->value().data();
    for (int i = 0; i < val.value().size(); ++i) {
        da[i] += dx[i] * exp(a[i]);
    }
}

Var Exp(const Var& x) {
    Eigen::MatrixXd res(x.value().rows(), x.value().cols());
    double* dst_ptr = res.data();
    const double* src_ptr = x.value().data();
    for (int i = 0; i < res.size(); ++i) {
        dst_ptr[i] = exp(src_ptr[i]);
    }
    return x.graph()->CreateNode(res, x, no_operand, ExpBackprop);
}

static void SoftmaxBackprop(Var& val, Var* lhs, Var*) {
    double* da = lhs->derivative().data();
    const double* dx = val.derivative().data();
    const double* a = val.value().data();
    size_t len = val.value().size();
    for (size_t i = 0; i < len; ++i) {
        double d = 0;
        for (size_t j = 0; j < len; ++j) {
            d += a[i] * (((i == j) ? 1 : 0) - a[j]) * dx[j];
        }
        da[i] += d;
    }
}

Var Softmax(const Var& x) {
    return x.graph()->CreateNode(
            Softmax(x.value()), x, no_operand, SoftmaxBackprop);
}

static void SigmoidBackprop(Var& val, Var* lhs, Var*) {
    const Eigen::MatrixXd& a = val.value();
    lhs->derivative() += val.derivative()
        .cwiseProduct((a.array() * (1.0 - a.array())).matrix());
}

Var Sigmoid(const Var& x) {
    Eigen::MatrixXd res(x.value().rows(), x.value().cols());
    double* dst_ptr = res.data();
    const double* src_ptr = x.value().data();
    for (int i = 0; i < res.size(); ++i) {
        dst_ptr[i] = 1.0 / (1 + exp(-src_ptr[i]));
    }

    return x.graph()->CreateNode(res, x, no_operand, SigmoidBackprop);
}

static void SumBackprop(Var& val, Var* lhs, Var*) {
    lhs->derivative().array() += (double)val.derivative()(0, 0);
}

Var Sum(const Var& a) {
    Eigen::MatrixXd res(1, 1);
    res << a.value().sum();
    return a.graph()->CreateNode(res, a, no_operand, SumBackprop);
}

static void MeanBackprop(Var& val, Var* lhs, Var*) {
    lhs->derivative().array() +=
        (double)val.derivative()(0, 0) / val.value().size();
}

Var Mean(const Var& a) {
    Eigen::MatrixXd res(1, 1);
    res << a.value().sum() / a.value().size();
    return a.graph()->CreateNode(res, a, no_operand, MeanBackprop);
}

Var MSE(const Var& h, const Var& y) {
    return Mean(EltSquare(h - y));
}

Var SSE(const Var& h, const Var& y) {
    return Sum(EltSquare(h - y));
}

static void NthColBackprop(Var& val, Var* lhs, Var* rhs) {
    lhs->derivative().col(rhs->value()(0, 0)) += val.derivative();
}

Var NthCol(const Var& w, int n) {
    Eigen::MatrixXd n_mat(1, 1);
    n_mat << n;
    Var n_var = w.graph()->CreateParam(n_mat);
    return w.graph()->CreateNode(w.value().col(n), w, n_var, NthColBackprop);
}

static void TanhBackprop(Var& val, Var* lhs, Var*) {
    double* da = lhs->derivative().data();
    const double* dx = val.derivative().data();
    const double* a = lhs->value().data();
    for (int i = 0; i < val.value().size(); ++i) {
        double denom = std::cosh(2 * a[i]) + 1;
        denom = denom * denom;
        if (std::isfinite(denom)) {
            double num = std::cosh(a[i]);
            num = 4 * num * num;
            double res = num / denom;
            da[i] += dx[i] * res;
        }
    }
}

Var Tanh(const Var& x) {
    Eigen::MatrixXd res(x.value().rows(), x.value().cols());
    double* dst_ptr = res.data();
    const double* src_ptr = x.value().data();
    for (int i = 0; i < res.size(); ++i) {
        dst_ptr[i] = std::tanh(src_ptr[i]);
    }

    return x.graph()->CreateNode(res, x, no_operand, TanhBackprop);
}

static void ColAppendBackprop(Var& val, Var* lhs, Var* rhs) {
    lhs->derivative() += val.derivative().block(0, 0, lhs->derivative().rows(), 1);
    rhs->derivative() += val.derivative().block(
            lhs->derivative().rows(), 0, rhs->derivative().rows(), 1);
}

Var ColAppend(Var x, Var y) {
    if (x.value().cols() != 1 || y.value().cols() != 1) {
        throw std::runtime_error("cannot append not-a-column-vectors");
    }

    Eigen::MatrixXd cated(x.value().rows() + y.value().rows(), 1);
    cated << x.value(), y.value();
    return x.graph()->CreateNode(cated, x, y, ColAppendBackprop);
}

}
<|endoftext|>


<commit_before>/*
 * fMBT, free Model Based Testing tool
 * Copyright (c) 2011, Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU Lesser General Public License,
 * version 2.1, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope 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 program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */
#include "adapter_model.hh"
#include "helper.hh"
#include <cstdio>
#include <sstream>
#include <cstdlib>

Adapter_model::Adapter_model(Log& l, std::string params) :
  Adapter::Adapter(l)
{
  model = ModelFactory::create(log, filetype(params),"");
  model->load(params);
  model->reset();
}

bool Adapter_model::init()
{
  std::vector<std::string>& mactions=model->getActionNames();
  adapter2model.resize(actions->size());
  for(unsigned i = 0; i < actions->size(); i++) {
      adapter2model[i]=find(mactions, (*actions)[i]);
  }
  adapter2model.resize(mactions.size());
  for(unsigned i = 0; i < mactions.size(); i++) {
    model2adapter[i]=find(*actions, mactions[i]);
  }
  return true;
}

std::string Adapter_model::stringify()
{
  std::ostringstream t(std::ios::out | std::ios::binary);

  std::string s=model->stringify();

  t << "model:" << capsulate(s) << std::endl;

  return t.str();
}

/* adapter can execute.. */
void Adapter_model::execute(std::vector<int> &action)
{
  log.push("Adapter_model");

  log.print("<action type=\"input\" name=\"%s\"/>",
	    getUActionName(action[0]));

  if (!model->execute(adapter2model[action[0]])) {
    action[0]=0;
  }

  log.pop();
}

bool Adapter_model::observe(std::vector<int> &action,bool block)
{
  int* act,*iact;
  int actions=-model->getIActions(&iact)+model->getActions(&act);
  int i=1+random()%actions;
  int a;
  if (!actions) {
    return false;
  }
  a=-1;
  while (i) {
    a++;
    while (!model->is_output(act[a])) {
      i--;
    }
  }
  action.resize(1);
  action[0]=act[a];
  return true;
}

FACTORY_DEFAULT_CREATOR(Adapter, Adapter_model, "model")
<commit_msg>adapter_model.cc: Missing/erroneous (re)initialisation of an attribute fixed.<commit_after>/*
 * fMBT, free Model Based Testing tool
 * Copyright (c) 2011, Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU Lesser General Public License,
 * version 2.1, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope 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 program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */
#include "adapter_model.hh"
#include "helper.hh"
#include <cstdio>
#include <sstream>
#include <cstdlib>

Adapter_model::Adapter_model(Log& l, std::string params) :
  Adapter::Adapter(l)
{
  model = ModelFactory::create(log, filetype(params),"");
  model->load(params);
  model->reset();
}

bool Adapter_model::init()
{
  std::vector<std::string>& mactions=model->getActionNames();
  adapter2model.resize(actions->size());
  for(unsigned i = 0; i < actions->size(); i++) {
      adapter2model[i]=find(mactions, (*actions)[i]);
  }
  model2adapter.resize(mactions.size());
  for(unsigned i = 0; i < mactions.size(); i++) {
    model2adapter[i]=find(*actions, mactions[i]);
  }
  return true;
}

std::string Adapter_model::stringify()
{
  std::ostringstream t(std::ios::out | std::ios::binary);

  std::string s=model->stringify();

  t << "model:" << capsulate(s) << std::endl;

  return t.str();
}

/* adapter can execute.. */
void Adapter_model::execute(std::vector<int> &action)
{
  log.push("Adapter_model");

  log.print("<action type=\"input\" name=\"%s\"/>",
	    getUActionName(action[0]));

  if (!model->execute(adapter2model[action[0]])) {
    action[0]=0;
  }

  log.pop();
}

bool Adapter_model::observe(std::vector<int> &action,bool block)
{
  int* act,*iact;
  int actions=-model->getIActions(&iact)+model->getActions(&act);
  int i=1+random()%actions;
  int a;
  if (!actions) {
    return false;
  }
  a=-1;
  while (i) {
    a++;
    while (!model->is_output(act[a])) {
      i--;
    }
  }
  action.resize(1);
  action[0]=act[a];
  return true;
}

FACTORY_DEFAULT_CREATOR(Adapter, Adapter_model, "model")
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the either Technology Preview License Agreement or the
** Beta Release License Agreement.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain
** additional rights. These rights are described in the Nokia Qt LGPL
** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
** package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://www.qtsoftware.com/contact.
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qdirectfbpixmap.h"

#include "qdirectfbscreen.h"
#include "qdirectfbpaintengine.h"

#include <QtGui/qbitmap.h>
#include <directfb.h>

static int global_ser_no = 0;

QDirectFBPixmapData::QDirectFBPixmapData(PixelType pixelType)
    : QPixmapData(pixelType, DirectFBClass),
      engine(0), format(QImage::Format_Invalid), alpha(false)
{
    setSerialNumber(0);
}

QDirectFBPixmapData::~QDirectFBPixmapData()
{
    unlockDirectFB();
    if (dfbSurface && QDirectFBScreen::instance())
        screen->releaseDFBSurface(dfbSurface);
    delete engine;
}

void QDirectFBPixmapData::resize(int width, int height)
{
    if (width <= 0 || height <= 0) {
        invalidate();
        return;
    }

    format = screen->pixelFormat();
    dfbSurface = screen->createDFBSurface(QSize(width, height),
                                          format,
                                          QDirectFBScreen::TrackSurface);
    d = screen->depth();
    alpha = false;
    if (!dfbSurface) {
        invalidate();
        qWarning("QDirectFBPixmapData::resize(): Unable to allocate surface");
        return;
    }

    w = width;
    h = height;
    is_null = (w <= 0 || h <= 0);
    d = metric(QPaintDevice::PdmDepth);
    setSerialNumber(++global_ser_no);
}

// mostly duplicated from qimage.cpp (QImageData::checkForAlphaPixels)
static bool checkForAlphaPixels(const QImage &img)
{
    const uchar *bits = img.bits();
    const int bytes_per_line = img.bytesPerLine();
    const uchar *end_bits = bits + bytes_per_line;
    const int width = img.width();
    const int height = img.height();
    switch (img.format()) {
    case QImage::Format_Indexed8:
        return img.hasAlphaChannel();
    case QImage::Format_ARGB32:
    case QImage::Format_ARGB32_Premultiplied:
        for (int y=0; y<height; ++y) {
            for (int x=0; x<width; ++x) {
                if ((((uint *)bits)[x] & 0xff000000) != 0xff000000) {
                    return true;
                }
            }
            bits += bytes_per_line;
        }
        break;

    case QImage::Format_ARGB8555_Premultiplied:
    case QImage::Format_ARGB8565_Premultiplied:
        for (int y=0; y<height; ++y) {
            while (bits < end_bits) {
                if (bits[0] != 0) {
                    return true;
                }
                bits += 3;
            }
            bits = end_bits;
            end_bits += bytes_per_line;
        }
        break;

    case QImage::Format_ARGB6666_Premultiplied:
        for (int y=0; y<height; ++y) {
            while (bits < end_bits) {
                if ((bits[0] & 0xfc) != 0) {
                    return true;
                }
                bits += 3;
            }
            bits = end_bits;
            end_bits += bytes_per_line;
        }
        break;

    case QImage::Format_ARGB4444_Premultiplied:
        for (int y=0; y<height; ++y) {
            while (bits < end_bits) {
                if ((bits[0] & 0xf0) != 0) {
                    return true;
                }
                bits += 2;
            }
            bits = end_bits;
            end_bits += bytes_per_line;
        }
        break;

    default:
        break;
    }

    return false;
}

bool QDirectFBPixmapData::hasAlphaChannel(const QImage &img)
{
#ifndef QT_NO_DIRECTFB_OPAQUE_DETECTION
    return ::checkForAlphaPixels(img);
#else
    return img.hasAlphaChannel();
#endif
}

void QDirectFBPixmapData::fromImage(const QImage &i,
                                    Qt::ImageConversionFlags flags)
{
#ifdef QT_NO_DIRECTFB_OPAQUE_DETECTION
    Q_UNUSED(flags);
#endif
    const QImage img = (i.depth() == 1 ? i.convertToFormat(screen->alphaPixmapFormat()) : i);
    if (img.hasAlphaChannel()
#ifndef QT_NO_DIRECTFB_OPAQUE_DETECTION
        && (flags & Qt::NoOpaqueDetection || QDirectFBPixmapData::hasAlphaChannel(img))
#endif
        ) {
        alpha = true;
        format = screen->alphaPixmapFormat();
    } else {
        alpha = false;
        format = screen->pixelFormat();
    }
    dfbSurface = screen->copyToDFBSurface(img, format,
                                          QDirectFBScreen::TrackSurface);
    if (!dfbSurface) {
        qWarning("QDirectFBPixmapData::fromImage()");
        invalidate();
        return;
    }
    w = img.width();
    h = img.height();
    is_null = (w <= 0 || h <= 0);
    d = metric(QPaintDevice::PdmDepth);
    setSerialNumber(++global_ser_no);
}

void QDirectFBPixmapData::copy(const QPixmapData *data, const QRect &rect)
{
    if (data->classId() != DirectFBClass) {
        QPixmapData::copy(data, rect);
        return;
    }

    const QDirectFBPixmapData *otherData = static_cast<const QDirectFBPixmapData*>(data);
    IDirectFBSurface *src = otherData->directFBSurface();
    alpha = data->hasAlphaChannel();
    format = (alpha
              ? QDirectFBScreen::instance()->alphaPixmapFormat()
              : QDirectFBScreen::instance()->pixelFormat());

    dfbSurface = screen->createDFBSurface(rect.size(), format,
                                          QDirectFBScreen::TrackSurface);
    if (!dfbSurface) {
        qWarning("QDirectFBPixmapData::copy()");
        invalidate();
        return;
    }

    if (alpha) {
        dfbSurface->Clear(dfbSurface, 0, 0, 0, 0);
        dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_BLEND_ALPHACHANNEL);
    } else {
        dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_NOFX);
    }
    const DFBRectangle blitRect = { rect.x(), rect.y(),
                                    rect.width(), rect.height() };
    w = rect.width();
    h = rect.height();
    d = otherData->d;
    DFBResult result = dfbSurface->Blit(dfbSurface, src, &blitRect, 0, 0);
#if (Q_DIRECTFB_VERSION >= 0x010000)
    dfbSurface->ReleaseSource(dfbSurface);
#endif
    if (result != DFB_OK) {
        DirectFBError("QDirectFBPixmapData::copy()", result);
        invalidate();
        return;
    }

    setSerialNumber(++global_ser_no);
}

static inline bool isOpaqueFormat(QImage::Format format)
{
    switch (format) {
    case QImage::Format_RGB32:
    case QImage::Format_RGB16:
    case QImage::Format_RGB666:
    case QImage::Format_RGB555:
    case QImage::Format_RGB888:
    case QImage::Format_RGB444:
        return true;
    default:
        break;
    }
    return false;
}

void QDirectFBPixmapData::fill(const QColor &color)
{
    if (!serialNumber())
        return;

    Q_ASSERT(dfbSurface);

    alpha = (color.alpha() < 255);

    if (alpha && ::isOpaqueFormat(format)) {
        QSize size;
        dfbSurface->GetSize(dfbSurface, &size.rwidth(), &size.rheight());
        screen->releaseDFBSurface(dfbSurface);
        format = screen->alphaPixmapFormat();
        dfbSurface = screen->createDFBSurface(size, screen->alphaPixmapFormat(), QDirectFBScreen::TrackSurface);
        setSerialNumber(++global_ser_no);
        if (!dfbSurface) {
            qWarning("QDirectFBPixmapData::fill()");
            invalidate();
            return;
        }
    }

    dfbSurface->Clear(dfbSurface, color.red(), color.green(), color.blue(), color.alpha());
}

QPixmap QDirectFBPixmapData::transformed(const QTransform &transform,
                                         Qt::TransformationMode mode) const
{
    if (!dfbSurface || transform.type() != QTransform::TxScale
        || mode != Qt::FastTransformation)
    {
        QDirectFBPixmapData *that = const_cast<QDirectFBPixmapData*>(this);
        const QImage *image = that->buffer();
        Q_ASSERT(image);
        const QImage transformed = image->transformed(transform, mode);
        that->unlockDirectFB();
        QDirectFBPixmapData *data = new QDirectFBPixmapData(QPixmapData::PixmapType);
        data->fromImage(transformed, Qt::AutoColor);
        return QPixmap(data);
    }

    const QSize size = transform.mapRect(QRect(0, 0, w, h)).size();
    if (size.isEmpty())
        return QPixmap();

    QDirectFBPixmapData *data = new QDirectFBPixmapData(QPixmapData::PixmapType);
    DFBSurfaceBlittingFlags flags = DSBLIT_NOFX;
    data->alpha = alpha;
    if (alpha) {
        flags = DSBLIT_BLEND_ALPHACHANNEL;
    }
    data->dfbSurface = screen->createDFBSurface(size,
                                                format,
                                                QDirectFBScreen::TrackSurface);
    if (flags & DSBLIT_BLEND_ALPHACHANNEL) {
        data->dfbSurface->Clear(data->dfbSurface, 0, 0, 0, 0);
    }
    data->dfbSurface->SetBlittingFlags(data->dfbSurface, flags);

    const DFBRectangle destRect = { 0, 0, size.width(), size.height() };
    data->dfbSurface->StretchBlit(data->dfbSurface, dfbSurface, 0, &destRect);
    data->w = size.width();
    data->h = size.height();
#if (Q_DIRECTFB_VERSION >= 0x010000)
    data->dfbSurface->ReleaseSource(data->dfbSurface);
#endif
    return QPixmap(data);
}

QImage QDirectFBPixmapData::toImage() const
{
    if (!dfbSurface)
        return QImage();

#ifndef QT_NO_DIRECTFB_PREALLOCATED
    QImage ret(w, h, QDirectFBScreen::getImageFormat(dfbSurface));
    if (IDirectFBSurface *imgSurface = screen->createDFBSurface(ret, QDirectFBScreen::DontTrackSurface)) {
        if (hasAlphaChannel()) {
            imgSurface->SetBlittingFlags(imgSurface, DSBLIT_BLEND_ALPHACHANNEL);
            imgSurface->Clear(imgSurface, 0, 0, 0, 0);
        } else {
            imgSurface->SetBlittingFlags(imgSurface, DSBLIT_NOFX);
        }
        imgSurface->Blit(imgSurface, dfbSurface, 0, 0, 0);
#if (Q_DIRECTFB_VERSION >= 0x010000)
        imgSurface->ReleaseSource(imgSurface);
#endif
        imgSurface->Release(imgSurface);
        return ret;
    }
#endif

    QDirectFBPixmapData *that = const_cast<QDirectFBPixmapData*>(this);
    const QImage *img = that->buffer();
    return img->copy();
}

QPaintEngine *QDirectFBPixmapData::paintEngine() const
{
    if (!engine) {
        // QDirectFBPixmapData is also a QCustomRasterPaintDevice, so pass
        // that to the paint engine:
        QDirectFBPixmapData *that = const_cast<QDirectFBPixmapData*>(this);
        that->engine = new QDirectFBPaintEngine(that);
    }
    return engine;
}

QImage *QDirectFBPixmapData::buffer()
{
    lockDirectFB(DSLF_READ|DSLF_WRITE);
    return lockedImage;
}

QImage * QDirectFBPixmapData::buffer(uint lockFlags)
{
    lockDirectFB(lockFlags);
    return lockedImage;
}

void QDirectFBPixmapData::invalidate()
{
    setSerialNumber(0);
    alpha = false;
    d = w = h = 0;
    format = QImage::Format_Invalid;
}

<commit_msg>Make sure to update is_null in copy/transformed<commit_after>/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the either Technology Preview License Agreement or the
** Beta Release License Agreement.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain
** additional rights. These rights are described in the Nokia Qt LGPL
** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
** package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://www.qtsoftware.com/contact.
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qdirectfbpixmap.h"

#include "qdirectfbscreen.h"
#include "qdirectfbpaintengine.h"

#include <QtGui/qbitmap.h>
#include <directfb.h>

static int global_ser_no = 0;

QDirectFBPixmapData::QDirectFBPixmapData(PixelType pixelType)
    : QPixmapData(pixelType, DirectFBClass),
      engine(0), format(QImage::Format_Invalid), alpha(false)
{
    setSerialNumber(0);
}

QDirectFBPixmapData::~QDirectFBPixmapData()
{
    unlockDirectFB();
    if (dfbSurface && QDirectFBScreen::instance())
        screen->releaseDFBSurface(dfbSurface);
    delete engine;
}

void QDirectFBPixmapData::resize(int width, int height)
{
    if (width <= 0 || height <= 0) {
        invalidate();
        return;
    }

    format = screen->pixelFormat();
    dfbSurface = screen->createDFBSurface(QSize(width, height),
                                          format,
                                          QDirectFBScreen::TrackSurface);
    d = screen->depth();
    alpha = false;
    if (!dfbSurface) {
        invalidate();
        qWarning("QDirectFBPixmapData::resize(): Unable to allocate surface");
        return;
    }

    w = width;
    h = height;
    is_null = (w <= 0 || h <= 0);
    d = metric(QPaintDevice::PdmDepth);
    setSerialNumber(++global_ser_no);
}

// mostly duplicated from qimage.cpp (QImageData::checkForAlphaPixels)
static bool checkForAlphaPixels(const QImage &img)
{
    const uchar *bits = img.bits();
    const int bytes_per_line = img.bytesPerLine();
    const uchar *end_bits = bits + bytes_per_line;
    const int width = img.width();
    const int height = img.height();
    switch (img.format()) {
    case QImage::Format_Indexed8:
        return img.hasAlphaChannel();
    case QImage::Format_ARGB32:
    case QImage::Format_ARGB32_Premultiplied:
        for (int y=0; y<height; ++y) {
            for (int x=0; x<width; ++x) {
                if ((((uint *)bits)[x] & 0xff000000) != 0xff000000) {
                    return true;
                }
            }
            bits += bytes_per_line;
        }
        break;

    case QImage::Format_ARGB8555_Premultiplied:
    case QImage::Format_ARGB8565_Premultiplied:
        for (int y=0; y<height; ++y) {
            while (bits < end_bits) {
                if (bits[0] != 0) {
                    return true;
                }
                bits += 3;
            }
            bits = end_bits;
            end_bits += bytes_per_line;
        }
        break;

    case QImage::Format_ARGB6666_Premultiplied:
        for (int y=0; y<height; ++y) {
            while (bits < end_bits) {
                if ((bits[0] & 0xfc) != 0) {
                    return true;
                }
                bits += 3;
            }
            bits = end_bits;
            end_bits += bytes_per_line;
        }
        break;

    case QImage::Format_ARGB4444_Premultiplied:
        for (int y=0; y<height; ++y) {
            while (bits < end_bits) {
                if ((bits[0] & 0xf0) != 0) {
                    return true;
                }
                bits += 2;
            }
            bits = end_bits;
            end_bits += bytes_per_line;
        }
        break;

    default:
        break;
    }

    return false;
}

bool QDirectFBPixmapData::hasAlphaChannel(const QImage &img)
{
#ifndef QT_NO_DIRECTFB_OPAQUE_DETECTION
    return ::checkForAlphaPixels(img);
#else
    return img.hasAlphaChannel();
#endif
}

void QDirectFBPixmapData::fromImage(const QImage &i,
                                    Qt::ImageConversionFlags flags)
{
#ifdef QT_NO_DIRECTFB_OPAQUE_DETECTION
    Q_UNUSED(flags);
#endif
    const QImage img = (i.depth() == 1 ? i.convertToFormat(screen->alphaPixmapFormat()) : i);
    if (img.hasAlphaChannel()
#ifndef QT_NO_DIRECTFB_OPAQUE_DETECTION
        && (flags & Qt::NoOpaqueDetection || QDirectFBPixmapData::hasAlphaChannel(img))
#endif
        ) {
        alpha = true;
        format = screen->alphaPixmapFormat();
    } else {
        alpha = false;
        format = screen->pixelFormat();
    }
    dfbSurface = screen->copyToDFBSurface(img, format,
                                          QDirectFBScreen::TrackSurface);
    if (!dfbSurface) {
        qWarning("QDirectFBPixmapData::fromImage()");
        invalidate();
        return;
    }
    w = img.width();
    h = img.height();
    is_null = (w <= 0 || h <= 0);
    d = metric(QPaintDevice::PdmDepth);
    setSerialNumber(++global_ser_no);
}

void QDirectFBPixmapData::copy(const QPixmapData *data, const QRect &rect)
{
    if (data->classId() != DirectFBClass) {
        QPixmapData::copy(data, rect);
        return;
    }

    const QDirectFBPixmapData *otherData = static_cast<const QDirectFBPixmapData*>(data);
    IDirectFBSurface *src = otherData->directFBSurface();
    alpha = data->hasAlphaChannel();
    format = (alpha
              ? QDirectFBScreen::instance()->alphaPixmapFormat()
              : QDirectFBScreen::instance()->pixelFormat());

    dfbSurface = screen->createDFBSurface(rect.size(), format,
                                          QDirectFBScreen::TrackSurface);
    if (!dfbSurface) {
        qWarning("QDirectFBPixmapData::copy()");
        invalidate();
        return;
    }

    if (alpha) {
        dfbSurface->Clear(dfbSurface, 0, 0, 0, 0);
        dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_BLEND_ALPHACHANNEL);
    } else {
        dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_NOFX);
    }
    const DFBRectangle blitRect = { rect.x(), rect.y(),
                                    rect.width(), rect.height() };
    w = rect.width();
    h = rect.height();
    d = otherData->d;
    is_null = (w <= 0 || h <= 0);
    DFBResult result = dfbSurface->Blit(dfbSurface, src, &blitRect, 0, 0);
#if (Q_DIRECTFB_VERSION >= 0x010000)
    dfbSurface->ReleaseSource(dfbSurface);
#endif
    if (result != DFB_OK) {
        DirectFBError("QDirectFBPixmapData::copy()", result);
        invalidate();
        return;
    }

    setSerialNumber(++global_ser_no);
}

static inline bool isOpaqueFormat(QImage::Format format)
{
    switch (format) {
    case QImage::Format_RGB32:
    case QImage::Format_RGB16:
    case QImage::Format_RGB666:
    case QImage::Format_RGB555:
    case QImage::Format_RGB888:
    case QImage::Format_RGB444:
        return true;
    default:
        break;
    }
    return false;
}

void QDirectFBPixmapData::fill(const QColor &color)
{
    if (!serialNumber())
        return;

    Q_ASSERT(dfbSurface);

    alpha = (color.alpha() < 255);

    if (alpha && ::isOpaqueFormat(format)) {
        QSize size;
        dfbSurface->GetSize(dfbSurface, &size.rwidth(), &size.rheight());
        screen->releaseDFBSurface(dfbSurface);
        format = screen->alphaPixmapFormat();
        dfbSurface = screen->createDFBSurface(size, screen->alphaPixmapFormat(), QDirectFBScreen::TrackSurface);
        setSerialNumber(++global_ser_no);
        if (!dfbSurface) {
            qWarning("QDirectFBPixmapData::fill()");
            invalidate();
            return;
        }
    }

    dfbSurface->Clear(dfbSurface, color.red(), color.green(), color.blue(), color.alpha());
}

QPixmap QDirectFBPixmapData::transformed(const QTransform &transform,
                                         Qt::TransformationMode mode) const
{
    if (!dfbSurface || transform.type() != QTransform::TxScale
        || mode != Qt::FastTransformation)
    {
        QDirectFBPixmapData *that = const_cast<QDirectFBPixmapData*>(this);
        const QImage *image = that->buffer();
        Q_ASSERT(image);
        const QImage transformed = image->transformed(transform, mode);
        that->unlockDirectFB();
        QDirectFBPixmapData *data = new QDirectFBPixmapData(QPixmapData::PixmapType);
        data->fromImage(transformed, Qt::AutoColor);
        return QPixmap(data);
    }

    const QSize size = transform.mapRect(QRect(0, 0, w, h)).size();
    if (size.isEmpty())
        return QPixmap();

    QDirectFBPixmapData *data = new QDirectFBPixmapData(QPixmapData::PixmapType);
    DFBSurfaceBlittingFlags flags = DSBLIT_NOFX;
    data->alpha = alpha;
    if (alpha) {
        flags = DSBLIT_BLEND_ALPHACHANNEL;
    }
    data->dfbSurface = screen->createDFBSurface(size,
                                                format,
                                                QDirectFBScreen::TrackSurface);
    if (flags & DSBLIT_BLEND_ALPHACHANNEL) {
        data->dfbSurface->Clear(data->dfbSurface, 0, 0, 0, 0);
    }
    data->dfbSurface->SetBlittingFlags(data->dfbSurface, flags);

    const DFBRectangle destRect = { 0, 0, size.width(), size.height() };
    data->dfbSurface->StretchBlit(data->dfbSurface, dfbSurface, 0, &destRect);
    data->w = size.width();
    data->h = size.height();
    data->is_null = (data->w <= 0 || data->h <= 0);

#if (Q_DIRECTFB_VERSION >= 0x010000)
    data->dfbSurface->ReleaseSource(data->dfbSurface);
#endif
    return QPixmap(data);
}

QImage QDirectFBPixmapData::toImage() const
{
    if (!dfbSurface)
        return QImage();

#ifndef QT_NO_DIRECTFB_PREALLOCATED
    QImage ret(w, h, QDirectFBScreen::getImageFormat(dfbSurface));
    if (IDirectFBSurface *imgSurface = screen->createDFBSurface(ret, QDirectFBScreen::DontTrackSurface)) {
        if (hasAlphaChannel()) {
            imgSurface->SetBlittingFlags(imgSurface, DSBLIT_BLEND_ALPHACHANNEL);
            imgSurface->Clear(imgSurface, 0, 0, 0, 0);
        } else {
            imgSurface->SetBlittingFlags(imgSurface, DSBLIT_NOFX);
        }
        imgSurface->Blit(imgSurface, dfbSurface, 0, 0, 0);
#if (Q_DIRECTFB_VERSION >= 0x010000)
        imgSurface->ReleaseSource(imgSurface);
#endif
        imgSurface->Release(imgSurface);
        return ret;
    }
#endif

    QDirectFBPixmapData *that = const_cast<QDirectFBPixmapData*>(this);
    const QImage *img = that->buffer();
    return img->copy();
}

QPaintEngine *QDirectFBPixmapData::paintEngine() const
{
    if (!engine) {
        // QDirectFBPixmapData is also a QCustomRasterPaintDevice, so pass
        // that to the paint engine:
        QDirectFBPixmapData *that = const_cast<QDirectFBPixmapData*>(this);
        that->engine = new QDirectFBPaintEngine(that);
    }
    return engine;
}

QImage *QDirectFBPixmapData::buffer()
{
    lockDirectFB(DSLF_READ|DSLF_WRITE);
    return lockedImage;
}

QImage * QDirectFBPixmapData::buffer(uint lockFlags)
{
    lockDirectFB(lockFlags);
    return lockedImage;
}

void QDirectFBPixmapData::invalidate()
{
    setSerialNumber(0);
    alpha = false;
    d = w = h = 0;
    format = QImage::Format_Invalid;
}

<|endoftext|>


<commit_before>/*******************************************************************************

Licensed to the OpenCOR team under one or more contributor license agreements.
See the NOTICE.txt file distributed with this work for additional information
regarding copyright ownership. The OpenCOR team licenses this file to you 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.

*******************************************************************************/

//==============================================================================
// GUI utilities
//==============================================================================

#include "corecliutils.h"
#include "commonwidget.h"
#include "coreguiutils.h"

//==============================================================================

#include <Qt>

//==============================================================================

#include <QAction>
#include <QApplication>
#include <QBuffer>
#include <QColor>
#include <QDate>
#include <QFileDialog>
#include <QFileInfo>
#include <QFont>
#include <QFrame>
#include <QIODevice>
#include <QLabel>
#include <QMainWindow>
#include <QMenu>
#include <QMessageBox>
#include <QPalette>
#include <QSizePolicy>

//==============================================================================

namespace OpenCOR {
namespace Core {

//==============================================================================

#include "coreguiutils.cpp.inl"

//==============================================================================

QString allFilters(const QString &pFilters)
{
    return  QObject::tr("All Files")
           +" (*"
#ifdef Q_OS_WIN
            ".*"
#endif
            ")"
           +(pFilters.isEmpty()?QString():";;"+pFilters);
}

//==============================================================================

QString getOpenFileName(const QString &pCaption, const QString &pFilters,
                        QString *pSelectedFilter)
{
    // Retrieve and return one open file name

    QString res = QFileDialog::getOpenFileName(qApp->activeWindow(),
                                               pCaption, activeDirectory(),
                                               allFilters(pFilters),
                                               pSelectedFilter);

    if (!res.isEmpty()) {
        // We have retrieved a file name, so keep track of the folder in which
        // it is
        // Note: normally, we would use QFileInfo::canonicalPath(), but this
        //       requires an existing file, so use QFileInfo::path() instead...

        setActiveDirectory(QFileInfo(res).path());
    }

    // Return the file name

    return res;
}

//==============================================================================

QStringList getOpenFileNames(const QString &pCaption, const QString &pFilters,
                             QString *pSelectedFilter)
{
    // Retrieve and return one or several open file names

    QStringList res = QFileDialog::getOpenFileNames(qApp->activeWindow(),
                                                    pCaption, activeDirectory(),
                                                    allFilters(pFilters),
                                                    pSelectedFilter);

    if (!res.isEmpty()) {
        // We have retrieved at least one file name, so keep track of the folder
        // in which it is
        // Note #1: we use the last open file name to determine the folder that
        //          is to be remembered since on Windows 7, at least, it's
        //          possible to search for files from within the file dialog
        //          box, and the last file name should be the one we are most
        //          'interested' in...
        // Note #2: this doesn't, unfortunately, address the case where the user
        //          goes to a directory and then closes the file dialog box
        //          without selecting any open file name. There might be a way
        //          to get it to work, but that would involve using the exec()
        //          method rather than the static getOpenFilesNames() method,
        //          which would result in a non-native looking file dialog box
        //          (on Windows 7 at least), so it's not an option
        //          unfortunately...
        // Note #3: normally, we would use QFileInfo::canonicalPath(), but this
        //          requires an existing file, so use QFileInfo::path()
        //          instead...

        setActiveDirectory(QFileInfo(res[res.count()-1]).path());
    }

    // Return the file name(s)

    return res;
}

//==============================================================================

QString getSaveFileName(const QString &pCaption, const QString &pFileName,
                        const QString &pFilters, QString *pSelectedFilter)
{
    // Retrieve and return a save file name

    QFileInfo fileInfo = pFileName;
    QString res = Core::nativeCanonicalFileName(QFileDialog::getSaveFileName(qApp->activeWindow(),
                                                                             pCaption,
                                                                             !fileInfo.canonicalPath().compare(".")?
                                                                                activeDirectory()+QDir::separator()+fileInfo.fileName():
                                                                                pFileName,
                                                                             allFilters(pFilters),
                                                                             pSelectedFilter,
                                                                             QFileDialog::DontConfirmOverwrite));

    // Make sure that we have got a save file name

    if (!res.isEmpty()) {
        // Update our active directory
        // Note: normally, we would use QFileInfo::canonicalPath(), but this
        //       requires an existing file, so use QFileInfo::path() instead...

        QFileInfo resInfo = res;

        setActiveDirectory(resInfo.path());

        // Check whether the save file already exists

        if (resInfo.exists()) {
            // The save file already exists, so ask whether we want to overwrite
            // it

            if (QMessageBox::question(mainWindow(), pCaption,
                                      QObject::tr("<strong>%1</strong> already exists. Do you want to overwrite it?").arg(res),
                                      QMessageBox::Yes|QMessageBox::No,
                                      QMessageBox::Yes) == QMessageBox::No) {
                return QString();
            }
        }
    }

    // Everything went fine,so return the save file name

    return res;
}

//==============================================================================

QString getExistingDirectory(const QString &pCaption, const QString &pDirName,
                             const bool &pEmptyDir)
{
    // Retrieve and return a save file name

    QString res = Core::nativeCanonicalDirName(QFileDialog::getExistingDirectory(qApp->activeWindow(),
                                                                                pCaption,
                                                                                pDirName.isEmpty()?
                                                                                activeDirectory():
                                                                                pDirName));

    // Make sure that we have got a directory

    if (!res.isEmpty()) {
        // Update our active directory

        setActiveDirectory(res);

        // Check whether the directory should be empty

        if (pEmptyDir) {
            if (QDir(res).entryInfoList(QDir::NoDotAndDotDot|QDir::AllEntries).count()) {
                QMessageBox::warning(mainWindow(), pCaption,
                                     QObject::tr("Please choose an empty directory."));

                return QString();
            }
        }
    }

    // Everything went fine,so return the directory

    return res;
}

//==============================================================================

void setFocusTo(QWidget *pWidget)
{
    // Give the focus to pWidget, but then revert the focus back to whoever had
    // it before, if needed

    if (!pWidget)
        return;

    QWidget *focusedWidget = qApp->activeWindow()?
                                 qApp->activeWindow()->focusWidget():
                                 0;

    if (   !focusedWidget
        || (pWidget->parentWidget() == focusedWidget->parentWidget())) {
        // Either there is no currently focused widget or the currently focused
        // widget and the one to which we want to set the focus share the same
        // parent, so set the focus to the given widget

        pWidget->setFocus();
    }
}

//==============================================================================

QMenu * newMenu(const QString &pName, QWidget *pParent)
{
    // Create and return a menu

    QMenu *res = new QMenu(pParent);

    res->setObjectName("menu"+pName.left(1).toUpper()+pName.right(pName.size()-1));

    return res;
}

//==============================================================================

QMenu * newMenu(const QIcon &pIcon, QWidget *pParent)
{
    // Create and return a menu

    QMenu *res = new QMenu(pParent);

    res->menuAction()->setIcon(pIcon);

    return res;
}

//==============================================================================

QAction * newAction(const bool &pCheckable, const QIcon &pIcon,
                    const QKeySequence &pKeySequence, QWidget *pParent)
{
    // Create and return an action

    QAction *res = new QAction(pParent);

    res->setCheckable(pCheckable);
    res->setIcon(pIcon);
    res->setShortcut(pKeySequence);

    return res;
}

//==============================================================================

QAction * newAction(const bool &pCheckable, const QKeySequence &pKeySequence,
                    QWidget *pParent)
{
    // Create and return an action

    QAction *res = new QAction(pParent);

    res->setCheckable(pCheckable);
    res->setShortcut(pKeySequence);

    return res;
}

//==============================================================================

QAction * newAction(const bool &pCheckable, QWidget *pParent)
{
    // Create and return an action

    QAction *res = new QAction(pParent);

    res->setCheckable(pCheckable);

    return res;
}

//==============================================================================

QAction * newAction(const QIcon &pIcon,
                    const QList<QKeySequence> &pKeySequences, QWidget *pParent)
{
    // Create and return an action

    QAction *res = new QAction(pParent);

    res->setIcon(pIcon);
    res->setShortcuts(pKeySequences);

    return res;
}

//==============================================================================

QAction * newAction(const QIcon &pIcon, const QKeySequence &pKeySequence,
                    QWidget *pParent)
{
    // Create and return an action

    QAction *res = new QAction(pParent);

    res->setIcon(pIcon);
    res->setShortcut(pKeySequence);

    return res;
}

//==============================================================================

QAction * newAction(const QIcon &pIcon, QWidget *pParent)
{
    // Create and return an action

    QAction *res = new QAction(pParent);

    res->setIcon(pIcon);

    return res;
}

//==============================================================================

QAction * newAction(const QKeySequence &pKeySequence, QWidget *pParent)
{
    // Create and return an action

    QAction *res = new QAction(pParent);

    res->setShortcut(pKeySequence);

    return res;
}

//==============================================================================

QAction * newAction(const QKeySequence::StandardKey &pStandardKey,
                    QWidget *pParent)
{
    // Create and return an action

    QAction *res = new QAction(pParent);

    res->setShortcut(pStandardKey);

    return res;
}

//==============================================================================

QFrame * newLineWidget(const bool &pHorizontal, const QColor &pColor,
                       QWidget *pParent)
{
    // Create and return a 'real' line widget, i.e. one which is 1 pixel wide,
    // using a QFrame widget

    QFrame *res = new QFrame(pParent);

    res->setStyleSheet(QString("QFrame {"
                               "    border: 1px solid rgb(%1, %2, %3);"
                               "}").arg(QString::number(pColor.red()),
                                        QString::number(pColor.green()),
                                        QString::number(pColor.blue())));

    if (pHorizontal) {
        res->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
        res->setFixedHeight(1);
    } else {
        res->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
        res->setFixedWidth(1);
    }

    return res;
}

//==============================================================================

QFrame * newLineWidget(const bool &pHorizontal, QWidget *pParent)
{
    // Create and return a 'real' horizontal line widget

    return newLineWidget(pHorizontal, borderColor(), pParent);
}

//==============================================================================

QFrame * newLineWidget(const QColor &pColor, QWidget *pParent)
{
    // Create and return a 'real' horizontal line widget

    return newLineWidget(true, pColor, pParent);
}

//==============================================================================

QFrame * newLineWidget(QWidget *pParent)
{
    // Create and return a 'real' horizontal line widget

    return newLineWidget(true, borderColor(), pParent);
}

//==============================================================================

QString iconDataUri(const QString &pIcon, const int &pWidth, const int &pHeight,
                    const QIcon::Mode &pMode)
{
    // Convert an icon, which resource name is given, to a data URI, after
    // having resized it, if requested

    QIcon icon(pIcon);

    if (icon.isNull())
        return QString();

    QByteArray data;
    QBuffer buffer(&data);
    QSize iconSize = icon.availableSizes().first();

    buffer.open(QIODevice::WriteOnly);
    icon.pixmap((pWidth == -1)?iconSize.width():pWidth,
                (pHeight == -1)?iconSize.height():pHeight,
                pMode).save(&buffer, "PNG");

    return QString("data:image/png;base64,%1").arg(QString(data.toBase64()));
}

//==============================================================================

void showEnableWidget(QWidget *pWidget, const bool &pVisible,
                      const bool &pEnabled)
{
    // Show/enable or hide/disable the given widget

    pWidget->setVisible(pVisible);
    pWidget->setEnabled(pVisible && pEnabled);
}

//==============================================================================

QColor lockedColor(const QColor &pColor)
{
    // Return the resulting locked version of the given colour

    int r = pColor.red();
    int g = pColor.green();
    int b = pColor.blue();

    static const int lr = 255;
    static const int lg = 0;
    static const int lb = 0;

    static const double alpha = 0.05;
    static const double oneMinusAlpha = 1.0-alpha;

    return QColor(alpha*lr+oneMinusAlpha*r,
                  alpha*lg+oneMinusAlpha*g,
                  alpha*lb+oneMinusAlpha*b);
}

//==============================================================================

QString fileTypes(const FileTypes &pFileTypes, const bool &pCheckMimeTypes,
                  const QStringList &pMimeTypes)
{
    // Convert and return as a string the given file types, using the given MIME
    // types, if required

    QString res = QString();

    foreach (FileType *fileType, pFileTypes) {
        if (!pCheckMimeTypes || pMimeTypes.contains(fileType->mimeType())) {
            if (!res.isEmpty())
                res += ";;";

            res +=  fileType->description()
                   +" (*."+fileType->fileExtension()+")";
        }
    }

    return res;
}

//==============================================================================

QString fileTypes(const FileTypes &pFileTypes)
{
    // Convert and return as a string the given file types

    return fileTypes(pFileTypes, false, QStringList());
}

//==============================================================================

QString fileTypes(const FileTypes &pFileTypes, const QStringList &pMimeTypes)
{
    // Convert and return as a string the given file types, using the given MIME
    // types, if any

    return fileTypes(pFileTypes, true, pMimeTypes);
}

//==============================================================================

}   // namespace Core
}   // namespace OpenCOR

//==============================================================================
// End of file
//==============================================================================
<commit_msg>Some work on ensuring that calls to QFileDialog now handle the case where a user cancels their action (#846) [ci skip].<commit_after>/*******************************************************************************

Licensed to the OpenCOR team under one or more contributor license agreements.
See the NOTICE.txt file distributed with this work for additional information
regarding copyright ownership. The OpenCOR team licenses this file to you 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.

*******************************************************************************/

//==============================================================================
// GUI utilities
//==============================================================================

#include "corecliutils.h"
#include "commonwidget.h"
#include "coreguiutils.h"

//==============================================================================

#include <Qt>

//==============================================================================

#include <QAction>
#include <QApplication>
#include <QBuffer>
#include <QColor>
#include <QDate>
#include <QFileDialog>
#include <QFileInfo>
#include <QFont>
#include <QFrame>
#include <QIODevice>
#include <QLabel>
#include <QMainWindow>
#include <QMenu>
#include <QMessageBox>
#include <QPalette>
#include <QSizePolicy>

//==============================================================================

namespace OpenCOR {
namespace Core {

//==============================================================================

#include "coreguiutils.cpp.inl"

//==============================================================================

QString allFilters(const QString &pFilters)
{
    return  QObject::tr("All Files")
           +" (*"
#ifdef Q_OS_WIN
            ".*"
#endif
            ")"
           +(pFilters.isEmpty()?QString():";;"+pFilters);
}

//==============================================================================

QString getOpenFileName(const QString &pCaption, const QString &pFilters,
                        QString *pSelectedFilter)
{
    // Retrieve and return one open file name

    QString res = QFileDialog::getOpenFileName(qApp->activeWindow(),
                                               pCaption, activeDirectory(),
                                               allFilters(pFilters),
                                               pSelectedFilter);

    if (!res.isEmpty()) {
        // We have retrieved a file name, so keep track of the folder in which
        // it is
        // Note: normally, we would use QFileInfo::canonicalPath(), but this
        //       requires an existing file, so use QFileInfo::path() instead...

        setActiveDirectory(QFileInfo(res).path());
    }

    // Return the file name

    return res;
}

//==============================================================================

QStringList getOpenFileNames(const QString &pCaption, const QString &pFilters,
                             QString *pSelectedFilter)
{
    // Retrieve and return one or several open file names

    QStringList res = QFileDialog::getOpenFileNames(qApp->activeWindow(),
                                                    pCaption, activeDirectory(),
                                                    allFilters(pFilters),
                                                    pSelectedFilter);

    if (!res.isEmpty()) {
        // We have retrieved at least one file name, so keep track of the folder
        // in which it is
        // Note #1: we use the last open file name to determine the folder that
        //          is to be remembered since on Windows 7, at least, it's
        //          possible to search for files from within the file dialog
        //          box, and the last file name should be the one we are most
        //          'interested' in...
        // Note #2: this doesn't, unfortunately, address the case where the user
        //          goes to a directory and then closes the file dialog box
        //          without selecting any open file name. There might be a way
        //          to get it to work, but that would involve using the exec()
        //          method rather than the static getOpenFilesNames() method,
        //          which would result in a non-native looking file dialog box
        //          (on Windows 7 at least), so it's not an option
        //          unfortunately...
        // Note #3: normally, we would use QFileInfo::canonicalPath(), but this
        //          requires an existing file, so use QFileInfo::path()
        //          instead...

        setActiveDirectory(QFileInfo(res[res.count()-1]).path());
    }

    // Return the file name(s)

    return res;
}

//==============================================================================

QString getSaveFileName(const QString &pCaption, const QString &pFileName,
                        const QString &pFilters, QString *pSelectedFilter)
{
    // Retrieve and return a save file name

    QFileInfo fileInfo = pFileName;
    QString res = Core::nativeCanonicalFileName(QFileDialog::getSaveFileName(qApp->activeWindow(),
                                                                             pCaption,
                                                                             !fileInfo.canonicalPath().compare(".")?
                                                                                activeDirectory()+QDir::separator()+fileInfo.fileName():
                                                                                pFileName,
                                                                             allFilters(pFilters),
                                                                             pSelectedFilter,
                                                                             QFileDialog::DontConfirmOverwrite));

    // Make sure that we have got a save file name

    if (!res.isEmpty()) {
        // Update our active directory
        // Note: normally, we would use QFileInfo::canonicalPath(), but this
        //       requires an existing file, so use QFileInfo::path() instead...

        QFileInfo resInfo = res;

        setActiveDirectory(resInfo.path());

        // Check whether the save file already exists

        if (resInfo.exists()) {
            // The save file already exists, so ask whether we want to overwrite
            // it

            if (QMessageBox::question(mainWindow(), pCaption,
                                      QObject::tr("<strong>%1</strong> already exists. Do you want to overwrite it?").arg(res),
                                      QMessageBox::Yes|QMessageBox::No,
                                      QMessageBox::Yes) == QMessageBox::No) {
                return QString();
            }
        }
    }

    // Everything went fine,so return the save file name

    return res;
}

//==============================================================================

QString getExistingDirectory(const QString &pCaption, const QString &pDirName,
                             const bool &pEmptyDir)
{
    // Retrieve and return an existing directory path
    // Note: normally, we would rely on QFileDialog::getExistingDirectory() to
    //       retrieve the path of an existing directory, but then we wouldn't be
    //       able to handle the case where the user cancels his/her action, so
    //       instead we create and execute our own QFileDialog object...

    QFileDialog dialog(qApp->activeWindow(), pCaption,
                       pDirName.isEmpty()?activeDirectory():pDirName);

    dialog.setOption(QFileDialog::ShowDirsOnly);

    if (dialog.exec() == QDialog::Accepted) {
        QString res = dialog.selectedFiles().first();

        if (!res.isEmpty()) {
            // We have retrieved a file name, so update our active directory

            setActiveDirectory(res);

            // Check whether the directory should be empty

            if (   pEmptyDir
                && QDir(res).entryInfoList(QDir::NoDotAndDotDot|QDir::AllEntries).count()) {
                QMessageBox::warning(qApp->activeWindow(), pCaption,
                                     QObject::tr("Please choose an empty directory."));

                return QString();
            }
        }

        return res;
    } else {
        return QString();
    }
}

//==============================================================================

void setFocusTo(QWidget *pWidget)
{
    // Give the focus to pWidget, but then revert the focus back to whoever had
    // it before, if needed

    if (!pWidget)
        return;

    QWidget *focusedWidget = qApp->activeWindow()?
                                 qApp->activeWindow()->focusWidget():
                                 0;

    if (   !focusedWidget
        || (pWidget->parentWidget() == focusedWidget->parentWidget())) {
        // Either there is no currently focused widget or the currently focused
        // widget and the one to which we want to set the focus share the same
        // parent, so set the focus to the given widget

        pWidget->setFocus();
    }
}

//==============================================================================

QMenu * newMenu(const QString &pName, QWidget *pParent)
{
    // Create and return a menu

    QMenu *res = new QMenu(pParent);

    res->setObjectName("menu"+pName.left(1).toUpper()+pName.right(pName.size()-1));

    return res;
}

//==============================================================================

QMenu * newMenu(const QIcon &pIcon, QWidget *pParent)
{
    // Create and return a menu

    QMenu *res = new QMenu(pParent);

    res->menuAction()->setIcon(pIcon);

    return res;
}

//==============================================================================

QAction * newAction(const bool &pCheckable, const QIcon &pIcon,
                    const QKeySequence &pKeySequence, QWidget *pParent)
{
    // Create and return an action

    QAction *res = new QAction(pParent);

    res->setCheckable(pCheckable);
    res->setIcon(pIcon);
    res->setShortcut(pKeySequence);

    return res;
}

//==============================================================================

QAction * newAction(const bool &pCheckable, const QKeySequence &pKeySequence,
                    QWidget *pParent)
{
    // Create and return an action

    QAction *res = new QAction(pParent);

    res->setCheckable(pCheckable);
    res->setShortcut(pKeySequence);

    return res;
}

//==============================================================================

QAction * newAction(const bool &pCheckable, QWidget *pParent)
{
    // Create and return an action

    QAction *res = new QAction(pParent);

    res->setCheckable(pCheckable);

    return res;
}

//==============================================================================

QAction * newAction(const QIcon &pIcon,
                    const QList<QKeySequence> &pKeySequences, QWidget *pParent)
{
    // Create and return an action

    QAction *res = new QAction(pParent);

    res->setIcon(pIcon);
    res->setShortcuts(pKeySequences);

    return res;
}

//==============================================================================

QAction * newAction(const QIcon &pIcon, const QKeySequence &pKeySequence,
                    QWidget *pParent)
{
    // Create and return an action

    QAction *res = new QAction(pParent);

    res->setIcon(pIcon);
    res->setShortcut(pKeySequence);

    return res;
}

//==============================================================================

QAction * newAction(const QIcon &pIcon, QWidget *pParent)
{
    // Create and return an action

    QAction *res = new QAction(pParent);

    res->setIcon(pIcon);

    return res;
}

//==============================================================================

QAction * newAction(const QKeySequence &pKeySequence, QWidget *pParent)
{
    // Create and return an action

    QAction *res = new QAction(pParent);

    res->setShortcut(pKeySequence);

    return res;
}

//==============================================================================

QAction * newAction(const QKeySequence::StandardKey &pStandardKey,
                    QWidget *pParent)
{
    // Create and return an action

    QAction *res = new QAction(pParent);

    res->setShortcut(pStandardKey);

    return res;
}

//==============================================================================

QFrame * newLineWidget(const bool &pHorizontal, const QColor &pColor,
                       QWidget *pParent)
{
    // Create and return a 'real' line widget, i.e. one which is 1 pixel wide,
    // using a QFrame widget

    QFrame *res = new QFrame(pParent);

    res->setStyleSheet(QString("QFrame {"
                               "    border: 1px solid rgb(%1, %2, %3);"
                               "}").arg(QString::number(pColor.red()),
                                        QString::number(pColor.green()),
                                        QString::number(pColor.blue())));

    if (pHorizontal) {
        res->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
        res->setFixedHeight(1);
    } else {
        res->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
        res->setFixedWidth(1);
    }

    return res;
}

//==============================================================================

QFrame * newLineWidget(const bool &pHorizontal, QWidget *pParent)
{
    // Create and return a 'real' horizontal line widget

    return newLineWidget(pHorizontal, borderColor(), pParent);
}

//==============================================================================

QFrame * newLineWidget(const QColor &pColor, QWidget *pParent)
{
    // Create and return a 'real' horizontal line widget

    return newLineWidget(true, pColor, pParent);
}

//==============================================================================

QFrame * newLineWidget(QWidget *pParent)
{
    // Create and return a 'real' horizontal line widget

    return newLineWidget(true, borderColor(), pParent);
}

//==============================================================================

QString iconDataUri(const QString &pIcon, const int &pWidth, const int &pHeight,
                    const QIcon::Mode &pMode)
{
    // Convert an icon, which resource name is given, to a data URI, after
    // having resized it, if requested

    QIcon icon(pIcon);

    if (icon.isNull())
        return QString();

    QByteArray data;
    QBuffer buffer(&data);
    QSize iconSize = icon.availableSizes().first();

    buffer.open(QIODevice::WriteOnly);
    icon.pixmap((pWidth == -1)?iconSize.width():pWidth,
                (pHeight == -1)?iconSize.height():pHeight,
                pMode).save(&buffer, "PNG");

    return QString("data:image/png;base64,%1").arg(QString(data.toBase64()));
}

//==============================================================================

void showEnableWidget(QWidget *pWidget, const bool &pVisible,
                      const bool &pEnabled)
{
    // Show/enable or hide/disable the given widget

    pWidget->setVisible(pVisible);
    pWidget->setEnabled(pVisible && pEnabled);
}

//==============================================================================

QColor lockedColor(const QColor &pColor)
{
    // Return the resulting locked version of the given colour

    int r = pColor.red();
    int g = pColor.green();
    int b = pColor.blue();

    static const int lr = 255;
    static const int lg = 0;
    static const int lb = 0;

    static const double alpha = 0.05;
    static const double oneMinusAlpha = 1.0-alpha;

    return QColor(alpha*lr+oneMinusAlpha*r,
                  alpha*lg+oneMinusAlpha*g,
                  alpha*lb+oneMinusAlpha*b);
}

//==============================================================================

QString fileTypes(const FileTypes &pFileTypes, const bool &pCheckMimeTypes,
                  const QStringList &pMimeTypes)
{
    // Convert and return as a string the given file types, using the given MIME
    // types, if required

    QString res = QString();

    foreach (FileType *fileType, pFileTypes) {
        if (!pCheckMimeTypes || pMimeTypes.contains(fileType->mimeType())) {
            if (!res.isEmpty())
                res += ";;";

            res +=  fileType->description()
                   +" (*."+fileType->fileExtension()+")";
        }
    }

    return res;
}

//==============================================================================

QString fileTypes(const FileTypes &pFileTypes)
{
    // Convert and return as a string the given file types

    return fileTypes(pFileTypes, false, QStringList());
}

//==============================================================================

QString fileTypes(const FileTypes &pFileTypes, const QStringList &pMimeTypes)
{
    // Convert and return as a string the given file types, using the given MIME
    // types, if any

    return fileTypes(pFileTypes, true, pMimeTypes);
}

//==============================================================================

}   // namespace Core
}   // namespace OpenCOR

//==============================================================================
// End of file
//==============================================================================
<|endoftext|>