<commit_before>#pragma once

#include "defaults.hpp"
#include "tools.hpp"
#include "grid_base.hpp"
#include "grid_tools.hpp"
#include "container.hpp"

namespace gftools {

/** A grid_object_base is a wrapper over container class, that stores data,
 * defined on multiple different grids.
 */
template <typename ContainerType, typename ...GridTypes>
class grid_object_base;

template <typename ValueType, typename ... GridTypes>
using grid_object = grid_object_base<container<ValueType, sizeof...(GridTypes)>, GridTypes...>;

template <typename ValueType, typename ... GridTypes>
using grid_object_ref = grid_object_base<container_ref<ValueType, sizeof...(GridTypes)>, GridTypes...>;

template <typename ContainerType, typename ...GridTypes>
class grid_object_base
{
public:
    /// A typedef for the container.
    typedef ContainerType container_type;
    /// A typedef for the values stored in the container.
    typedef typename ContainerType::value_type value_type;
    /// A typedef for a tuple of grids.
    typedef std::tuple<GridTypes...> grid_tuple;
    /// Tuple of grids traits.
    typedef tools::grid_tuple_traits<grid_tuple> trs;
    /// Total number of grids.
    static constexpr size_t N = sizeof...(GridTypes);

    /// A typedef for a function that gives the analytical value of the object, when it's not stored.
    typedef typename tools::GridArgTypeExtractor<value_type, std::tuple<GridTypes...> >::f_type function_type;
    /// A typedef for a function that gives the analytical value of the object, when it's not stored.
    typedef typename tools::GridPointExtractor<value_type, std::tuple<GridTypes...> >::f_type point_function_type;
    /// A typedef for a tuple of grid points.
    typedef typename trs::point_tuple point_tuple;
    /// A typedef for a tuple of grid point values.
    typedef typename trs::arg_tuple arg_tuple;
    /// A typedef for an array of grid indices.
    typedef typename trs::indices indices_t;

    class exPointMismatch : public std::exception { virtual const char* what() const throw() { return "Index mismatch."; }; };
    class exIOProblem : public std::exception { virtual const char* what() const throw(){return "IO problem.";} };
    class ex_wrong_index : public std::exception { virtual const char* what() const throw(){return "Index out of bounds";}};
protected:
    /// Grids on which the data is defined.
    const std::tuple<GridTypes...> grids_;
    /// Cache data dimensions.
    const indices_t dims_;
    /// Actual data - can be a container (data allocated) or a view (proxy to some other data).
    container_type data_;
public:
    /// This function returns the value of the object when the point is not in container.
    function_type tail_;

// Constructors
    /// Constructs a grid object out of a tuple containing various grids.
    grid_object_base( const std::tuple<GridTypes...> &grids);
    //grid_object_base( const std::tuple<GridTypes...> &grids, ContainerType&& in);
    grid_object_base( GridTypes... grids):grid_object_base(std::forward_as_tuple(grids...)){};
    /// Constructor of grids and data.

    template <typename CType>
        grid_object_base( const std::tuple<GridTypes...> &grids, CType& data);
    grid_object_base( const std::tuple<GridTypes...> &grids, ContainerType&& data);

    /// Copy constructor.
    grid_object_base( const grid_object_base<ContainerType, GridTypes...>& rhs);
    template <typename CType>
        grid_object_base( const grid_object_base<CType, GridTypes...>& rhs);
    /// Move constructor.
    grid_object_base( grid_object_base<ContainerType, GridTypes...>&& rhs);
// Assignments
    grid_object_base& operator= (const grid_object_base & rhs);
    template <typename CType>
        grid_object_base& operator= (const grid_object_base<CType,GridTypes...> & rhs);
    grid_object_base& operator= (grid_object_base && rhs);
    grid_object_base& operator= (const value_type & rhs);

// Properties of gridobjects - dimensions, grids, etc
    std::tuple<GridTypes...> const& grids() const { return grids_; }
    /// Returns an Mth grid in grids_.
    template<size_t M = 0>
        auto grid() const -> const typename std::tuple_element<M, std::tuple<GridTypes...>>::type&
           { return std::get<M>(grids_); };
    size_t size() const { return data_.size(); }
    point_tuple points(indices_t in) const { return trs::points(in,grids_); }
    arg_tuple get_args(indices_t in) const { return trs::get_args(in, grids_); }
    arg_tuple get_args(point_tuple in) const { return trs::get_args(in, grids_); }
    indices_t get_indices(point_tuple in) const { return trs::get_indices(in, grids_); }
    /// Returns the data_ container.
    container_type& data(){return data_;}
    container_type const& data() const {return data_;}
    function_type& tail(){return tail_;}

// Global operations - reductions, shifts
    /// Returns the complex conjugate of this object, if it's complex valued.
    grid_object_base<ContainerType, GridTypes...> conj() { return grid_object_base(grids_, data_.conj()); }
    /// Returns a norm of difference between two objects.
    template <typename CT>
        real_type diff (const grid_object_base<CT, GridTypes...> &rhs) const { return data_.diff(rhs.data()); } ;
    /// Returns the sum of all elements in the container.
    value_type sum() { return data_.sum(); };
    /// Returns an object with arguments, shifted by the given values.
    template <typename ...ArgTypes>
        typename std::enable_if<
            (std::is_convertible<std::tuple<typename std::remove_reference<ArgTypes>::type...>, arg_tuple>::value || std::is_convertible<std::tuple<ArgTypes...>, point_tuple>::value),
            grid_object<value_type, GridTypes...>>::type shift(ArgTypes... args) const { return this->shift(std::forward_as_tuple(args...)); }
    template <typename ...ArgTypes>
        typename std::enable_if<
            (std::is_convertible<std::tuple<ArgTypes...>, arg_tuple>::value || std::is_same<std::tuple<ArgTypes...>, point_tuple>::value),
            grid_object<value_type, GridTypes...>>::type shift(const std::tuple<ArgTypes...>& arg_tuple) const ;

// IO
    /// Save the data to the txt file.
    void savetxt(const std::string& fname) const;
    /// Loads the data to the txt file.
    void loadtxt(const std::string& fname, real_type tol = 1e-8);
    /// Dumps the object to the stream.
    template <typename CT, class ...GridTypes2> friend std::ostream& operator<<(std::ostream& lhs, const grid_object_base<CT,GridTypes2...> &in);

// Access operators
    /// Returns element number i, which corresponds to (*_grid)[i].
    auto operator[](size_t i)->decltype(data_[i]) { return data_[i]; };
    //template <size_t M> value_type& operator[](const std::array<size_t,M>& in);
    /// Returns tail_(in).
    value_type tail_eval(const arg_tuple& in) const { return tuple_tools::unfold_tuple(tail_, in); }
    template <typename ... ArgTypes>
        typename std::enable_if<std::is_convertible<std::tuple<ArgTypes...>, arg_tuple>::value, value_type>::type
            tail_eval(ArgTypes...in) { return tail_(in...); };
    /// Return the value by grid values.
    value_type& get(const point_tuple& in) { return data_(get_indices(in)); }

    //value_type& operator()(const point_tuple& in) { return data_(get_indices(in)); }

    const value_type& operator()(const point_tuple& in) const { return data_(get_indices(in)); }

    template <int M=N>
    typename std::enable_if<(M>1 ), value_type>::type  operator()(arg_tuple in) const
    	{ throw std::logic_error("operator() for many arguments is not implemented."); }
    template <int M=N>
    typename std::enable_if<(M==1 ), value_type>::type  operator()(arg_tuple in) const
    	{ return std::get<0>(grids_).eval(data_, std::get<0>(in)); }

    template <typename ...ArgTypes>
    	typename std::enable_if<std::is_convertible<std::tuple<ArgTypes...>, point_tuple>::value
    							, value_type>::type
        operator()(ArgTypes... in) const { return (*this)(point_tuple(std::forward_as_tuple(in...))); }
    template <typename ...ArgTypes>
        	typename std::enable_if<!std::is_convertible<std::tuple<ArgTypes...>, point_tuple>::value &&
        							sizeof...(ArgTypes)!=1 && (sizeof...(ArgTypes)==N)
        							, value_type>::type
            operator()(ArgTypes... in) const { return (*this)(arg_tuple(std::forward_as_tuple(in...))); }

    template <typename ArgType>
    	typename std::enable_if<std::is_same<std::tuple<ArgType>, arg_tuple>::value, value_type>::type
    	 operator()(ArgType in) const { return std::get<0>(grids_).eval(data_, in); }

    template <typename ArgType>
        	typename std::enable_if<std::is_same<std::tuple<ArgType>, arg_tuple>::value, value_type>::type
        	 operator()(ArgType in) { return std::get<0>(grids_).eval(data_, in); }

