<commit_before>//  (C) Copyright Gennadiy Rozental 2011-2014.
//  Distributed under the Boost Software License, Version 1.0.
//  (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

//  See http://www.boost.org/libs/test for the library home page.
//
/// @file
/// Defines @ref boost::unit_test::test_unit "test_unit", @ref boost::unit_test::test_case "test_case",
/// @ref boost::unit_test::test_suite "test_suite" and @ref boost::unit_test::master_test_suite_t "master_test_suite_t"
// ***************************************************************************

#ifndef BOOST_TEST_TREE_TEST_UNIT_HPP_100211GER
#define BOOST_TEST_TREE_TEST_UNIT_HPP_100211GER

// Boost.Test
#include <boost/test/detail/config.hpp>
#include <boost/test/detail/global_typedef.hpp>
#include <boost/test/detail/fwd_decl.hpp>
#include <boost/test/tree/decorator.hpp>
#include <boost/test/tree/fixture.hpp>
#include <boost/test/utils/class_properties.hpp>

// Boost
#include <boost/function/function0.hpp>

// STL
#include <list>
#include <vector>
#include <string>

#include <boost/test/detail/suppress_warnings.hpp>

//____________________________________________________________________________//

namespace boost {
namespace unit_test {

// ************************************************************************** //
// **************                   test_unit                  ************** //
// ************************************************************************** //

class BOOST_TEST_DECL test_unit {
public:
    enum { type = TUT_ANY };
    typedef std::list<test_unit_id>             id_list;
    typedef std::list<test_unit_fixture_ptr>    fixture_list;

    // dependencies management
    void    depends_on( test_unit* tu );
    bool    check_dependencies() const;

    // labels management
    void    add_label( const_string l );
    bool    has_label( const_string l ) const;

    // helper access method
    void    increase_exp_fail( unsigned num );

    // Public r/o properties
    typedef BOOST_READONLY_PROPERTY(test_unit_id,(framework_impl))  id_t;
    typedef BOOST_READONLY_PROPERTY(test_unit_id,(test_suite))      parent_id_t;
    typedef BOOST_READONLY_PROPERTY(id_list,(test_unit))            id_list_t;
    typedef decorator::for_test_unit_ptr                            decorator_base;

    readonly_property<test_unit_type>   p_type;                 // type for this test unit
    readonly_property<const_string>     p_type_name;            // "case"/"suite"/"module"
    readonly_property<const_string>     p_file_name;
    readonly_property<std::size_t>      p_line_num;
    id_t                                p_id;                   // unique id for this test unit
    parent_id_t                         p_parent_id;            // parent test suite id
    id_list_t                           p_dependencies;         // list of test units this one depends on

    // Public r/w properties
    readwrite_property<std::string>     p_name;                 // name for this test unit
    readwrite_property<std::string>     p_description;          // description for this test unit
    readwrite_property<unsigned>        p_timeout;              // timeout for the test unit execution
    readwrite_property<counter_t>       p_expected_failures;    // number of expected failures in this test unit
    mutable readwrite_property<bool>    p_enabled;              // enabled/disabled status for this unit
    readwrite_property<decorator_base>  p_decorators;           // automatically assigned decorators; execution is delayed till framework::init function
    readwrite_property<fixture_list>    p_fixtures;             // fixtures associated with this test unit

protected:
    ~test_unit();
    // Constructor
    test_unit( const_string tu_name, const_string tc_file, std::size_t tc_line, test_unit_type t );
    // Master test suite constructor
    explicit                            test_unit( const_string module_name );

private:
    // Data members
    std::list<std::string>              m_labels;
};

// ************************************************************************** //
// **************              test_unit_generator             ************** //
// ************************************************************************** //

class BOOST_TEST_DECL test_unit_generator {
public:
    virtual test_unit*  next() const = 0;

protected:
    BOOST_TEST_PROTECTED_VIRTUAL ~test_unit_generator() {}
};

// ************************************************************************** //
// **************                   test_case                  ************** //
// ************************************************************************** //

class BOOST_TEST_DECL test_case : public test_unit {
public:
    enum { type = TUT_CASE };

    // Constructor
    test_case( const_string tc_name, boost::function<void ()> const& test_func );
    test_case( const_string tc_name, const_string tc_file, std::size_t tc_line, boost::function<void ()> const& test_func );

    // Public property
    typedef BOOST_READONLY_PROPERTY(boost::function<void ()>,(test_case))  test_func;

    test_func   p_test_func;

private:
    friend class framework_impl;
    ~test_case() {}
};

// ************************************************************************** //
// **************                  test_suite                  ************** //
// ************************************************************************** //

//! Class representing test suites
class BOOST_TEST_DECL test_suite : public test_unit {
public:
    enum { type = TUT_SUITE };

    // Constructor
    explicit        test_suite( const_string ts_name, const_string ts_file, std::size_t ts_line );

    // test unit list management

    //! Adds a test unit to a test suite, with possibility to specify the timeout and the expected failures.
    void            add( test_unit* tu, counter_t expected_failures = 0, unsigned timeout = 0 );
    //! @overload boost::unit_test::test_suite::add
    void            add( test_unit_generator const& gen, unsigned timeout = 0 );

    //! Removes a test from the test suite.
    void            remove( test_unit_id id );

    // access methods
    test_unit_id    get( const_string tu_name ) const;
    std::size_t     size() const { return m_members.size(); }

protected:
    // Master test suite constructor
    explicit        test_suite( const_string module_name );

    friend BOOST_TEST_DECL
    void        traverse_test_tree( test_suite const&, test_tree_visitor&, bool );
    friend class framework_impl;
    virtual     ~test_suite() {}

    // Data members
    std::vector<test_unit_id> m_members;
};

// ************************************************************************** //
// **************               master_test_suite              ************** //
// ************************************************************************** //

class BOOST_TEST_DECL master_test_suite_t : public test_suite {
public:
    master_test_suite_t();

    // Data members
    int      argc;
    char**   argv;
};

// ************************************************************************** //
// **************            user_tc_method_invoker            ************** //
// ************************************************************************** //

namespace ut_detail {

BOOST_TEST_DECL std::string normalize_test_case_name( const_string tu_name );

//____________________________________________________________________________//

template<typename InstanceType,typename UserTestCase>
struct user_tc_method_invoker {
    typedef void (UserTestCase::*TestMethod )();

    user_tc_method_invoker( shared_ptr<InstanceType> inst, TestMethod test_method )
    : m_inst( inst ), m_test_method( test_method ) {}

    void operator()() { ((*m_inst).*m_test_method)(); }

    shared_ptr<InstanceType> m_inst;
    TestMethod               m_test_method;
};

} // namespace ut_detail

// ************************************************************************** //
// **************                make_test_case                ************** //
// ************************************************************************** //

inline test_case*
make_test_case( boost::function<void ()> const& test_func, const_string tc_name, const_string tc_file, std::size_t tc_line )
{
    return new test_case( ut_detail::normalize_test_case_name( tc_name ), tc_file, tc_line, test_func );
}

//____________________________________________________________________________//

template<typename UserTestCase, typename InstanceType>
inline test_case*
make_test_case( void (UserTestCase::*           test_method )(),
                const_string                    tc_name,
                const_string                    tc_file,
                std::size_t                     tc_line,
                boost::shared_ptr<InstanceType> user_test_case )
{
    return new test_case( ut_detail::normalize_test_case_name( tc_name ),
                          tc_file,
                          tc_line,
                          ut_detail::user_tc_method_invoker<InstanceType,UserTestCase>( user_test_case, test_method ) );
}

//____________________________________________________________________________//

} // namespace unit_test
} // namespace boost

#include <boost/test/detail/enable_warnings.hpp>

#endif // BOOST_TEST_TREE_TEST_UNIT_HPP_100211GER

<commit_msg>Trying again this overload stuff in doxygen, but cannot get rid of the warnings<commit_after>//  (C) Copyright Gennadiy Rozental 2011-2014.
//  Distributed under the Boost Software License, Version 1.0.
//  (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

//  See http://www.boost.org/libs/test for the library home page.
//
/// @file
/// Defines @ref boost::unit_test::test_unit "test_unit", @ref boost::unit_test::test_case "test_case",
/// @ref boost::unit_test::test_suite "test_suite" and @ref boost::unit_test::master_test_suite_t "master_test_suite_t"
// ***************************************************************************

#ifndef BOOST_TEST_TREE_TEST_UNIT_HPP_100211GER
#define BOOST_TEST_TREE_TEST_UNIT_HPP_100211GER

// Boost.Test
#include <boost/test/detail/config.hpp>
#include <boost/test/detail/global_typedef.hpp>
#include <boost/test/detail/fwd_decl.hpp>
#include <boost/test/tree/decorator.hpp>
#include <boost/test/tree/fixture.hpp>
#include <boost/test/utils/class_properties.hpp>

// Boost
#include <boost/function/function0.hpp>

// STL
#include <list>
#include <vector>
#include <string>

#include <boost/test/detail/suppress_warnings.hpp>

//____________________________________________________________________________//

namespace boost {
namespace unit_test {

// ************************************************************************** //
// **************                   test_unit                  ************** //
// ************************************************************************** //

class BOOST_TEST_DECL test_unit {
public:
    enum { type = TUT_ANY };
    typedef std::list<test_unit_id>             id_list;
    typedef std::list<test_unit_fixture_ptr>    fixture_list;

    // dependencies management
    void    depends_on( test_unit* tu );
    bool    check_dependencies() const;

    // labels management
    void    add_label( const_string l );
    bool    has_label( const_string l ) const;

    // helper access method
    void    increase_exp_fail( unsigned num );

    // Public r/o properties
    typedef BOOST_READONLY_PROPERTY(test_unit_id,(framework_impl))  id_t;
    typedef BOOST_READONLY_PROPERTY(test_unit_id,(test_suite))      parent_id_t;
    typedef BOOST_READONLY_PROPERTY(id_list,(test_unit))            id_list_t;
    typedef decorator::for_test_unit_ptr                            decorator_base;

    readonly_property<test_unit_type>   p_type;                 // type for this test unit
    readonly_property<const_string>     p_type_name;            // "case"/"suite"/"module"
    readonly_property<const_string>     p_file_name;
    readonly_property<std::size_t>      p_line_num;
    id_t                                p_id;                   // unique id for this test unit
    parent_id_t                         p_parent_id;            // parent test suite id
    id_list_t                           p_dependencies;         // list of test units this one depends on

    // Public r/w properties
    readwrite_property<std::string>     p_name;                 // name for this test unit
    readwrite_property<std::string>     p_description;          // description for this test unit
    readwrite_property<unsigned>        p_timeout;              // timeout for the test unit execution
    readwrite_property<counter_t>       p_expected_failures;    // number of expected failures in this test unit
    mutable readwrite_property<bool>    p_enabled;              // enabled/disabled status for this unit
    readwrite_property<decorator_base>  p_decorators;           // automatically assigned decorators; execution is delayed till framework::init function
    readwrite_property<fixture_list>    p_fixtures;             // fixtures associated with this test unit

protected:
    ~test_unit();
    // Constructor
    test_unit( const_string tu_name, const_string tc_file, std::size_t tc_line, test_unit_type t );
    // Master test suite constructor
    explicit                            test_unit( const_string module_name );

private:
    // Data members
    std::list<std::string>              m_labels;
};

// ************************************************************************** //
// **************              test_unit_generator             ************** //
// ************************************************************************** //

class BOOST_TEST_DECL test_unit_generator {
public:
    virtual test_unit*  next() const = 0;

protected:
    BOOST_TEST_PROTECTED_VIRTUAL ~test_unit_generator() {}
};

// ************************************************************************** //
// **************                   test_case                  ************** //
// ************************************************************************** //

class BOOST_TEST_DECL test_case : public test_unit {
public:
    enum { type = TUT_CASE };

