<commit_before>//=======================================================================
// Copyright (c) 2014-2015 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#define CPM_BENCHMARK "Tests Benchmarks"
#include "benchmark.hpp"

//Bench assignment
CPM_BENCH() {
    CPM_TWO_PASS_NS(
        "r = a (s) [std][assign][s]",
        [](std::size_t d){ return std::make_tuple(svec(d), svec(d)); },
        [](svec& a, svec& r){ r = a; }
        );

    CPM_TWO_PASS_NS(
        "r = a (d) [std][assign][d]",
        [](std::size_t d){ return std::make_tuple(dvec(d), dvec(d)); },
        [](dvec& a, dvec& r){ r = a; }
        );

    CPM_TWO_PASS_NS(
        "r = a (c) [std][assign][c]",
        [](std::size_t d){ return std::make_tuple(cvec(d), cvec(d)); },
        [](cvec& a, cvec& r){ r = a; }
        );

    CPM_TWO_PASS_NS(
        "r = a (z) [std][assign][z]",
        [](std::size_t d){ return std::make_tuple(zvec(d), zvec(d)); },
        [](zvec& a, zvec& r){ r = a; }
        );

    CPM_TWO_PASS_NS_P(
        mat_policy_2d,
        "R = A (d) [std][assign][d]",
        [](auto d1, auto d2){ return std::make_tuple(dmat(d1, d2), dmat(d1, d2)); },
        [](dmat& A, dmat& R){ R = A; }
        );
}

//Bench addition
CPM_BENCH() {
    CPM_TWO_PASS_NS(
        "r = a + b [std][add][d]",
        [](std::size_t d){ return std::make_tuple(dvec(d), dvec(d), dvec(d)); },
        [](dvec& a, dvec& b, dvec& r){ r = a + b; }
        );

    CPM_TWO_PASS_NS(
        "r = a + b + c [std][add][d]",
        [](std::size_t d){ return std::make_tuple(dvec(d), dvec(d), dvec(d), dvec(d)); },
        [](dvec& a, dvec& b, dvec& c, dvec& r){ r = a + b + c; },
        [](std::size_t d){ return 2 * d; }
        );

    CPM_TWO_PASS_NS_P(
        mat_policy_2d,
        "R = A + B [std][add][d]",
        [](auto d1, auto d2){ return std::make_tuple(dmat(d1, d2), dmat(d1, d2), dmat(d1, d2)); },
        [](dmat& A, dmat& B, dmat& R){ R = A + B; }
        );

    CPM_TWO_PASS_NS_P(
        mat_policy_2d,
        "R += A [std][add][d]",
        [](auto d1, auto d2){ return std::make_tuple(dmat(d1, d2), dmat(d1, d2)); },
        [](dmat& A, dmat& R){ R += A; }
        );

    CPM_TWO_PASS_NS_P(
        mat_policy_2d,
        "R += A + B [std][add][d]",
        [](auto d1, auto d2){ return std::make_tuple(dmat(d1, d2), dmat(d1, d2), dmat(d1, d2)); },
        [](dmat& A, dmat& B, dmat& R){ R += A + B; },
        [](std::size_t d1, std::size_t d2){ return 2 * d1 * d2; }
        );

    CPM_TWO_PASS_NS_P(
        mat_policy_2d,
        "R = A + B + C [std][add][s]",
        [](auto d1, auto d2){ return std::make_tuple(dmat(d1, d2), dmat(d1, d2), dmat(d1, d2), dmat(d1, d2)); },
        [](dmat& A, dmat& B, dmat& C, dmat& R){ R = A + B + C; },
        [](std::size_t d1, std::size_t d2){ return 2 * d1 * d2; }
        );

    CPM_TWO_PASS_NS(
        "r = a + b (c) [std][add][complex][c]",
        [](std::size_t d){ return std::make_tuple(cvec(d), cvec(d), cvec(d)); },
        [](cvec& a, cvec& b, cvec& r){ r = a + b; },
        [](std::size_t d){ return 2 * d; }
        );

    CPM_TWO_PASS_NS(
        "r = a + b (z) [std][add][complex][z]",
        [](std::size_t d){ return std::make_tuple(zvec(d), zvec(d), zvec(d)); },
        [](zvec& a, zvec& b, zvec& r){ r = a + b; },
        [](std::size_t d){ return 2 * d; }
        );
}

//Bench subtraction
CPM_BENCH() {
    CPM_TWO_PASS_NS(
        "r = a - b",
        [](std::size_t d){ return std::make_tuple(dvec(d), dvec(d), dvec(d)); },
        [](dvec& a, dvec& b, dvec& r){ r = a - b; }
        );

    CPM_TWO_PASS_NS_P(
        mat_policy_2d,
        "R = A - B",
        [](auto d1, auto d2){ return std::make_tuple(dmat(d1, d2), dmat(d1, d2), dmat(d1, d2)); },
        [](dmat& A, dmat& B, dmat& R){ R = A - B; }
        );
}

//Bench multiplication
CPM_BENCH() {
    CPM_TWO_PASS_NS(
        "r = a >> b",
        [](std::size_t d){ return std::make_tuple(dvec(d), dvec(d), dvec(d)); },
        [](dvec& a, dvec& b, dvec& r){ r = a >> b; }
        );

    CPM_TWO_PASS_NS(
        "r = a >> b (c)",
        [](std::size_t d){ return std::make_tuple(cvec(d), cvec(d), cvec(d)); },
        [](cvec& a, cvec& b, cvec& r){ r = a >> b; }
        );

    CPM_TWO_PASS_NS(
        "r = a >> b (z) [std][mul][complex][z]",
        [](std::size_t d){ return std::make_tuple(zvec(d), zvec(d), zvec(d)); },
        [](zvec& a, zvec& b, zvec& r){ r = a >> b; },
        [](std::size_t d){ return 6 * d; }
        );

    CPM_TWO_PASS_NS_P(
        mat_policy_2d,
        "R = A >> B",
        [](auto d1, auto d2){ return std::make_tuple(dmat(d1, d2), dmat(d1, d2), dmat(d1, d2)); },
        [](dmat& A, dmat& B, dmat& R){ R = A >> B; }
        );
}

//Bench division
CPM_BENCH() {
    CPM_TWO_PASS_NS(
        "r = a / b",
        [](std::size_t d){ return std::make_tuple(dvec(d), dvec(d), dvec(d)); },
        [](dvec& a, dvec& b, dvec& r){ r = a / b; }
        );

    CPM_TWO_PASS_NS(
        "r = a / b (c)",
        [](std::size_t d){ return std::make_tuple(cvec(d), cvec(d), cvec(d)); },
        [](cvec& a, cvec& b, cvec& r){ r = a / b; },
        [](std::size_t d){ return 6 * d; }
        );

    CPM_TWO_PASS_NS(
        "r = a / b (z)",
        [](std::size_t d){ return std::make_tuple(zvec(d), zvec(d), zvec(d)); },
        [](zvec& a, zvec& b, zvec& r){ r = a / b; },
        [](std::size_t d){ return 6 * d; }
        );

    CPM_TWO_PASS_NS_P(
        mat_policy_2d,
        "R = A / B",
        [](auto d1, auto d2){ return std::make_tuple(dmat(d1, d2), dmat(d1, d2), dmat(d1, d2)); },
        [](dmat& A, dmat& B, dmat& R){ R = A / B; }
        );
}

//Bench saxpy
CPM_BENCH() {
    CPM_TWO_PASS_NS(
        "saxpy [std][axpy][s]",
        [](std::size_t d){ return std::make_tuple(svec(d), svec(d)); },
        [](svec& a, svec& r){ r = a * 2.3 + r; }
        );

    CPM_TWO_PASS_NS(
        "daxpy [std][axpy][d]",
        [](std::size_t d){ return std::make_tuple(dvec(d), dvec(d)); },
        [](dvec& a, dvec& r){ r = a * 2.3 + r; }
        );
}

CPM_DIRECT_SECTION_TWO_PASS_NS("ssum [std][sum][sse][s]",
    CPM_SECTION_INIT([](std::size_t d1){ return std::make_tuple(0.0f, svec(d1)); }),
    CPM_SECTION_FUNCTOR("default", [](float& r, svec& a){ r = etl::sum(a); }),
    CPM_SECTION_FUNCTOR("std", [](float& r, svec& a){ r = etl::detail::sum_direct(a, etl::detail::sum_imple::STD); })
    SSE_SECTION_FUNCTOR("sse", [](float& r, svec& a){ r = etl::detail::sum_direct(a, etl::detail::sum_imple::SSE); })
    SSE_SECTION_FUNCTOR("avx", [](float& r, svec& a){ r = etl::detail::sum_direct(a, etl::detail::sum_imple::AVX); })
)

//Bench reductions
CPM_BENCH() {
    CPM_TWO_PASS_NS(
        "dsum [std][sum][d]",
        [](std::size_t d){ return std::make_tuple(0.0, dvec(d)); },
        [](double& a, dvec& b){ a = etl::sum(b); }
        );
}

//Bench transposition
CPM_BENCH() {
    CPM_TWO_PASS_NS_P(
        trans_policy,
        "r = tranpose(a) (s)",
        [](std::size_t d1, std::size_t d2){ return std::make_tuple(smat(d1, d2), smat(d1, d2)); },
        [](smat& a, smat& r){ r = a.transpose(); }
        );

    CPM_TWO_PASS_NS_P(
        trans_policy,
        "r = tranpose(a) (d)",
        [](std::size_t d1, std::size_t d2){ return std::make_tuple(dmat(d1, d2), dmat(d1, d2)); },
        [](dmat& a, dmat& r){ r = a.transpose(); }
        );

    CPM_TWO_PASS_NS_P(
        trans_policy,
        "a = tranpose(a) (s)",
        [](std::size_t d1, std::size_t d2){ return std::make_tuple(smat(d1, d2)); },
        [](smat& a){ a.transpose_inplace(); }
        );

    CPM_TWO_PASS_NS_P(
        trans_policy,
        "a = tranpose(a) (d)",
        [](std::size_t d1, std::size_t d2){ return std::make_tuple(dmat(d1, d2)); },
        [](dmat& a){ a.transpose_inplace(); }
        );
}

//Sigmoid benchmark
CPM_BENCH() {
    //Flops: 20 for exp, 1 for div, 1 for add

    CPM_TWO_PASS_NS(
        "r = sigmoid(a)",
        [](std::size_t d){ return std::make_tuple(dvec(d), dvec(d)); },
        [](dvec& a, dvec& r){ r = etl::sigmoid(a); },
        [](std::size_t d){ return 22 * d; }
        );

    CPM_TWO_PASS_NS_P(
        mat_policy_2d,
        "R = sigmoid(A)",
        [](auto d1, auto d2){ return std::make_tuple(dmat(d1, d2), dmat(d1, d2)); },
        [](dmat& A, dmat& R){ R = etl::sigmoid(A); },
        [](auto d1, auto d2){ return 22 * d1 * d2; }
        );
}

CPM_DIRECT_SECTION_TWO_PASS_NS_PF("sigmoid(s)", sigmoid_policy,
    FLOPS([](std::size_t d){ return 22 * d; }),
    CPM_SECTION_INIT([](std::size_t d){ return std::make_tuple(smat(d,d), smat(d,d)); }),
    CPM_SECTION_FUNCTOR("default", [](smat& a, smat& b){ a = etl::sigmoid(b); }),
    CPM_SECTION_FUNCTOR("fast", [](smat& a, smat& b){ a = etl::fast_sigmoid(b); }),
    CPM_SECTION_FUNCTOR("hard", [](smat& a, smat& b){ a = etl::hard_sigmoid(b); })
)