    /// Return value of grid_object. eval methods of grids are used, so interpolation is done if provided with grids

// Fill values
    /// Fills the container with a provided function.
    void fill(const function_type &in);
    void fill(const point_function_type &in);
    void fill(const std::function<value_type(arg_tuple)>& in) { this->fill(tools::extract_tuple_f(in)); }
    void fill(const std::function<value_type(point_tuple)>& in) { this->fill(tools::extract_tuple_f(in)); }
    /// A shortcut for fill method.
    //template <typename ...ArgTypes> grid_object_base& operator= (const std::function<value_type(ArgTypes...)> &);
    /// Same as operator=, but allows for non-equal grids. Slow. Uses analytic function to provide missing values.
    template <typename CType2>
    grid_object_base& copy_interpolate(const grid_object_base<CType2, GridTypes...> &rhs);

// Math (should be removed to an external algebra class).
    grid_object_base& operator*= (const grid_object_base & rhs);
    grid_object_base& operator*= (const value_type& rhs);
    grid_object_base operator* (const grid_object_base & rhs) const;
    grid_object_base operator* (const value_type & rhs) const;
    grid_object_base& operator+= (const grid_object_base & rhs);
    grid_object_base& operator+= (const value_type& rhs);
    grid_object_base operator+ (const grid_object_base & rhs) const;
    grid_object_base operator+ (const value_type & rhs) const;
    grid_object_base& operator-= (const grid_object_base & rhs);
    grid_object_base& operator-= (const value_type& rhs);
    grid_object_base operator- (const grid_object_base & rhs) const;
    grid_object_base operator- (const value_type & rhs) const;
    grid_object_base& operator/= (const grid_object_base & rhs);
    grid_object_base& operator/= (const value_type& rhs);
    grid_object_base operator/ (const grid_object_base & rhs) const;
    grid_object_base operator/ (const value_type & rhs) const;
    friend grid_object_base operator* (const value_type & lhs, const grid_object_base & rhs) {return rhs*lhs;};
    friend grid_object_base operator+ (const value_type & lhs, const grid_object_base & rhs) {return rhs+lhs;};
    friend grid_object_base operator- (const value_type & lhs, const grid_object_base & rhs) {return rhs*(-1.0)+lhs;};
    friend grid_object_base operator/ (const value_type & lhs, const grid_object_base & rhs) {grid_object_base out(rhs); out=lhs; return out/rhs;};
};

/*
/// A helper recursive template utility to extract and set data from the container.
    template <size_t Nc, typename CT, typename ArgType1, typename ...ArgTypes> struct containerExtractor {
        typedef typename CT::value_type value_type;
        /// Gets the data by values.
        static value_type get(CT &data, const std::tuple<GridTypes...> &grids, const ArgType1& arg1, const ArgTypes&... args);
        static value_type& get_ref(CT &data, const std::tuple<GridTypes...> &grids, const ArgType1& arg1, const ArgTypes&... args);
             };
    /// Specialization of containerExtractor for 1-dim container.
    template <typename CT, typename ArgType1> struct containerExtractor<1,CT,ArgType1> {
        typedef typename CT::value_type value_type;
        static value_type get(CT &data, const std::tuple<GridTypes...> &grids, const ArgType1& arg1);
        static value_type get(CT &data, const std::tuple<GridTypes...> &grids, const std::tuple<ArgType1>& arg1);

        static value_type& get_ref(CT &data, const std::tuple<GridTypes...> &grids, const ArgType1& arg1);
        static value_type& get_ref(CT &data, const std::tuple<GridTypes...> &grids, const std::tuple<ArgType1>& arg1);
        };
*/

} // end of namespace gftools

#include "grid_object.hxx"

<commit_msg>restored operator() of grid_objects using find_nearest : FIXME with expression templates<commit_after>#pragma once

#include "defaults.hpp"
#include "tools.hpp"
#include "grid_base.hpp"
#include "grid_tools.hpp"
#include "container.hpp"

namespace gftools {

/** A grid_object_base is a wrapper over container class, that stores data,
 * defined on multiple different grids.
 */
template <typename ContainerType, typename ...GridTypes>
class grid_object_base;

template <typename ValueType, typename ... GridTypes>
using grid_object = grid_object_base<container<ValueType, sizeof...(GridTypes)>, GridTypes...>;

template <typename ValueType, typename ... GridTypes>
using grid_object_ref = grid_object_base<container_ref<ValueType, sizeof...(GridTypes)>, GridTypes...>;

template <typename ContainerType, typename ...GridTypes>
class grid_object_base
{
public:
    /// A typedef for the container.
    typedef ContainerType container_type;
    /// A typedef for the values stored in the container.
    typedef typename ContainerType::value_type value_type;
    /// A typedef for a tuple of grids.
    typedef std::tuple<GridTypes...> grid_tuple;
    /// Tuple of grids traits.
    typedef tools::grid_tuple_traits<grid_tuple> trs;
    /// Total number of grids.
    static constexpr size_t N = sizeof...(GridTypes);

    /// A typedef for a function that gives the analytical value of the object, when it's not stored.
    typedef typename tools::GridArgTypeExtractor<value_type, std::tuple<GridTypes...> >::f_type function_type;
    /// A typedef for a function that gives the analytical value of the object, when it's not stored.
    typedef typename tools::GridPointExtractor<value_type, std::tuple<GridTypes...> >::f_type point_function_type;
    /// A typedef for a tuple of grid points.
    typedef typename trs::point_tuple point_tuple;
    /// A typedef for a tuple of grid point values.
    typedef typename trs::arg_tuple arg_tuple;
    /// A typedef for an array of grid indices.
    typedef typename trs::indices indices_t;

    class exPointMismatch : public std::exception { virtual const char* what() const throw() { return "Index mismatch."; }; };
    class exIOProblem : public std::exception { virtual const char* what() const throw(){return "IO problem.";} };
    class ex_wrong_index : public std::exception { virtual const char* what() const throw(){return "Index out of bounds";}};
protected:
    /// Grids on which the data is defined.
    const std::tuple<GridTypes...> grids_;
    /// Cache data dimensions.
    const indices_t dims_;
    /// Actual data - can be a container (data allocated) or a view (proxy to some other data).
    container_type data_;
public:
    /// This function returns the value of the object when the point is not in container.
    function_type tail_;

// Constructors
    /// Constructs a grid object out of a tuple containing various grids.
    grid_object_base( const std::tuple<GridTypes...> &grids);
    //grid_object_base( const std::tuple<GridTypes...> &grids, ContainerType&& in);
    grid_object_base( GridTypes... grids):grid_object_base(std::forward_as_tuple(grids...)){};
    /// Constructor of grids and data.

    template <typename CType>
        grid_object_base( const std::tuple<GridTypes...> &grids, CType& data);
    grid_object_base( const std::tuple<GridTypes...> &grids, ContainerType&& data);

    /// Copy constructor.
    grid_object_base( const grid_object_base<ContainerType, GridTypes...>& rhs);
    template <typename CType>
        grid_object_base( const grid_object_base<CType, GridTypes...>& rhs);
    /// Move constructor.
    grid_object_base( grid_object_base<ContainerType, GridTypes...>&& rhs);
// Assignments
    grid_object_base& operator= (const grid_object_base & rhs);
    template <typename CType>
        grid_object_base& operator= (const grid_object_base<CType,GridTypes...> & rhs);
    grid_object_base& operator= (grid_object_base && rhs);
    grid_object_base& operator= (const value_type & rhs);

// Properties of gridobjects - dimensions, grids, etc
    std::tuple<GridTypes...> const& grids() const { return grids_; }
    /// Returns an Mth grid in grids_.
    template<size_t M = 0>
        auto grid() const -> const typename std::tuple_element<M, std::tuple<GridTypes...>>::type&
           { return std::get<M>(grids_); };
    size_t size() const { return data_.size(); }
    point_tuple points(indices_t in) const { return trs::points(in,grids_); }
    arg_tuple get_args(indices_t in) const { return trs::get_args(in, grids_); }
    arg_tuple get_args(point_tuple in) const { return trs::get_args(in, grids_); }
    indices_t get_indices(point_tuple in) const { return trs::get_indices(in, grids_); }
    /// Returns the data_ container.
    container_type& data(){return data_;}
    container_type const& data() const {return data_;}
    function_type& tail(){return tail_;}

// Global operations - reductions, shifts
    /// Returns the complex conjugate of this object, if it's complex valued.
    grid_object_base<ContainerType, GridTypes...> conj() { return grid_object_base(grids_, data_.conj()); }
    /// Returns a norm of difference between two objects.
    template <typename CT>
        real_type diff (const grid_object_base<CT, GridTypes...> &rhs) const { return data_.diff(rhs.data()); } ;
    /// Returns the sum of all elements in the container.
    value_type sum() { return data_.sum(); };
    /// Returns an object with arguments, shifted by the given values.
    template <typename ...ArgTypes>
        typename std::enable_if<
            (std::is_convertible<std::tuple<typename std::remove_reference<ArgTypes>::type...>, arg_tuple>::value || std::is_convertible<std::tuple<ArgTypes...>, point_tuple>::value),
            grid_object<value_type, GridTypes...>>::type shift(ArgTypes... args) const { return this->shift(std::forward_as_tuple(args...)); }
    template <typename ...ArgTypes>
        typename std::enable_if<
            (std::is_convertible<std::tuple<ArgTypes...>, arg_tuple>::value || std::is_same<std::tuple<ArgTypes...>, point_tuple>::value),
            grid_object<value_type, GridTypes...>>::type shift(const std::tuple<ArgTypes...>& arg_tuple) const ;

// IO
    /// Save the data to the txt file.
    void savetxt(const std::string& fname) const;
    /// Loads the data to the txt file.
    void loadtxt(const std::string& fname, real_type tol = 1e-8);
    /// Dumps the object to the stream.
    template <typename CT, class ...GridTypes2> friend std::ostream& operator<<(std::ostream& lhs, const grid_object_base<CT,GridTypes2...> &in);

// Access operators
    /// Returns element number i, which corresponds to (*_grid)[i].
    auto operator[](size_t i)->decltype(data_[i]) { return data_[i]; };
    //template <size_t M> value_type& operator[](const std::array<size_t,M>& in);
    /// Returns tail_(in).
    value_type tail_eval(const arg_tuple& in) const { return tuple_tools::unfold_tuple(tail_, in); }
    template <typename ... ArgTypes>
        typename std::enable_if<std::is_convertible<std::tuple<ArgTypes...>, arg_tuple>::value, value_type>::type
            tail_eval(ArgTypes...in) { return tail_(in...); };
    /// Return the value by grid values.
    value_type& get(const point_tuple& in) { return data_(get_indices(in)); }

    //value_type& operator()(const point_tuple& in) { return data_(get_indices(in)); }

    const value_type& operator()(const point_tuple& in) const { return data_(get_indices(in)); }

    template <int M=N>
    typename std::enable_if<(M>1 ), value_type>::type  operator()(arg_tuple in) const
    	{  point_tuple x = trs::find_nearest(in, grids_); return (*this)(x); // FIXME with expression templates
        # warning grid_object::operator() doesn't provide interpolation for D>=2
        }
    template <int M=N>
    typename std::enable_if<(M==1 ), value_type>::type  operator()(arg_tuple in) const
    	{ return std::get<0>(grids_).eval(data_, std::get<0>(in)); }

    template <typename ...ArgTypes>
    	typename std::enable_if<std::is_convertible<std::tuple<ArgTypes...>, point_tuple>::value
    							, value_type>::type
        operator()(ArgTypes... in) const { return (*this)(point_tuple(std::forward_as_tuple(in...))); }
    template <typename ...ArgTypes>
        	typename std::enable_if<!std::is_convertible<std::tuple<ArgTypes...>, point_tuple>::value &&
        							sizeof...(ArgTypes)!=1 && (sizeof...(ArgTypes)==N)
        							, value_type>::type
            operator()(ArgTypes... in) const { return (*this)(arg_tuple(std::forward_as_tuple(in...))); }