    // Constructor
    test_case( const_string tc_name, boost::function<void ()> const& test_func );
    test_case( const_string tc_name, const_string tc_file, std::size_t tc_line, boost::function<void ()> const& test_func );

    // Public property
    typedef BOOST_READONLY_PROPERTY(boost::function<void ()>,(test_case))  test_func;

    test_func   p_test_func;

private:
    friend class framework_impl;
    ~test_case() {}
};

// ************************************************************************** //
// **************                  test_suite                  ************** //
// ************************************************************************** //

//! Class representing test suites
class BOOST_TEST_DECL test_suite : public test_unit {
public:
    enum { type = TUT_SUITE };

    // Constructor
    explicit        test_suite( const_string ts_name, const_string ts_file, std::size_t ts_line );

    // test unit list management

    /*!@brief Adds a test unit to a test suite.
     *
     * It is possible to specify the timeout and the expected failures.
     */
    void            add( test_unit* tu, counter_t expected_failures = 0, unsigned timeout = 0 );

    //  boost::unit_test::test_suite::add( test_unit* tu, counter_t expected_failures = 0, unsigned timeout = 0 )

    /// @overload
    void            add( test_unit_generator const& gen, unsigned timeout = 0 );

    //! Removes a test from the test suite.
    void            remove( test_unit_id id );

    // access methods
    test_unit_id    get( const_string tu_name ) const;
    std::size_t     size() const { return m_members.size(); }

protected:
    // Master test suite constructor
    explicit        test_suite( const_string module_name );

    friend BOOST_TEST_DECL
    void        traverse_test_tree( test_suite const&, test_tree_visitor&, bool );
    friend class framework_impl;
    virtual     ~test_suite() {}

    // Data members
    std::vector<test_unit_id> m_members;
};

// ************************************************************************** //
// **************               master_test_suite              ************** //
// ************************************************************************** //

class BOOST_TEST_DECL master_test_suite_t : public test_suite {
public:
    master_test_suite_t();

    // Data members
    int      argc;
    char**   argv;
};

// ************************************************************************** //
// **************            user_tc_method_invoker            ************** //
// ************************************************************************** //

namespace ut_detail {

BOOST_TEST_DECL std::string normalize_test_case_name( const_string tu_name );

//____________________________________________________________________________//

template<typename InstanceType,typename UserTestCase>
struct user_tc_method_invoker {
    typedef void (UserTestCase::*TestMethod )();

    user_tc_method_invoker( shared_ptr<InstanceType> inst, TestMethod test_method )
    : m_inst( inst ), m_test_method( test_method ) {}

    void operator()() { ((*m_inst).*m_test_method)(); }

    shared_ptr<InstanceType> m_inst;
    TestMethod               m_test_method;
};

} // namespace ut_detail

// ************************************************************************** //
// **************                make_test_case                ************** //
// ************************************************************************** //

inline test_case*
make_test_case( boost::function<void ()> const& test_func, const_string tc_name, const_string tc_file, std::size_t tc_line )
{
    return new test_case( ut_detail::normalize_test_case_name( tc_name ), tc_file, tc_line, test_func );
}

//____________________________________________________________________________//

template<typename UserTestCase, typename InstanceType>
inline test_case*
make_test_case( void (UserTestCase::*           test_method )(),
                const_string                    tc_name,
                const_string                    tc_file,
                std::size_t                     tc_line,
                boost::shared_ptr<InstanceType> user_test_case )
{
    return new test_case( ut_detail::normalize_test_case_name( tc_name ),
                          tc_file,
                          tc_line,
                          ut_detail::user_tc_method_invoker<InstanceType,UserTestCase>( user_test_case, test_method ) );
}

//____________________________________________________________________________//

} // namespace unit_test
} // namespace boost

#include <boost/test/detail/enable_warnings.hpp>

#endif // BOOST_TEST_TREE_TEST_UNIT_HPP_100211GER

<|endoftext|>


<commit_before>#ifndef DSB_EXECUTION_VARIABLE_IO_HPP
#define DSB_EXECUTION_VARIABLE_IO_HPP

#include <map>
#include <memory>
#include <queue>
#include <string>

#include "boost/chrono/duration.hpp"
#include "zmq.hpp"

#include "dsb/model.hpp"

namespace dsb
{
namespace execution
{

/// A class which handles publishing of variable values on the network.
class VariablePublisher
{
public:
    /**
    \brief  Default constructor.

    Note that Connect() must be called before any variables may be published.
    */
    VariablePublisher();

    /**
    \brief  Connects to the remote endpoint to which variable values should be
            published, and set the slave ID used for the outgoing data.

    This is typically used to connect to an XPUB/XSUB broker.

    \param [in] endpoint    The address to an XSUB or SUB endpoint.
    \param [in] ownID       The slave ID with which to tag the outgoing data.

    \pre Connect() has not been called previously on this instance.
    */
    void Connect(const std::string& endpoint, dsb::model::SlaveID ownID);

    /**
    \brief  Publishes the value of a single variable.

    While this is not enforced by the present function, the recipient (i.e.,
    the VariableSubscriber) requires that all subscribed-to variables be
    published for any given time step, and that the time step ID never
    decreases.

    \param [in] stepID      Time step ID
    \param [in] variableID  Variable ID (which is paired with the slave ID
                            to form a "global" variable ID before sending)
    \param [in] value       The variable value

    \pre Connect() has been called successfully on this instance.
    */
    void Publish(
        dsb::model::StepID stepID,
        dsb::model::VariableID variableID,
        dsb::model::ScalarValue value);

private:
    dsb::model::SlaveID m_ownID;
    std::unique_ptr<zmq::socket_t> m_socket;
};

/// A class which handles subscriptions to and receiving of variable values.
class VariableSubscriber
{
public:
    /**
    \brief  Default constructor.

    Note that Connect() must be called before any variables can be received.
    */
    VariableSubscriber();

    /**
    \brief  Connects to the remote endpoint from which variable values should
            be received.

    This is typically used to connect to an XPUB/XSUB broker.

    \param [in] endpoint    The address to an XPUB or PUB endpoint.

    \pre Connect() has not been called previously on this instance.
    */
    void Connect(const std::string& endpoint);

    /**
    \brief Subscribes to the given variable.

    \pre Connect() has been called successfully on this instance.
    */
    void Subscribe(const dsb::model::Variable& variable);

    /**
    \brief Unsubscribes from the given variable.

    \pre Connect() has been called successfully on this instance.
    */
    void Unsubscribe(const dsb::model::Variable& variable);

    /**
    \brief  Waits until the values of all subscribed-to variables have been
            received for the given time step.

    \param [in] stepID      The timestep ID for which we should wait for
                            variable data.
    \param [in] timeout     How long to wait without receiving any data.

    \throws std::runtime_error if no data is received for the duration
        specified by `timeout`.
    \pre Connect() has been called successfully on this instance.
    */
    void Update(
        dsb::model::StepID stepID,
        boost::chrono::milliseconds timeout);

    /**
    \brief  Returns the value of the given variable which was acquired with the
            last Update() call.

    This function may not be called if Update() has not been called yet, or if
    the last Update() call failed.  Furthermore, the returned reference is only
    guaranteed to be valid until the next Update() call.

    \param [in] variable    A variable identifier. The variable must be one
                            which has previously been subscribed to with
                            Subscribe().

    \pre Update() has been called successfully.
    */
    const dsb::model::ScalarValue& Value(const dsb::model::Variable& variable)
        const;

private:
    typedef std::queue<std::pair<dsb::model::StepID, dsb::model::ScalarValue>>
        ValueQueue;

    // A less-than comparison operator for Variable objects, so we can put
    // them in a std::map (below).
    struct VariableLess
    {
        bool operator()(const dsb::model::Variable& a, const dsb::model::Variable& b) const
        {
            return ((a.Slave() << 16) + a.ID()) < ((b.Slave() << 16) + b.ID());
        }
    };

    dsb::model::StepID m_currentStepID;
    std::unique_ptr<zmq::socket_t> m_socket;
    std::map<dsb::model::Variable, ValueQueue, VariableLess> m_values;
};

}} // namespace
#endif // header guard
<commit_msg>Use an unordered_map in VariableSubscriber<commit_after>#ifndef DSB_EXECUTION_VARIABLE_IO_HPP
#define DSB_EXECUTION_VARIABLE_IO_HPP

#include <memory>
#include <queue>
#include <string>
#include <unordered_map>

#include "boost/chrono/duration.hpp"
#include "zmq.hpp"

#include "dsb/model.hpp"

namespace dsb
{
namespace execution
{

/// A class which handles publishing of variable values on the network.
class VariablePublisher
{
public:
    /**
    \brief  Default constructor.

    Note that Connect() must be called before any variables may be published.
    */
    VariablePublisher();

    /**
    \brief  Connects to the remote endpoint to which variable values should be
            published, and set the slave ID used for the outgoing data.

    This is typically used to connect to an XPUB/XSUB broker.

    \param [in] endpoint    The address to an XSUB or SUB endpoint.
    \param [in] ownID       The slave ID with which to tag the outgoing data.

    \pre Connect() has not been called previously on this instance.
    */
    void Connect(const std::string& endpoint, dsb::model::SlaveID ownID);

    /**
    \brief  Publishes the value of a single variable.

    While this is not enforced by the present function, the recipient (i.e.,
    the VariableSubscriber) requires that all subscribed-to variables be
    published for any given time step, and that the time step ID never
    decreases.

    \param [in] stepID      Time step ID
    \param [in] variableID  Variable ID (which is paired with the slave ID
                            to form a "global" variable ID before sending)
    \param [in] value       The variable value

    \pre Connect() has been called successfully on this instance.
    */
    void Publish(
        dsb::model::StepID stepID,
        dsb::model::VariableID variableID,
        dsb::model::ScalarValue value);

private:
    dsb::model::SlaveID m_ownID;
    std::unique_ptr<zmq::socket_t> m_socket;
};

/// A class which handles subscriptions to and receiving of variable values.
class VariableSubscriber
{
public:
    /**
    \brief  Default constructor.

    Note that Connect() must be called before any variables can be received.
    */
    VariableSubscriber();

    /**
    \brief  Connects to the remote endpoint from which variable values should
            be received.

    This is typically used to connect to an XPUB/XSUB broker.

    \param [in] endpoint    The address to an XPUB or PUB endpoint.

    \pre Connect() has not been called previously on this instance.
    */
    void Connect(const std::string& endpoint);