CPM_DIRECT_SECTION_TWO_PASS_NS_PF("sigmoid(d)", sigmoid_policy,
    FLOPS([](std::size_t d){ return 22 * d; }),
    CPM_SECTION_INIT([](std::size_t d){ return std::make_tuple(dmat(d,d), dmat(d,d)); }),
    CPM_SECTION_FUNCTOR("default", [](dmat& a, dmat& b){ a = etl::sigmoid(b); }),
    CPM_SECTION_FUNCTOR("fast", [](dmat& a, dmat& b){ a = etl::fast_sigmoid(b); }),
    CPM_SECTION_FUNCTOR("hard", [](dmat& a, dmat& b){ a = etl::hard_sigmoid(b); })
)
<commit_msg>Introduce dsum benchmark<commit_after>//=======================================================================
// Copyright (c) 2014-2015 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#define CPM_BENCHMARK "Tests Benchmarks"
#include "benchmark.hpp"

//Bench assignment
CPM_BENCH() {
    CPM_TWO_PASS_NS(
        "r = a (s) [std][assign][s]",
        [](std::size_t d){ return std::make_tuple(svec(d), svec(d)); },
        [](svec& a, svec& r){ r = a; }
        );

    CPM_TWO_PASS_NS(
        "r = a (d) [std][assign][d]",
        [](std::size_t d){ return std::make_tuple(dvec(d), dvec(d)); },
        [](dvec& a, dvec& r){ r = a; }
        );

    CPM_TWO_PASS_NS(
        "r = a (c) [std][assign][c]",
        [](std::size_t d){ return std::make_tuple(cvec(d), cvec(d)); },
        [](cvec& a, cvec& r){ r = a; }
        );

    CPM_TWO_PASS_NS(
        "r = a (z) [std][assign][z]",
        [](std::size_t d){ return std::make_tuple(zvec(d), zvec(d)); },
        [](zvec& a, zvec& r){ r = a; }
        );

    CPM_TWO_PASS_NS_P(
        mat_policy_2d,
        "R = A (d) [std][assign][d]",
        [](auto d1, auto d2){ return std::make_tuple(dmat(d1, d2), dmat(d1, d2)); },
        [](dmat& A, dmat& R){ R = A; }
        );
}

//Bench addition
CPM_BENCH() {
    CPM_TWO_PASS_NS(
        "r = a + b [std][add][d]",
        [](std::size_t d){ return std::make_tuple(dvec(d), dvec(d), dvec(d)); },
        [](dvec& a, dvec& b, dvec& r){ r = a + b; }
        );

    CPM_TWO_PASS_NS(
        "r = a + b + c [std][add][d]",
        [](std::size_t d){ return std::make_tuple(dvec(d), dvec(d), dvec(d), dvec(d)); },
        [](dvec& a, dvec& b, dvec& c, dvec& r){ r = a + b + c; },
        [](std::size_t d){ return 2 * d; }
        );

    CPM_TWO_PASS_NS_P(
        mat_policy_2d,
        "R = A + B [std][add][d]",
        [](auto d1, auto d2){ return std::make_tuple(dmat(d1, d2), dmat(d1, d2), dmat(d1, d2)); },
        [](dmat& A, dmat& B, dmat& R){ R = A + B; }
        );

    CPM_TWO_PASS_NS_P(
        mat_policy_2d,
        "R += A [std][add][d]",
        [](auto d1, auto d2){ return std::make_tuple(dmat(d1, d2), dmat(d1, d2)); },
        [](dmat& A, dmat& R){ R += A; }
        );

    CPM_TWO_PASS_NS_P(
        mat_policy_2d,
        "R += A + B [std][add][d]",
        [](auto d1, auto d2){ return std::make_tuple(dmat(d1, d2), dmat(d1, d2), dmat(d1, d2)); },
        [](dmat& A, dmat& B, dmat& R){ R += A + B; },
        [](std::size_t d1, std::size_t d2){ return 2 * d1 * d2; }
        );

    CPM_TWO_PASS_NS_P(
        mat_policy_2d,
        "R = A + B + C [std][add][s]",
        [](auto d1, auto d2){ return std::make_tuple(dmat(d1, d2), dmat(d1, d2), dmat(d1, d2), dmat(d1, d2)); },
        [](dmat& A, dmat& B, dmat& C, dmat& R){ R = A + B + C; },
        [](std::size_t d1, std::size_t d2){ return 2 * d1 * d2; }
        );

    CPM_TWO_PASS_NS(
        "r = a + b (c) [std][add][complex][c]",
        [](std::size_t d){ return std::make_tuple(cvec(d), cvec(d), cvec(d)); },
        [](cvec& a, cvec& b, cvec& r){ r = a + b; },
        [](std::size_t d){ return 2 * d; }
        );

    CPM_TWO_PASS_NS(
        "r = a + b (z) [std][add][complex][z]",
        [](std::size_t d){ return std::make_tuple(zvec(d), zvec(d), zvec(d)); },
        [](zvec& a, zvec& b, zvec& r){ r = a + b; },
        [](std::size_t d){ return 2 * d; }
        );
}

//Bench subtraction
CPM_BENCH() {
    CPM_TWO_PASS_NS(
        "r = a - b",
        [](std::size_t d){ return std::make_tuple(dvec(d), dvec(d), dvec(d)); },
        [](dvec& a, dvec& b, dvec& r){ r = a - b; }
        );

    CPM_TWO_PASS_NS_P(
        mat_policy_2d,
        "R = A - B",
        [](auto d1, auto d2){ return std::make_tuple(dmat(d1, d2), dmat(d1, d2), dmat(d1, d2)); },
        [](dmat& A, dmat& B, dmat& R){ R = A - B; }
        );
}

//Bench multiplication
CPM_BENCH() {
    CPM_TWO_PASS_NS(
        "r = a >> b",
        [](std::size_t d){ return std::make_tuple(dvec(d), dvec(d), dvec(d)); },
        [](dvec& a, dvec& b, dvec& r){ r = a >> b; }
        );

    CPM_TWO_PASS_NS(
        "r = a >> b (c)",
        [](std::size_t d){ return std::make_tuple(cvec(d), cvec(d), cvec(d)); },
        [](cvec& a, cvec& b, cvec& r){ r = a >> b; }
        );

    CPM_TWO_PASS_NS(
        "r = a >> b (z) [std][mul][complex][z]",
        [](std::size_t d){ return std::make_tuple(zvec(d), zvec(d), zvec(d)); },
        [](zvec& a, zvec& b, zvec& r){ r = a >> b; },
        [](std::size_t d){ return 6 * d; }
        );

    CPM_TWO_PASS_NS_P(
        mat_policy_2d,
        "R = A >> B",
        [](auto d1, auto d2){ return std::make_tuple(dmat(d1, d2), dmat(d1, d2), dmat(d1, d2)); },
        [](dmat& A, dmat& B, dmat& R){ R = A >> B; }
        );
}

//Bench division
CPM_BENCH() {
    CPM_TWO_PASS_NS(
        "r = a / b",
        [](std::size_t d){ return std::make_tuple(dvec(d), dvec(d), dvec(d)); },
        [](dvec& a, dvec& b, dvec& r){ r = a / b; }
        );

    CPM_TWO_PASS_NS(
        "r = a / b (c)",
        [](std::size_t d){ return std::make_tuple(cvec(d), cvec(d), cvec(d)); },
        [](cvec& a, cvec& b, cvec& r){ r = a / b; },
        [](std::size_t d){ return 6 * d; }
        );

    CPM_TWO_PASS_NS(
        "r = a / b (z)",
        [](std::size_t d){ return std::make_tuple(zvec(d), zvec(d), zvec(d)); },
        [](zvec& a, zvec& b, zvec& r){ r = a / b; },
        [](std::size_t d){ return 6 * d; }
        );

    CPM_TWO_PASS_NS_P(
        mat_policy_2d,
        "R = A / B",
        [](auto d1, auto d2){ return std::make_tuple(dmat(d1, d2), dmat(d1, d2), dmat(d1, d2)); },
        [](dmat& A, dmat& B, dmat& R){ R = A / B; }
        );
}

//Bench saxpy
CPM_BENCH() {
    CPM_TWO_PASS_NS(
        "saxpy [std][axpy][s]",
        [](std::size_t d){ return std::make_tuple(svec(d), svec(d)); },
        [](svec& a, svec& r){ r = a * 2.3 + r; }
        );

    CPM_TWO_PASS_NS(
        "daxpy [std][axpy][d]",
        [](std::size_t d){ return std::make_tuple(dvec(d), dvec(d)); },
        [](dvec& a, dvec& r){ r = a * 2.3 + r; }
        );
}

CPM_DIRECT_SECTION_TWO_PASS_NS("ssum [std][sum][sse][s]",
    CPM_SECTION_INIT([](std::size_t d1){ return std::make_tuple(0.0f, svec(d1)); }),
    CPM_SECTION_FUNCTOR("default", [](float& r, svec& a){ r = etl::sum(a); }),
    CPM_SECTION_FUNCTOR("std", [](float& r, svec& a){ r = etl::detail::sum_direct(a, etl::detail::sum_imple::STD); })
    SSE_SECTION_FUNCTOR("sse", [](float& r, svec& a){ r = etl::detail::sum_direct(a, etl::detail::sum_imple::SSE); })
    SSE_SECTION_FUNCTOR("avx", [](float& r, svec& a){ r = etl::detail::sum_direct(a, etl::detail::sum_imple::AVX); })
)

CPM_DIRECT_SECTION_TWO_PASS_NS("dsum [std][sum][sse][s]",
    CPM_SECTION_INIT([](std::size_t d1){ return std::make_tuple(0.0, dvec(d1)); }),
    CPM_SECTION_FUNCTOR("default", [](double& r, dvec& a){ r = etl::sum(a); }),
    CPM_SECTION_FUNCTOR("std", [](double& r, dvec& a){ r = etl::detail::sum_direct(a, etl::detail::sum_imple::STD); })
    SSE_SECTION_FUNCTOR("sse", [](double& r, dvec& a){ r = etl::detail::sum_direct(a, etl::detail::sum_imple::SSE); })
    SSE_SECTION_FUNCTOR("avx", [](double& r, dvec& a){ r = etl::detail::sum_direct(a, etl::detail::sum_imple::AVX); })
)

//Bench transposition
CPM_BENCH() {
    CPM_TWO_PASS_NS_P(
        trans_policy,
        "r = tranpose(a) (s)",
        [](std::size_t d1, std::size_t d2){ return std::make_tuple(smat(d1, d2), smat(d1, d2)); },
        [](smat& a, smat& r){ r = a.transpose(); }
        );

    CPM_TWO_PASS_NS_P(
        trans_policy,
        "r = tranpose(a) (d)",
        [](std::size_t d1, std::size_t d2){ return std::make_tuple(dmat(d1, d2), dmat(d1, d2)); },
        [](dmat& a, dmat& r){ r = a.transpose(); }
        );

    CPM_TWO_PASS_NS_P(
        trans_policy,
        "a = tranpose(a) (s)",
        [](std::size_t d1, std::size_t d2){ return std::make_tuple(smat(d1, d2)); },
        [](smat& a){ a.transpose_inplace(); }
        );

    CPM_TWO_PASS_NS_P(
        trans_policy,
        "a = tranpose(a) (d)",
        [](std::size_t d1, std::size_t d2){ return std::make_tuple(dmat(d1, d2)); },
        [](dmat& a){ a.transpose_inplace(); }
        );
}

//Sigmoid benchmark
CPM_BENCH() {
    //Flops: 20 for exp, 1 for div, 1 for add

    CPM_TWO_PASS_NS(
        "r = sigmoid(a)",
        [](std::size_t d){ return std::make_tuple(dvec(d), dvec(d)); },
        [](dvec& a, dvec& r){ r = etl::sigmoid(a); },
        [](std::size_t d){ return 22 * d; }
        );

    CPM_TWO_PASS_NS_P(
        mat_policy_2d,
        "R = sigmoid(A)",
        [](auto d1, auto d2){ return std::make_tuple(dmat(d1, d2), dmat(d1, d2)); },
        [](dmat& A, dmat& R){ R = etl::sigmoid(A); },
        [](auto d1, auto d2){ return 22 * d1 * d2; }
        );
}