    template <typename ArgType>
    	typename std::enable_if<std::is_same<std::tuple<ArgType>, arg_tuple>::value, value_type>::type
    	 operator()(ArgType in) const { return std::get<0>(grids_).eval(data_, in); }

    template <typename ArgType>
        	typename std::enable_if<std::is_same<std::tuple<ArgType>, arg_tuple>::value, value_type>::type
        	 operator()(ArgType in) { return std::get<0>(grids_).eval(data_, in); }

    /// Return value of grid_object. eval methods of grids are used, so interpolation is done if provided with grids

// Fill values
    /// Fills the container with a provided function.
    void fill(const function_type &in);
    void fill(const point_function_type &in);
    void fill(const std::function<value_type(arg_tuple)>& in) { this->fill(tools::extract_tuple_f(in)); }
    void fill(const std::function<value_type(point_tuple)>& in) { this->fill(tools::extract_tuple_f(in)); }
    /// A shortcut for fill method.
    //template <typename ...ArgTypes> grid_object_base& operator= (const std::function<value_type(ArgTypes...)> &);
    /// Same as operator=, but allows for non-equal grids. Slow. Uses analytic function to provide missing values.
    template <typename CType2>
    grid_object_base& copy_interpolate(const grid_object_base<CType2, GridTypes...> &rhs);

// Math (should be removed to an external algebra class).
    grid_object_base& operator*= (const grid_object_base & rhs);
    grid_object_base& operator*= (const value_type& rhs);
    grid_object_base operator* (const grid_object_base & rhs) const;
    grid_object_base operator* (const value_type & rhs) const;
    grid_object_base& operator+= (const grid_object_base & rhs);
    grid_object_base& operator+= (const value_type& rhs);
    grid_object_base operator+ (const grid_object_base & rhs) const;
    grid_object_base operator+ (const value_type & rhs) const;
    grid_object_base& operator-= (const grid_object_base & rhs);
    grid_object_base& operator-= (const value_type& rhs);
    grid_object_base operator- (const grid_object_base & rhs) const;
    grid_object_base operator- (const value_type & rhs) const;
    grid_object_base& operator/= (const grid_object_base & rhs);
    grid_object_base& operator/= (const value_type& rhs);
    grid_object_base operator/ (const grid_object_base & rhs) const;
    grid_object_base operator/ (const value_type & rhs) const;
    friend grid_object_base operator* (const value_type & lhs, const grid_object_base & rhs) {return rhs*lhs;};
    friend grid_object_base operator+ (const value_type & lhs, const grid_object_base & rhs) {return rhs+lhs;};
    friend grid_object_base operator- (const value_type & lhs, const grid_object_base & rhs) {return rhs*(-1.0)+lhs;};
    friend grid_object_base operator/ (const value_type & lhs, const grid_object_base & rhs) {grid_object_base out(rhs); out=lhs; return out/rhs;};
};

/*
/// A helper recursive template utility to extract and set data from the container.
    template <size_t Nc, typename CT, typename ArgType1, typename ...ArgTypes> struct containerExtractor {
        typedef typename CT::value_type value_type;
        /// Gets the data by values.
        static value_type get(CT &data, const std::tuple<GridTypes...> &grids, const ArgType1& arg1, const ArgTypes&... args);
        static value_type& get_ref(CT &data, const std::tuple<GridTypes...> &grids, const ArgType1& arg1, const ArgTypes&... args);
             };
    /// Specialization of containerExtractor for 1-dim container.
    template <typename CT, typename ArgType1> struct containerExtractor<1,CT,ArgType1> {
        typedef typename CT::value_type value_type;
        static value_type get(CT &data, const std::tuple<GridTypes...> &grids, const ArgType1& arg1);
        static value_type get(CT &data, const std::tuple<GridTypes...> &grids, const std::tuple<ArgType1>& arg1);

        static value_type& get_ref(CT &data, const std::tuple<GridTypes...> &grids, const ArgType1& arg1);
        static value_type& get_ref(CT &data, const std::tuple<GridTypes...> &grids, const std::tuple<ArgType1>& arg1);
        };
*/

} // end of namespace gftools

#include "grid_object.hxx"

<|endoftext|>


<commit_before>/*
  This file is part of KAddressBook.
  Copyright (c) 2002 Mike Pilone <mpilone@slac.com>

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

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

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

  As a special exception, permission is given to link this program
  with any edition of Qt, and distribute the resulting executable,
  without including the source code for Qt in the source distribution.
*/

#include <qapplication.h>
#include <qclipboard.h>

#include <kapplication.h>
#include <kconfig.h>
#include <kdebug.h>
#include <klocale.h>
#include <kprotocolinfo.h>
#include <kxmlguiclient.h>
#include <kxmlguifactory.h>

#include "actionmanager.h"
#include "kaddressbook.h"
#include "viewmanager.h"
#include "undo.h"

ActionManager::ActionManager(KXMLGUIClient *client, KAddressBook *widget,
                             bool readWrite, QObject *parent)
    : QObject(parent)
{
    mGUIClient = client;
    mACollection = mGUIClient->actionCollection();

    mWidget = widget;
    connect( mWidget, SIGNAL( addresseeSelected( bool ) ),
             SLOT( addresseeSelected( bool ) ) );
    connect( mWidget, SIGNAL( modified( bool ) ),
             SLOT( modified( bool ) ) );

    mViewManager = mWidget->viewManager();
    connect( mViewManager, SIGNAL( viewConfigChanged(const QString &) ),
             SLOT( viewConfigChanged(const QString &) ) );

    connect( QApplication::clipboard(), SIGNAL( dataChanged() ),
             SLOT( clipboardDataChanged() ) );

    mReadWrite = readWrite;
    initReadOnlyActions();
    if (mReadWrite)
        initReadWriteActions();

    // Read our own config
    KConfig *config = kapp->config();
    config->setGroup("Views");
    mActiveViewName = config->readEntry("Active");
    config->setGroup("MainWindow");
    mActionJumpBar->setChecked(config->readBoolEntry("JumpBar", false));
    mActionQuickEdit->setChecked(config->readBoolEntry("QuickEdit", false));

    // Set the defaults
    addresseeSelected(false);
    modified(false);
    quickToolsAction();

    mActionViewList.setAutoDelete(true);

    // Connect to the signals from the undo/redo stacks so we can update the
    // edit menu
    connect(UndoStack::instance(), SIGNAL(changed()), SLOT(updateEditMenu()));
    connect(RedoStack::instance(), SIGNAL(changed()), SLOT(updateEditMenu()));
}

ActionManager::~ActionManager()
{
    // Write our own config
    KConfig *config = kapp->config();

    config->setGroup("Views");
    config->writeEntry("Active", mActiveViewName);

    config->setGroup("MainWindow");
    config->writeEntry("JumpBar", mActionJumpBar->isChecked());
    config->writeEntry("QuickEdit", mActionQuickEdit->isChecked());
}

void ActionManager::setReadWrite(bool rw)
{
    if (rw == mReadWrite)
        return;

    mReadWrite = rw;
    if (mReadWrite)
        initReadWriteActions();
    else
        destroyReadWriteActions();
}

void ActionManager::clipboardDataChanged()
{
    if (mReadWrite)
        mActionPaste->setEnabled( !QApplication::clipboard()->text().isEmpty() );
}

void ActionManager::initReadOnlyActions()
{
    // File menu
    mActionSave = new KAction(i18n("&Save"), "filesave", CTRL+Key_S, mWidget,
                              SLOT(save()), mACollection,"file_sync");

    new KAction(i18n("&New Contact"), "filenew", CTRL+Key_N, mWidget,
                SLOT(newAddressee()),mACollection,"file_new_contact");

    new KAction(i18n("&Distribution List..."), 0, mWidget,
                SLOT(slotDistributionList()), mACollection,
                "file_distribution_list");

    mActionMail = KStdAction::mail(mViewManager, SLOT(sendMail()),
                                   mACollection);
    mActionEditAddressee = new KAction(i18n("&Edit Contact..."), "edit", 0,
                                       mWidget, SLOT(editAddressee()),
                                       mACollection, "file_properties");

    KStdAction::print(mWidget, SLOT(print()), mACollection);

    new KAction(i18n("Import &KDE 2 Address Book..."), 0, mWidget,
                SLOT(importKDE2()), mACollection, "file_import_kde2");

    new KAction(i18n("Import vCard2.1..."), 0, mWidget, SLOT(importVCard21()),
                mACollection, "file_import_vcard21");

    new KAction(i18n("Import vCard3.0..."), 0, mWidget, SLOT(importVCard30()),
                mACollection, "file_import_vcard30");

    new KAction(i18n("&Import List..."), 0, mWidget, SLOT(importCSV()),
                mACollection, "file_import_csv");

    new KAction(i18n("&Export List..."), 0, mWidget, SLOT(exportCSV()),
                mACollection, "file_export_csv");

    new KAction(i18n("&Export vCard3.0..."), 0, mWidget, SLOT(exportVCard30()),
                mACollection, "file_export_vcard30");

    // Edit menu
    mActionCopy = KStdAction::copy(mViewManager, SLOT(copy()),
                                   mACollection);

    KStdAction::selectAll(mViewManager, SLOT(setSelected()), mACollection);

    mActionDelete = new KAction(i18n("&Delete Contact"), "editdelete",
                                Key_Delete, mViewManager,
                                SLOT(deleteAddressee()), mACollection,
                                "edit_delete");

    mActionUndo = KStdAction::undo(mWidget, SLOT(undo()), mACollection);
    mActionUndo->setEnabled(false);

    mActionRedo = KStdAction::redo(mWidget, SLOT(redo()), mACollection);
    mActionRedo->setEnabled( false );

    // View menu
    new KAction(i18n("Modify View..."), "configure", 0, mViewManager,
                SLOT(modifyView()), mACollection,
                "view_modify");
    new KAction(i18n("Add View..."), "window_new", 0, mViewManager,
                SLOT(addView()), mACollection,
                "view_add");
    mActionDeleteView = new KAction(i18n("Delete View..."), "delete", 0,
                                    mViewManager,
                                    SLOT(deleteView()), mACollection,
                                    "view_delete");
    new KAction(i18n("Refresh View"), "reload", 0, mViewManager,
                SLOT(refresh()), mACollection,
                "view_refresh");

    // Only enable LDAP lookup if we can handle the protocol
    if( KProtocolInfo::isKnownProtocol( KURL("ldap://localhost") )) {
        // LDAP button on toolbar
        new KAction(i18n("&Lookup addresses in directory"),
                    "ldap_lookup", 0, mWidget, SLOT(slotOpenLDAPDialog()),
                    mACollection,"ldap_lookup");
    }

    // Settings menu
    mActionJumpBar = new KToggleAction(i18n("Show Jump Bar"), "next", 0,
                                       this, SLOT(quickToolsAction()),
                                       mACollection,
                                       "options_show_jump_bar");
    mActionQuickEdit = new KToggleAction(i18n("Show Quick Edit"), "edit",
                                         0, this, SLOT(quickToolsAction()),
                                         mACollection,
                                         "options_show_quick_edit");
    (void) new KAction(i18n("Edit &Filters"), "filter",
                       0, mWidget, SLOT(configureFilters()),
                       mACollection, "options_edit_filters");
    mActionSelectFilter = new KSelectAction(i18n("Select Filter"), "select_filter",
                                            0,
                                            this, SLOT(slotFilterActivated(int)),
                                            mACollection, "select_filter");
    connect(mActionSelectFilter, SIGNAL(activated(int)),
            SLOT(slotFilterActivated(int)));
    connect(this, SIGNAL(filterActivated(int)),
            mViewManager, SLOT(filterActivated(int)));
    connect(mViewManager, SIGNAL(setFilterNames(const QStringList&)),
            SLOT(setFilterNames(const QStringList&)));
    connect(mViewManager, SIGNAL(setCurrentFilterName(const QString&)),
            SLOT(setCurrentFilterName(const QString&)));
    connect(mViewManager, SIGNAL(setCurrentFilter(int index)),
            SLOT(setCurrentFilter(int index)));
}