    /**
    \brief Subscribes to the given variable.

    \pre Connect() has been called successfully on this instance.
    */
    void Subscribe(const dsb::model::Variable& variable);

    /**
    \brief Unsubscribes from the given variable.

    \pre Connect() has been called successfully on this instance.
    */
    void Unsubscribe(const dsb::model::Variable& variable);

    /**
    \brief  Waits until the values of all subscribed-to variables have been
            received for the given time step.

    \param [in] stepID      The timestep ID for which we should wait for
                            variable data.
    \param [in] timeout     How long to wait without receiving any data.

    \throws std::runtime_error if no data is received for the duration
        specified by `timeout`.
    \pre Connect() has been called successfully on this instance.
    */
    void Update(
        dsb::model::StepID stepID,
        boost::chrono::milliseconds timeout);

    /**
    \brief  Returns the value of the given variable which was acquired with the
            last Update() call.

    This function may not be called if Update() has not been called yet, or if
    the last Update() call failed.  Furthermore, the returned reference is only
    guaranteed to be valid until the next Update() call.

    \param [in] variable    A variable identifier. The variable must be one
                            which has previously been subscribed to with
                            Subscribe().

    \pre Update() has been called successfully.
    */
    const dsb::model::ScalarValue& Value(const dsb::model::Variable& variable)
        const;

private:
    typedef std::queue<std::pair<dsb::model::StepID, dsb::model::ScalarValue>>
        ValueQueue;

    // A hash function for Variable objects, so we can put them in a
    // std::unordered_map (below)
    struct VariableHash
    {
        std::size_t operator()(const dsb::model::Variable& v) const
        {
            return static_cast<std::size_t>((v.Slave() << 16) + v.ID());
        }
    };

    dsb::model::StepID m_currentStepID;
    std::unique_ptr<zmq::socket_t> m_socket;
    std::unordered_map<dsb::model::Variable, ValueQueue, VariableHash> m_values;
};

}} // namespace
#endif // header guard
<|endoftext|>


<commit_before>/*

Copyright (c) 2003, Magnus Jonsson, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

//The Standard Library defines the two template functions std::min()
//and std::max() in the <algorithm> header. In general, you should
//use these template functions for calculating the min and max values
//of a pair. Unfortunately, Visual C++ does not define these function
// templates. This is because the names min and max clash with
//the traditional min and max macros defined in <windows.h>.
//As a workaround, Visual C++ defines two alternative templates with
//identical functionality called _cpp_min() and _cpp_max(). You can
//use them instead of std::min() and std::max().To disable the
//generation of the min and max macros in Visual C++, #define
//NOMINMAX before #including <windows.h>.
#ifdef _WIN32
    //support boost1.32.0(2004-11-19 18:47)
    //now all libs can be compiled and linked with static module
	#define NOMINMAX
#endif

#include "libtorrent/allocate_resources.hpp"
#include "libtorrent/size_type.hpp"
#include "libtorrent/peer_connection.hpp"
#include "libtorrent/torrent.hpp"

#include <cassert>
#include <algorithm>
#include <boost/limits.hpp>

#if defined(_MSC_VER) && _MSC_VER < 1310
#define for if (false) {} else for
#else
#include <boost/iterator/transform_iterator.hpp>
#endif

namespace libtorrent
{
	int saturated_add(int a, int b)
	{
		assert(a >= 0);
		assert(b >= 0);
		assert(std::numeric_limits<int>::max() + std::numeric_limits<int>::max() < 0);

		int sum = a + b;
		if(sum < 0)
			sum = std::numeric_limits<int>::max();

		assert(sum >= a && sum >= b);
		return sum;
	}

	namespace
	{
		// give num_resources to r,
		// return how how many were actually accepted.
		int give(resource_request& r, int num_resources)
		{
			assert(num_resources >= 0);
			assert(r.given <= r.max);

			int accepted = std::min(num_resources, r.max - r.given);
			assert(accepted >= 0);

			r.given += accepted;
			assert(r.given <= r.max);

			return accepted;
		}

#ifndef NDEBUG

		template<class It, class T>
		class allocate_resources_contract_check
		{
			int m_resources;
			It m_start;
			It m_end;
			resource_request T::* m_res;

		public:
			allocate_resources_contract_check(
				int resources
				, It start
				, It end
				, resource_request T::* res)
				: m_resources(resources)
				, m_start(start)
				, m_end(end)
				, m_res(res)
			{
				assert(m_resources >= 0);
				for (It i = m_start, end(m_end); i != end; ++i)
				{
					assert(((*i).*m_res).used >= 0);
					assert(((*i).*m_res).max >= 0);
					assert(((*i).*m_res).given >= 0);
				}
			}

			~allocate_resources_contract_check()
			{
				int sum_given = 0;
				int sum_max = 0;
				int sum_min = 0;
				for (It i = m_start, end(m_end); i != end; ++i)
				{
					assert(((*i).*m_res).max >= 0);
					assert(((*i).*m_res).min >= 0);
					assert(((*i).*m_res).max >= ((*i).*m_res).min);
					assert(((*i).*m_res).given >= 0);
					assert(((*i).*m_res).given <= ((*i).*m_res).max);

					sum_given = saturated_add(sum_given, ((*i).*m_res).given);
					sum_max = saturated_add(sum_max, ((*i).*m_res).max);
					sum_min = saturated_add(sum_min, ((*i).*m_res).min);
				}
				assert(sum_given == std::min(std::max(m_resources, sum_min), sum_max));
			}
		};

#endif

		template<class It, class T>
		void allocate_resources_impl(
			int resources
			, It start
			, It end
			, resource_request T::* res)
		{
	#ifndef NDEBUG
			allocate_resources_contract_check<It, T> contract_check(
				resources
				, start
				, end
				, res);
	#endif

			if(resources == std::numeric_limits<int>::max())
			{
				// No competition for resources.
				// Just give everyone what they want.
				for (It i = start; i != end; ++i)
				{
					((*i).*res).given = ((*i).*res).max;
				}
				return;
			}

			// Resources are scarce

			int sum_max = 0;
			int sum_min = 0;
			for (It i = start; i != end; ++i)
			{
				sum_max = saturated_add(sum_max, ((*i).*res).max);
				assert(((*i).*res).min < std::numeric_limits<int>::max());
				assert(((*i).*res).min >= 0);
				assert(((*i).*res).min <= ((*i).*res).max);
				sum_min += ((*i).*res).min;
				((*i).*res).given = ((*i).*res).min;
			}

			if (resources == 0 || sum_max == 0)
				return;

			resources = std::max(resources, sum_min);
			int resources_to_distribute = std::min(resources, sum_max) - sum_min;
			assert(resources_to_distribute >= 0);

			while (resources_to_distribute > 0)
			{
				size_type total_used = 0;
				size_type max_used = 0;
				for (It i = start; i != end; ++i)
				{
					resource_request& r = (*i).*res;
					if(r.given == r.max) continue;

					assert(r.given < r.max);

					max_used = std::max(max_used, (size_type)r.used + 1);
					total_used += (size_type)r.used + 1;
				}

				size_type kNumer = resources_to_distribute;
				size_type kDenom = total_used;

				if (kNumer * max_used <= kDenom)
				{
					kNumer = 1;
					kDenom = max_used;
				}

				for (It i = start; i != end && resources_to_distribute > 0; ++i)
				{
					resource_request& r = (*i).*res;
					if(r.given == r.max) continue;

					assert(r.given < r.max);

					size_type used = (size_type)r.used + 1;
					size_type toGive = used * kNumer / kDenom;
					if(toGive > std::numeric_limits<int>::max())
						toGive = std::numeric_limits<int>::max();
					resources_to_distribute -= give(r, (int)toGive);
				}

				assert(resources_to_distribute >= 0);
			}
		}

		peer_connection& pick_peer(
			std::pair<boost::shared_ptr<socket>, boost::shared_ptr<peer_connection> > const& p)
		{
			return *p.second;
		}

		peer_connection& pick_peer2(
			std::pair<address, peer_connection*> const& p)
		{
			return *p.second;
		}

		torrent& deref(std::pair<sha1_hash, boost::shared_ptr<torrent> > const& p)
		{
			return *p.second;
		}

	} // namespace anonymous

/*
	void allocate_resources(
		int resources
		, std::map<boost::shared_ptr<socket>, boost::shared_ptr<peer_connection> >& c
		, resource_request peer_connection::* res)
	{
		typedef std::map<boost::shared_ptr<socket>, boost::shared_ptr<peer_connection> >::iterator orig_iter;
		typedef std::pair<boost::shared_ptr<socket>, boost::shared_ptr<peer_connection> > in_param;
		typedef boost::transform_iterator<peer_connection& (*)(in_param const&), orig_iter> new_iter;

		allocate_resources_impl(
			resources
			, new_iter(c.begin(), &pick_peer)
			, new_iter(c.end(), &pick_peer)
			, res);
	}
*/
#if defined(_MSC_VER) && _MSC_VER < 1310

	namespace detail
	{
		struct iterator_wrapper
		{
			typedef std::map<sha1_hash, boost::shared_ptr<torrent> >::iterator orig_iter;

			orig_iter iter;

			iterator_wrapper(orig_iter i): iter(i) {}
			void operator++() { ++iter; }
			torrent& operator*() { return *(iter->second); }
			bool operator==(const iterator_wrapper& i) const
			{ return iter == i.iter; }
			bool operator!=(const iterator_wrapper& i) const
			{ return iter != i.iter; }
		};

		struct iterator_wrapper2
		{
			typedef std::map<address, peer_connection*>::iterator orig_iter;

			orig_iter iter;

			iterator_wrapper2(orig_iter i): iter(i) {}
			void operator++() { ++iter; }
			peer_connection& operator*() { return *(iter->second); }
			bool operator==(const iterator_wrapper2& i) const
			{ return iter == i.iter; }
			bool operator!=(const iterator_wrapper2& i) const
			{ return iter != i.iter; }
		};

	}

	void allocate_resources(
		int resources
		, std::map<sha1_hash, boost::shared_ptr<torrent> >& c
		, resource_request torrent::* res)
	{
		allocate_resources_impl(
			resources
			, detail::iterator_wrapper(c.begin())
			, detail::iterator_wrapper(c.end())
			, res);
	}

	void allocate_resources(
		int resources
		, std::map<address, peer_connection*>& c
		, resource_request peer_connection::* res)
	{
		allocate_resources_impl(
			resources
			, detail::iterator_wrapper2(c.begin())
			, detail::iterator_wrapper2(c.end())
			, res);
	}

#else

	void allocate_resources(
		int resources
		, std::map<sha1_hash, boost::shared_ptr<torrent> >& c
		, resource_request torrent::* res)
	{
		typedef std::map<sha1_hash, boost::shared_ptr<torrent> >::iterator orig_iter;
		typedef std::pair<sha1_hash, boost::shared_ptr<torrent> > in_param;
		typedef boost::transform_iterator<torrent& (*)(in_param const&), orig_iter> new_iter;

		allocate_resources_impl(
			resources
			, new_iter(c.begin(), &deref)
			, new_iter(c.end(), &deref)
			, res);
	}

	void allocate_resources(
		int resources
		, std::map<address, peer_connection*>& c
		, resource_request peer_connection::* res)
	{
		typedef std::map<address, peer_connection*>::iterator orig_iter;
		typedef std::pair<address, peer_connection*> in_param;
		typedef boost::transform_iterator<peer_connection& (*)(in_param const&), orig_iter> new_iter;

		allocate_resources_impl(
			resources
			, new_iter(c.begin(), &pick_peer2)
			, new_iter(c.end(), &pick_peer2)
			, res);
	}