CPM_DIRECT_SECTION_TWO_PASS_NS_PF("sigmoid(s)", sigmoid_policy,
    FLOPS([](std::size_t d){ return 22 * d; }),
    CPM_SECTION_INIT([](std::size_t d){ return std::make_tuple(smat(d,d), smat(d,d)); }),
    CPM_SECTION_FUNCTOR("default", [](smat& a, smat& b){ a = etl::sigmoid(b); }),
    CPM_SECTION_FUNCTOR("fast", [](smat& a, smat& b){ a = etl::fast_sigmoid(b); }),
    CPM_SECTION_FUNCTOR("hard", [](smat& a, smat& b){ a = etl::hard_sigmoid(b); })
)

CPM_DIRECT_SECTION_TWO_PASS_NS_PF("sigmoid(d)", sigmoid_policy,
    FLOPS([](std::size_t d){ return 22 * d; }),
    CPM_SECTION_INIT([](std::size_t d){ return std::make_tuple(dmat(d,d), dmat(d,d)); }),
    CPM_SECTION_FUNCTOR("default", [](dmat& a, dmat& b){ a = etl::sigmoid(b); }),
    CPM_SECTION_FUNCTOR("fast", [](dmat& a, dmat& b){ a = etl::fast_sigmoid(b); }),
    CPM_SECTION_FUNCTOR("hard", [](dmat& a, dmat& b){ a = etl::hard_sigmoid(b); })
)
<|endoftext|>


<commit_before>/**
 * Mutable Fibonacci Heap implementation
 * © 2013 Philips Healthcare
 * Author: Maurice Termeer
 * Version 8 (2013-07-16)
 */

#ifndef _FIBONACCI_HEAP_
#define _FIBONACCI_HEAP_

#include <array>

template<typename T>
class fibonacci_heap
{
public:
	struct node {
		T element;
		bool marked;
		node* parent;
		node *first, *last;
		std::size_t degree;
		node *next, *prev;
	};

	typedef T value_type;
	typedef std::size_t size_type;
	typedef const T& const_reference;
	typedef T& reference;
	typedef const node* const_pointer;
	typedef node* pointer;

	struct iterator {
		const_reference operator*() const {
			return p_->element;
		}

		reference operator*() {
			return p_->element;
		}

		iterator() { }

		iterator(pointer p) : p_(p) { }

		pointer p_;
	};

	fibonacci_heap()
		: first_(nullptr), last_(nullptr), min_element_(nullptr), n_(0) {
	}

	std::size_t size() const {
		return n_;
	}

	iterator top() const
	{
		return iterator(min_element_);
	}

	iterator insert(const_reference element)
	{
		pointer new_node = new node();
		new_node->element = element;
		new_node->marked = false;
		new_node->parent = nullptr;
		new_node->degree = 0;

		if (first_ == nullptr) {
			new_node->prev = nullptr;
			new_node->next = nullptr;
			first_ = new_node;
			last_ = new_node;
		} else {
			new_node->prev = last_;
			new_node->next = nullptr;
			last_->next = new_node;
			last_ = new_node;
		}

		if (n_ == 0 || new_node->element < min_element_->element
		) {
			min_element_ = new_node;
		}

		++n_;

		return iterator(new_node);
	}

	void pop()
	{
		if (min_element_->prev != nullptr) {
			min_element_->prev->next = min_element_->next;
		}

		if (min_element_->next != nullptr) {
			min_element_->next->prev = min_element_->prev;
		}

		if (first_ == min_element_) {
			first_ = min_element_->next;
		}

		if (last_ == min_element_) {
			last_ = min_element_->prev;
		}

		for (pointer p = min_element_->first; p != nullptr;) {
			pointer q = p;
			p = p->next;

			q->marked = false;
			q->parent = nullptr;

			if (first_ == nullptr) {
				q->prev = nullptr;
				q->next = nullptr;
				first_ = q;
				last_ = q;
			} else {
				q->prev = last_;
				q->next = nullptr;
				last_->next = q;
				last_ = q;
			}
		}

		delete min_element_;
		min_element_ = nullptr;

		merge_roots();

		--n_;
	}

	void decrease_key(iterator it)
	{
		pointer p = it.p_;
		pointer parent = p->parent;

		if (parent == nullptr) return;
		if (!(p->element < parent->element)) return;

		for (;;) {
			if (last_ == nullptr) {
				p->prev = nullptr;
				p->next = nullptr;
				first_ = last_ = p;
			} else {
				p->prev = last_;
				p->next = nullptr;
				last_->next = p;
				last_ = p;
			}

			p->parent = nullptr;
			p->marked = false;

			p = parent;
			parent = p->parent;

			if (parent == nullptr) break;

			if (!p->marked) {
				p->marked = true;
				break;
			}
		}
	}

private:
	void merge_roots()
	{
		min_element_ = nullptr;
		degrees_.fill(nullptr);

		auto i = first_;

		while (i != nullptr) {
			auto root = i;
			i = i->next;

			auto degree = root->degree;

			while (true) {
				auto k = degrees_[degree];

				if (k == nullptr) {
					degrees_[degree] = root;
					break;
				} else {
					auto other = k;

					if (other->element < root->element) {
						if (root->prev != nullptr) {
							root->prev->next = root->next;
						}

						if (root->next != nullptr) {
							root->next->prev = root->prev;
						}

						if (root->parent != nullptr) {
							if (root->parent->first == root) {
								root->parent->first = root->next;
							}

							if (root->parent->last == root) {
								root->parent->last = root->prev;
							}

							--root->parent->degree;
						} else {
							if (first_ == root) {
								first_ = root->next;
							}

							if (last_ == root) {
								last_ = root->prev;
							}
						}

						root->parent = other;

						if (other->first == nullptr) {
							other->first = root;
							other->last = root;
							root->next = nullptr;
							root->prev = nullptr;
						} else {
							root->prev = other->last;
							root->next = nullptr;
							other->last->next = root;
							other->last = root;
						}

						++other->degree;
						root = other;
					} else {
						if (other->prev != nullptr) {
							other->prev->next = other->next;
						}

						if (other->next != nullptr) {
							other->next->prev = other->prev;
						}

						if (other->parent != nullptr) {
							if (other->parent->first == other) {
								other->parent->first = other->next;
							}

							if (other->parent->last == other) {
								other->parent->last = other->prev;
							}

							--other->parent->degree;
						} else {
							if (first_ == other) {
								first_ = other->next;
							}

							if (last_ == other) {
								last_ = other->prev;
							}
						}

						other->parent = root;

						if (root->first == nullptr) {
							root->first = other;
							root->last = other;
							other->next = nullptr;
							other->prev = nullptr;
						} else {
							other->prev = root->last;
							other->next = nullptr;
							root->last->next = other;
							root->last = other;
						}

						++other->parent->degree;
					}

					degrees_[degree] = nullptr;
					++degree;
				}
			}

			if (min_element_ == nullptr ||
				root->element < min_element_->element
			) {
				min_element_ = root;
			}
		}
	}

	std::array<pointer, sizeof(std::size_t) * 8> degrees_;
	pointer first_, last_;
	pointer min_element_;
	size_type n_;
};

#endif // _FIBONACCI_HEAP_
<commit_msg>explicit memory initialization in node construction<commit_after>/**
 * Mutable Fibonacci Heap implementation
 * © 2013 Philips Healthcare
 * Author: Maurice Termeer
 * Version 9 (2013-07-17)
 */

#ifndef _FIBONACCI_HEAP_
#define _FIBONACCI_HEAP_

#include <array>
#include <iostream>

template<typename T>
class fibonacci_heap
{
public:
	struct node {
		T element;
		bool marked;
		node* parent;
		node *first, *last;
		std::size_t degree;
		node *next, *prev;
	};

	typedef T value_type;
	typedef std::size_t size_type;
	typedef const T& const_reference;
	typedef T& reference;
	typedef const node* const_pointer;
	typedef node* pointer;

	struct iterator {
		const_reference operator*() const {
			return p_->element;
		}

		reference operator*() {
			return p_->element;
		}

		iterator() { }

		iterator(pointer p) : p_(p) { }

		pointer p_;
	};

	fibonacci_heap()
		: first_(nullptr), last_(nullptr), min_element_(nullptr), n_(0) {
	}

	std::size_t size() const {
		return n_;
	}

	iterator top() const
	{
		return iterator(min_element_);
	}

	iterator insert(const_reference element)
	{
		pointer new_node = new node();
		new_node->element = element;
		new_node->marked = false;
		new_node->parent = nullptr;
		new_node->degree = 0;
		new_node->first = nullptr;
		new_node->last = nullptr;

		if (first_ == nullptr) {
			new_node->prev = nullptr;
			new_node->next = nullptr;
			first_ = new_node;
			last_ = new_node;
		} else {
			new_node->prev = last_;
			new_node->next = nullptr;
			last_->next = new_node;
			last_ = new_node;
		}

		if (n_ == 0 || new_node->element < min_element_->element
		) {
			min_element_ = new_node;
		}

		++n_;

		return iterator(new_node);
	}

	void pop()
	{
		if (min_element_->prev != nullptr) {
			min_element_->prev->next = min_element_->next;
		}

		if (min_element_->next != nullptr) {
			min_element_->next->prev = min_element_->prev;
		}

		if (first_ == min_element_) {
			first_ = min_element_->next;
		}

		if (last_ == min_element_) {
			last_ = min_element_->prev;
		}

		for (pointer p = min_element_->first; p != nullptr;) {
			pointer q = p;
			p = p->next;

			q->marked = false;
			q->parent = nullptr;

			if (first_ == nullptr) {
				q->prev = nullptr;
				q->next = nullptr;
				first_ = q;
				last_ = q;
			} else {
				q->prev = last_;
				q->next = nullptr;
				last_->next = q;
				last_ = q;
			}
		}

		delete min_element_;
		min_element_ = nullptr;

		merge_roots();

		--n_;
	}

	void decrease_key(iterator it)
	{
		pointer p = it.p_;
		pointer parent = p->parent;

		if (parent == nullptr) return;
		if (!(p->element < parent->element)) return;

		for (;;) {
			if (last_ == nullptr) {
				p->prev = nullptr;
				p->next = nullptr;
				first_ = last_ = p;
			} else {
				p->prev = last_;
				p->next = nullptr;
				last_->next = p;
				last_ = p;
			}

			p->parent = nullptr;
			p->marked = false;

			p = parent;
			parent = p->parent;

			if (parent == nullptr) break;

			if (!p->marked) {
				p->marked = true;
				break;
			}
		}
	}

private:
	void merge_roots()
	{
		min_element_ = nullptr;
		degrees_.fill(nullptr);

		auto i = first_;

		while (i != nullptr) {
			auto root = i;
			i = i->next;

			auto degree = root->degree;

			while (true) {
				auto k = degrees_[degree];

				if (k == nullptr) {
					degrees_[degree] = root;
					break;
				} else {
					auto other = k;

					if (other->element < root->element) {
						if (root->prev != nullptr) {
							root->prev->next = root->next;
						}

						if (root->next != nullptr) {
							root->next->prev = root->prev;
						}

						if (root->parent != nullptr) {
							if (root->parent->first == root) {
								root->parent->first = root->next;
							}

							if (root->parent->last == root) {
								root->parent->last = root->prev;
							}

							--root->parent->degree;
						} else {
							if (first_ == root) {
								first_ = root->next;
							}

							if (last_ == root) {
								last_ = root->prev;
							}
						}

						root->parent = other;

						if (other->first == nullptr) {
							other->first = root;
							other->last = root;
							root->next = nullptr;
							root->prev = nullptr;
						} else {
							root->prev = other->last;
							root->next = nullptr;
							other->last->next = root;
							other->last = root;
						}

						++other->degree;
						root = other;
					} else {
						if (other->prev != nullptr) {
							other->prev->next = other->next;
						}

						if (other->next != nullptr) {
							other->next->prev = other->prev;
						}

						if (other->parent != nullptr) {
							if (other->parent->first == other) {
								other->parent->first = other->next;
							}

							if (other->parent->last == other) {
								other->parent->last = other->prev;
							}

							--other->parent->degree;
						} else {
							if (first_ == other) {
								first_ = other->next;
							}

							if (last_ == other) {
								last_ = other->prev;
							}
						}

						other->parent = root;

						if (root->first == nullptr) {
							root->first = other;
							root->last = other;
							other->next = nullptr;
							other->prev = nullptr;
						} else {
							other->prev = root->last;
							other->next = nullptr;
							root->last->next = other;
							root->last = other;
						}

						++other->parent->degree;
					}

					degrees_[degree] = nullptr;
					++degree;
				}
			}

			if (min_element_ == nullptr ||
				root->element < min_element_->element
			) {
				min_element_ = root;
			}
		}
	}