void ActionManager::initReadWriteActions()
{
    // Edit menu
    mActionCut = KStdAction::cut(mViewManager, SLOT(cut()), mACollection);
    mActionPaste = KStdAction::paste(mViewManager, SLOT(paste()),
                                     mACollection);
    clipboardDataChanged();
}

void ActionManager::destroyReadWriteActions()
{
    delete mActionCut;
    delete mActionPaste;
}

void ActionManager::updateEditMenu()
{
    UndoStack *undo = UndoStack::instance();
    RedoStack *redo = RedoStack::instance();

    if (undo->isEmpty())
        mActionUndo->setText( i18n( "Undo" ) );
    else
        mActionUndo->setText( i18n( "Undo" ) + " " + undo->top()->name() );
    mActionUndo->setEnabled( !undo->isEmpty() );

    if (!redo->top())
        mActionRedo->setText( i18n( "Redo" ) );
    else
        mActionRedo->setText( i18n( "Redo" ) + " " + redo->top()->name() );
    mActionRedo->setEnabled( !redo->isEmpty() );
}

void ActionManager::addresseeSelected(bool selected)
{
    if (mReadWrite)
    {
        mActionCut->setEnabled(selected);
    }

    mActionCopy->setEnabled(selected);
    mActionDelete->setEnabled(selected);
    mActionEditAddressee->setEnabled(selected);
    mActionMail->setEnabled(selected);
}

void ActionManager::modified(bool mod)
{
    mActionSave->setEnabled(mod);
}

void ActionManager::initActionViewList()
{
    // Create the view actions, and set the active view
    // Find the last active view
    QStringList viewNameList = mViewManager->viewNames();
    KToggleAction *viewAction = 0;

    // Just incast there is no active view!
    if (mActiveViewName.isEmpty() ||
        (viewNameList.contains(mActiveViewName) == 0))
        mActiveViewName = *(viewNameList).at(0);

    // unplug the current ones
    mGUIClient->factory()->unplugActionList(mGUIClient, "view_loadedviews");

    // delete the current ones
    mActionViewList.clear();
    mActiveActionView = 0L;

    // Now find the active one, check the menu item, and raise it to the top
    QStringList::Iterator iter;
    QString viewName;
    for (iter = viewNameList.begin(); iter != viewNameList.end(); ++iter)
    {
        viewName = *iter;

        viewAction = new KToggleAction(viewName, QString::null, this,
                                       SLOT(selectViewAction()), mACollection,
                                       viewName.latin1());

        if (mActiveViewName == viewName)
        {
            mViewManager->setActiveView(viewName);

            viewAction->setChecked(true);
            mActiveActionView = viewAction;
        }

        mActionViewList.append(viewAction);
    }

    // Now append all the actions to the menu.
    mGUIClient->factory()->plugActionList(mGUIClient, "view_loadedviews",
                                          mActionViewList);
}

void ActionManager::viewConfigChanged(const QString &newActive)
{
    if (!newActive.isEmpty())
    {
        mActiveViewName = newActive;
    }

    // we need to rebuild the actions
    initActionViewList();

    // Only enable delete if there is more than one view
    mActionDeleteView->setEnabled(mViewManager->viewNames().size() > 1);
}

void ActionManager::selectViewAction()
{
    // See if we can find the selected action
    KToggleAction *action = 0;

    QString activatedName = sender()->name();
    QPtrListIterator<KAction> iter(mActionViewList);
    for (iter.toFirst(); iter.current(); ++iter)
    {
        action = dynamic_cast<KToggleAction*>(*iter);

        if (action->name() != activatedName)
            action->setChecked(false);
        else
        {
            mActiveActionView = action;
            mActiveActionView->setChecked(true);
            mActiveViewName = mActiveActionView->name();

            // Last, tell the main widget to set the view.
            mViewManager->setActiveView(mActiveViewName);
        }
    }
}

void ActionManager::quickToolsAction()
{
    mViewManager->setJumpButtonBarVisible(mActionJumpBar->isChecked());
    mViewManager->setQuickEditVisible(mActionQuickEdit->isChecked());
}

void ActionManager::setFilterNames(const QStringList& list)
{
    QStringList items;
    items.append(i18n("None"));
    items+=list;
    mActionSelectFilter->setItems(items);
}

void ActionManager::slotFilterActivated(int index)
{
    kdDebug() << "ActionManager::slotFilterActivated: Filter "
              << index << " activated." << endl;
    emit(filterActivated(index-1));
}

void ActionManager::setCurrentFilterName(const QString& name)
{
    QStringList items=mActionSelectFilter->items();
    int index=items.findIndex(name);
    if(index!=-1)
    {
        setCurrentFilter(index);
    }
}

void ActionManager::setCurrentFilter(int index)
{
    mActionSelectFilter->setCurrentItem(index);
}

#include "actionmanager.moc"
<commit_msg>- updated (partly deleted) useless debug messages --Mirko.<commit_after>/*
  This file is part of KAddressBook.
  Copyright (c) 2002 Mike Pilone <mpilone@slac.com>

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

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

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

  As a special exception, permission is given to link this program
  with any edition of Qt, and distribute the resulting executable,
  without including the source code for Qt in the source distribution.
*/

#include <qapplication.h>
#include <qclipboard.h>

#include <kapplication.h>
#include <kconfig.h>
#include <kdebug.h>
#include <klocale.h>
#include <kprotocolinfo.h>
#include <kxmlguiclient.h>
#include <kxmlguifactory.h>

#include "actionmanager.h"
#include "kaddressbook.h"
#include "viewmanager.h"
#include "undo.h"

ActionManager::ActionManager(KXMLGUIClient *client, KAddressBook *widget,
                             bool readWrite, QObject *parent)
    : QObject(parent)
{
    mGUIClient = client;
    mACollection = mGUIClient->actionCollection();

    mWidget = widget;
    connect( mWidget, SIGNAL( addresseeSelected( bool ) ),
             SLOT( addresseeSelected( bool ) ) );
    connect( mWidget, SIGNAL( modified( bool ) ),
             SLOT( modified( bool ) ) );

    mViewManager = mWidget->viewManager();
    connect( mViewManager, SIGNAL( viewConfigChanged(const QString &) ),
             SLOT( viewConfigChanged(const QString &) ) );

    connect( QApplication::clipboard(), SIGNAL( dataChanged() ),
             SLOT( clipboardDataChanged() ) );

    mReadWrite = readWrite;
    initReadOnlyActions();
    if (mReadWrite)
        initReadWriteActions();

    // Read our own config
    KConfig *config = kapp->config();
    config->setGroup("Views");
    mActiveViewName = config->readEntry("Active");
    config->setGroup("MainWindow");
    mActionJumpBar->setChecked(config->readBoolEntry("JumpBar", false));
    mActionQuickEdit->setChecked(config->readBoolEntry("QuickEdit", false));

    // Set the defaults
    addresseeSelected(false);
    modified(false);
    quickToolsAction();

    mActionViewList.setAutoDelete(true);

    // Connect to the signals from the undo/redo stacks so we can update the
    // edit menu
    connect(UndoStack::instance(), SIGNAL(changed()), SLOT(updateEditMenu()));
    connect(RedoStack::instance(), SIGNAL(changed()), SLOT(updateEditMenu()));
}

ActionManager::~ActionManager()
{
    // Write our own config
    KConfig *config = kapp->config();

    config->setGroup("Views");
    config->writeEntry("Active", mActiveViewName);

    config->setGroup("MainWindow");
    config->writeEntry("JumpBar", mActionJumpBar->isChecked());
    config->writeEntry("QuickEdit", mActionQuickEdit->isChecked());
}

void ActionManager::setReadWrite(bool rw)
{
    if (rw == mReadWrite)
        return;

    mReadWrite = rw;
    if (mReadWrite)
        initReadWriteActions();
    else
        destroyReadWriteActions();
}

void ActionManager::clipboardDataChanged()
{
    if (mReadWrite)
        mActionPaste->setEnabled( !QApplication::clipboard()->text().isEmpty() );
}