#endif

} // namespace libtorrent
<commit_msg>*** empty log message ***<commit_after>/*

Copyright (c) 2003, Magnus Jonsson, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

//The Standard Library defines the two template functions std::min()
//and std::max() in the <algorithm> header. In general, you should
//use these template functions for calculating the min and max values
//of a pair. Unfortunately, Visual C++ does not define these function
// templates. This is because the names min and max clash with
//the traditional min and max macros defined in <windows.h>.
//As a workaround, Visual C++ defines two alternative templates with
//identical functionality called _cpp_min() and _cpp_max(). You can
//use them instead of std::min() and std::max().To disable the
//generation of the min and max macros in Visual C++, #define
//NOMINMAX before #including <windows.h>.

#ifdef _WIN32
    //support boost1.32.0(2004-11-19 18:47)
    //now all libs can be compiled and linked with static module
	#define NOMINMAX
#endif

#include "libtorrent/allocate_resources.hpp"
#include "libtorrent/size_type.hpp"
#include "libtorrent/peer_connection.hpp"
#include "libtorrent/torrent.hpp"

#include <cassert>
#include <algorithm>
#include <boost/limits.hpp>

#if defined(_MSC_VER) && _MSC_VER < 1310
#define for if (false) {} else for
#else
#include <boost/iterator/transform_iterator.hpp>
#endif

namespace libtorrent
{
	int saturated_add(int a, int b)
	{
		assert(a >= 0);
		assert(b >= 0);
		assert(std::numeric_limits<int>::max() + std::numeric_limits<int>::max() < 0);

		int sum = a + b;
		if(sum < 0)
			sum = std::numeric_limits<int>::max();

		assert(sum >= a && sum >= b);
		return sum;
	}

	namespace
	{
		// give num_resources to r,
		// return how how many were actually accepted.
		int give(resource_request& r, int num_resources)
		{
			assert(num_resources >= 0);
			assert(r.given <= r.max);

			int accepted = std::min(num_resources, r.max - r.given);
			assert(accepted >= 0);

			r.given += accepted;
			assert(r.given <= r.max);

			return accepted;
		}

#ifndef NDEBUG

		template<class It, class T>
		class allocate_resources_contract_check
		{
			int m_resources;
			It m_start;
			It m_end;
			resource_request T::* m_res;

		public:
			allocate_resources_contract_check(
				int resources
				, It start
				, It end
				, resource_request T::* res)
				: m_resources(resources)
				, m_start(start)
				, m_end(end)
				, m_res(res)
			{
				assert(m_resources >= 0);
				for (It i = m_start, end(m_end); i != end; ++i)
				{
					assert(((*i).*m_res).used >= 0);
					assert(((*i).*m_res).max >= 0);
					assert(((*i).*m_res).given >= 0);
				}
			}

			~allocate_resources_contract_check()
			{
				int sum_given = 0;
				int sum_max = 0;
				int sum_min = 0;
				for (It i = m_start, end(m_end); i != end; ++i)
				{
					assert(((*i).*m_res).max >= 0);
					assert(((*i).*m_res).min >= 0);
					assert(((*i).*m_res).max >= ((*i).*m_res).min);
					assert(((*i).*m_res).given >= 0);
					assert(((*i).*m_res).given <= ((*i).*m_res).max);

					sum_given = saturated_add(sum_given, ((*i).*m_res).given);
					sum_max = saturated_add(sum_max, ((*i).*m_res).max);
					sum_min = saturated_add(sum_min, ((*i).*m_res).min);
				}
				assert(sum_given == std::min(std::max(m_resources, sum_min), sum_max));
			}
		};

#endif

		template<class It, class T>
		void allocate_resources_impl(
			int resources
			, It start
			, It end
			, resource_request T::* res)
		{
	#ifndef NDEBUG
			allocate_resources_contract_check<It, T> contract_check(
				resources
				, start
				, end
				, res);
	#endif

			if(resources == std::numeric_limits<int>::max())
			{
				// No competition for resources.
				// Just give everyone what they want.
				for (It i = start; i != end; ++i)
				{
					((*i).*res).given = ((*i).*res).max;
				}
				return;
			}

			// Resources are scarce

			int sum_max = 0;
			int sum_min = 0;
			for (It i = start; i != end; ++i)
			{
				sum_max = saturated_add(sum_max, ((*i).*res).max);
				assert(((*i).*res).min < std::numeric_limits<int>::max());
				assert(((*i).*res).min >= 0);
				assert(((*i).*res).min <= ((*i).*res).max);
				sum_min += ((*i).*res).min;
				((*i).*res).given = ((*i).*res).min;
			}

			if (resources == 0 || sum_max == 0)
				return;

			resources = std::max(resources, sum_min);
			int resources_to_distribute = std::min(resources, sum_max) - sum_min;
			assert(resources_to_distribute >= 0);

			while (resources_to_distribute > 0)
			{
				size_type total_used = 0;
				size_type max_used = 0;
				for (It i = start; i != end; ++i)
				{
					resource_request& r = (*i).*res;
					if(r.given == r.max) continue;

					assert(r.given < r.max);

					max_used = std::max(max_used, (size_type)r.used + 1);
					total_used += (size_type)r.used + 1;
				}

				size_type kNumer = resources_to_distribute;
				size_type kDenom = total_used;

				if (kNumer * max_used <= kDenom)
				{
					kNumer = 1;
					kDenom = max_used;
				}

				for (It i = start; i != end && resources_to_distribute > 0; ++i)
				{
					resource_request& r = (*i).*res;
					if(r.given == r.max) continue;

					assert(r.given < r.max);

					size_type used = (size_type)r.used + 1;
					size_type toGive = used * kNumer / kDenom;
					if(toGive > std::numeric_limits<int>::max())
						toGive = std::numeric_limits<int>::max();
					resources_to_distribute -= give(r, (int)toGive);
				}

				assert(resources_to_distribute >= 0);
			}
		}

		peer_connection& pick_peer(
			std::pair<boost::shared_ptr<socket>, boost::shared_ptr<peer_connection> > const& p)
		{
			return *p.second;
		}

		peer_connection& pick_peer2(
			std::pair<address, peer_connection*> const& p)
		{
			return *p.second;
		}

		torrent& deref(std::pair<sha1_hash, boost::shared_ptr<torrent> > const& p)
		{
			return *p.second;
		}

	} // namespace anonymous

/*
	void allocate_resources(
		int resources
		, std::map<boost::shared_ptr<socket>, boost::shared_ptr<peer_connection> >& c
		, resource_request peer_connection::* res)
	{
		typedef std::map<boost::shared_ptr<socket>, boost::shared_ptr<peer_connection> >::iterator orig_iter;
		typedef std::pair<boost::shared_ptr<socket>, boost::shared_ptr<peer_connection> > in_param;
		typedef boost::transform_iterator<peer_connection& (*)(in_param const&), orig_iter> new_iter;

		allocate_resources_impl(
			resources
			, new_iter(c.begin(), &pick_peer)
			, new_iter(c.end(), &pick_peer)
			, res);
	}
*/
#if defined(_MSC_VER) && _MSC_VER < 1310

	namespace detail
	{
		struct iterator_wrapper
		{
			typedef std::map<sha1_hash, boost::shared_ptr<torrent> >::iterator orig_iter;

			orig_iter iter;

			iterator_wrapper(orig_iter i): iter(i) {}
			void operator++() { ++iter; }
			torrent& operator*() { return *(iter->second); }
			bool operator==(const iterator_wrapper& i) const
			{ return iter == i.iter; }
			bool operator!=(const iterator_wrapper& i) const
			{ return iter != i.iter; }
		};

		struct iterator_wrapper2
		{
			typedef std::map<address, peer_connection*>::iterator orig_iter;

			orig_iter iter;

			iterator_wrapper2(orig_iter i): iter(i) {}
			void operator++() { ++iter; }
			peer_connection& operator*() { return *(iter->second); }
			bool operator==(const iterator_wrapper2& i) const
			{ return iter == i.iter; }
			bool operator!=(const iterator_wrapper2& i) const
			{ return iter != i.iter; }
		};

	}

	void allocate_resources(
		int resources
		, std::map<sha1_hash, boost::shared_ptr<torrent> >& c
		, resource_request torrent::* res)
	{
		allocate_resources_impl(
			resources
			, detail::iterator_wrapper(c.begin())
			, detail::iterator_wrapper(c.end())
			, res);
	}

	void allocate_resources(
		int resources
		, std::map<address, peer_connection*>& c
		, resource_request peer_connection::* res)
	{
		allocate_resources_impl(
			resources
			, detail::iterator_wrapper2(c.begin())
			, detail::iterator_wrapper2(c.end())
			, res);
	}

#else

	void allocate_resources(
		int resources
		, std::map<sha1_hash, boost::shared_ptr<torrent> >& c
		, resource_request torrent::* res)
	{
		typedef std::map<sha1_hash, boost::shared_ptr<torrent> >::iterator orig_iter;
		typedef std::pair<sha1_hash, boost::shared_ptr<torrent> > in_param;
		typedef boost::transform_iterator<torrent& (*)(in_param const&), orig_iter> new_iter;

		allocate_resources_impl(
			resources
			, new_iter(c.begin(), &deref)
			, new_iter(c.end(), &deref)
			, res);
	}

	void allocate_resources(
		int resources
		, std::map<address, peer_connection*>& c
		, resource_request peer_connection::* res)
	{
		typedef std::map<address, peer_connection*>::iterator orig_iter;
		typedef std::pair<address, peer_connection*> in_param;
		typedef boost::transform_iterator<peer_connection& (*)(in_param const&), orig_iter> new_iter;

		allocate_resources_impl(
			resources
			, new_iter(c.begin(), &pick_peer2)
			, new_iter(c.end(), &pick_peer2)
			, res);
	}
#endif

} // namespace libtorrent
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: dbfunc.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: nn $ $Date: 2000-11-10 19:07:44 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef SC_DBFUNC_HXX
#define SC_DBFUNC_HXX

#include "viewfunc.hxx"

struct ScSortParam;
struct ScQueryParam;
class ScDBData;
class ScDBCollection;
class ScDPObject;
class ScDPSaveData;

// ---------------------------------------------------------------------------

class ScDBFunc : public ScViewFunc
{
public:
                    ScDBFunc( Window* pParent, ScDocShell& rDocSh, ScTabViewShell* pViewShell );
                    ScDBFunc( Window* pParent, const ScDBFunc& rDBFunc, ScTabViewShell* pViewShell );
                    ~ScDBFunc();

                    //  nur UISort wiederholt bei Bedarf die Teilergebnisse

    void            UISort( const ScSortParam& rSortParam,
                          BOOL bRecord = TRUE );