	std::array<pointer, sizeof(std::size_t) * 8> degrees_;
	pointer first_, last_;
	pointer min_element_;
	size_type n_;
};

#endif // _FIBONACCI_HEAP_
<|endoftext|>


<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/chromeos/cros/brightness_library.h"

#include "base/basictypes.h"
#include "base/logging.h"
#include "base/message_loop.h"
#include "base/observer_list.h"
#include "chrome/browser/chromeos/cros/cros_library.h"
#include "content/browser/browser_thread.h"
#include "third_party/cros/chromeos_brightness.h"

namespace chromeos {

class BrightnessLibraryImpl : public BrightnessLibrary {
 public:
  BrightnessLibraryImpl() : brightness_connection_(NULL) {}

  ~BrightnessLibraryImpl() {
    if (brightness_connection_) {
      chromeos::DisconnectBrightness(brightness_connection_);
      brightness_connection_ = NULL;
    }
  }

  void Init() {
    if (CrosLibrary::Get()->EnsureLoaded()) {
      CHECK(!brightness_connection_) << "Already intialized";
      brightness_connection_ =
          chromeos::MonitorBrightnessV2(&BrightnessChangedHandler, this);
    }
  }

  void AddObserver(Observer* observer) {
    observers_.AddObserver(observer);
  }

  void RemoveObserver(Observer* observer) {
    observers_.RemoveObserver(observer);
  }

  void DecreaseScreenBrightness(bool allow_off) {
    if (chromeos::DecreaseScreenBrightness)
      chromeos::DecreaseScreenBrightness(allow_off);
  }

  void IncreaseScreenBrightness() {
    if (chromeos::IncreaseScreenBrightness)
      chromeos::IncreaseScreenBrightness();
  }

 private:
  static void BrightnessChangedHandler(void* object,
                                       int brightness_level,
                                       bool user_initiated) {
    BrightnessLibraryImpl* self = static_cast<BrightnessLibraryImpl*>(object);
    self->OnBrightnessChanged(brightness_level, user_initiated);
  }

  void OnBrightnessChanged(int brightness_level, bool user_initiated) {
    // Make sure we run on the UI thread.
    if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
      BrowserThread::PostTask(
          BrowserThread::UI, FROM_HERE,
          NewRunnableMethod(this,
                            &BrightnessLibraryImpl::OnBrightnessChanged,
                            brightness_level,
                            user_initiated));
      return;
    }

    FOR_EACH_OBSERVER(Observer, observers_,
                      BrightnessChanged(brightness_level, user_initiated));
  }

  chromeos::BrightnessConnection brightness_connection_;

  ObserverList<Observer> observers_;

  DISALLOW_COPY_AND_ASSIGN(BrightnessLibraryImpl);
};

class BrightnessLibraryStubImpl : public BrightnessLibrary {
 public:
  BrightnessLibraryStubImpl() {}
  ~BrightnessLibraryStubImpl() {}
  void Init() {}
  void AddObserver(Observer* observer) {}
  void RemoveObserver(Observer* observer) {}
  void DecreaseScreenBrightness(bool allow_off) {}
  void IncreaseScreenBrightness() {}
};

// static
BrightnessLibrary* BrightnessLibrary::GetImpl(bool stub) {
  BrightnessLibrary* impl;
  if (stub)
    impl = new BrightnessLibraryStubImpl();
  else
    impl = new BrightnessLibraryImpl();
  impl->Init();
  return impl;
}

}  // namespace chromeos

// Needed for NewRunnableMethod() call above.
DISABLE_RUNNABLE_METHOD_REFCOUNT(chromeos::BrightnessLibraryImpl);
<commit_msg>cros: Add missing "virtual" and OVERRIDE to overridden virtual methods of BrightnessLibrary.<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/chromeos/cros/brightness_library.h"

#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/message_loop.h"
#include "base/observer_list.h"
#include "chrome/browser/chromeos/cros/cros_library.h"
#include "content/browser/browser_thread.h"
#include "third_party/cros/chromeos_brightness.h"

namespace chromeos {

class BrightnessLibraryImpl : public BrightnessLibrary {
 public:
  BrightnessLibraryImpl() : brightness_connection_(NULL) {}

  virtual ~BrightnessLibraryImpl() {
    if (brightness_connection_) {
      chromeos::DisconnectBrightness(brightness_connection_);
      brightness_connection_ = NULL;
    }
  }

  // Begin BrightnessLibrary implementation.
  virtual void Init() OVERRIDE {
    if (CrosLibrary::Get()->EnsureLoaded()) {
      CHECK(!brightness_connection_) << "Already intialized";
      brightness_connection_ =
          chromeos::MonitorBrightnessV2(&BrightnessChangedHandler, this);
    }
  }

  virtual void AddObserver(Observer* observer) OVERRIDE {
    observers_.AddObserver(observer);
  }

  virtual void RemoveObserver(Observer* observer) OVERRIDE {
    observers_.RemoveObserver(observer);
  }

  virtual void DecreaseScreenBrightness(bool allow_off) OVERRIDE {
    if (chromeos::DecreaseScreenBrightness)
      chromeos::DecreaseScreenBrightness(allow_off);
  }

  virtual void IncreaseScreenBrightness() OVERRIDE {
    if (chromeos::IncreaseScreenBrightness)
      chromeos::IncreaseScreenBrightness();
  }
  // End BrightnessLibrary implementation.

 private:
  static void BrightnessChangedHandler(void* object,
                                       int brightness_level,
                                       bool user_initiated) {
    BrightnessLibraryImpl* self = static_cast<BrightnessLibraryImpl*>(object);
    self->OnBrightnessChanged(brightness_level, user_initiated);
  }

  void OnBrightnessChanged(int brightness_level, bool user_initiated) {
    // Make sure we run on the UI thread.
    if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
      BrowserThread::PostTask(
          BrowserThread::UI, FROM_HERE,
          NewRunnableMethod(this,
                            &BrightnessLibraryImpl::OnBrightnessChanged,
                            brightness_level,
                            user_initiated));
      return;
    }

    FOR_EACH_OBSERVER(Observer, observers_,
                      BrightnessChanged(brightness_level, user_initiated));
  }

  chromeos::BrightnessConnection brightness_connection_;

  ObserverList<Observer> observers_;

  DISALLOW_COPY_AND_ASSIGN(BrightnessLibraryImpl);
};

class BrightnessLibraryStubImpl : public BrightnessLibrary {
 public:
  BrightnessLibraryStubImpl() {}
  virtual ~BrightnessLibraryStubImpl() {}
  virtual void Init() OVERRIDE {}
  virtual void AddObserver(Observer* observer) OVERRIDE {}
  virtual void RemoveObserver(Observer* observer) OVERRIDE {}
  virtual void DecreaseScreenBrightness(bool allow_off) OVERRIDE {}
  virtual void IncreaseScreenBrightness() OVERRIDE {}
};

// static
BrightnessLibrary* BrightnessLibrary::GetImpl(bool stub) {
  BrightnessLibrary* impl;
  if (stub)
    impl = new BrightnessLibraryStubImpl();
  else
    impl = new BrightnessLibraryImpl();
  impl->Init();
  return impl;
}

}  // namespace chromeos

// Needed for NewRunnableMethod() call above.
DISABLE_RUNNABLE_METHOD_REFCOUNT(chromeos::BrightnessLibraryImpl);
<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/dom_ui/new_tab_page_sync_handler.h"

#include "app/l10n_util.h"
#include "base/callback.h"
#include "base/string_split.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/net/chrome_url_request_context.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/pref_names.h"
#include "grit/browser_resources.h"
#include "grit/generated_resources.h"
#include "net/base/cookie_monster.h"
#include "net/url_request/url_request_context.h"

// Default URL for the sync web interface.
//
// TODO(idana): when we figure out how we are going to allow third parties to
// plug in their own sync engine, we should allow this value to be
// configurable.
static const char kSyncDefaultViewOnlineUrl[] = "http://docs.google.com";

// TODO(idana): the following code was originally copied from
// toolbar_importer.h/cc and it needs to be moved to a common Google Accounts
// utility.

// A simple pair of fields that identify a set of Google cookies, used to
// filter from a larger set.
struct GoogleCookieFilter {
  // The generalized, fully qualified URL of pages where
  // cookies with id |cookie_id| are obtained / accessed.
  const char* url;
  // The id of the cookie this filter is selecting,
  // with name/value delimiter (i.e '=').
  const char* cookie_id;
};

// Filters to select Google GAIA cookies.
static const GoogleCookieFilter kGAIACookieFilters[] = {
  { "http://.google.com/",       "SID=" },     // Gmail.
  // Add filters here for other interesting cookies that should result in
  // showing the promotions (e.g ASIDAS for dasher accounts).
};

bool IsGoogleGAIACookieInstalled() {
  for (size_t i = 0; i < arraysize(kGAIACookieFilters); ++i) {
    // Since we are running on the UI thread don't call GetURLRequestContext().
    net::CookieStore* store =
        Profile::GetDefaultRequestContext()->GetCookieStore();
    GURL url(kGAIACookieFilters[i].url);
    net::CookieOptions options;
    options.set_include_httponly();  // The SID cookie might be httponly.
    std::string cookies = store->GetCookiesWithOptions(url, options);
    std::vector<std::string> cookie_list;
    base::SplitString(cookies, ';', &cookie_list);
    for (std::vector<std::string>::iterator current = cookie_list.begin();
         current != cookie_list.end();
         ++current) {
      size_t position =
          current->find(kGAIACookieFilters[i].cookie_id);
      if (0 == position)
        return true;
    }
  }
  return false;
}

NewTabPageSyncHandler::NewTabPageSyncHandler() : sync_service_(NULL),
  waiting_for_initial_page_load_(true) {
}

NewTabPageSyncHandler::~NewTabPageSyncHandler() {
  if (sync_service_)
    sync_service_->RemoveObserver(this);
}

// static
NewTabPageSyncHandler::MessageType
    NewTabPageSyncHandler::FromSyncStatusMessageType(
        sync_ui_util::MessageType type) {
  switch (type) {
    case sync_ui_util::SYNC_ERROR:
      return SYNC_ERROR;
    case sync_ui_util::PRE_SYNCED:
    case sync_ui_util::SYNCED:
    default:
      return HIDE;
  }
}

DOMMessageHandler* NewTabPageSyncHandler::Attach(DOMUI* dom_ui) {
  sync_service_ = dom_ui->GetProfile()->GetProfileSyncService();
  DCHECK(sync_service_);  // This shouldn't get called by an incognito NTP.
  DCHECK(!sync_service_->IsManaged());  // And neither if sync is managed.
  sync_service_->AddObserver(this);
  return DOMMessageHandler::Attach(dom_ui);
}

void NewTabPageSyncHandler::RegisterMessages() {
  dom_ui_->RegisterMessageCallback("GetSyncMessage",
      NewCallback(this, &NewTabPageSyncHandler::HandleGetSyncMessage));
  dom_ui_->RegisterMessageCallback("SyncLinkClicked",
      NewCallback(this, &NewTabPageSyncHandler::HandleSyncLinkClicked));
}

void NewTabPageSyncHandler::HandleGetSyncMessage(const ListValue* args) {
  waiting_for_initial_page_load_ = false;
  BuildAndSendSyncStatus();
}

void NewTabPageSyncHandler::HideSyncStatusSection() {
  SendSyncMessageToPage(HIDE, std::string(), std::string());
}