void ActionManager::initReadOnlyActions()
{
    // File menu
    mActionSave = new KAction(i18n("&Save"), "filesave", CTRL+Key_S, mWidget,
                              SLOT(save()), mACollection,"file_sync");

    new KAction(i18n("&New Contact"), "filenew", CTRL+Key_N, mWidget,
                SLOT(newAddressee()),mACollection,"file_new_contact");

    new KAction(i18n("&Distribution List..."), 0, mWidget,
                SLOT(slotDistributionList()), mACollection,
                "file_distribution_list");

    mActionMail = KStdAction::mail(mViewManager, SLOT(sendMail()),
                                   mACollection);
    mActionEditAddressee = new KAction(i18n("&Edit Contact..."), "edit", 0,
                                       mWidget, SLOT(editAddressee()),
                                       mACollection, "file_properties");

    KStdAction::print(mWidget, SLOT(print()), mACollection);

    new KAction(i18n("Import &KDE 2 Address Book..."), 0, mWidget,
                SLOT(importKDE2()), mACollection, "file_import_kde2");

    new KAction(i18n("Import vCard2.1..."), 0, mWidget, SLOT(importVCard21()),
                mACollection, "file_import_vcard21");

    new KAction(i18n("Import vCard3.0..."), 0, mWidget, SLOT(importVCard30()),
                mACollection, "file_import_vcard30");

    new KAction(i18n("&Import List..."), 0, mWidget, SLOT(importCSV()),
                mACollection, "file_import_csv");

    new KAction(i18n("&Export List..."), 0, mWidget, SLOT(exportCSV()),
                mACollection, "file_export_csv");

    new KAction(i18n("&Export vCard3.0..."), 0, mWidget, SLOT(exportVCard30()),
                mACollection, "file_export_vcard30");

    // Edit menu
    mActionCopy = KStdAction::copy(mViewManager, SLOT(copy()),
                                   mACollection);

    KStdAction::selectAll(mViewManager, SLOT(setSelected()), mACollection);

    mActionDelete = new KAction(i18n("&Delete Contact"), "editdelete",
                                Key_Delete, mViewManager,
                                SLOT(deleteAddressee()), mACollection,
                                "edit_delete");

    mActionUndo = KStdAction::undo(mWidget, SLOT(undo()), mACollection);
    mActionUndo->setEnabled(false);

    mActionRedo = KStdAction::redo(mWidget, SLOT(redo()), mACollection);
    mActionRedo->setEnabled( false );

    // View menu
    new KAction(i18n("Modify View..."), "configure", 0, mViewManager,
                SLOT(modifyView()), mACollection,
                "view_modify");
    new KAction(i18n("Add View..."), "window_new", 0, mViewManager,
                SLOT(addView()), mACollection,
                "view_add");
    mActionDeleteView = new KAction(i18n("Delete View..."), "delete", 0,
                                    mViewManager,
                                    SLOT(deleteView()), mACollection,
                                    "view_delete");
    new KAction(i18n("Refresh View"), "reload", 0, mViewManager,
                SLOT(refresh()), mACollection,
                "view_refresh");

    // Only enable LDAP lookup if we can handle the protocol
    if( KProtocolInfo::isKnownProtocol( KURL("ldap://localhost") )) {
        // LDAP button on toolbar
        new KAction(i18n("&Lookup addresses in directory"),
                    "ldap_lookup", 0, mWidget, SLOT(slotOpenLDAPDialog()),
                    mACollection,"ldap_lookup");
    }

    // Settings menu
    mActionJumpBar = new KToggleAction(i18n("Show Jump Bar"), "next", 0,
                                       this, SLOT(quickToolsAction()),
                                       mACollection,
                                       "options_show_jump_bar");
    mActionQuickEdit = new KToggleAction(i18n("Show Quick Edit"), "edit",
                                         0, this, SLOT(quickToolsAction()),
                                         mACollection,
                                         "options_show_quick_edit");
    (void) new KAction(i18n("Edit &Filters"), "filter",
                       0, mWidget, SLOT(configureFilters()),
                       mACollection, "options_edit_filters");
    mActionSelectFilter = new KSelectAction(i18n("Select Filter"), "select_filter",
                                            0,
                                            this, SLOT(slotFilterActivated(int)),
                                            mACollection, "select_filter");
    connect(mActionSelectFilter, SIGNAL(activated(int)),
            SLOT(slotFilterActivated(int)));
    connect(this, SIGNAL(filterActivated(int)),
            mViewManager, SLOT(filterActivated(int)));
    connect(mViewManager, SIGNAL(setFilterNames(const QStringList&)),
            SLOT(setFilterNames(const QStringList&)));
    connect(mViewManager, SIGNAL(setCurrentFilterName(const QString&)),
            SLOT(setCurrentFilterName(const QString&)));
    connect(mViewManager, SIGNAL(setCurrentFilter(int index)),
            SLOT(setCurrentFilter(int index)));
}

void ActionManager::initReadWriteActions()
{
    // Edit menu
    mActionCut = KStdAction::cut(mViewManager, SLOT(cut()), mACollection);
    mActionPaste = KStdAction::paste(mViewManager, SLOT(paste()),
                                     mACollection);
    clipboardDataChanged();
}

void ActionManager::destroyReadWriteActions()
{
    delete mActionCut;
    delete mActionPaste;
}

void ActionManager::updateEditMenu()
{
    UndoStack *undo = UndoStack::instance();
    RedoStack *redo = RedoStack::instance();

    if (undo->isEmpty())
        mActionUndo->setText( i18n( "Undo" ) );
    else
        mActionUndo->setText( i18n( "Undo" ) + " " + undo->top()->name() );
    mActionUndo->setEnabled( !undo->isEmpty() );

    if (!redo->top())
        mActionRedo->setText( i18n( "Redo" ) );
    else
        mActionRedo->setText( i18n( "Redo" ) + " " + redo->top()->name() );
    mActionRedo->setEnabled( !redo->isEmpty() );
}

void ActionManager::addresseeSelected(bool selected)
{
    if (mReadWrite)
    {
        mActionCut->setEnabled(selected);
    }

    mActionCopy->setEnabled(selected);
    mActionDelete->setEnabled(selected);
    mActionEditAddressee->setEnabled(selected);
    mActionMail->setEnabled(selected);
}

void ActionManager::modified(bool mod)
{
    mActionSave->setEnabled(mod);
}

void ActionManager::initActionViewList()
{
    // Create the view actions, and set the active view
    // Find the last active view
    QStringList viewNameList = mViewManager->viewNames();
    KToggleAction *viewAction = 0;

    // Just incast there is no active view!
    if (mActiveViewName.isEmpty() ||
        (viewNameList.contains(mActiveViewName) == 0))
        mActiveViewName = *(viewNameList).at(0);

    // unplug the current ones
    mGUIClient->factory()->unplugActionList(mGUIClient, "view_loadedviews");

    // delete the current ones
    mActionViewList.clear();
    mActiveActionView = 0L;

    // Now find the active one, check the menu item, and raise it to the top
    QStringList::Iterator iter;
    QString viewName;
    for (iter = viewNameList.begin(); iter != viewNameList.end(); ++iter)
    {
        viewName = *iter;

        viewAction = new KToggleAction(viewName, QString::null, this,
                                       SLOT(selectViewAction()), mACollection,
                                       viewName.latin1());

        if (mActiveViewName == viewName)
        {
            mViewManager->setActiveView(viewName);

            viewAction->setChecked(true);
            mActiveActionView = viewAction;
        }

        mActionViewList.append(viewAction);
    }

    // Now append all the actions to the menu.
    mGUIClient->factory()->plugActionList(mGUIClient, "view_loadedviews",
                                          mActionViewList);
}

void ActionManager::viewConfigChanged(const QString &newActive)
{
    if (!newActive.isEmpty())
    {
        mActiveViewName = newActive;
    }

    // we need to rebuild the actions
    initActionViewList();

    // Only enable delete if there is more than one view
    mActionDeleteView->setEnabled(mViewManager->viewNames().size() > 1);
}

void ActionManager::selectViewAction()
{
    // See if we can find the selected action
    KToggleAction *action = 0;

    QString activatedName = sender()->name();
    QPtrListIterator<KAction> iter(mActionViewList);
    for (iter.toFirst(); iter.current(); ++iter)
    {
        action = dynamic_cast<KToggleAction*>(*iter);

        if (action->name() != activatedName)
            action->setChecked(false);
        else
        {
            mActiveActionView = action;
            mActiveActionView->setChecked(true);
            mActiveViewName = mActiveActionView->name();

            // Last, tell the main widget to set the view.
            mViewManager->setActiveView(mActiveViewName);
        }
    }
}

void ActionManager::quickToolsAction()
{
    mViewManager->setJumpButtonBarVisible(mActionJumpBar->isChecked());
    mViewManager->setQuickEditVisible(mActionQuickEdit->isChecked());
}

void ActionManager::setFilterNames(const QStringList& list)
{
    QStringList items;
    items.append(i18n("None"));
    items+=list;
    mActionSelectFilter->setItems(items);
}

void ActionManager::slotFilterActivated(int index)
{
    emit(filterActivated(index-1));
}

void ActionManager::setCurrentFilterName(const QString& name)
{
    QStringList items=mActionSelectFilter->items();
    int index=items.findIndex(name);
    if(index!=-1)
    {
        setCurrentFilter(index);
    }
}

void ActionManager::setCurrentFilter(int index)
{
    mActionSelectFilter->setCurrentItem(index);
}

#include "actionmanager.moc"
<|endoftext|>


<commit_before>#include <algorithm>
#include <iostream>
#include <fstream>
#include <libxml/xmlmemory.h>
#include <stdexcept>
#include <string>
#include <vector>
#include "retriever.h"
#include "../node.h"
#include "../node_util.h"
#include "../string_util.h"
#include "../tree.hh"

using std::ifstream;
using std::invalid_argument;
using std::runtime_error;
using std::string;
using std::cout;
using std::endl;
using std::vector;
using string_util::starts_with;

typedef vector<string> StringVec;