    void            Sort( const ScSortParam& rSortParam,
                          BOOL bRecord = TRUE, BOOL bPaint = TRUE );
    void            Query( const ScQueryParam& rQueryParam,
                           const ScRange* pAdvSource, BOOL bRecord );
    void            DoSubTotals( const ScSubTotalParam& rParam, BOOL bRecord = TRUE,
                            const ScSortParam* pForceNewSort = NULL );

    void            ToggleAutoFilter();
    void            HideAutoFilter();

    void            RepeatDB( BOOL bRecord = TRUE );

    BOOL            ImportData( const ScImportParam& rParam, BOOL bRecord = TRUE );

    void            GotoDBArea( const String& rDBName );

                    // DB-Bereich vom Cursor
    ScDBData*       GetDBData( BOOL bMarkArea = TRUE, ScGetDBMode eMode = SC_DB_MAKE );

    void            NotifyCloseDbNameDlg( const ScDBCollection& rNewColl, const List& rDelAreaList );

    void            Consolidate( const ScConsolidateParam& rParam, BOOL bRecord = TRUE );

    void            MakePivotTable( const ScDPSaveData& rData, const ScRange& rDest, BOOL bNewTable,
                                    const ScDPObject& rSource, BOOL bApi = FALSE );
    void            DeletePivotTable();
    void            RecalcPivotTable();

    void            MakeOutline( BOOL bColumns, BOOL bRecord = TRUE );
    void            RemoveOutline( BOOL bColumns, BOOL bRecord = TRUE );
    void            RemoveAllOutlines( BOOL bRecord = TRUE );
    void            TestRemoveOutline( BOOL& rCol, BOOL& rRow );

    void            AutoOutline( BOOL bRecord = TRUE );

    void            SelectLevel( BOOL bColumns, USHORT nLevel,
                                    BOOL bRecord = TRUE, BOOL bPaint = TRUE );
    void            ShowOutline( BOOL bColumns, USHORT nLevel, USHORT nEntry,
                                    BOOL bRecord = TRUE, BOOL bPaint = TRUE );
    void            HideOutline( BOOL bColumns, USHORT nLevel, USHORT nEntry,
                                    BOOL bRecord = TRUE, BOOL bPaint = TRUE );

    void            ShowMarkedOutlines( BOOL bRecord = TRUE );
    void            HideMarkedOutlines( BOOL bRecord = TRUE );
    BOOL            OutlinePossible(BOOL bHide);

    void            UpdateCharts(BOOL bAllCharts = FALSE);      // Default: am Cursor
};

#endif

<commit_msg>INTEGRATION: CWS tableoptions (1.2.518); FILE MERGED 2004/07/05 17:07:30 nn 1.2.518.1: #i25111# table options, drill to details<commit_after>/*************************************************************************
 *
 *  $RCSfile: dbfunc.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: hr $ $Date: 2004-07-23 12:59:52 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef SC_DBFUNC_HXX
#define SC_DBFUNC_HXX

#include "viewfunc.hxx"

struct ScSortParam;
struct ScQueryParam;
class ScDBData;
class ScDBCollection;
class ScDPObject;
class ScDPSaveData;
class StrCollection;

// ---------------------------------------------------------------------------

class ScDBFunc : public ScViewFunc
{
private:
    void            GetSelectedMemberList( StrCollection& rEntries, long& rDimension );

public:
                    ScDBFunc( Window* pParent, ScDocShell& rDocSh, ScTabViewShell* pViewShell );
                    ScDBFunc( Window* pParent, const ScDBFunc& rDBFunc, ScTabViewShell* pViewShell );
                    ~ScDBFunc();

                    //  nur UISort wiederholt bei Bedarf die Teilergebnisse

    void            UISort( const ScSortParam& rSortParam,
                          BOOL bRecord = TRUE );

    void            Sort( const ScSortParam& rSortParam,
                          BOOL bRecord = TRUE, BOOL bPaint = TRUE );
    void            Query( const ScQueryParam& rQueryParam,
                           const ScRange* pAdvSource, BOOL bRecord );
    void            DoSubTotals( const ScSubTotalParam& rParam, BOOL bRecord = TRUE,
                            const ScSortParam* pForceNewSort = NULL );

    void            ToggleAutoFilter();
    void            HideAutoFilter();

    void            RepeatDB( BOOL bRecord = TRUE );

    BOOL            ImportData( const ScImportParam& rParam, BOOL bRecord = TRUE );

    void            GotoDBArea( const String& rDBName );

                    // DB-Bereich vom Cursor
    ScDBData*       GetDBData( BOOL bMarkArea = TRUE, ScGetDBMode eMode = SC_DB_MAKE );

    void            NotifyCloseDbNameDlg( const ScDBCollection& rNewColl, const List& rDelAreaList );

    void            Consolidate( const ScConsolidateParam& rParam, BOOL bRecord = TRUE );

    void            MakePivotTable( const ScDPSaveData& rData, const ScRange& rDest, BOOL bNewTable,
                                    const ScDPObject& rSource, BOOL bApi = FALSE );
    void            DeletePivotTable();
    void            RecalcPivotTable();

    BOOL            HasSelectionForDrillDown( USHORT& rOrientation );
    void            SetDataPilotDetails( BOOL bShow, const String* pNewDimensionName = NULL );

    void            MakeOutline( BOOL bColumns, BOOL bRecord = TRUE );
    void            RemoveOutline( BOOL bColumns, BOOL bRecord = TRUE );
    void            RemoveAllOutlines( BOOL bRecord = TRUE );
    void            TestRemoveOutline( BOOL& rCol, BOOL& rRow );

    void            AutoOutline( BOOL bRecord = TRUE );

    void            SelectLevel( BOOL bColumns, USHORT nLevel,
                                    BOOL bRecord = TRUE, BOOL bPaint = TRUE );
    void            ShowOutline( BOOL bColumns, USHORT nLevel, USHORT nEntry,
                                    BOOL bRecord = TRUE, BOOL bPaint = TRUE );
    void            HideOutline( BOOL bColumns, USHORT nLevel, USHORT nEntry,
                                    BOOL bRecord = TRUE, BOOL bPaint = TRUE );

    void            ShowMarkedOutlines( BOOL bRecord = TRUE );
    void            HideMarkedOutlines( BOOL bRecord = TRUE );
    BOOL            OutlinePossible(BOOL bHide);

    void            UpdateCharts(BOOL bAllCharts = FALSE);      // Default: am Cursor
};

#endif

<|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/edit_search_engine_dialog.h"

#include <gtk/gtk.h>

#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "base/i18n/rtl.h"
#include "base/message_loop.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/gtk/accessible_widget_helper_gtk.h"
#include "chrome/browser/gtk/gtk_util.h"
#include "chrome/browser/net/url_fixer_upper.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/search_engines/edit_search_engine_controller.h"
#include "chrome/browser/search_engines/template_url.h"
#include "chrome/browser/search_engines/template_url_model.h"
#include "googleurl/src/gurl.h"
#include "grit/app_resources.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"

namespace {

std::string GetDisplayURL(const TemplateURL& turl) {
  return turl.url() ? WideToUTF8(turl.url()->DisplayURL()) : std::string();
}

// Forces text to lowercase when connected to an editable's "insert-text"
// signal.  (Like views Textfield::STYLE_LOWERCASE.)
void LowercaseInsertTextHandler(GtkEditable *editable, const gchar *text,
                                gint length, gint *position, gpointer data) {
  string16 original_text = UTF8ToUTF16(text);
  string16 lower_text = l10n_util::ToLower(original_text);
  if (lower_text != original_text) {
    std::string result = UTF16ToUTF8(lower_text);
    // Prevent ourselves getting called recursively about our own edit.
    g_signal_handlers_block_by_func(G_OBJECT(editable),
        reinterpret_cast<gpointer>(LowercaseInsertTextHandler), data);
    gtk_editable_insert_text(editable, result.c_str(), result.size(), position);
    g_signal_handlers_unblock_by_func(G_OBJECT(editable),
        reinterpret_cast<gpointer>(LowercaseInsertTextHandler), data);
    // We've inserted our modified version, stop the defalut handler from
    // inserting the original.
    g_signal_stop_emission_by_name(G_OBJECT(editable), "insert_text");
  }
}

}  // namespace

EditSearchEngineDialog::EditSearchEngineDialog(
    GtkWindow* parent_window,
    const TemplateURL* template_url,
    EditSearchEngineControllerDelegate* delegate,
    Profile* profile)
    : controller_(new EditSearchEngineController(template_url, delegate,
                                                 profile)) {
  Init(parent_window, profile);
}