void NewTabPageSyncHandler::BuildAndSendSyncStatus() {
  DCHECK(!waiting_for_initial_page_load_);

  // Hide the sync status section if sync is managed or disabled entirely.
  if (!sync_service_ || sync_service_->IsManaged()) {
    HideSyncStatusSection();
    return;
  }

  // Don't show sync status if setup is not complete.
  if (!sync_service_->HasSyncSetupCompleted()) {
    return;
  }

  // Once sync has been enabled, the supported "sync statuses" for the NNTP
  // from the user's perspective are:
  //
  // "Sync error", when we can't authenticate or establish a connection with
  //               the sync server (appropriate information appended to
  //               message).
  string16 status_msg;
  string16 link_text;
  sync_ui_util::MessageType type =
      sync_ui_util::GetStatusLabels(sync_service_, &status_msg, &link_text);
  SendSyncMessageToPage(FromSyncStatusMessageType(type),
                        UTF16ToUTF8(status_msg), UTF16ToUTF8(link_text));
}

void NewTabPageSyncHandler::HandleSyncLinkClicked(const ListValue* args) {
  DCHECK(!waiting_for_initial_page_load_);
  DCHECK(sync_service_);
  if (!sync_service_->IsSyncEnabled())
    return;
  if (sync_service_->HasSyncSetupCompleted()) {
    if (sync_service_->GetAuthError().state() ==
        GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS ||
        sync_service_->GetAuthError().state() ==
        GoogleServiceAuthError::CAPTCHA_REQUIRED ||
        sync_service_->GetAuthError().state() ==
        GoogleServiceAuthError::ACCOUNT_DELETED ||
        sync_service_->GetAuthError().state() ==
        GoogleServiceAuthError::ACCOUNT_DISABLED ||
        sync_service_->GetAuthError().state() ==
        GoogleServiceAuthError::SERVICE_UNAVAILABLE) {
      sync_service_->ShowLoginDialog(NULL);
      return;
    }
    DictionaryValue value;
    value.SetString("syncEnabledMessage",
                    l10n_util::GetStringFUTF16(IDS_SYNC_NTP_SYNCED_TO,
                        sync_service_->GetAuthenticatedUsername()));
    dom_ui_->CallJavascriptFunction(L"syncAlreadyEnabled", value);
  } else {
    // User clicked the 'Start now' link to begin syncing.
    ProfileSyncService::SyncEvent(ProfileSyncService::START_FROM_NTP);
    sync_service_->ShowLoginDialog(NULL);
  }
}

void NewTabPageSyncHandler::OnStateChanged() {
  // Don't do anything if the page has not yet loaded.
  if (waiting_for_initial_page_load_)
    return;
  BuildAndSendSyncStatus();
}

void NewTabPageSyncHandler::SendSyncMessageToPage(
    MessageType type, std::string msg,
    std::string linktext) {
  DictionaryValue value;
  std::string user;
  std::string title;
  std::string linkurl;

  // If there is no message to show, we should hide the sync section
  // altogether.
  if (type == HIDE || msg.empty()) {
    value.SetBoolean("syncsectionisvisible", false);
  } else {  // type == SYNC_ERROR
    title = l10n_util::GetStringUTF8(IDS_SYNC_NTP_SYNC_SECTION_ERROR_TITLE);

    value.SetBoolean("syncsectionisvisible", true);
    value.SetString("msg", msg);
    value.SetString("title", title);
    if (linktext.empty()) {
      value.SetBoolean("linkisvisible", false);
    } else {
      value.SetBoolean("linkisvisible", true);
      value.SetString("linktext", linktext);

      // The only time we set the URL is when the user is synced and we need to
      // show a link to a web interface (e.g. http://docs.google.com). When we
      // set that URL, HandleSyncLinkClicked won't be called when the user
      // clicks on the link.
      if (linkurl.empty()) {
        value.SetBoolean("linkurlisset", false);
      } else {
        value.SetBoolean("linkurlisset", true);
        value.SetString("linkurl", linkurl);
      }
    }
  }
  dom_ui_->CallJavascriptFunction(L"syncMessageChanged", value);
}
<commit_msg>We will show the link on the NTP when a passphrase is required, but we don't take action on it.  In that case, open the wizard when the link is clicked (it already goes to the correct place).<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/dom_ui/new_tab_page_sync_handler.h"

#include "app/l10n_util.h"
#include "base/callback.h"
#include "base/string_split.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/net/chrome_url_request_context.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/pref_names.h"
#include "grit/browser_resources.h"
#include "grit/generated_resources.h"
#include "net/base/cookie_monster.h"
#include "net/url_request/url_request_context.h"

// Default URL for the sync web interface.
//
// TODO(idana): when we figure out how we are going to allow third parties to
// plug in their own sync engine, we should allow this value to be
// configurable.
static const char kSyncDefaultViewOnlineUrl[] = "http://docs.google.com";

// TODO(idana): the following code was originally copied from
// toolbar_importer.h/cc and it needs to be moved to a common Google Accounts
// utility.

// A simple pair of fields that identify a set of Google cookies, used to
// filter from a larger set.
struct GoogleCookieFilter {
  // The generalized, fully qualified URL of pages where
  // cookies with id |cookie_id| are obtained / accessed.
  const char* url;
  // The id of the cookie this filter is selecting,
  // with name/value delimiter (i.e '=').
  const char* cookie_id;
};

// Filters to select Google GAIA cookies.
static const GoogleCookieFilter kGAIACookieFilters[] = {
  { "http://.google.com/",       "SID=" },     // Gmail.
  // Add filters here for other interesting cookies that should result in
  // showing the promotions (e.g ASIDAS for dasher accounts).
};

bool IsGoogleGAIACookieInstalled() {
  for (size_t i = 0; i < arraysize(kGAIACookieFilters); ++i) {
    // Since we are running on the UI thread don't call GetURLRequestContext().
    net::CookieStore* store =
        Profile::GetDefaultRequestContext()->GetCookieStore();
    GURL url(kGAIACookieFilters[i].url);
    net::CookieOptions options;
    options.set_include_httponly();  // The SID cookie might be httponly.
    std::string cookies = store->GetCookiesWithOptions(url, options);
    std::vector<std::string> cookie_list;
    base::SplitString(cookies, ';', &cookie_list);
    for (std::vector<std::string>::iterator current = cookie_list.begin();
         current != cookie_list.end();
         ++current) {
      size_t position =
          current->find(kGAIACookieFilters[i].cookie_id);
      if (0 == position)
        return true;
    }
  }
  return false;
}

NewTabPageSyncHandler::NewTabPageSyncHandler() : sync_service_(NULL),
  waiting_for_initial_page_load_(true) {
}

NewTabPageSyncHandler::~NewTabPageSyncHandler() {
  if (sync_service_)
    sync_service_->RemoveObserver(this);
}

// static
NewTabPageSyncHandler::MessageType
    NewTabPageSyncHandler::FromSyncStatusMessageType(
        sync_ui_util::MessageType type) {
  switch (type) {
    case sync_ui_util::SYNC_ERROR:
      return SYNC_ERROR;
    case sync_ui_util::PRE_SYNCED:
    case sync_ui_util::SYNCED:
    default:
      return HIDE;
  }
}

DOMMessageHandler* NewTabPageSyncHandler::Attach(DOMUI* dom_ui) {
  sync_service_ = dom_ui->GetProfile()->GetProfileSyncService();
  DCHECK(sync_service_);  // This shouldn't get called by an incognito NTP.
  DCHECK(!sync_service_->IsManaged());  // And neither if sync is managed.
  sync_service_->AddObserver(this);
  return DOMMessageHandler::Attach(dom_ui);
}

void NewTabPageSyncHandler::RegisterMessages() {
  dom_ui_->RegisterMessageCallback("GetSyncMessage",
      NewCallback(this, &NewTabPageSyncHandler::HandleGetSyncMessage));
  dom_ui_->RegisterMessageCallback("SyncLinkClicked",
      NewCallback(this, &NewTabPageSyncHandler::HandleSyncLinkClicked));
}

void NewTabPageSyncHandler::HandleGetSyncMessage(const ListValue* args) {
  waiting_for_initial_page_load_ = false;
  BuildAndSendSyncStatus();
}

void NewTabPageSyncHandler::HideSyncStatusSection() {
  SendSyncMessageToPage(HIDE, std::string(), std::string());
}

void NewTabPageSyncHandler::BuildAndSendSyncStatus() {
  DCHECK(!waiting_for_initial_page_load_);

  // Hide the sync status section if sync is managed or disabled entirely.
  if (!sync_service_ || sync_service_->IsManaged()) {
    HideSyncStatusSection();
    return;
  }

  // Don't show sync status if setup is not complete.
  if (!sync_service_->HasSyncSetupCompleted()) {
    return;
  }

  // Once sync has been enabled, the supported "sync statuses" for the NNTP
  // from the user's perspective are:
  //
  // "Sync error", when we can't authenticate or establish a connection with
  //               the sync server (appropriate information appended to
  //               message).
  string16 status_msg;
  string16 link_text;
  sync_ui_util::MessageType type =
      sync_ui_util::GetStatusLabels(sync_service_, &status_msg, &link_text);
  SendSyncMessageToPage(FromSyncStatusMessageType(type),
                        UTF16ToUTF8(status_msg), UTF16ToUTF8(link_text));
}

void NewTabPageSyncHandler::HandleSyncLinkClicked(const ListValue* args) {
  DCHECK(!waiting_for_initial_page_load_);
  DCHECK(sync_service_);
  if (!sync_service_->IsSyncEnabled())
    return;
  if (sync_service_->HasSyncSetupCompleted()) {
    if (sync_service_->GetAuthError().state() ==
        GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS ||
        sync_service_->GetAuthError().state() ==
        GoogleServiceAuthError::CAPTCHA_REQUIRED ||
        sync_service_->GetAuthError().state() ==
        GoogleServiceAuthError::ACCOUNT_DELETED ||
        sync_service_->GetAuthError().state() ==
        GoogleServiceAuthError::ACCOUNT_DISABLED ||
        sync_service_->GetAuthError().state() ==
        GoogleServiceAuthError::SERVICE_UNAVAILABLE ||
        sync_service_->observed_passphrase_required()) {
      sync_service_->ShowLoginDialog(NULL);
      return;
    }
    DictionaryValue value;
    value.SetString("syncEnabledMessage",
                    l10n_util::GetStringFUTF16(IDS_SYNC_NTP_SYNCED_TO,
                        sync_service_->GetAuthenticatedUsername()));
    dom_ui_->CallJavascriptFunction(L"syncAlreadyEnabled", value);
  } else {
    // User clicked the 'Start now' link to begin syncing.
    ProfileSyncService::SyncEvent(ProfileSyncService::START_FROM_NTP);
    sync_service_->ShowLoginDialog(NULL);
  }
}

void NewTabPageSyncHandler::OnStateChanged() {
  // Don't do anything if the page has not yet loaded.
  if (waiting_for_initial_page_load_)
    return;
  BuildAndSendSyncStatus();
}

void NewTabPageSyncHandler::SendSyncMessageToPage(
    MessageType type, std::string msg,
    std::string linktext) {
  DictionaryValue value;
  std::string user;
  std::string title;
  std::string linkurl;

  // If there is no message to show, we should hide the sync section
  // altogether.
  if (type == HIDE || msg.empty()) {
    value.SetBoolean("syncsectionisvisible", false);
  } else {  // type == SYNC_ERROR
    title = l10n_util::GetStringUTF8(IDS_SYNC_NTP_SYNC_SECTION_ERROR_TITLE);

    value.SetBoolean("syncsectionisvisible", true);
    value.SetString("msg", msg);
    value.SetString("title", title);
    if (linktext.empty()) {
      value.SetBoolean("linkisvisible", false);
    } else {
      value.SetBoolean("linkisvisible", true);
      value.SetString("linktext", linktext);

      // The only time we set the URL is when the user is synced and we need to
      // show a link to a web interface (e.g. http://docs.google.com). When we
      // set that URL, HandleSyncLinkClicked won't be called when the user
      // clicks on the link.
      if (linkurl.empty()) {
        value.SetBoolean("linkurlisset", false);
      } else {
        value.SetBoolean("linkurlisset", true);
        value.SetString("linkurl", linkurl);
      }
    }
  }
  dom_ui_->CallJavascriptFunction(L"syncMessageChanged", value);
}
<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/gtk/bookmark_menu_controller_gtk.h"