static string get_type(const string &location){
  static const string CHAR("CHAR");
  if(starts_with(location,CHAR))
    return "NX_CHAR";

  static const string INT8("INT8");
  if(starts_with(location,INT8))
    return "NX_INT8";

  static const string INT16("INT16");
  if(starts_with(location,INT16))
    return "NX_INT16";

  static const string INT32("INT32");
  if(starts_with(location,INT32))
    return "NX_INT32";

  static const string UINT8("UINT8");
  if(starts_with(location,UINT8))
    return "NX_UINT8";

  static const string UINT16("UINT16");
  if(starts_with(location,UINT16))
    return "NX_UINT16";

  static const string UINT32("UINT32");
  if(starts_with(location,UINT32))
    return "NX_UINT32";

  static const string FLOAT32("FLOAT32");
  if(starts_with(location,FLOAT32))
    return "NX_FLOAT32";

  static const string FLOAT64("FLOAT64");
  if(starts_with(location,FLOAT64))
    return "NX_FLOAT64";

  throw invalid_argument("Cannot determine type in location: "+location);
}

static string xmlChar_to_str(const xmlChar *ch, int len){
  string result((char *)ch);
  if( (len>0) && ((unsigned int)len<result.size()) )
    result.erase(result.begin()+len,result.end());

  return string_util::trim(result);
}

static bool is_right_square_bracket(const char c){
  static const string RIGHT="]";
  return find(RIGHT.begin(),RIGHT.end(),c)!=RIGHT.end();
}

static string get_dims(const string &location){
  using std::find;
  static const string LEFT("[");

  if(!starts_with(location,LEFT))
    return "";

  string result="";
  for(string::const_iterator it=location.begin() ; it!=location.end() ; it++ ){
    result+=(*it);
    if(is_right_square_bracket(*it))
      break;
  }

  if(result.size()==location.size())
    return "";
  else
    return result;
}

static xmlNode* find_element(xmlNode *a_node, const string &name){
  xmlNode *cur_node=NULL;

  string nodeName;
  for( cur_node=a_node ; cur_node!=NULL ; cur_node=cur_node->next ){
    nodeName=xmlChar_to_str(cur_node->name,-1);
    if(nodeName==name)
      return cur_node->xmlChildrenNode;
  }
  return NULL;
}

static void print_element_names(xmlNode * a_node){
    xmlNode *cur_node = NULL;

    for( cur_node=a_node ; cur_node!=NULL ; cur_node=cur_node->next ){
        if(cur_node->type == XML_ELEMENT_NODE){
          cout << "node type: Element, name: " << cur_node->name << endl;
        }

        //print_element_names(cur_node->children);
    }
}

static xmlNode* open_path(xmlNode *node,StringVec::iterator begin, StringVec::iterator end){
  // error check input
  if(begin==end)
    return NULL;

  // locate the next part of the path
  node=find_element(node,*begin);

  // if it returned poorly then get out now
  if(node==NULL)
    return NULL;

  // go to next step
  begin++;
  if(begin==end)
    return node;

  // recursively call self
  return open_path(node,begin,end);
}

/**
 * The factory will call the constructor with a string. The string
 * specifies where to locate the data (e.g. a filename), but
 * interpreting the string is left up to the implementing code.
 */
TextXmlRetriever::TextXmlRetriever(const string &str): source(str) /*,current_line(0)*/{
  cout << "****************************************"
       << "****************************************" << endl; // REMOVE
  cout << "TextXmlRetriever(" << source << ")" << endl; // REMOVE

  // open the file
  doc=xmlParseFile(source.c_str());

  // check that open was successful
  if(doc==NULL){
    xmlFreeDoc(doc);
    xmlCleanupParser();
    throw runtime_error("Parsing "+source+" was not successful");
  }
}

TextXmlRetriever::~TextXmlRetriever(){
  //cout << "~TextXmlRetriever()" << endl;

  if(doc==NULL) return;

  // close the file
  xmlFreeDoc(doc);
  xmlCleanupParser();
}

/**
 * This is the method for retrieving data from a file. The whole
 * tree will be written to the new file immediately after being
 * called. Interpreting the string is left up to the implementing
 * code.
 */
void TextXmlRetriever::getData(const string &location, tree<Node> &tr){
  cout << "TextXmlRetriever::getData(" << location << ",tree)" << endl; // REMOVE
  // check that the argument is not an empty string
  if(location.size()<=0)
    throw invalid_argument("cannot parse empty string");

  // variables for the divided string version of the location
  string str_path;
  string type;
  string str_dims;

  // convert the location to a type and (string) path
  if(starts_with(location,"/")){
    str_path=location;
    type="NX_CHAR";
    str_dims="";
  }else{
    // get the type and remove it from the location
    type=get_type(location);
    str_path=location.substr(type.size()-3,location.size());
    // get the dimensions and remove it from the location
    str_dims=get_dims(str_path);
    str_path=str_path.substr(str_dims.size(),str_path.size());
    // remove the separating colon
    str_path=str_path.substr(1,str_path.size());
  }
  std::cout << "TYPE=" << type << " DIMS=" << str_dims << " PATH=" << str_path << std::endl; // REMOVE
  StringVec path=string_util::string_to_path(str_path);

  // get the root
  xmlNode *xml_node = NULL;
  xml_node = xmlDocGetRootElement(doc);

  // open the path
  xml_node=open_path(xml_node,path.begin(),path.end());
  if(xml_node==NULL)
    throw invalid_argument("path ["+location+"] does not exist in file");

  // print out contents at current location
  cout << "NAMES:" << endl;
  print_element_names(xml_node);

/*
  // check that the argument is an integer
  int line_num=string_util::str_to_int(location);

  // set stream to the line before
  skip_to_line(infile,current_line,line_num);
  // read the line and print it to the console
  string text=read_line(infile);
*/
  // create an empty node
  Node node("empty","empty");

  // put the data in the node
/*
  vector<int> dims;
  dims.push_back(text.size());
  update_node_from_string(node,text,dims,Node::CHAR);
*/
  tr.insert(tr.begin(),node);
}

static void openPath(  xmlNode *root_element, const std::vector<std::string> &path, int &num_group, int &num_data){

}

static void closePath(  xmlNode *root_element, int &num_group, int &num_data){

}

const string TextXmlRetriever::MIME_TYPE("text/xml");

string TextXmlRetriever::toString() const{
  return "["+MIME_TYPE+"] "+source;
}
<commit_msg>Added ability to get data (as strings) from file. Added aditional error check in constructor for empty xml document.<commit_after>#include <algorithm>
#include <iostream>
#include <fstream>
#include <libxml/xmlmemory.h>
#include <stdexcept>
#include <string>
#include <vector>
#include "retriever.h"
#include "../node.h"
#include "../node_util.h"
#include "../string_util.h"
#include "../tree.hh"

using std::ifstream;
using std::invalid_argument;
using std::runtime_error;
using std::string;
using std::cout;
using std::endl;
using std::vector;
using string_util::starts_with;

typedef vector<string> StringVec;

static string get_type(const string &location){
  static const string CHAR("CHAR");
  if(starts_with(location,CHAR))
    return "NX_CHAR";

  static const string INT8("INT8");
  if(starts_with(location,INT8))
    return "NX_INT8";

  static const string INT16("INT16");
  if(starts_with(location,INT16))
    return "NX_INT16";

  static const string INT32("INT32");
  if(starts_with(location,INT32))
    return "NX_INT32";

  static const string UINT8("UINT8");
  if(starts_with(location,UINT8))
    return "NX_UINT8";

  static const string UINT16("UINT16");
  if(starts_with(location,UINT16))
    return "NX_UINT16";

  static const string UINT32("UINT32");
  if(starts_with(location,UINT32))
    return "NX_UINT32";

  static const string FLOAT32("FLOAT32");
  if(starts_with(location,FLOAT32))
    return "NX_FLOAT32";

  static const string FLOAT64("FLOAT64");
  if(starts_with(location,FLOAT64))
    return "NX_FLOAT64";

  throw invalid_argument("Cannot determine type in location: "+location);
}

static string xmlChar_to_str(const xmlChar *ch, int len){
  string result((char *)ch);
  if( (len>0) && ((unsigned int)len<result.size()) )
    result.erase(result.begin()+len,result.end());

  return string_util::trim(result);
}

static bool is_right_square_bracket(const char c){
  static const string RIGHT="]";
  return find(RIGHT.begin(),RIGHT.end(),c)!=RIGHT.end();
}

static string get_dims(const string &location){
  using std::find;
  static const string LEFT("[");

  if(!starts_with(location,LEFT))
    return "";

  string result="";
  for(string::const_iterator it=location.begin() ; it!=location.end() ; it++ ){
    result+=(*it);
    if(is_right_square_bracket(*it))
      break;
  }

  if(result.size()==location.size())
    return "";
  else
    return result;
}

static xmlNode* find_element(xmlNode *a_node, const string &name){
  xmlNode *cur_node=NULL;

  string nodeName;
  for( cur_node=a_node ; cur_node!=NULL ; cur_node=cur_node->next ){
    nodeName=xmlChar_to_str(cur_node->name,-1);
    if(nodeName==name)
      return cur_node->xmlChildrenNode;
  }
  return NULL;
}

static void print_element_names(xmlNode * a_node){
    xmlNode *cur_node = NULL;

    for( cur_node=a_node ; cur_node!=NULL ; cur_node=cur_node->next ){
        if(cur_node->type == XML_ELEMENT_NODE){
          cout << "node type: Element, name: " << cur_node->name << endl;
        }

        //print_element_names(cur_node->children);
    }
}

static xmlNode* open_path(xmlNode *node,StringVec::iterator begin, StringVec::iterator end){
  // error check input
  if(begin==end)
    return NULL;

  // locate the next part of the path
  node=find_element(node,*begin);

  // if it returned poorly then get out now
  if(node==NULL)
    return NULL;

  // go to next step
  begin++;
  if(begin==end)
    return node;

  // recursively call self
  return open_path(node,begin,end);
}

static string getStrValue(const xmlDocPtr &doc, const xmlNodePtr &node){
  xmlChar *char_value=xmlNodeListGetString(doc,node,1);
  if(char_value==NULL)
    throw runtime_error("blah");
  string value=xmlChar_to_str(char_value,-1);
  xmlFree(char_value);
  return value;
}

/**
 * The factory will call the constructor with a string. The string
 * specifies where to locate the data (e.g. a filename), but
 * interpreting the string is left up to the implementing code.
 */