void EditSearchEngineDialog::Init(GtkWindow* parent_window, Profile* profile) {
  std::string dialog_name = l10n_util::GetStringUTF8(
      controller_->template_url() ?
      IDS_SEARCH_ENGINES_EDITOR_EDIT_WINDOW_TITLE :
      IDS_SEARCH_ENGINES_EDITOR_NEW_WINDOW_TITLE);

  dialog_ = gtk_dialog_new_with_buttons(
      dialog_name.c_str(),
      parent_window,
      static_cast<GtkDialogFlags>(GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR),
      GTK_STOCK_CANCEL,
      GTK_RESPONSE_CANCEL,
      NULL);

  accessible_widget_helper_.reset(new AccessibleWidgetHelper(
      dialog_, profile));
  accessible_widget_helper_->SendOpenWindowNotification(dialog_name);

  ok_button_ = gtk_dialog_add_button(GTK_DIALOG(dialog_),
                                     controller_->template_url() ?
                                     GTK_STOCK_SAVE :
                                     GTK_STOCK_ADD,
                                     GTK_RESPONSE_OK);
  gtk_dialog_set_default_response(GTK_DIALOG(dialog_), GTK_RESPONSE_OK);

  // The dialog layout hierarchy looks like this:
  //
  // \ GtkVBox |dialog_->vbox|
  // +-\ GtkTable |controls|
  // | +-\ row 0
  // | | +- GtkLabel
  // | | +-\ GtkHBox
  // | |   +- GtkEntry |title_entry_|
  // | |   +- GtkImage |title_image_|
  // | +-\ row 1
  // | | +- GtkLabel
  // | | +-\ GtkHBox
  // | |   +- GtkEntry |keyword_entry_|
  // | |   +- GtkImage |keyword_image_|
  // | +-\ row 2
  // |   +- GtkLabel
  // |   +-\ GtkHBox
  // |     +- GtkEntry |url_entry_|
  // |     +- GtkImage |url_image_|
  // +- GtkLabel |description_label|

  title_entry_ = gtk_entry_new();
  gtk_entry_set_activates_default(GTK_ENTRY(title_entry_), TRUE);
  g_signal_connect(title_entry_, "changed",
                   G_CALLBACK(OnEntryChangedThunk), this);
  accessible_widget_helper_->SetWidgetName(
      title_entry_,
      IDS_SEARCH_ENGINES_EDITOR_DESCRIPTION_LABEL);

  keyword_entry_ = gtk_entry_new();
  gtk_entry_set_activates_default(GTK_ENTRY(keyword_entry_), TRUE);
  g_signal_connect(keyword_entry_, "changed",
                   G_CALLBACK(OnEntryChangedThunk), this);
  g_signal_connect(keyword_entry_, "insert-text",
                   G_CALLBACK(LowercaseInsertTextHandler), NULL);
  accessible_widget_helper_->SetWidgetName(
      keyword_entry_,
      IDS_SEARCH_ENGINES_EDITOR_KEYWORD_LABEL);

  url_entry_ = gtk_entry_new();
  gtk_entry_set_activates_default(GTK_ENTRY(url_entry_), TRUE);
  g_signal_connect(url_entry_, "changed",
                   G_CALLBACK(OnEntryChangedThunk), this);
  accessible_widget_helper_->SetWidgetName(
      url_entry_,
      IDS_SEARCH_ENGINES_EDITOR_URL_LABEL);

  title_image_ = gtk_image_new_from_pixbuf(NULL);
  keyword_image_ = gtk_image_new_from_pixbuf(NULL);
  url_image_ = gtk_image_new_from_pixbuf(NULL);

  if (controller_->template_url()) {
    gtk_entry_set_text(
        GTK_ENTRY(title_entry_),
        WideToUTF8(controller_->template_url()->short_name()).c_str());
    gtk_entry_set_text(
        GTK_ENTRY(keyword_entry_),
        WideToUTF8(controller_->template_url()->keyword()).c_str());
    gtk_entry_set_text(
        GTK_ENTRY(url_entry_),
        GetDisplayURL(*controller_->template_url()).c_str());
    // We don't allow users to edit prepopulated URLs.
    gtk_editable_set_editable(
        GTK_EDITABLE(url_entry_),
        controller_->template_url()->prepopulate_id() == 0);
  }

  GtkWidget* controls = gtk_util::CreateLabeledControlsGroup(NULL,
      l10n_util::GetStringUTF8(
          IDS_SEARCH_ENGINES_EDITOR_DESCRIPTION_LABEL).c_str(),
      gtk_util::CreateEntryImageHBox(title_entry_, title_image_),
      l10n_util::GetStringUTF8(IDS_SEARCH_ENGINES_EDITOR_KEYWORD_LABEL).c_str(),
      gtk_util::CreateEntryImageHBox(keyword_entry_, keyword_image_),
      l10n_util::GetStringUTF8(IDS_SEARCH_ENGINES_EDITOR_URL_LABEL).c_str(),
      gtk_util::CreateEntryImageHBox(url_entry_, url_image_),
      NULL);
  gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog_)->vbox), controls,
                     FALSE, FALSE, 0);

  // On RTL UIs (such as Arabic and Hebrew) the description text is not
  // displayed correctly since it contains the substring "%s". This substring
  // is not interpreted by the Unicode BiDi algorithm as an LTR string and
  // therefore the end result is that the following right to left text is
  // displayed: ".three two s% one" (where 'one', 'two', etc. are words in
  // Hebrew).
  //
  // In order to fix this problem we transform the substring "%s" so that it
  // is displayed correctly when rendered in an RTL context.
  std::string description =
      l10n_util::GetStringUTF8(IDS_SEARCH_ENGINES_EDITOR_URL_DESCRIPTION_LABEL);
  if (base::i18n::IsRTL()) {
    const std::string reversed_percent("s%");
    std::wstring::size_type percent_index =
        description.find("%s", static_cast<std::string::size_type>(0));
    if (percent_index != std::string::npos)
      description.replace(percent_index,
                          reversed_percent.length(),
                          reversed_percent);
  }

  GtkWidget* description_label = gtk_label_new(description.c_str());
  gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog_)->vbox), description_label,
                     FALSE, FALSE, 0);

  gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog_)->vbox),
                      gtk_util::kContentAreaSpacing);

  EnableControls();

  gtk_util::ShowDialog(dialog_);

  g_signal_connect(dialog_, "response", G_CALLBACK(OnResponseThunk), this);
  g_signal_connect(dialog_, "destroy", G_CALLBACK(OnWindowDestroyThunk), this);
}

std::wstring EditSearchEngineDialog::GetTitleInput() const {
  return UTF8ToWide(gtk_entry_get_text(GTK_ENTRY(title_entry_)));
}

std::wstring EditSearchEngineDialog::GetKeywordInput() const {
  return UTF8ToWide(gtk_entry_get_text(GTK_ENTRY(keyword_entry_)));
}

std::wstring EditSearchEngineDialog::GetURLInput() const {
  return UTF8ToWide(gtk_entry_get_text(GTK_ENTRY(url_entry_)));
}

void EditSearchEngineDialog::EnableControls() {
  gtk_widget_set_sensitive(ok_button_,
                           controller_->IsKeywordValid(GetKeywordInput()) &&
                           controller_->IsTitleValid(GetTitleInput()) &&
                           controller_->IsURLValid(GetURLInput()));
  UpdateImage(keyword_image_, controller_->IsKeywordValid(GetKeywordInput()),
              IDS_SEARCH_ENGINES_INVALID_KEYWORD_TT);
  UpdateImage(url_image_, controller_->IsURLValid(GetURLInput()),
              IDS_SEARCH_ENGINES_INVALID_URL_TT);
  UpdateImage(title_image_, controller_->IsTitleValid(GetTitleInput()),
              IDS_SEARCH_ENGINES_INVALID_TITLE_TT);
}

void EditSearchEngineDialog::UpdateImage(GtkWidget* image,
                                         bool is_valid,
                                         int invalid_message_id) {
  if (is_valid) {
    gtk_widget_set_has_tooltip(image, FALSE);
    gtk_image_set_from_pixbuf(GTK_IMAGE(image),
        ResourceBundle::GetSharedInstance().GetPixbufNamed(
            IDR_INPUT_GOOD));
  } else {
    gtk_widget_set_tooltip_text(
        image, l10n_util::GetStringUTF8(invalid_message_id).c_str());
    gtk_image_set_from_pixbuf(GTK_IMAGE(image),
        ResourceBundle::GetSharedInstance().GetPixbufNamed(
            IDR_INPUT_ALERT));
  }
}

void EditSearchEngineDialog::OnEntryChanged(GtkEditable* editable) {
  EnableControls();
}

void EditSearchEngineDialog::OnResponse(GtkDialog* dialog, int response_id) {
  if (response_id == GTK_RESPONSE_OK) {
    controller_->AcceptAddOrEdit(GetTitleInput(),
                                 GetKeywordInput(),
                                 GetURLInput());
  } else {
    controller_->CleanUpCancelledAdd();
  }
  gtk_widget_destroy(dialog_);
}

void EditSearchEngineDialog::OnWindowDestroy(GtkWidget* widget) {
  MessageLoop::current()->DeleteSoon(FROM_HERE, this);
}
<commit_msg>gtk: Gray out uneditable search URLs.<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/edit_search_engine_dialog.h"

#include <gtk/gtk.h>

#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "base/i18n/rtl.h"
#include "base/message_loop.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/gtk/accessible_widget_helper_gtk.h"
#include "chrome/browser/gtk/gtk_util.h"
#include "chrome/browser/net/url_fixer_upper.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/search_engines/edit_search_engine_controller.h"
#include "chrome/browser/search_engines/template_url.h"
#include "chrome/browser/search_engines/template_url_model.h"
#include "googleurl/src/gurl.h"
#include "grit/app_resources.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"

namespace {

std::string GetDisplayURL(const TemplateURL& turl) {
  return turl.url() ? WideToUTF8(turl.url()->DisplayURL()) : std::string();
}

// Forces text to lowercase when connected to an editable's "insert-text"
// signal.  (Like views Textfield::STYLE_LOWERCASE.)
void LowercaseInsertTextHandler(GtkEditable *editable, const gchar *text,
                                gint length, gint *position, gpointer data) {
  string16 original_text = UTF8ToUTF16(text);
  string16 lower_text = l10n_util::ToLower(original_text);
  if (lower_text != original_text) {
    std::string result = UTF16ToUTF8(lower_text);
    // Prevent ourselves getting called recursively about our own edit.
    g_signal_handlers_block_by_func(G_OBJECT(editable),
        reinterpret_cast<gpointer>(LowercaseInsertTextHandler), data);
    gtk_editable_insert_text(editable, result.c_str(), result.size(), position);
    g_signal_handlers_unblock_by_func(G_OBJECT(editable),
        reinterpret_cast<gpointer>(LowercaseInsertTextHandler), data);
    // We've inserted our modified version, stop the defalut handler from
    // inserting the original.
    g_signal_stop_emission_by_name(G_OBJECT(editable), "insert_text");
  }
}

void SetWidgetStyle(GtkWidget* entry, GtkStyle* label_style,
                    GtkStyle* dialog_style) {
  gtk_widget_modify_fg(entry, GTK_STATE_NORMAL,
                       &label_style->fg[GTK_STATE_NORMAL]);
  gtk_widget_modify_fg(entry, GTK_STATE_INSENSITIVE,
                       &label_style->fg[GTK_STATE_INSENSITIVE]);
  // GTK_NO_WINDOW widgets like GtkLabel don't draw their own background, so we
  // combine the normal or insensitive foreground of the label style with the
  // normal background of the window style to achieve the "normal label" and
  // "insensitive label" colors.
  gtk_widget_modify_base(entry, GTK_STATE_NORMAL,
                         &dialog_style->bg[GTK_STATE_NORMAL]);
  gtk_widget_modify_base(entry, GTK_STATE_INSENSITIVE,
                         &dialog_style->bg[GTK_STATE_NORMAL]);
}

}  // namespace

EditSearchEngineDialog::EditSearchEngineDialog(
    GtkWindow* parent_window,
    const TemplateURL* template_url,
    EditSearchEngineControllerDelegate* delegate,
    Profile* profile)
    : controller_(new EditSearchEngineController(template_url, delegate,
                                                 profile)) {
  Init(parent_window, profile);
}