#include <gtk/gtk.h>

#include "app/gtk_dnd_util.h"
#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "base/string_util.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/browser/gtk/bookmark_utils_gtk.h"
#include "chrome/browser/gtk/gtk_chrome_button.h"
#include "chrome/browser/gtk/gtk_theme_provider.h"
#include "chrome/browser/gtk/gtk_util.h"
#include "chrome/browser/gtk/menu_gtk.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/page_navigator.h"
#include "gfx/gtk_util.h"
#include "grit/app_resources.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "webkit/glue/window_open_disposition.h"

namespace {

// TODO(estade): It might be a good idea to vary this by locale.
const int kMaxChars = 50;

void SetImageMenuItem(GtkWidget* menu_item,
                      const BookmarkNode* node,
                      BookmarkModel* model) {
  GdkPixbuf* pixbuf = bookmark_utils::GetPixbufForNode(node, model, true);
  gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_item),
                                gtk_image_new_from_pixbuf(pixbuf));
  g_object_unref(pixbuf);
}

const BookmarkNode* GetNodeFromMenuItem(GtkWidget* menu_item) {
  return static_cast<const BookmarkNode*>(
      g_object_get_data(G_OBJECT(menu_item), "bookmark-node"));
}

const BookmarkNode* GetParentNodeFromEmptyMenu(GtkWidget* menu) {
  return static_cast<const BookmarkNode*>(
      g_object_get_data(G_OBJECT(menu), "parent-node"));
}

void* AsVoid(const BookmarkNode* node) {
  return const_cast<BookmarkNode*>(node);
}

// The context menu has been dismissed, restore the X and application grabs
// to whichever menu last had them. (Assuming that menu is still showing.)
// The event mask in this function is taken from gtkmenu.c.
void OnContextMenuHide(GtkWidget* context_menu, GtkWidget* grab_menu) {
  gtk_util::GrabAllInput(grab_menu);
  // Match the ref we took when connecting this signal.
  g_object_unref(grab_menu);
}

}  // namespace

BookmarkMenuController::BookmarkMenuController(Browser* browser,
                                               Profile* profile,
                                               PageNavigator* navigator,
                                               GtkWindow* window,
                                               const BookmarkNode* node,
                                               int start_child_index)
    : browser_(browser),
      profile_(profile),
      page_navigator_(navigator),
      parent_window_(window),
      model_(profile->GetBookmarkModel()),
      node_(node),
      drag_icon_(NULL),
      ignore_button_release_(false),
      triggering_widget_(NULL) {
  menu_ = gtk_menu_new();
  BuildMenu(node, start_child_index, menu_);
  g_signal_connect(menu_, "hide",
                   G_CALLBACK(OnMenuHiddenThunk), this);
  gtk_widget_show_all(menu_);
}

BookmarkMenuController::~BookmarkMenuController() {
  profile_->GetBookmarkModel()->RemoveObserver(this);
  gtk_menu_popdown(GTK_MENU(menu_));
}

void BookmarkMenuController::Popup(GtkWidget* widget, gint button_type,
                                   guint32 timestamp) {
  profile_->GetBookmarkModel()->AddObserver(this);

  triggering_widget_ = widget;
  gtk_chrome_button_set_paint_state(GTK_CHROME_BUTTON(widget),
                                    GTK_STATE_ACTIVE);
  gtk_menu_popup(GTK_MENU(menu_), NULL, NULL,
                 &MenuGtk::WidgetMenuPositionFunc,
                 widget, button_type, timestamp);
}

void BookmarkMenuController::BookmarkModelChanged() {
  gtk_menu_popdown(GTK_MENU(menu_));
}

void BookmarkMenuController::BookmarkNodeFavIconLoaded(
    BookmarkModel* model, const BookmarkNode* node) {
  std::map<const BookmarkNode*, GtkWidget*>::iterator it =
      node_to_menu_widget_map_.find(node);
  if (it != node_to_menu_widget_map_.end())
    SetImageMenuItem(it->second, node, model);
}

void BookmarkMenuController::WillExecuteCommand() {
  gtk_menu_popdown(GTK_MENU(menu_));
}

void BookmarkMenuController::CloseMenu() {
  context_menu_->Cancel();
}

void BookmarkMenuController::NavigateToMenuItem(
    GtkWidget* menu_item,
    WindowOpenDisposition disposition) {
  const BookmarkNode* node = GetNodeFromMenuItem(menu_item);
  DCHECK(node);
  DCHECK(page_navigator_);
  page_navigator_->OpenURL(
      node->GetURL(), GURL(), disposition, PageTransition::AUTO_BOOKMARK);
}

void BookmarkMenuController::BuildMenu(const BookmarkNode* parent,
                                       int start_child_index,
                                       GtkWidget* menu) {
  DCHECK(!parent->GetChildCount() ||
         start_child_index < parent->GetChildCount());

  g_signal_connect(menu, "button-press-event",
                   G_CALLBACK(OnButtonPressedThunk), this);

  for (int i = start_child_index; i < parent->GetChildCount(); ++i) {
    const BookmarkNode* node = parent->GetChild(i);

    // This breaks on word boundaries. Ideally we would break on character
    // boundaries.
    std::wstring elided_name =
        l10n_util::TruncateString(node->GetTitle(), kMaxChars);
    GtkWidget* menu_item =
        gtk_image_menu_item_new_with_label(WideToUTF8(elided_name).c_str());
    g_object_set_data(G_OBJECT(menu_item), "bookmark-node", AsVoid(node));
    SetImageMenuItem(menu_item, node, profile_->GetBookmarkModel());
    gtk_util::SetAlwaysShowImage(menu_item);

    g_signal_connect(menu_item, "button-release-event",
                     G_CALLBACK(OnButtonReleasedThunk), this);
    if (node->is_url()) {
      g_signal_connect(menu_item, "activate",
                       G_CALLBACK(OnMenuItemActivatedThunk), this);
    } else if (node->is_folder()) {
      GtkWidget* submenu = gtk_menu_new();
      BuildMenu(node, 0, submenu);
      gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item), submenu);
    } else {
      NOTREACHED();
    }

    gtk_drag_source_set(menu_item, GDK_BUTTON1_MASK, NULL, 0,
        static_cast<GdkDragAction>(GDK_ACTION_COPY | GDK_ACTION_LINK));
    int target_mask = gtk_dnd_util::CHROME_BOOKMARK_ITEM;
    if (node->is_url())
      target_mask |= gtk_dnd_util::TEXT_URI_LIST | gtk_dnd_util::NETSCAPE_URL;
    gtk_dnd_util::SetSourceTargetListFromCodeMask(menu_item, target_mask);
    g_signal_connect(menu_item, "drag-begin",
                     G_CALLBACK(OnMenuItemDragBeginThunk), this);
    g_signal_connect(menu_item, "drag-end",
                     G_CALLBACK(OnMenuItemDragEndThunk), this);
    g_signal_connect(menu_item, "drag-data-get",
                     G_CALLBACK(OnMenuItemDragGetThunk), this);

    // It is important to connect to this signal after setting up the drag
    // source because we only want to stifle the menu's default handler and
    // not the handler that the drag source uses.
    if (node->is_folder()) {
      g_signal_connect(menu_item, "button-press-event",
                       G_CALLBACK(OnFolderButtonPressedThunk), this);
    }

    gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
    node_to_menu_widget_map_[node] = menu_item;
  }

  if (parent->GetChildCount() == 0) {
    GtkWidget* empty_menu = gtk_menu_item_new_with_label(
        l10n_util::GetStringUTF8(IDS_MENU_EMPTY_SUBMENU).c_str());
    gtk_widget_set_sensitive(empty_menu, FALSE);
    g_object_set_data(G_OBJECT(menu), "parent-node", AsVoid(parent));
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), empty_menu);
  }
}

gboolean BookmarkMenuController::OnButtonPressed(
    GtkWidget* sender,
    GdkEventButton* event) {
  ignore_button_release_ = false;
  GtkMenuShell* menu_shell = GTK_MENU_SHELL(sender);

  if (event->button == 3) {
    // If the cursor is outside our bounds, pass this event up to the parent.
    if (!gtk_util::WidgetContainsCursor(sender)) {
      if (menu_shell->parent_menu_shell) {
        return OnButtonPressed(menu_shell->parent_menu_shell, event);
      } else {
        // We are the top level menu; we can propagate no further.
        return FALSE;
      }
    }

    // This will return NULL if we are not an empty menu.
    const BookmarkNode* parent = GetParentNodeFromEmptyMenu(sender);
    bool is_empty_menu = !!parent;
    // If there is no active menu item and we are not an empty menu, then do
    // nothing.
    GtkWidget* menu_item = menu_shell->active_menu_item;
    if (!is_empty_menu && !menu_item)
      return FALSE;

    const BookmarkNode* node =
        menu_item ? GetNodeFromMenuItem(menu_item) : NULL;
    DCHECK_NE(is_empty_menu, !!node);
    if (!is_empty_menu)
      parent = node->GetParent();

    // Show the right click menu and stop processing this button event.
    std::vector<const BookmarkNode*> nodes;
    if (node)
      nodes.push_back(node);
    context_menu_controller_.reset(
        new BookmarkContextMenuController(
            parent_window_, this, profile_,
            page_navigator_, parent, nodes));
    context_menu_.reset(
        new MenuGtk(NULL, context_menu_controller_->menu_model()));

    // Our bookmark folder menu loses the grab to the context menu. When the
    // context menu is hidden, re-assert our grab.
    GtkWidget* grabbing_menu = gtk_grab_get_current();
    g_object_ref(grabbing_menu);
    g_signal_connect(context_menu_->widget(), "hide",
                     G_CALLBACK(OnContextMenuHide), grabbing_menu);

    context_menu_->PopupAsContext(event->time);
    return TRUE;
  }

  return FALSE;
}

gboolean BookmarkMenuController::OnButtonReleased(
    GtkWidget* sender,
    GdkEventButton* event) {
  if (ignore_button_release_) {
    // Don't handle this message; it was a drag.
    ignore_button_release_ = false;
    return FALSE;
  }

  // Releasing either button 1 or 2 should trigger the bookmark.
  if (!gtk_menu_item_get_submenu(GTK_MENU_ITEM(sender))) {
    // The menu item is a link node.
    if (event->button == 1 || event->button == 2) {
      WindowOpenDisposition disposition =
          event_utils::DispositionFromEventFlags(event->state);
      NavigateToMenuItem(sender, disposition);

      // We need to manually dismiss the popup menu because we're overriding
      // button-release-event.
      gtk_menu_popdown(GTK_MENU(menu_));
      return TRUE;
    }
  } else {
    // The menu item is a folder node.
    if (event->button == 1) {
      gtk_menu_popup(GTK_MENU(gtk_menu_item_get_submenu(GTK_MENU_ITEM(sender))),
                     sender->parent, sender, NULL, NULL,
                     event->button, event->time);
    }
  }

  return FALSE;
}

gboolean BookmarkMenuController::OnFolderButtonPressed(
    GtkWidget* sender, GdkEventButton* event) {
  // The button press may start a drag; don't let the default handler run.
  if (event->button == 1)
    return TRUE;
  return FALSE;
}

void BookmarkMenuController::OnMenuHidden(GtkWidget* menu) {
  if (triggering_widget_)
    gtk_chrome_button_unset_paint_state(GTK_CHROME_BUTTON(triggering_widget_));
}

void BookmarkMenuController::OnMenuItemActivated(GtkWidget* menu_item) {
  NavigateToMenuItem(menu_item, CURRENT_TAB);
}

void BookmarkMenuController::OnMenuItemDragBegin(GtkWidget* menu_item,
                                                 GdkDragContext* drag_context) {
  // The parent menu item might be removed during the drag. Ref it so |button|
  // won't get destroyed.
  g_object_ref(menu_item->parent);

  // Signal to any future OnButtonReleased calls that we're dragging instead of
  // pressing.
  ignore_button_release_ = true;

  const BookmarkNode* node = bookmark_utils::BookmarkNodeForWidget(menu_item);
  drag_icon_ = bookmark_utils::GetDragRepresentationForNode(
      node, model_, GtkThemeProvider::GetFrom(profile_));
  gint x, y;
  gtk_widget_get_pointer(menu_item, &x, &y);
  gtk_drag_set_icon_widget(drag_context, drag_icon_, x, y);

  // Hide our node.
  gtk_widget_hide(menu_item);
}