TextXmlRetriever::TextXmlRetriever(const string &str): source(str) /*,current_line(0)*/{
  cout << "****************************************"
       << "****************************************" << endl; // REMOVE
  cout << "TextXmlRetriever(" << source << ")" << endl; // REMOVE

  // open the file
  doc=xmlParseFile(source.c_str());

  // check that open was successful
  if(doc==NULL){
    xmlFreeDoc(doc);
    xmlCleanupParser();
    throw runtime_error("Parsing "+source+" was not successful");
  }

  // check that the document is not empty
  xmlNode *xml_node = NULL;
  xml_node = xmlDocGetRootElement(doc);
  if(xml_node==NULL)
    throw runtime_error("Empty document ["+source+"]");
}

TextXmlRetriever::~TextXmlRetriever(){
  //cout << "~TextXmlRetriever()" << endl;

  if(doc==NULL) return;

  // close the file
  xmlFreeDoc(doc);
  xmlCleanupParser();
}

/**
 * This is the method for retrieving data from a file. The whole
 * tree will be written to the new file immediately after being
 * called. Interpreting the string is left up to the implementing
 * code.
 */
void TextXmlRetriever::getData(const string &location, tree<Node> &tr){
  cout << "TextXmlRetriever::getData(" << location << ",tree)" << endl; // REMOVE
  // check that the argument is not an empty string
  if(location.size()<=0)
    throw invalid_argument("cannot parse empty string");

  // variables for the divided string version of the location
  string str_path;
  string type;
  string str_dims;

  // convert the location to a type and (string) path
  if(starts_with(location,"/")){
    str_path=location;
    type="NX_CHAR";
    str_dims="";
  }else{
    // get the type and remove it from the location
    type=get_type(location);
    str_path=location.substr(type.size()-3,location.size());
    // get the dimensions and remove it from the location
    str_dims=get_dims(str_path);
    str_path=str_path.substr(str_dims.size(),str_path.size());
    // remove the separating colon
    str_path=str_path.substr(1,str_path.size());
  }
  std::cout << "TYPE=" << type << " DIMS=" << str_dims << " PATH=" << str_path << std::endl; // REMOVE
  StringVec path=string_util::string_to_path(str_path);

  // get the root
  xmlNode *xml_node = NULL;
  xml_node = xmlDocGetRootElement(doc);

  // open the path
  xml_node=open_path(xml_node,path.begin(),path.end());
  if(xml_node==NULL)
    throw invalid_argument("path ["+location+"] does not exist in file");

  // get the value
  string value=getStrValue(doc, xml_node);
  if(value.size()<=0)
    throw runtime_error("Encountered empty value ["+source+","+location+"]");

  // create an empty node
  Node node(*(path.rbegin()),"empty");

  // put the data in the node
  vector<int> dims;
  dims.push_back(value.size());
  update_node_from_string(node,value,dims,Node::CHAR);

  tr.insert(tr.begin(),node);
}

static void openPath(  xmlNode *root_element, const std::vector<std::string> &path, int &num_group, int &num_data){

}

static void closePath(  xmlNode *root_element, int &num_group, int &num_data){

}

const string TextXmlRetriever::MIME_TYPE("text/xml");

string TextXmlRetriever::toString() const{
  return "["+MIME_TYPE+"] "+source;
}
<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
 * ITS 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
// Class header file.
#include "XercesDOMPrintWriter.hpp"

#include <cassert>

#include <dom/DOMString.hpp>

#include <PlatformSupport/DOMStringHelper.hpp>
#include <PlatformSupport/TextOutputStream.hpp>

XercesDOMPrintWriter::XercesDOMPrintWriter(
			TextOutputStream&	theOutputStream,
			bool				fAutoFlush) :
	PrintWriter(fAutoFlush),
	m_OutputStream(theOutputStream)
{
}

XercesDOMPrintWriter::~XercesDOMPrintWriter()
{
}

bool
XercesDOMPrintWriter::checkError() const
{
	return false;
}

void
XercesDOMPrintWriter::close()
{
}

void
XercesDOMPrintWriter::flush()
{
	m_OutputStream.flush();
}

void
XercesDOMPrintWriter::write(
			const char*		s,
			unsigned int	theOffset,
			unsigned int	theLength)
{
	write(DOMString(s), theOffset, theLength);
}

void
XercesDOMPrintWriter::write(
			const XMLCh*	s,
			unsigned int	theOffset,
			unsigned int	theLength)
{
	assert(s != 0);
	assert(theOffset >= 0 && theOffset < length(s));
	assert(theLength >= 0 || theLength == -1);

	if (theLength == -1)
	{
		if (theOffset == 0)
		{
			m_OutputStream.write(s);
		}
		else
		{
			m_OutputStream.write(s + theOffset);
		}
	}
	else
	{
		const long	theStopIndex = theOffset + theLength;

		for (long i = theOffset; i < theStopIndex; i++)
		{
			m_OutputStream.write(s[i]);
		}
	}
}

void
XercesDOMPrintWriter::write(XMLCh	c)
{
	m_OutputStream.write(c);
}

void
XercesDOMPrintWriter::write(
			const DOMString&	s,
			unsigned int		theOffset,
			unsigned int		theLength)
{
	assert(theOffset >= 0);
	assert(theLength >= 0 || theLength == -1);
	assert(theLength == -1 && length(s) > theOffset || length(s) >= theOffset + theLength);

#if 1
	write(c_wstr(s), theOffset, theLength);
#else
	if (theOffset == 0 && theLength == -1)
	{
		m_OutputStream << s;
	}
	else
	{
		const long	theStopIndex = (theLength == -1) ? length(s) :
													   theOffset + theLength;

		for (long i = theOffset; i < theStopIndex; i++)
		{
			m_OutputStream << s.charAt(i);
		}
	}
#endif
}

void
XercesDOMPrintWriter::print(bool	b)
{
	if (b == true)
	{
		print(DOMString("true"));
	}
	else
	{
		print(DOMString("false"));
	}
}

void
XercesDOMPrintWriter::print(char	c)
{
	write(c);
}

void
XercesDOMPrintWriter::print(
			const char*		s,
			unsigned int	theLength)
{
	write(s,
		  0,
		  theLength);
}

void
XercesDOMPrintWriter::print(
			const XMLCh*	s,
			unsigned int	theLength)
{
	assert(s != 0);
	assert(theLength >= 0 || theLength == -1);

	write(s,
		  0,
		  theLength);
}

void
XercesDOMPrintWriter::print(double	d)
{
	m_OutputStream.write(c_wstr(DoubleToDOMString(d)));
}

void
XercesDOMPrintWriter::print(int	i)
{
	m_OutputStream.write(c_wstr(LongToDOMString(i)));
}

void
XercesDOMPrintWriter::print(long	l)
{
	m_OutputStream.write(c_wstr(LongToDOMString(l)));
}

void
XercesDOMPrintWriter::print(const DOMString&	s)
{
	m_OutputStream.write(c_wstr(s));
}

void
XercesDOMPrintWriter::println()
{
	m_OutputStream.write("\n");
}

void
XercesDOMPrintWriter::println(bool	b)
{
	print(b);

	println();
}

void
XercesDOMPrintWriter::println(char	c)
{
	print(c);

	println();
}

void
XercesDOMPrintWriter::println(
			const char*		s,
			unsigned int	theLength)
{
	print(s, theLength);

	println();
}

void
XercesDOMPrintWriter::println(
			const XMLCh*	s,
			unsigned int	theLength)
{
	print(s, theLength);

	println();
}

void
XercesDOMPrintWriter::println(double	d)
{
	print(d);

	println();
}

void
XercesDOMPrintWriter::println(int		i)
{
	print(i);

	println();
}

void
XercesDOMPrintWriter::println(long	l)
{
	print(l);

	println();
}

void
XercesDOMPrintWriter::println(const DOMString&	s)
{
	print(s);

	println();
}
<commit_msg>Fixed some asserts and removed some old code that was not compiled in.<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
 * ITS 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
// Class header file.
#include "XercesDOMPrintWriter.hpp"

#include <cassert>

#include <dom/DOMString.hpp>

#include <PlatformSupport/DOMStringHelper.hpp>
#include <PlatformSupport/TextOutputStream.hpp>

XercesDOMPrintWriter::XercesDOMPrintWriter(
			TextOutputStream&	theOutputStream,
			bool				fAutoFlush) :
	PrintWriter(fAutoFlush),
	m_OutputStream(theOutputStream)
{
}

XercesDOMPrintWriter::~XercesDOMPrintWriter()
{
}

bool
XercesDOMPrintWriter::checkError() const
{
	return false;
}

void
XercesDOMPrintWriter::close()
{
}

void
XercesDOMPrintWriter::flush()
{
	m_OutputStream.flush();
}

void
XercesDOMPrintWriter::write(
			const char*		s,
			unsigned int	theOffset,
			unsigned int	theLength)
{
	write(DOMString(s), theOffset, theLength);
}

void
XercesDOMPrintWriter::write(
			const XMLCh*	s,
			unsigned int	theOffset,
			unsigned int	theLength)
{
	assert(s != 0);
	assert(length(s) == 0 || theOffset < length(s));

	if (theLength == -1)
	{
		if (theOffset == 0)
		{
			m_OutputStream.write(s);
		}
		else
		{
			m_OutputStream.write(s + theOffset);
		}
	}
	else
	{
		const long	theStopIndex = theOffset + theLength;

		for (long i = theOffset; i < theStopIndex; i++)
		{
			m_OutputStream.write(s[i]);
		}
	}
}

void
XercesDOMPrintWriter::write(XMLCh	c)
{
	m_OutputStream.write(c);
}

void
XercesDOMPrintWriter::write(
			const DOMString&	s,
			unsigned int		theOffset,
			unsigned int		theLength)
{
	write(c_wstr(s), theOffset, theLength);
}

void
XercesDOMPrintWriter::print(bool	b)
{
	if (b == true)
	{
		print(DOMString("true"));
	}
	else
	{
		print(DOMString("false"));
	}
}

void
XercesDOMPrintWriter::print(char	c)
{
	write(c);
}

void
XercesDOMPrintWriter::print(
			const char*		s,
			unsigned int	theLength)
{
	write(s,
		  0,
		  theLength);
}

void
XercesDOMPrintWriter::print(
			const XMLCh*	s,
			unsigned int	theLength)
{
	assert(s != 0);
	assert(theLength >= 0 || theLength == -1);

	write(s,
		  0,
		  theLength);
}