void EditSearchEngineDialog::Init(GtkWindow* parent_window, Profile* profile) {
  std::string dialog_name = l10n_util::GetStringUTF8(
      controller_->template_url() ?
      IDS_SEARCH_ENGINES_EDITOR_EDIT_WINDOW_TITLE :
      IDS_SEARCH_ENGINES_EDITOR_NEW_WINDOW_TITLE);

  dialog_ = gtk_dialog_new_with_buttons(
      dialog_name.c_str(),
      parent_window,
      static_cast<GtkDialogFlags>(GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR),
      GTK_STOCK_CANCEL,
      GTK_RESPONSE_CANCEL,
      NULL);

  accessible_widget_helper_.reset(new AccessibleWidgetHelper(
      dialog_, profile));
  accessible_widget_helper_->SendOpenWindowNotification(dialog_name);

  ok_button_ = gtk_dialog_add_button(GTK_DIALOG(dialog_),
                                     controller_->template_url() ?
                                     GTK_STOCK_SAVE :
                                     GTK_STOCK_ADD,
                                     GTK_RESPONSE_OK);
  gtk_dialog_set_default_response(GTK_DIALOG(dialog_), GTK_RESPONSE_OK);

  // The dialog layout hierarchy looks like this:
  //
  // \ GtkVBox |dialog_->vbox|
  // +-\ GtkTable |controls|
  // | +-\ row 0
  // | | +- GtkLabel
  // | | +-\ GtkHBox
  // | |   +- GtkEntry |title_entry_|
  // | |   +- GtkImage |title_image_|
  // | +-\ row 1
  // | | +- GtkLabel
  // | | +-\ GtkHBox
  // | |   +- GtkEntry |keyword_entry_|
  // | |   +- GtkImage |keyword_image_|
  // | +-\ row 2
  // |   +- GtkLabel
  // |   +-\ GtkHBox
  // |     +- GtkEntry |url_entry_|
  // |     +- GtkImage |url_image_|
  // +- GtkLabel |description_label|

  title_entry_ = gtk_entry_new();
  gtk_entry_set_activates_default(GTK_ENTRY(title_entry_), TRUE);
  g_signal_connect(title_entry_, "changed",
                   G_CALLBACK(OnEntryChangedThunk), this);
  accessible_widget_helper_->SetWidgetName(
      title_entry_,
      IDS_SEARCH_ENGINES_EDITOR_DESCRIPTION_LABEL);

  keyword_entry_ = gtk_entry_new();
  gtk_entry_set_activates_default(GTK_ENTRY(keyword_entry_), TRUE);
  g_signal_connect(keyword_entry_, "changed",
                   G_CALLBACK(OnEntryChangedThunk), this);
  g_signal_connect(keyword_entry_, "insert-text",
                   G_CALLBACK(LowercaseInsertTextHandler), NULL);
  accessible_widget_helper_->SetWidgetName(
      keyword_entry_,
      IDS_SEARCH_ENGINES_EDITOR_KEYWORD_LABEL);

  url_entry_ = gtk_entry_new();
  gtk_entry_set_activates_default(GTK_ENTRY(url_entry_), TRUE);
  g_signal_connect(url_entry_, "changed",
                   G_CALLBACK(OnEntryChangedThunk), this);
  accessible_widget_helper_->SetWidgetName(
      url_entry_,
      IDS_SEARCH_ENGINES_EDITOR_URL_LABEL);

  title_image_ = gtk_image_new_from_pixbuf(NULL);
  keyword_image_ = gtk_image_new_from_pixbuf(NULL);
  url_image_ = gtk_image_new_from_pixbuf(NULL);

  if (controller_->template_url()) {
    gtk_entry_set_text(
        GTK_ENTRY(title_entry_),
        WideToUTF8(controller_->template_url()->short_name()).c_str());
    gtk_entry_set_text(
        GTK_ENTRY(keyword_entry_),
        WideToUTF8(controller_->template_url()->keyword()).c_str());
    gtk_entry_set_text(
        GTK_ENTRY(url_entry_),
        GetDisplayURL(*controller_->template_url()).c_str());
    // We don't allow users to edit prepopulated URLs.
    gtk_editable_set_editable(
        GTK_EDITABLE(url_entry_),
        controller_->template_url()->prepopulate_id() == 0);

    if (controller_->template_url()->prepopulate_id() != 0) {
      GtkWidget* fake_label = gtk_label_new("Fake label");
      gtk_widget_set_sensitive(fake_label,
          controller_->template_url()->prepopulate_id() == 0);
      GtkStyle* label_style = gtk_widget_get_style(fake_label);
      GtkStyle* dialog_style = gtk_widget_get_style(dialog_);
      SetWidgetStyle(url_entry_, label_style, dialog_style);
      gtk_widget_destroy(fake_label);
    }
  }

  GtkWidget* controls = gtk_util::CreateLabeledControlsGroup(NULL,
      l10n_util::GetStringUTF8(
          IDS_SEARCH_ENGINES_EDITOR_DESCRIPTION_LABEL).c_str(),
      gtk_util::CreateEntryImageHBox(title_entry_, title_image_),
      l10n_util::GetStringUTF8(IDS_SEARCH_ENGINES_EDITOR_KEYWORD_LABEL).c_str(),
      gtk_util::CreateEntryImageHBox(keyword_entry_, keyword_image_),
      l10n_util::GetStringUTF8(IDS_SEARCH_ENGINES_EDITOR_URL_LABEL).c_str(),
      gtk_util::CreateEntryImageHBox(url_entry_, url_image_),
      NULL);
  gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog_)->vbox), controls,
                     FALSE, FALSE, 0);

  // On RTL UIs (such as Arabic and Hebrew) the description text is not
  // displayed correctly since it contains the substring "%s". This substring
  // is not interpreted by the Unicode BiDi algorithm as an LTR string and
  // therefore the end result is that the following right to left text is
  // displayed: ".three two s% one" (where 'one', 'two', etc. are words in
  // Hebrew).
  //
  // In order to fix this problem we transform the substring "%s" so that it
  // is displayed correctly when rendered in an RTL context.
  std::string description =
      l10n_util::GetStringUTF8(IDS_SEARCH_ENGINES_EDITOR_URL_DESCRIPTION_LABEL);
  if (base::i18n::IsRTL()) {
    const std::string reversed_percent("s%");
    std::wstring::size_type percent_index =
        description.find("%s", static_cast<std::string::size_type>(0));
    if (percent_index != std::string::npos)
      description.replace(percent_index,
                          reversed_percent.length(),
                          reversed_percent);
  }

  GtkWidget* description_label = gtk_label_new(description.c_str());
  gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog_)->vbox), description_label,
                     FALSE, FALSE, 0);

  gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog_)->vbox),
                      gtk_util::kContentAreaSpacing);

  EnableControls();

  gtk_util::ShowDialog(dialog_);

  g_signal_connect(dialog_, "response", G_CALLBACK(OnResponseThunk), this);
  g_signal_connect(dialog_, "destroy", G_CALLBACK(OnWindowDestroyThunk), this);
}

std::wstring EditSearchEngineDialog::GetTitleInput() const {
  return UTF8ToWide(gtk_entry_get_text(GTK_ENTRY(title_entry_)));
}

std::wstring EditSearchEngineDialog::GetKeywordInput() const {
  return UTF8ToWide(gtk_entry_get_text(GTK_ENTRY(keyword_entry_)));
}

std::wstring EditSearchEngineDialog::GetURLInput() const {
  return UTF8ToWide(gtk_entry_get_text(GTK_ENTRY(url_entry_)));
}

void EditSearchEngineDialog::EnableControls() {
  gtk_widget_set_sensitive(ok_button_,
                           controller_->IsKeywordValid(GetKeywordInput()) &&
                           controller_->IsTitleValid(GetTitleInput()) &&
                           controller_->IsURLValid(GetURLInput()));
  UpdateImage(keyword_image_, controller_->IsKeywordValid(GetKeywordInput()),
              IDS_SEARCH_ENGINES_INVALID_KEYWORD_TT);
  UpdateImage(url_image_, controller_->IsURLValid(GetURLInput()),
              IDS_SEARCH_ENGINES_INVALID_URL_TT);
  UpdateImage(title_image_, controller_->IsTitleValid(GetTitleInput()),
              IDS_SEARCH_ENGINES_INVALID_TITLE_TT);
}

void EditSearchEngineDialog::UpdateImage(GtkWidget* image,
                                         bool is_valid,
                                         int invalid_message_id) {
  if (is_valid) {
    gtk_widget_set_has_tooltip(image, FALSE);
    gtk_image_set_from_pixbuf(GTK_IMAGE(image),
        ResourceBundle::GetSharedInstance().GetPixbufNamed(
            IDR_INPUT_GOOD));
  } else {
    gtk_widget_set_tooltip_text(
        image, l10n_util::GetStringUTF8(invalid_message_id).c_str());
    gtk_image_set_from_pixbuf(GTK_IMAGE(image),
        ResourceBundle::GetSharedInstance().GetPixbufNamed(
            IDR_INPUT_ALERT));
  }
}

void EditSearchEngineDialog::OnEntryChanged(GtkEditable* editable) {
  EnableControls();
}

void EditSearchEngineDialog::OnResponse(GtkDialog* dialog, int response_id) {
  if (response_id == GTK_RESPONSE_OK) {
    controller_->AcceptAddOrEdit(GetTitleInput(),
                                 GetKeywordInput(),
                                 GetURLInput());
  } else {
    controller_->CleanUpCancelledAdd();
  }
  gtk_widget_destroy(dialog_);
}

void EditSearchEngineDialog::OnWindowDestroy(GtkWidget* widget) {
  MessageLoop::current()->DeleteSoon(FROM_HERE, this);
}
<|endoftext|>


<commit_before>// Copyright (c) 2012 Intel Corp
// Copyright (c) 2012 The Chromium Authors
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell co
// pies of the Software, and to permit persons to whom the Software is furnished
//  to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in al
// l copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IM
// PLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNES
// S FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
//  OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WH
// ETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
//  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#include "content/nw/src/api/menu/menu.h"

#include "base/run_loop.h"
#include "base/values.h"
#include "base/task/current_thread.h"
#include "base/strings/utf_string_conversions.h"
#include "content/nw/src/api/object_manager.h"
#include "content/nw/src/api/menuitem/menuitem.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents.h"
#include "extensions/browser/app_window/app_window.h"
#include "skia/ext/image_operations.h"
#include "ui/aura/client/screen_position_client.h"
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
#include "ui/events/platform/platform_event_source.h"
#include "ui/views/controls/menu/menu_runner.h"
#include "ui/views/widget/widget.h"
#include "ui/views/focus/focus_manager.h"
#include "vector"

namespace ui {

NwMenuModel::NwMenuModel(Delegate* delegate) : SimpleMenuModel(delegate) {
}

bool NwMenuModel::HasIcons() const {
  // Always return false, see the comment about |NwMenuModel|.
  return false;
}

} // namespace ui