void BookmarkMenuController::OnMenuItemDragEnd(GtkWidget* menu_item,
                                               GdkDragContext* drag_context) {
  gtk_widget_show(menu_item);
  g_object_unref(menu_item->parent);

  gtk_widget_destroy(drag_icon_);
  drag_icon_ = NULL;
}

void BookmarkMenuController::OnMenuItemDragGet(
    GtkWidget* widget, GdkDragContext* context,
    GtkSelectionData* selection_data,
    guint target_type, guint time) {
  const BookmarkNode* node = bookmark_utils::BookmarkNodeForWidget(widget);
  bookmark_utils::WriteBookmarkToSelection(node, selection_data, target_type,
                                           profile_);
}
<commit_msg>GTK: improve bookmark menu subfolder drag workaround.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/gtk/bookmark_menu_controller_gtk.h"

#include <gtk/gtk.h>

#include "app/gtk_dnd_util.h"
#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "base/string_util.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/browser/gtk/bookmark_utils_gtk.h"
#include "chrome/browser/gtk/gtk_chrome_button.h"
#include "chrome/browser/gtk/gtk_theme_provider.h"
#include "chrome/browser/gtk/gtk_util.h"
#include "chrome/browser/gtk/menu_gtk.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/page_navigator.h"
#include "gfx/gtk_util.h"
#include "grit/app_resources.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "webkit/glue/window_open_disposition.h"

namespace {

// TODO(estade): It might be a good idea to vary this by locale.
const int kMaxChars = 50;

void SetImageMenuItem(GtkWidget* menu_item,
                      const BookmarkNode* node,
                      BookmarkModel* model) {
  GdkPixbuf* pixbuf = bookmark_utils::GetPixbufForNode(node, model, true);
  gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_item),
                                gtk_image_new_from_pixbuf(pixbuf));
  g_object_unref(pixbuf);
}

const BookmarkNode* GetNodeFromMenuItem(GtkWidget* menu_item) {
  return static_cast<const BookmarkNode*>(
      g_object_get_data(G_OBJECT(menu_item), "bookmark-node"));
}

const BookmarkNode* GetParentNodeFromEmptyMenu(GtkWidget* menu) {
  return static_cast<const BookmarkNode*>(
      g_object_get_data(G_OBJECT(menu), "parent-node"));
}

void* AsVoid(const BookmarkNode* node) {
  return const_cast<BookmarkNode*>(node);
}

// The context menu has been dismissed, restore the X and application grabs
// to whichever menu last had them. (Assuming that menu is still showing.)
void OnContextMenuHide(GtkWidget* context_menu, GtkWidget* grab_menu) {
  gtk_util::GrabAllInput(grab_menu);

  // Match the ref we took when connecting this signal.
  g_object_unref(grab_menu);
}

}  // namespace

BookmarkMenuController::BookmarkMenuController(Browser* browser,
                                               Profile* profile,
                                               PageNavigator* navigator,
                                               GtkWindow* window,
                                               const BookmarkNode* node,
                                               int start_child_index)
    : browser_(browser),
      profile_(profile),
      page_navigator_(navigator),
      parent_window_(window),
      model_(profile->GetBookmarkModel()),
      node_(node),
      drag_icon_(NULL),
      ignore_button_release_(false),
      triggering_widget_(NULL) {
  menu_ = gtk_menu_new();
  BuildMenu(node, start_child_index, menu_);
  g_signal_connect(menu_, "hide",
                   G_CALLBACK(OnMenuHiddenThunk), this);
  gtk_widget_show_all(menu_);
}

BookmarkMenuController::~BookmarkMenuController() {
  profile_->GetBookmarkModel()->RemoveObserver(this);
  gtk_menu_popdown(GTK_MENU(menu_));
}

void BookmarkMenuController::Popup(GtkWidget* widget, gint button_type,
                                   guint32 timestamp) {
  profile_->GetBookmarkModel()->AddObserver(this);

  triggering_widget_ = widget;
  gtk_chrome_button_set_paint_state(GTK_CHROME_BUTTON(widget),
                                    GTK_STATE_ACTIVE);
  gtk_menu_popup(GTK_MENU(menu_), NULL, NULL,
                 &MenuGtk::WidgetMenuPositionFunc,
                 widget, button_type, timestamp);
}

void BookmarkMenuController::BookmarkModelChanged() {
  gtk_menu_popdown(GTK_MENU(menu_));
}

void BookmarkMenuController::BookmarkNodeFavIconLoaded(
    BookmarkModel* model, const BookmarkNode* node) {
  std::map<const BookmarkNode*, GtkWidget*>::iterator it =
      node_to_menu_widget_map_.find(node);
  if (it != node_to_menu_widget_map_.end())
    SetImageMenuItem(it->second, node, model);
}

void BookmarkMenuController::WillExecuteCommand() {
  gtk_menu_popdown(GTK_MENU(menu_));
}

void BookmarkMenuController::CloseMenu() {
  context_menu_->Cancel();
}

void BookmarkMenuController::NavigateToMenuItem(
    GtkWidget* menu_item,
    WindowOpenDisposition disposition) {
  const BookmarkNode* node = GetNodeFromMenuItem(menu_item);
  DCHECK(node);
  DCHECK(page_navigator_);
  page_navigator_->OpenURL(
      node->GetURL(), GURL(), disposition, PageTransition::AUTO_BOOKMARK);
}

void BookmarkMenuController::BuildMenu(const BookmarkNode* parent,
                                       int start_child_index,
                                       GtkWidget* menu) {
  DCHECK(!parent->GetChildCount() ||
         start_child_index < parent->GetChildCount());

  g_signal_connect(menu, "button-press-event",
                   G_CALLBACK(OnButtonPressedThunk), this);

  for (int i = start_child_index; i < parent->GetChildCount(); ++i) {
    const BookmarkNode* node = parent->GetChild(i);

    // This breaks on word boundaries. Ideally we would break on character
    // boundaries.
    std::wstring elided_name =
        l10n_util::TruncateString(node->GetTitle(), kMaxChars);
    GtkWidget* menu_item =
        gtk_image_menu_item_new_with_label(WideToUTF8(elided_name).c_str());
    g_object_set_data(G_OBJECT(menu_item), "bookmark-node", AsVoid(node));
    SetImageMenuItem(menu_item, node, profile_->GetBookmarkModel());
    gtk_util::SetAlwaysShowImage(menu_item);

    g_signal_connect(menu_item, "button-release-event",
                     G_CALLBACK(OnButtonReleasedThunk), this);
    if (node->is_url()) {
      g_signal_connect(menu_item, "activate",
                       G_CALLBACK(OnMenuItemActivatedThunk), this);
    } else if (node->is_folder()) {
      GtkWidget* submenu = gtk_menu_new();
      BuildMenu(node, 0, submenu);
      gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item), submenu);
    } else {
      NOTREACHED();
    }

    gtk_drag_source_set(menu_item, GDK_BUTTON1_MASK, NULL, 0,
        static_cast<GdkDragAction>(GDK_ACTION_COPY | GDK_ACTION_LINK));
    int target_mask = gtk_dnd_util::CHROME_BOOKMARK_ITEM;
    if (node->is_url())
      target_mask |= gtk_dnd_util::TEXT_URI_LIST | gtk_dnd_util::NETSCAPE_URL;
    gtk_dnd_util::SetSourceTargetListFromCodeMask(menu_item, target_mask);
    g_signal_connect(menu_item, "drag-begin",
                     G_CALLBACK(OnMenuItemDragBeginThunk), this);
    g_signal_connect(menu_item, "drag-end",
                     G_CALLBACK(OnMenuItemDragEndThunk), this);
    g_signal_connect(menu_item, "drag-data-get",
                     G_CALLBACK(OnMenuItemDragGetThunk), this);

    // It is important to connect to this signal after setting up the drag
    // source because we only want to stifle the menu's default handler and
    // not the handler that the drag source uses.
    if (node->is_folder()) {
      g_signal_connect(menu_item, "button-press-event",
                       G_CALLBACK(OnFolderButtonPressedThunk), this);
    }

    gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
    node_to_menu_widget_map_[node] = menu_item;
  }

  if (parent->GetChildCount() == 0) {
    GtkWidget* empty_menu = gtk_menu_item_new_with_label(
        l10n_util::GetStringUTF8(IDS_MENU_EMPTY_SUBMENU).c_str());
    gtk_widget_set_sensitive(empty_menu, FALSE);
    g_object_set_data(G_OBJECT(menu), "parent-node", AsVoid(parent));
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), empty_menu);
  }
}

gboolean BookmarkMenuController::OnButtonPressed(
    GtkWidget* sender,
    GdkEventButton* event) {
  ignore_button_release_ = false;
  GtkMenuShell* menu_shell = GTK_MENU_SHELL(sender);

  if (event->button == 3) {
    // If the cursor is outside our bounds, pass this event up to the parent.
    if (!gtk_util::WidgetContainsCursor(sender)) {
      if (menu_shell->parent_menu_shell) {
        return OnButtonPressed(menu_shell->parent_menu_shell, event);
      } else {
        // We are the top level menu; we can propagate no further.
        return FALSE;
      }
    }

    // This will return NULL if we are not an empty menu.
    const BookmarkNode* parent = GetParentNodeFromEmptyMenu(sender);
    bool is_empty_menu = !!parent;
    // If there is no active menu item and we are not an empty menu, then do
    // nothing. This can happen if the user has canceled a context menu while
    // the cursor is hovering over a bookmark menu. Doing nothing is not optimal
    // (the hovered item should be active), but it's a hopefully rare corner
    // case.
    GtkWidget* menu_item = menu_shell->active_menu_item;
    if (!is_empty_menu && !menu_item)
      return TRUE;

    const BookmarkNode* node =
        menu_item ? GetNodeFromMenuItem(menu_item) : NULL;
    DCHECK_NE(is_empty_menu, !!node);
    if (!is_empty_menu)
      parent = node->GetParent();

    // Show the right click menu and stop processing this button event.
    std::vector<const BookmarkNode*> nodes;
    if (node)
      nodes.push_back(node);
    context_menu_controller_.reset(
        new BookmarkContextMenuController(
            parent_window_, this, profile_,
            page_navigator_, parent, nodes));
    context_menu_.reset(
        new MenuGtk(NULL, context_menu_controller_->menu_model()));

    // Our bookmark folder menu loses the grab to the context menu. When the
    // context menu is hidden, re-assert our grab.
    GtkWidget* grabbing_menu = gtk_grab_get_current();
    g_object_ref(grabbing_menu);
    g_signal_connect(context_menu_->widget(), "hide",
                     G_CALLBACK(OnContextMenuHide), grabbing_menu);

    context_menu_->PopupAsContext(event->time);
    return TRUE;
  }

  return FALSE;
}

gboolean BookmarkMenuController::OnButtonReleased(
    GtkWidget* sender,
    GdkEventButton* event) {
  if (ignore_button_release_) {
    // Don't handle this message; it was a drag.
    ignore_button_release_ = false;
    return FALSE;
  }

  // Releasing either button 1 or 2 should trigger the bookmark.
  if (!gtk_menu_item_get_submenu(GTK_MENU_ITEM(sender))) {
    // The menu item is a link node.
    if (event->button == 1 || event->button == 2) {
      WindowOpenDisposition disposition =
          event_utils::DispositionFromEventFlags(event->state);
      NavigateToMenuItem(sender, disposition);

      // We need to manually dismiss the popup menu because we're overriding
      // button-release-event.
      gtk_menu_popdown(GTK_MENU(menu_));
      return TRUE;
    }
  } else {
    // The menu item is a folder node.
    if (event->button == 1) {
      gtk_menu_shell_select_item(GTK_MENU_SHELL(sender->parent), sender);
      g_signal_emit_by_name(sender->parent, "activate-current");
      return TRUE;
    }
  }

  return FALSE;
}