void
XercesDOMPrintWriter::print(double	d)
{
	m_OutputStream.write(c_wstr(DoubleToDOMString(d)));
}

void
XercesDOMPrintWriter::print(int	i)
{
	m_OutputStream.write(c_wstr(LongToDOMString(i)));
}

void
XercesDOMPrintWriter::print(long	l)
{
	m_OutputStream.write(c_wstr(LongToDOMString(l)));
}

void
XercesDOMPrintWriter::print(const DOMString&	s)
{
	m_OutputStream.write(c_wstr(s));
}

void
XercesDOMPrintWriter::println()
{
	m_OutputStream.write("\n");
}

void
XercesDOMPrintWriter::println(bool	b)
{
	print(b);

	println();
}

void
XercesDOMPrintWriter::println(char	c)
{
	print(c);

	println();
}

void
XercesDOMPrintWriter::println(
			const char*		s,
			unsigned int	theLength)
{
	print(s, theLength);

	println();
}

void
XercesDOMPrintWriter::println(
			const XMLCh*	s,
			unsigned int	theLength)
{
	print(s, theLength);

	println();
}

void
XercesDOMPrintWriter::println(double	d)
{
	print(d);

	println();
}

void
XercesDOMPrintWriter::println(int		i)
{
	print(i);

	println();
}

void
XercesDOMPrintWriter::println(long	l)
{
	print(l);

	println();
}

void
XercesDOMPrintWriter::println(const DOMString&	s)
{
	print(s);

	println();
}
<|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2017.  All rights reserved
 */
#include "Stroika/Frameworks/StroikaPreComp.h"

#include <cstdlib>
#include <iostream>

#include "Stroika/Foundation/Characters/String_Constant.h"
#include "Stroika/Foundation/Characters/ToString.h"
#include "Stroika/Foundation/Execution/Finally.h"
#include "Stroika/Foundation/Execution/Sleep.h"
#include "Stroika/Foundation/Execution/Thread.h"
#include "Stroika/Foundation/Execution/WaitableEvent.h"
#include "Stroika/Frameworks/Service/Main.h"

#include "AppVersion.h"

#include "Service.h"

using namespace std;

using namespace Stroika::Foundation;
using namespace Stroika::Frameworks::Service;

using Characters::String_Constant;
using Execution::Thread;

using namespace Samples::SimpleService;

#if qUseLogger
#include "Stroika/Foundation/Execution/Logger.h"
using Execution::Logger;
#endif

namespace {
    const Main::ServiceDescription kServiceDescription_{
        String_Constant{L"Test-Service"},
        String_Constant{L"Test Service"}};
}

namespace {
    //
    // Typically have one like this for each major module your service manages.
    //
    // These get defined/declared in that module, and just referenced here
    //
    struct SomeModuleALikeWebServer_ {
        // initialize that service//module here, including starting any threads
        SomeModuleALikeWebServer_ ()
            : fSomeOtherTaskDoingRealWork_{
                  []() {
                      Execution::Sleep (1 * 24 * 60 * 60); // wait 1 day ... simple test....
                  },
                  Thread::eAutoStart}
        {
        }
        ~SomeModuleALikeWebServer_ ()
        {
            // shutdown your threads here.
            Execution::Thread::SuppressInterruptionInContext suppressInterruption; // critical to probibit this thread from interuption until its killed owned threads
            fSomeOtherTaskDoingRealWork_.AbortAndWaitForDone ();
        }
        Thread fSomeOtherTaskDoingRealWork_;
    };
}

void SampleAppServiceRep::MainLoop (const std::function<void()>& startedCB)
{
/*
     *  The lifetime of the service roughly matches the lifetime of this MainLoop. Terminating the service (myService --stop)
     *  will cause a Thread::AbortException to be sent to this MainLoop, so that it unwinds.
     *
     *  The simplest and safest way to construct this MainLoop is using RAII, referencing external
     *  'modules' which start and stop any needed threads and do whatever setup/shutdown is needed.
     */

#if qUseLogger
    // Just so you get a clear message in the log that the service didn't startup. The things that actually caused the problem should
    bool   successfullyStarted{false};
    auto&& cleanup = Execution::Finally ([&]() {
        if (not successfullyStarted) {
            Logger::Get ().Log (Logger::Priority::eError, L"Failed to successfully start service");
        }
    });
#endif

    /*
     *  Startup modules.
     *
     *  \note initialized in the order given here, and shutdown in the reverse order, so order really does matter.
     *        Put the more general ones with fewest dependencies first.
     */
    SomeModuleALikeWebServer_ moduleA;
    SomeModuleALikeWebServer_ moduleB; // typically of a differnt type

    startedCB (); // Notify service control mgr that the service has started

#if qUseLogger
    //@todo fix to use #include of autogenerated verison stuff ... Logger::Get ().Log (Logger::Priority::eInfo, L"%s Service (version %s) started", kServiceDescription_.fPrettyName.c_str (), MyServiceVersion::kVersion.AsPrettyVersionString ().c_str ());
    Logger::Get ().Log (Logger::Priority::eInfo, L"%s (version %s) service started successfully", kServiceDescription_.fPrettyName.c_str (), Characters::ToString (AppVersion::kVersion).c_str ());
    successfullyStarted = true;

    // the final object delcared on the stack before we wait, so its the first run when we are handling the
    // thread aboort exception, and unwinding this call.
    auto&& cleanup2 = Execution::Finally ([&]() {
        Logger::Get ().Log (Logger::Priority::eInfo, L"Beginning service shutdown");
    });
#endif

    /*
     *  This thread will block here, and never go any further. When the service is terminated, WaitableEvent will
     *  abort (raise exception) and all the destructors on the stack (above) from this routine will get played
     *  backewards to cleanup.
     */
    Execution::WaitableEvent (Execution::WaitableEvent::eAutoReset).Wait (); // until told to stop by abort exception

    AssertNotReached ();
}

Main::ServiceDescription SampleAppServiceRep::GetServiceDescription () const
{
    return kServiceDescription_;
}
<commit_msg>cosmetic<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2017.  All rights reserved
 */
#include "Stroika/Frameworks/StroikaPreComp.h"

#include <cstdlib>
#include <iostream>

#include "Stroika/Foundation/Characters/String_Constant.h"
#include "Stroika/Foundation/Characters/ToString.h"
#include "Stroika/Foundation/Execution/Finally.h"
#include "Stroika/Foundation/Execution/Sleep.h"
#include "Stroika/Foundation/Execution/Thread.h"
#include "Stroika/Foundation/Execution/WaitableEvent.h"
#include "Stroika/Frameworks/Service/Main.h"

#include "AppVersion.h"

#include "Service.h"

using namespace std;

using namespace Stroika::Foundation;
using namespace Stroika::Frameworks::Service;

using Characters::String_Constant;
using Execution::Thread;

using namespace Samples::SimpleService;

#if qUseLogger
#include "Stroika/Foundation/Execution/Logger.h"
using Execution::Logger;
#endif

namespace {
    const Main::ServiceDescription kServiceDescription_{
        String_Constant{L"Test-Service"},
        String_Constant{L"Test Service"}};
}

namespace {
    //
    // Typically have one like this for each major module your service manages.
    //
    // These get defined/declared in that module, and just referenced here
    //
    struct SomeModuleALikeWebServer_ {
        // initialize that service//module here, including starting any threads
        SomeModuleALikeWebServer_ ()
            : fSomeOtherTaskDoingRealWork_{
                  []() {
                      Execution::Sleep (1 * 24 * 60 * 60); // wait 1 day ... simple test....
                  },
                  Thread::eAutoStart}
        {
        }
        ~SomeModuleALikeWebServer_ ()
        {
            // shutdown your threads here.
            Execution::Thread::SuppressInterruptionInContext suppressInterruption; // critical to probibit this thread from interuption until its killed owned threads
            fSomeOtherTaskDoingRealWork_.AbortAndWaitForDone ();
        }
        Thread fSomeOtherTaskDoingRealWork_;
    };
}

void SampleAppServiceRep::MainLoop (const std::function<void()>& startedCB)
{
/*
     *  The lifetime of the service roughly matches the lifetime of this MainLoop. Terminating the service (myService --stop)
     *  will cause a Thread::AbortException to be sent to this MainLoop, so that it unwinds.
     *
     *  The simplest and safest way to construct this MainLoop is using RAII, referencing external
     *  'modules' which start and stop any needed threads and do whatever setup/shutdown is needed.
     */

#if qUseLogger
    // Just so you get a clear message in the log that the service didn't startup. The things that actually caused the problem should
    bool   successfullyStarted{false};
    auto&& cleanup = Execution::Finally ([&]() {
        if (not successfullyStarted) {
            Logger::Get ().Log (Logger::Priority::eError, L"Failed to successfully start service");
        }
    });
#endif

    /*
     *  Startup modules.
     *
     *  \note initialized in the order given here, and shutdown in the reverse order, so order really does matter.
     *        Put the more general ones with fewest dependencies first.
     */
    SomeModuleALikeWebServer_ moduleA;
    SomeModuleALikeWebServer_ moduleB; // typically of a differnt type

    startedCB (); // Notify service control mgr that the service has started

#if qUseLogger
    Logger::Get ().Log (Logger::Priority::eInfo, L"%s (version %s) service started successfully", kServiceDescription_.fPrettyName.c_str (), Characters::ToString (AppVersion::kVersion).c_str ());
    successfullyStarted = true;

    // the final object delcared on the stack before we wait, so its the first run when we are handling the
    // thread aboort exception, and unwinding this call.
    auto&& cleanup2 = Execution::Finally ([&]() {
        Logger::Get ().Log (Logger::Priority::eInfo, L"Beginning service shutdown");
    });
#endif

    /*
     *  This thread will block here, and never go any further. When the service is terminated, WaitableEvent will
     *  abort (raise exception) and all the destructors on the stack (above) from this routine will get played
     *  backewards to cleanup.
     */
    Execution::WaitableEvent (Execution::WaitableEvent::eAutoReset).Wait (); // until told to stop by abort exception

    AssertNotReached ();
}

Main::ServiceDescription SampleAppServiceRep::GetServiceDescription () const
{
    return kServiceDescription_;
}
<|endoftext|>