namespace nw {

void Menu::Create(const base::DictionaryValue& option) {
  is_menu_modified_ = true;
  menu_delegate_.reset(new MenuDelegate(object_manager()));
  menu_model_.reset(new ui::NwMenuModel(menu_delegate_.get()));

  focus_manager_ = NULL;
  window_ = NULL;

  std::string type;

  ignore_result(menu_items_.empty());
}

void Menu::Destroy() {
}

void Menu::Append(MenuItem* menu_item) {
  if (menu_item->submenu_)
    menu_model_->AddSubMenu(menu_item->id(), menu_item->label_,
                            menu_item->submenu_->menu_model_.get());
  else if (menu_item->type_ == "normal")
    menu_model_->AddItem(menu_item->id(), menu_item->label_);
  else if (menu_item->type_ == "checkbox")
    menu_model_->AddCheckItem(menu_item->id(), menu_item->label_);
  else if (menu_item->type_ == "separator")
    menu_model_->AddSeparator(ui::NORMAL_SEPARATOR);

  is_menu_modified_ = true;
  menu_items_.push_back(menu_item);
  menu_item->menu_ = this;
}

void Menu::Insert(MenuItem* menu_item, int pos) {
  if (pos < 0 || pos > (int)menu_items_.size()) return;

  if (menu_item->submenu_)
    menu_model_->InsertSubMenuAt(pos, menu_item->id(), menu_item->label_,
                                 menu_item->submenu_->menu_model_.get());
  else if (menu_item->type_ == "normal")
    menu_model_->InsertItemAt(pos, menu_item->id(), menu_item->label_);
  else if (menu_item->type_ == "checkbox")
    menu_model_->InsertCheckItemAt(pos, menu_item->id(), menu_item->label_);
  else if (menu_item->type_ == "separator")
    menu_model_->InsertSeparatorAt(pos, ui::NORMAL_SEPARATOR);

  is_menu_modified_ = true;
  menu_item->menu_ = this;
  menu_items_.insert(menu_items_.begin() + pos, menu_item);
}

void Menu::Remove(MenuItem* menu_item, int pos) {
  if (pos < 0 || pos >= (int)menu_items_.size()) return;

  menu_model_->RemoveItemAt(pos);
  menu_items_.erase(menu_items_.begin() + pos);
  is_menu_modified_ = true;
  menu_item->menu_ = NULL;
  menu_item->RemoveKeys();
}

void Menu::Popup(int x, int y, content::RenderFrameHost* rfh) {
  // Rebuild();

  // Map point from document to screen.
  gfx::Point screen_point(x, y);

  // Convert from content coordinates to window coordinates.
  // This code copied from chrome_web_contents_view_delegate_views.cc
  aura::Window* target_window = GetActiveNativeView(rfh);
  aura::Window* root_window = target_window->GetRootWindow();
  views::Widget* top_level_widget =
    views::Widget::GetTopLevelWidgetForNativeView(target_window);
  aura::client::ScreenPositionClient* screen_position_client =
        aura::client::GetScreenPositionClient(root_window);
  if (screen_position_client) {
    screen_position_client->ConvertPointToScreen(target_window,
             &screen_point);
  }
  set_delay_destruction(true);
  menu_runner_.reset(new views::MenuRunner(menu_model_.get(), views::MenuRunner::CONTEXT_MENU,
                                           base::Bind(&Menu::OnMenuClosed, base::Unretained(this))));
  menu_runner_->RunMenuAt(top_level_widget,
                       nullptr,
                       gfx::Rect(screen_point, gfx::Size()),
                          views::MenuAnchorPosition::kTopRight,
                       ui::MENU_SOURCE_NONE);
  // It is possible for the same MenuMessageLoopAura to start a nested
  // message-loop while it is already running a nested loop. So make
  // sure the quit-closure gets reset to the outer loop's quit-closure
  // once the innermost loop terminates.
  {
    base::AutoReset<base::Closure> reset_quit_closure(&message_loop_quit_,
                                                      base::Closure());

    //base::MessageLoop* loop = base::MessageLoop::current();
    base::CurrentThread::ScopedNestableTaskAllower allow;
    base::RunLoop run_loop;
    message_loop_quit_ = run_loop.QuitClosure();

    run_loop.Run();
  }
  set_delay_destruction(false);
  if (pending_destruction())
    object_manager_->OnDeallocateObject(id_);
}

void Menu::OnMenuClosed() {
  CHECK(!message_loop_quit_.is_null());
  message_loop_quit_.Run();

#if !defined(OS_WIN)
  // Ask PlatformEventSource to stop dispatching
  // events in this message loop
  // iteration. We want our menu's loop to return
  // before the next event.
  if (ui::PlatformEventSource::GetInstance())
    ui::PlatformEventSource::GetInstance()->StopCurrentEventStream();
#endif
}

void Menu::UpdateKeys(views::FocusManager *focus_manager){
  if (focus_manager == NULL){
    return ;
  } else {
    focus_manager_ = focus_manager;
    for(auto* item : menu_items_) {
      item->UpdateKeys(focus_manager);
    }
  }
}

void Menu::RemoveKeys() {
  if (!focus_manager_) return;

  for(auto* item: menu_items_) {
    item->RemoveKeys();
  }

  focus_manager_ = NULL;
}

void Menu::UpdateStates() {
}

aura::Window* Menu::GetActiveNativeView(content::RenderFrameHost* rfh) {
  content::WebContents* web_contents =
    content::WebContents::FromRenderFrameHost(rfh);
  if (!web_contents) {
    LOG(ERROR) << "Menu: couldn't find WebContents";
    return NULL;
  }
  return web_contents->GetFullscreenRenderWidgetHostView()
             ? web_contents->GetFullscreenRenderWidgetHostView()
                   ->GetNativeView()
             : web_contents->GetNativeView();
}

}  // namespace nw
<commit_msg>patch for GetFullscreenRenderWidgetHostView removal<commit_after>// Copyright (c) 2012 Intel Corp
// Copyright (c) 2012 The Chromium Authors
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell co
// pies of the Software, and to permit persons to whom the Software is furnished
//  to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in al
// l copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IM
// PLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNES
// S FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
//  OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WH
// ETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
//  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#include "content/nw/src/api/menu/menu.h"

#include "base/run_loop.h"
#include "base/values.h"
#include "base/task/current_thread.h"
#include "base/strings/utf_string_conversions.h"
#include "content/nw/src/api/object_manager.h"
#include "content/nw/src/api/menuitem/menuitem.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents.h"
#include "extensions/browser/app_window/app_window.h"
#include "skia/ext/image_operations.h"
#include "ui/aura/client/screen_position_client.h"
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
#include "ui/events/platform/platform_event_source.h"
#include "ui/views/controls/menu/menu_runner.h"
#include "ui/views/widget/widget.h"
#include "ui/views/focus/focus_manager.h"
#include "vector"

namespace ui {

NwMenuModel::NwMenuModel(Delegate* delegate) : SimpleMenuModel(delegate) {
}

bool NwMenuModel::HasIcons() const {
  // Always return false, see the comment about |NwMenuModel|.
  return false;
}

} // namespace ui

namespace nw {

void Menu::Create(const base::DictionaryValue& option) {
  is_menu_modified_ = true;
  menu_delegate_.reset(new MenuDelegate(object_manager()));
  menu_model_.reset(new ui::NwMenuModel(menu_delegate_.get()));

  focus_manager_ = NULL;
  window_ = NULL;

  std::string type;

  ignore_result(menu_items_.empty());
}

void Menu::Destroy() {
}

void Menu::Append(MenuItem* menu_item) {
  if (menu_item->submenu_)
    menu_model_->AddSubMenu(menu_item->id(), menu_item->label_,
                            menu_item->submenu_->menu_model_.get());
  else if (menu_item->type_ == "normal")
    menu_model_->AddItem(menu_item->id(), menu_item->label_);
  else if (menu_item->type_ == "checkbox")
    menu_model_->AddCheckItem(menu_item->id(), menu_item->label_);
  else if (menu_item->type_ == "separator")
    menu_model_->AddSeparator(ui::NORMAL_SEPARATOR);

  is_menu_modified_ = true;
  menu_items_.push_back(menu_item);
  menu_item->menu_ = this;
}

void Menu::Insert(MenuItem* menu_item, int pos) {
  if (pos < 0 || pos > (int)menu_items_.size()) return;

  if (menu_item->submenu_)
    menu_model_->InsertSubMenuAt(pos, menu_item->id(), menu_item->label_,
                                 menu_item->submenu_->menu_model_.get());
  else if (menu_item->type_ == "normal")
    menu_model_->InsertItemAt(pos, menu_item->id(), menu_item->label_);
  else if (menu_item->type_ == "checkbox")
    menu_model_->InsertCheckItemAt(pos, menu_item->id(), menu_item->label_);
  else if (menu_item->type_ == "separator")
    menu_model_->InsertSeparatorAt(pos, ui::NORMAL_SEPARATOR);

  is_menu_modified_ = true;
  menu_item->menu_ = this;
  menu_items_.insert(menu_items_.begin() + pos, menu_item);
}

void Menu::Remove(MenuItem* menu_item, int pos) {
  if (pos < 0 || pos >= (int)menu_items_.size()) return;

  menu_model_->RemoveItemAt(pos);
  menu_items_.erase(menu_items_.begin() + pos);
  is_menu_modified_ = true;
  menu_item->menu_ = NULL;
  menu_item->RemoveKeys();
}

void Menu::Popup(int x, int y, content::RenderFrameHost* rfh) {
  // Rebuild();

  // Map point from document to screen.
  gfx::Point screen_point(x, y);

  // Convert from content coordinates to window coordinates.
  // This code copied from chrome_web_contents_view_delegate_views.cc
  aura::Window* target_window = GetActiveNativeView(rfh);
  aura::Window* root_window = target_window->GetRootWindow();
  views::Widget* top_level_widget =
    views::Widget::GetTopLevelWidgetForNativeView(target_window);
  aura::client::ScreenPositionClient* screen_position_client =
        aura::client::GetScreenPositionClient(root_window);
  if (screen_position_client) {
    screen_position_client->ConvertPointToScreen(target_window,
             &screen_point);
  }
  set_delay_destruction(true);
  menu_runner_.reset(new views::MenuRunner(menu_model_.get(), views::MenuRunner::CONTEXT_MENU,
                                           base::Bind(&Menu::OnMenuClosed, base::Unretained(this))));
  menu_runner_->RunMenuAt(top_level_widget,
                       nullptr,
                       gfx::Rect(screen_point, gfx::Size()),
                          views::MenuAnchorPosition::kTopRight,
                       ui::MENU_SOURCE_NONE);
  // It is possible for the same MenuMessageLoopAura to start a nested
  // message-loop while it is already running a nested loop. So make
  // sure the quit-closure gets reset to the outer loop's quit-closure
  // once the innermost loop terminates.
  {
    base::AutoReset<base::Closure> reset_quit_closure(&message_loop_quit_,
                                                      base::Closure());

    //base::MessageLoop* loop = base::MessageLoop::current();
    base::CurrentThread::ScopedNestableTaskAllower allow;
    base::RunLoop run_loop;
    message_loop_quit_ = run_loop.QuitClosure();

    run_loop.Run();
  }
  set_delay_destruction(false);
  if (pending_destruction())
    object_manager_->OnDeallocateObject(id_);
}

void Menu::OnMenuClosed() {
  CHECK(!message_loop_quit_.is_null());
  message_loop_quit_.Run();

#if !defined(OS_WIN)
  // Ask PlatformEventSource to stop dispatching
  // events in this message loop
  // iteration. We want our menu's loop to return
  // before the next event.
  if (ui::PlatformEventSource::GetInstance())
    ui::PlatformEventSource::GetInstance()->StopCurrentEventStream();
#endif
}

void Menu::UpdateKeys(views::FocusManager *focus_manager){
  if (focus_manager == NULL){
    return ;
  } else {
    focus_manager_ = focus_manager;
    for(auto* item : menu_items_) {
      item->UpdateKeys(focus_manager);
    }
  }
}

void Menu::RemoveKeys() {
  if (!focus_manager_) return;

  for(auto* item: menu_items_) {
    item->RemoveKeys();
  }

  focus_manager_ = NULL;
}

void Menu::UpdateStates() {
}

aura::Window* Menu::GetActiveNativeView(content::RenderFrameHost* rfh) {
  content::WebContents* web_contents =
    content::WebContents::FromRenderFrameHost(rfh);
  if (!web_contents) {
    LOG(ERROR) << "Menu: couldn't find WebContents";
    return NULL;
  }
  return web_contents->GetNativeView();
}

}  // namespace nw
<|endoftext|>