gboolean BookmarkMenuController::OnFolderButtonPressed(
    GtkWidget* sender, GdkEventButton* event) {
  // The button press may start a drag; don't let the default handler run.
  if (event->button == 1)
    return TRUE;
  return FALSE;
}

void BookmarkMenuController::OnMenuHidden(GtkWidget* menu) {
  if (triggering_widget_)
    gtk_chrome_button_unset_paint_state(GTK_CHROME_BUTTON(triggering_widget_));
}

void BookmarkMenuController::OnMenuItemActivated(GtkWidget* menu_item) {
  NavigateToMenuItem(menu_item, CURRENT_TAB);
}

void BookmarkMenuController::OnMenuItemDragBegin(GtkWidget* menu_item,
                                                 GdkDragContext* drag_context) {
  // The parent menu item might be removed during the drag. Ref it so |button|
  // won't get destroyed.
  g_object_ref(menu_item->parent);

  // Signal to any future OnButtonReleased calls that we're dragging instead of
  // pressing.
  ignore_button_release_ = true;

  const BookmarkNode* node = bookmark_utils::BookmarkNodeForWidget(menu_item);
  drag_icon_ = bookmark_utils::GetDragRepresentationForNode(
      node, model_, GtkThemeProvider::GetFrom(profile_));
  gint x, y;
  gtk_widget_get_pointer(menu_item, &x, &y);
  gtk_drag_set_icon_widget(drag_context, drag_icon_, x, y);

  // Hide our node.
  gtk_widget_hide(menu_item);
}

void BookmarkMenuController::OnMenuItemDragEnd(GtkWidget* menu_item,
                                               GdkDragContext* drag_context) {
  gtk_widget_show(menu_item);
  g_object_unref(menu_item->parent);

  gtk_widget_destroy(drag_icon_);
  drag_icon_ = NULL;
}

void BookmarkMenuController::OnMenuItemDragGet(
    GtkWidget* widget, GdkDragContext* context,
    GtkSelectionData* selection_data,
    guint target_type, guint time) {
  const BookmarkNode* node = bookmark_utils::BookmarkNodeForWidget(widget);
  bookmark_utils::WriteBookmarkToSelection(node, selection_data, target_type,
                                           profile_);
}
<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <gtk/gtk.h>

#include "app/l10n_util.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/extensions/extension_install_ui.h"
#include "chrome/browser/gtk/browser_window_gtk.h"
#include "chrome/browser/gtk/gtk_util.h"
#include "chrome/common/extensions/extension.h"
#include "gfx/gtk_util.h"
#include "grit/generated_resources.h"

class Profile;

namespace {

const int kRightColumnWidth = 290;

// Left or right margin.
const int kPanelHorizMargin = 13;

GtkWidget* MakeMarkupLabel(const char* format, const std::string& str) {
  GtkWidget* label = gtk_label_new(NULL);
  char* markup = g_markup_printf_escaped(format, str.c_str());
  gtk_label_set_markup(GTK_LABEL(label), markup);
  g_free(markup);

  // Left align it.
  gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);

  return label;
}

void OnDialogResponse(GtkDialog* dialog, int response_id,
                      ExtensionInstallUI::Delegate* delegate) {
  if (response_id == GTK_RESPONSE_ACCEPT) {
    delegate->InstallUIProceed(false);
  } else {
    delegate->InstallUIAbort();
  }

  gtk_widget_destroy(GTK_WIDGET(dialog));
}

void ShowInstallPromptDialog(GtkWindow* parent, SkBitmap* skia_icon,
                             Extension *extension,
                             ExtensionInstallUI::Delegate *delegate,
                             const string16& warning_text,
                             ExtensionInstallUI::PromptType type) {
  // Build the dialog.
  int title_id = ExtensionInstallUI::kTitleIds[type];
  int button_id = ExtensionInstallUI::kButtonIds[type];
  GtkWidget* dialog = gtk_dialog_new_with_buttons(
      l10n_util::GetStringUTF8(title_id).c_str(),
      parent,
      GTK_DIALOG_MODAL,
      GTK_STOCK_CANCEL,
      GTK_RESPONSE_CLOSE,
      l10n_util::GetStringUTF8(button_id).c_str(),
      GTK_RESPONSE_ACCEPT,
      NULL);
  gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);

  // Create a two column layout.
  GtkWidget* content_area = GTK_DIALOG(dialog)->vbox;
  gtk_box_set_spacing(GTK_BOX(content_area), gtk_util::kContentAreaSpacing);

  GtkWidget* icon_hbox = gtk_hbox_new(FALSE, gtk_util::kContentAreaSpacing);
  gtk_box_pack_start(GTK_BOX(content_area), icon_hbox, TRUE, TRUE, 0);

  // Put Icon in the left column.
  GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap(skia_icon);
  GtkWidget* icon = gtk_image_new_from_pixbuf(pixbuf);
  g_object_unref(pixbuf);
  gtk_box_pack_start(GTK_BOX(icon_hbox), icon, TRUE, TRUE, 0);

  // Create a new vbox for the right column.
  GtkWidget* right_column_area = gtk_vbox_new(FALSE, 0);
  gtk_box_pack_start(GTK_BOX(icon_hbox), right_column_area, TRUE, TRUE, 0);

  int heading_id = ExtensionInstallUI::kHeadingIds[type];
  std::string heading_text = l10n_util::GetStringFUTF8(
      heading_id, UTF8ToUTF16(extension->name()));
  GtkWidget* heading_label = MakeMarkupLabel("%s",
                                             heading_text);
  gtk_misc_set_alignment(GTK_MISC(heading_label), 0.0, 0.5);
  gtk_label_set_selectable(GTK_LABEL(heading_label), TRUE);
  gtk_box_pack_start(GTK_BOX(right_column_area), heading_label, TRUE, TRUE, 0);

  GtkWidget* warning_label = gtk_label_new(UTF16ToUTF8(warning_text).c_str());
  gtk_label_set_line_wrap(GTK_LABEL(warning_label), TRUE);
  gtk_widget_set_size_request(warning_label, kRightColumnWidth, -1);
  gtk_misc_set_alignment(GTK_MISC(warning_label), 0.0, 0.5);
  gtk_label_set_selectable(GTK_LABEL(warning_label), TRUE);
  gtk_box_pack_start(GTK_BOX(right_column_area), warning_label, TRUE, TRUE, 0);

  g_signal_connect(dialog, "response", G_CALLBACK(OnDialogResponse), delegate);
  gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
  gtk_widget_show_all(dialog);
}

}  // namespace

void ExtensionInstallUI::ShowExtensionInstallUIPromptImpl(
    Profile* profile, Delegate* delegate, Extension* extension, SkBitmap* icon,
    const string16& warning_text, ExtensionInstallUI::PromptType type) {
  Browser* browser = BrowserList::GetLastActiveWithProfile(profile);
  if (!browser) {
    delegate->InstallUIAbort();
    return;
  }

  BrowserWindowGtk* browser_window = static_cast<BrowserWindowGtk*>(
      browser->window());
  if (!browser_window) {
    delegate->InstallUIAbort();
    return;
  }

  ShowInstallPromptDialog(browser_window->window(), icon, extension,
      delegate, warning_text, type);
}
<commit_msg>[GTK] Don't line wrap on the extension uninstall dialog.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Currently this file is only used for the uninstall prompt. The install prompt
// code is in extension_install_prompt2_gtk.cc.

#include <gtk/gtk.h>

#include "app/l10n_util.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/extensions/extension_install_ui.h"
#include "chrome/browser/gtk/browser_window_gtk.h"
#include "chrome/browser/gtk/gtk_util.h"
#include "chrome/common/extensions/extension.h"
#include "gfx/gtk_util.h"
#include "grit/generated_resources.h"

class Profile;

namespace {

// Left or right margin.
const int kPanelHorizMargin = 13;

GtkWidget* MakeMarkupLabel(const char* format, const std::string& str) {
  GtkWidget* label = gtk_label_new(NULL);
  char* markup = g_markup_printf_escaped(format, str.c_str());
  gtk_label_set_markup(GTK_LABEL(label), markup);
  g_free(markup);

  // Left align it.
  gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);

  return label;
}

void OnDialogResponse(GtkDialog* dialog, int response_id,
                      ExtensionInstallUI::Delegate* delegate) {
  if (response_id == GTK_RESPONSE_ACCEPT) {
    delegate->InstallUIProceed(false);
  } else {
    delegate->InstallUIAbort();
  }

  gtk_widget_destroy(GTK_WIDGET(dialog));
}

void ShowInstallPromptDialog(GtkWindow* parent, SkBitmap* skia_icon,
                             Extension *extension,
                             ExtensionInstallUI::Delegate *delegate,
                             const string16& warning_text,
                             ExtensionInstallUI::PromptType type) {
  // Build the dialog.
  int title_id = ExtensionInstallUI::kTitleIds[type];
  int button_id = ExtensionInstallUI::kButtonIds[type];
  GtkWidget* dialog = gtk_dialog_new_with_buttons(
      l10n_util::GetStringUTF8(title_id).c_str(),
      parent,
      GTK_DIALOG_MODAL,
      GTK_STOCK_CANCEL,
      GTK_RESPONSE_CLOSE,
      l10n_util::GetStringUTF8(button_id).c_str(),
      GTK_RESPONSE_ACCEPT,
      NULL);
  gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);

  // Create a two column layout.
  GtkWidget* content_area = GTK_DIALOG(dialog)->vbox;
  gtk_box_set_spacing(GTK_BOX(content_area), gtk_util::kContentAreaSpacing);

  GtkWidget* icon_hbox = gtk_hbox_new(FALSE, gtk_util::kContentAreaSpacing);
  gtk_box_pack_start(GTK_BOX(content_area), icon_hbox, TRUE, TRUE, 0);

  // Put Icon in the left column.
  GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap(skia_icon);
  GtkWidget* icon = gtk_image_new_from_pixbuf(pixbuf);
  g_object_unref(pixbuf);
  gtk_box_pack_start(GTK_BOX(icon_hbox), icon, TRUE, TRUE, 0);

  // Create a new vbox for the right column.
  GtkWidget* right_column_area = gtk_vbox_new(FALSE, 0);
  gtk_box_pack_start(GTK_BOX(icon_hbox), right_column_area, TRUE, TRUE, 0);

  int heading_id = ExtensionInstallUI::kHeadingIds[type];
  std::string heading_text = l10n_util::GetStringFUTF8(
      heading_id, UTF8ToUTF16(extension->name()));
  GtkWidget* heading_label = MakeMarkupLabel("%s",
                                             heading_text);
  gtk_misc_set_alignment(GTK_MISC(heading_label), 0.0, 0.5);
  gtk_box_pack_start(GTK_BOX(right_column_area), heading_label, TRUE, TRUE, 0);

  GtkWidget* warning_label = gtk_label_new(UTF16ToUTF8(warning_text).c_str());
  gtk_misc_set_alignment(GTK_MISC(warning_label), 0.0, 0.5);
  gtk_box_pack_start(GTK_BOX(right_column_area), warning_label, TRUE, TRUE, 0);

  g_signal_connect(dialog, "response", G_CALLBACK(OnDialogResponse), delegate);
  gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
  gtk_widget_show_all(dialog);
}

}  // namespace

void ExtensionInstallUI::ShowExtensionInstallUIPromptImpl(
    Profile* profile, Delegate* delegate, Extension* extension, SkBitmap* icon,
    const string16& warning_text, ExtensionInstallUI::PromptType type) {
  Browser* browser = BrowserList::GetLastActiveWithProfile(profile);
  if (!browser) {
    delegate->InstallUIAbort();
    return;
  }

  BrowserWindowGtk* browser_window = static_cast<BrowserWindowGtk*>(
      browser->window());
  if (!browser_window) {
    delegate->InstallUIAbort();
    return;
  }

  ShowInstallPromptDialog(browser_window->window(), icon, extension,
      delegate, warning_text, type);
}
<|endoftext|>