<commit_before>// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "frtconnection.h"
#include <vespa/config/common/errorcode.h>
#include <vespa/fnet/frt/supervisor.h>
#include <vespa/fnet/frt/target.h>
#include <vespa/fnet/frt/rpcrequest.h>

#include <vespa/log/log.h>
LOG_SETUP(".config.frt.frtconnection");

using namespace vespalib;

namespace config {

FRTConnection::FRTConnection(const vespalib::string& address, FRT_Supervisor& supervisor, const TimingValues & timingValues)
    : _address(address),
      _supervisor(supervisor),
      _target(0),
      _suspendedUntil(0),
      _suspendWarned(0),
      _transientFailures(0),
      _fatalFailures(0),
      _transientDelay(timingValues.transientDelay),
      _fatalDelay(timingValues.fatalDelay)
{
}

FRTConnection::~FRTConnection()
{
    if (_target != nullptr) {
        _target->SubRef();
        _target = nullptr;
    }
}

FRT_Target *
FRTConnection::getTarget()
{
    if (_target == nullptr) {
        _target = _supervisor.GetTarget(_address.c_str());
    } else if ( ! _target->IsValid()) {
        _target->SubRef();
        _target = _supervisor.GetTarget(_address.c_str());
    }
    return _target;
}

void
FRTConnection::invoke(FRT_RPCRequest * req, double timeout, FRT_IRequestWait * waiter)
{
    getTarget()->InvokeAsync(req, timeout, waiter);
}

void
FRTConnection::setError(int errorCode)
{
    switch(errorCode) {
    case FRTE_RPC_CONNECTION:
    case FRTE_RPC_TIMEOUT:
        calculateSuspension(TRANSIENT); break;
    case ErrorCode::UNKNOWN_CONFIG:
    case ErrorCode::UNKNOWN_DEFINITION:
    case ErrorCode::UNKNOWN_VERSION:
    case ErrorCode::UNKNOWN_CONFIGID:
    case ErrorCode::UNKNOWN_DEF_MD5:
    case ErrorCode::ILLEGAL_NAME:
    case ErrorCode::ILLEGAL_VERSION:
    case ErrorCode::ILLEGAL_CONFIGID:
    case ErrorCode::ILLEGAL_DEF_MD5:
    case ErrorCode::ILLEGAL_CONFIG_MD5:
    case ErrorCode::ILLEGAL_TIMEOUT:
    case ErrorCode::OUTDATED_CONFIG:
    case ErrorCode::INTERNAL_ERROR:
        calculateSuspension(FATAL); break;
    }
}

void FRTConnection::setSuccess()
{
    _transientFailures = 0;
    _fatalFailures = 0;
    _suspendedUntil = 0;
}

void FRTConnection::calculateSuspension(ErrorType type)
{
    int64_t delay = 0;
    switch(type) {
    case TRANSIENT:
        _transientFailures.fetch_add(1);
        delay = _transientFailures * getTransientDelay();
        if (delay > getMaxTransientDelay()) {
            delay = getMaxTransientDelay();
        }
        LOG(warning, "Connection to %s failed or timed out", _address.c_str());
        break;
    case FATAL:
        _fatalFailures.fetch_add(1);
        delay = _fatalFailures * getFatalDelay();
        if (delay > getMaxFatalDelay()) {
            delay = getMaxFatalDelay();
        }
        break;
    }
    int64_t now = milliSecsSinceEpoch();
    _suspendedUntil = now + delay;
    if (_suspendWarned < (now - 5000)) {
        char date[32];
        struct tm* timeinfo;
        time_t suspendedSeconds = _suspendedUntil / 1000;
        timeinfo = gmtime(&suspendedSeconds);
        strftime(date, 32, "%Y-%m-%d %H:%M:%S %Z", timeinfo);
        LOG(warning, "FRT Connection %s suspended until %s", _address.c_str(), date);
        _suspendWarned = now;
    }
}

FRT_RPCRequest *
FRTConnection::allocRPCRequest() {
    return _supervisor.AllocRPCRequest();
}

using namespace std::chrono;
int64_t
FRTConnection::milliSecsSinceEpoch() {
    return duration_cast<microseconds>(system_clock::now().time_since_epoch()).count();
}

}
<commit_msg>Use milliseconds as promised.<commit_after>// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "frtconnection.h"
#include <vespa/config/common/errorcode.h>
#include <vespa/fnet/frt/supervisor.h>
#include <vespa/fnet/frt/target.h>
#include <vespa/fnet/frt/rpcrequest.h>

#include <vespa/log/log.h>
LOG_SETUP(".config.frt.frtconnection");

using namespace vespalib;

namespace config {

FRTConnection::FRTConnection(const vespalib::string& address, FRT_Supervisor& supervisor, const TimingValues & timingValues)
    : _address(address),
      _supervisor(supervisor),
      _target(0),
      _suspendedUntil(0),
      _suspendWarned(0),
      _transientFailures(0),
      _fatalFailures(0),
      _transientDelay(timingValues.transientDelay),
      _fatalDelay(timingValues.fatalDelay)
{
}

FRTConnection::~FRTConnection()
{
    if (_target != nullptr) {
        _target->SubRef();
        _target = nullptr;
    }
}

FRT_Target *
FRTConnection::getTarget()
{
    if (_target == nullptr) {
        _target = _supervisor.GetTarget(_address.c_str());
    } else if ( ! _target->IsValid()) {
        _target->SubRef();
        _target = _supervisor.GetTarget(_address.c_str());
    }
    return _target;
}

void
FRTConnection::invoke(FRT_RPCRequest * req, double timeout, FRT_IRequestWait * waiter)
{
    getTarget()->InvokeAsync(req, timeout, waiter);
}

void
FRTConnection::setError(int errorCode)
{
    switch(errorCode) {
    case FRTE_RPC_CONNECTION:
    case FRTE_RPC_TIMEOUT:
        calculateSuspension(TRANSIENT); break;
    case ErrorCode::UNKNOWN_CONFIG:
    case ErrorCode::UNKNOWN_DEFINITION:
    case ErrorCode::UNKNOWN_VERSION:
    case ErrorCode::UNKNOWN_CONFIGID:
    case ErrorCode::UNKNOWN_DEF_MD5:
    case ErrorCode::ILLEGAL_NAME:
    case ErrorCode::ILLEGAL_VERSION:
    case ErrorCode::ILLEGAL_CONFIGID:
    case ErrorCode::ILLEGAL_DEF_MD5:
    case ErrorCode::ILLEGAL_CONFIG_MD5:
    case ErrorCode::ILLEGAL_TIMEOUT:
    case ErrorCode::OUTDATED_CONFIG:
    case ErrorCode::INTERNAL_ERROR:
        calculateSuspension(FATAL); break;
    }
}

void FRTConnection::setSuccess()
{
    _transientFailures = 0;
    _fatalFailures = 0;
    _suspendedUntil = 0;
}

void FRTConnection::calculateSuspension(ErrorType type)
{
    int64_t delay = 0;
    switch(type) {
    case TRANSIENT:
        _transientFailures.fetch_add(1);
        delay = _transientFailures * getTransientDelay();
        if (delay > getMaxTransientDelay()) {
            delay = getMaxTransientDelay();
        }
        LOG(warning, "Connection to %s failed or timed out", _address.c_str());
        break;
    case FATAL:
        _fatalFailures.fetch_add(1);
        delay = _fatalFailures * getFatalDelay();
        if (delay > getMaxFatalDelay()) {
            delay = getMaxFatalDelay();
        }
        break;
    }
    int64_t now = milliSecsSinceEpoch();
    _suspendedUntil = now + delay;
    if (_suspendWarned < (now - 5000)) {
        char date[32];
        struct tm* timeinfo;
        time_t suspendedSeconds = _suspendedUntil / 1000;
        timeinfo = gmtime(&suspendedSeconds);
        strftime(date, 32, "%Y-%m-%d %H:%M:%S %Z", timeinfo);
        LOG(warning, "FRT Connection %s suspended until %s", _address.c_str(), date);
        _suspendWarned = now;
    }
}

FRT_RPCRequest *
FRTConnection::allocRPCRequest() {
    return _supervisor.AllocRPCRequest();
}

using namespace std::chrono;
int64_t
FRTConnection::milliSecsSinceEpoch() {
    return duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
}

}
<|endoftext|>


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

#ifndef _XMLOFF_ELEMENTEXPORT_HXX_
#define _XMLOFF_ELEMENTEXPORT_HXX_

#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XINDEXACCESS_HPP_
#include <com/sun/star/container/XIndexAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_SCRIPT_SCRIPTEVENTDESCRIPTOR_HPP_
#include <com/sun/star/script/ScriptEventDescriptor.hpp>
#endif
#ifndef _XMLOFF_FORMS_PROPERTYEXPORT_HXX_
#include "propertyexport.hxx"
#endif
#ifndef _XMLOFF_FORMS_CALLBACKS_HXX_
#include "callbacks.hxx"
#endif
#ifndef _XMLOFF_FORMS_CONTROLELEMENT_HXX_
#include "controlelement.hxx"
#endif
#ifndef _XMLOFF_FORMS_VALUEPROPERTIES_HXX_
#include "valueproperties.hxx"
#endif

class SvXMLElementExport;
//.........................................................................
namespace xmloff
{
//.........................................................................

    //=====================================================================
    //= OElementExport
    //=====================================================================
    class OElementExport : public OPropertyExport
    {
    protected:
        ::com::sun::star::uno::Sequence< ::com::sun::star::script::ScriptEventDescriptor >
                                m_aEvents;

        SvXMLElementExport*     m_pXMLElement;          // XML element doing the concrete startElement etc.

    public:
        OElementExport(IFormsExportContext& _rContext,
            const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxProps,
            const ::com::sun::star::uno::Sequence< ::com::sun::star::script::ScriptEventDescriptor >& _rEvents);
        ~OElementExport();

        void doExport();

    protected:
        /// get the name of the XML element
        virtual const sal_Char* getXMLElementName() const = 0;
        /// examine the element we're exporting
        virtual void examine();
        /// export the attributes
        virtual void exportAttributes();
        /// export any sub tags
        virtual void exportSubTags();

        /** exports the events (as script:events tag)
        */
        void exportEvents();

        /** add the service-name attribute to the export context
        */
        virtual void exportServiceNameAttribute();

        /// start the XML element
        virtual void implStartElement(const sal_Char* _pName);

        /// ends the XML element
        virtual void implEndElement();
    };

    //=====================================================================
    //= OControlExport
    //=====================================================================
    /** Helper class for handling xml elements representing a form control
    */
    class OControlExport
                :public OControlElement
                ,public OValuePropertiesMetaData
                ,public OElementExport
    {
    protected:
        DECLARE_STL_STDKEY_SET(sal_Int16, Int16Set);
            // used below

        ::rtl::OUString         m_sControlId;           // the control id to use when exporting
        ::rtl::OUString         m_sReferringControls;   // list of referring controls (i.e. their id's)
        sal_Int16               m_nClassId;             // class id of the control we're representing
        ElementType             m_eType;                // (XML) type of the control we're representing
        sal_Int32               m_nIncludeCommon;       // common control attributes to include
        sal_Int32               m_nIncludeDatabase;     // common database attributes to include
        sal_Int32               m_nIncludeSpecial;      // special attributes to include
        sal_Int32               m_nIncludeEvents;       // events to include
        sal_Int32               m_nIncludeBindings;     // binding attributes to include

        SvXMLElementExport*     m_pOuterElement;        // XML element doing the concrete startElement etc. for the outer element

    public:
        /** constructs an object capable of exporting controls

You need at least two pre-requisites from outside: The control to be exported needs to have a class id
            assigned, and you need the list control-ids of all the controls referring to this one as LabelControl.

            This information can't be collected when known only the control itself and not it's complete context.

            @param _rControlId
                the control id to use when exporting the control
            @param _rReferringControls
                the comma-separated list of control-ids of all the controls referring to this one as LabelControl
        */
        OControlExport(IFormsExportContext& _rContext,
            const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxControl,
            const ::rtl::OUString& _rControlId,
            const ::rtl::OUString& _rReferringControls,
            const ::com::sun::star::uno::Sequence< ::com::sun::star::script::ScriptEventDescriptor >& _rxEvents);
        ~OControlExport();

    protected:
        /// start the XML element
        virtual void implStartElement(const sal_Char* _pName);

        /// ends the XML element
        virtual void implEndElement();

        /// get the name of the outer XML element
        virtual const sal_Char* getOuterXMLElementName() const;

        // get the name of the XML element
        virtual const sal_Char* getXMLElementName() const;

        /** examine the control. Some kind of CtorImpl.
        */
        virtual void examine();

        /// exports the attributes for the outer element
        void exportOuterAttributes();

        /// exports the attributes for the inner element
        void exportInnerAttributes();

        /// export the attributes
        virtual void exportAttributes();

        /** writes everything which needs to be represented as sub tag
        */
        void exportSubTags() throw (::com::sun::star::uno::Exception);

        /** adds common control attributes to the XMLExport context given

The attribute list of the context is not cleared initially, this is the responsibility of the caller.

        */
        void exportCommonControlAttributes();

        /** adds database attributes to the XMLExport context given

The attribute list of the context is not cleared initially, this is the responsibility of the caller.

        */
        void exportDatabaseAttributes();

        /** adds the XML attributes which are related to binding controls to
            external values and/or list sources
        */
        void exportBindingAtributes();

        /** adds attributes which are special to a control type to the export context's attribute list
        */
        void exportSpecialAttributes();

        /** exports the ListSource property of a control as attribute

            The ListSource property may be exported in different ways: For a ComboBox, it is an attribute
            of the form:combobox element.

            For a ListBox, it's an attribute if the ListSourceType states that the ListBox does not
            display a value list. In case of a value list, the ListSource is not exported, and the pairs of
            StringItem/ValueItem are exported as sub-elements.

            This method does the attribute part: It exports the ListSource property as attribute, not caring
            about whether the object is a ComboBox or a ListBox.
        */
        void exportListSourceAsAttribute();

        /** exports the ListSource property of a control as XML elements

            @see exportListSourceAsAttribute
        */
        void exportListSourceAsElements();

        /** get's a Sequence< sal_Int16 > property value as set of sal_Int16's
            @param _rPropertyName
                the property name to use
            @param _rOut
                out parameter. The set of integers.
        */
        void getSequenceInt16PropertyAsSet(const ::rtl::OUString& _rPropertyName, Int16Set& _rOut);

        /** exports the attribute which descrives a cell value binding of a control
            in a spreadsheet document
        */
        void exportCellBindingAttributes( bool _bIncludeListLinkageType );

        /** exports the attribute(s) which bind this control to XForms */
        void exportXFormsBindAttributes();

        /** exports the attribute(s) which bind the list of a list
            control to XForms */
        void exportXFormsListAttributes();

        /** exports the attribute(s) for an XForms submission */
        void exportXFormsSubmissionAttributes();

        /** exports the attribute which descrives a cell range which acts as list source for
            a list-like control
        */
        void exportCellListSourceRange( );

        /** exports the attribut(s) for the ImagePosition property
        */
        void exportImagePositionAttributes();

        /** determines whether the control we're exporting has an active data binding.

            Bindings which count here are:

an established connection to a database field

a binding to an external value supplier (<type scope="com::sun::star::form::binding">XValueBinding</type>)

        */
        bool controlHasActiveDataBinding() const;

        /** retrieves the string specifying the ListSource of a list or combo box
        */
        ::rtl::OUString OControlExport::getScalarListSourceValue() const;

        /** determines whether the list entries (of a combo or list box) are supplied by the user

            List entries may be

specified by the user

specified by an external list source (<type scope="com::sun::star::form::binding">XListEntrySource</type>)

obtained from a database query (in various ways)

            In the latter two cases, this method will return <FALSE/>
        */
        bool controlHasUserSuppliedListEntries() const;
    };

    //=====================================================================
    //= OColumnExport
    //=====================================================================
    /** Helper class for exporting a grid column
    */
    class OColumnExport : public OControlExport
    {
    public:
        /** ctor
            @see OColumnExport::OColumnExport
        */
        OColumnExport(IFormsExportContext& _rContext,
            const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxControl,
            const ::com::sun::star::uno::Sequence< ::com::sun::star::script::ScriptEventDescriptor >& _rxEvents);

        ~OColumnExport();

    protected:
        // OControlExport overridables
        virtual const sal_Char* getOuterXMLElementName() const;
        virtual void exportServiceNameAttribute();
        virtual void exportAttributes();

        // OElementExport overridables
        virtual void examine();
    };

    //=====================================================================
    //= OFormExport
    //=====================================================================
    /** Helper class for handling xml elements representing a form

In opposite to the class <type>OControlExport</type>, OFormExport is unable to export a complete
        form. Instead the client has to care for sub elements of the form itself.

    */
    class OFormExport
                :public OControlElement
                ,public OElementExport
    {
        sal_Bool m_bCreateConnectionResourceElement;
    public:
        /** constructs an object capable of exporting controls
        */
        OFormExport(IFormsExportContext& _rContext,
            const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxForm,
            const ::com::sun::star::uno::Sequence< ::com::sun::star::script::ScriptEventDescriptor >& _rxEvents
            );

    protected:
        virtual const sal_Char* getXMLElementName() const;
        virtual void exportSubTags();
        virtual void exportAttributes();
    };
//.........................................................................
}   // namespace xmloff
//.........................................................................

#endif // _XMLOFF_ELEMENTEXPORT_HXX_

<commit_msg>INTEGRATION: CWS gcc41 (1.14.58); FILE MERGED 2005/12/07 15:27:23 pmladek 1.14.58.1: #i58967# Removed extra qualification to fix build with gcc-4.1<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: elementexport.hxx,v $
 *
 *  $Revision: 1.15 $
 *
 *  last change: $Author: obo $ $Date: 2006-01-19 18:08:06 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _XMLOFF_ELEMENTEXPORT_HXX_
#define _XMLOFF_ELEMENTEXPORT_HXX_

#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XINDEXACCESS_HPP_
#include <com/sun/star/container/XIndexAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_SCRIPT_SCRIPTEVENTDESCRIPTOR_HPP_
#include <com/sun/star/script/ScriptEventDescriptor.hpp>
#endif
#ifndef _XMLOFF_FORMS_PROPERTYEXPORT_HXX_
#include "propertyexport.hxx"
#endif
#ifndef _XMLOFF_FORMS_CALLBACKS_HXX_
#include "callbacks.hxx"
#endif
#ifndef _XMLOFF_FORMS_CONTROLELEMENT_HXX_
#include "controlelement.hxx"
#endif
#ifndef _XMLOFF_FORMS_VALUEPROPERTIES_HXX_
#include "valueproperties.hxx"
#endif

class SvXMLElementExport;
//.........................................................................
namespace xmloff
{
//.........................................................................

    //=====================================================================
    //= OElementExport
    //=====================================================================
    class OElementExport : public OPropertyExport
    {
    protected:
        ::com::sun::star::uno::Sequence< ::com::sun::star::script::ScriptEventDescriptor >
                                m_aEvents;

        SvXMLElementExport*     m_pXMLElement;          // XML element doing the concrete startElement etc.

    public:
        OElementExport(IFormsExportContext& _rContext,
            const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxProps,
            const ::com::sun::star::uno::Sequence< ::com::sun::star::script::ScriptEventDescriptor >& _rEvents);
        ~OElementExport();

        void doExport();

    protected:
        /// get the name of the XML element
        virtual const sal_Char* getXMLElementName() const = 0;
        /// examine the element we're exporting
        virtual void examine();
        /// export the attributes
        virtual void exportAttributes();
        /// export any sub tags
        virtual void exportSubTags();

        /** exports the events (as script:events tag)
        */
        void exportEvents();

        /** add the service-name attribute to the export context
        */
        virtual void exportServiceNameAttribute();

        /// start the XML element
        virtual void implStartElement(const sal_Char* _pName);

        /// ends the XML element
        virtual void implEndElement();
    };

    //=====================================================================
    //= OControlExport
    //=====================================================================
    /** Helper class for handling xml elements representing a form control
    */
    class OControlExport
                :public OControlElement
                ,public OValuePropertiesMetaData
                ,public OElementExport
    {
    protected:
        DECLARE_STL_STDKEY_SET(sal_Int16, Int16Set);
            // used below

        ::rtl::OUString         m_sControlId;           // the control id to use when exporting
        ::rtl::OUString         m_sReferringControls;   // list of referring controls (i.e. their id's)
        sal_Int16               m_nClassId;             // class id of the control we're representing
        ElementType             m_eType;                // (XML) type of the control we're representing
        sal_Int32               m_nIncludeCommon;       // common control attributes to include
        sal_Int32               m_nIncludeDatabase;     // common database attributes to include
        sal_Int32               m_nIncludeSpecial;      // special attributes to include
        sal_Int32               m_nIncludeEvents;       // events to include
        sal_Int32               m_nIncludeBindings;     // binding attributes to include

        SvXMLElementExport*     m_pOuterElement;        // XML element doing the concrete startElement etc. for the outer element

    public:
        /** constructs an object capable of exporting controls

You need at least two pre-requisites from outside: The control to be exported needs to have a class id
            assigned, and you need the list control-ids of all the controls referring to this one as LabelControl.

            This information can't be collected when known only the control itself and not it's complete context.

            @param _rControlId
                the control id to use when exporting the control
            @param _rReferringControls
                the comma-separated list of control-ids of all the controls referring to this one as LabelControl
        */
        OControlExport(IFormsExportContext& _rContext,
            const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxControl,
            const ::rtl::OUString& _rControlId,
            const ::rtl::OUString& _rReferringControls,
            const ::com::sun::star::uno::Sequence< ::com::sun::star::script::ScriptEventDescriptor >& _rxEvents);
        ~OControlExport();

    protected:
        /// start the XML element
        virtual void implStartElement(const sal_Char* _pName);

        /// ends the XML element
        virtual void implEndElement();

        /// get the name of the outer XML element
        virtual const sal_Char* getOuterXMLElementName() const;

        // get the name of the XML element
        virtual const sal_Char* getXMLElementName() const;

        /** examine the control. Some kind of CtorImpl.
        */
        virtual void examine();

        /// exports the attributes for the outer element
        void exportOuterAttributes();

        /// exports the attributes for the inner element
        void exportInnerAttributes();

        /// export the attributes
        virtual void exportAttributes();

        /** writes everything which needs to be represented as sub tag
        */
        void exportSubTags() throw (::com::sun::star::uno::Exception);

        /** adds common control attributes to the XMLExport context given

The attribute list of the context is not cleared initially, this is the responsibility of the caller.

        */
        void exportCommonControlAttributes();

        /** adds database attributes to the XMLExport context given

The attribute list of the context is not cleared initially, this is the responsibility of the caller.

        */
        void exportDatabaseAttributes();

        /** adds the XML attributes which are related to binding controls to
            external values and/or list sources
        */
        void exportBindingAtributes();

        /** adds attributes which are special to a control type to the export context's attribute list
        */
        void exportSpecialAttributes();

        /** exports the ListSource property of a control as attribute

            The ListSource property may be exported in different ways: For a ComboBox, it is an attribute
            of the form:combobox element.

            For a ListBox, it's an attribute if the ListSourceType states that the ListBox does not
            display a value list. In case of a value list, the ListSource is not exported, and the pairs of
            StringItem/ValueItem are exported as sub-elements.

            This method does the attribute part: It exports the ListSource property as attribute, not caring
            about whether the object is a ComboBox or a ListBox.
        */
        void exportListSourceAsAttribute();

        /** exports the ListSource property of a control as XML elements

            @see exportListSourceAsAttribute
        */
        void exportListSourceAsElements();

        /** get's a Sequence< sal_Int16 > property value as set of sal_Int16's
            @param _rPropertyName
                the property name to use
            @param _rOut
                out parameter. The set of integers.
        */
        void getSequenceInt16PropertyAsSet(const ::rtl::OUString& _rPropertyName, Int16Set& _rOut);

        /** exports the attribute which descrives a cell value binding of a control
            in a spreadsheet document
        */
        void exportCellBindingAttributes( bool _bIncludeListLinkageType );

        /** exports the attribute(s) which bind this control to XForms */
        void exportXFormsBindAttributes();

        /** exports the attribute(s) which bind the list of a list
            control to XForms */
        void exportXFormsListAttributes();

        /** exports the attribute(s) for an XForms submission */
        void exportXFormsSubmissionAttributes();

        /** exports the attribute which descrives a cell range which acts as list source for
            a list-like control
        */
        void exportCellListSourceRange( );

        /** exports the attribut(s) for the ImagePosition property
        */
        void exportImagePositionAttributes();

        /** determines whether the control we're exporting has an active data binding.

            Bindings which count here are:

an established connection to a database field

a binding to an external value supplier (<type scope="com::sun::star::form::binding">XValueBinding</type>)

        */
        bool controlHasActiveDataBinding() const;

        /** retrieves the string specifying the ListSource of a list or combo box
        */
        ::rtl::OUString getScalarListSourceValue() const;

        /** determines whether the list entries (of a combo or list box) are supplied by the user

            List entries may be

specified by the user

specified by an external list source (<type scope="com::sun::star::form::binding">XListEntrySource</type>)

obtained from a database query (in various ways)

            In the latter two cases, this method will return <FALSE/>
        */
        bool controlHasUserSuppliedListEntries() const;
    };

    //=====================================================================
    //= OColumnExport
    //=====================================================================
    /** Helper class for exporting a grid column
    */
    class OColumnExport : public OControlExport
    {
    public:
        /** ctor
            @see OColumnExport::OColumnExport
        */
        OColumnExport(IFormsExportContext& _rContext,
            const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxControl,
            const ::com::sun::star::uno::Sequence< ::com::sun::star::script::ScriptEventDescriptor >& _rxEvents);

        ~OColumnExport();

    protected:
        // OControlExport overridables
        virtual const sal_Char* getOuterXMLElementName() const;
        virtual void exportServiceNameAttribute();
        virtual void exportAttributes();

        // OElementExport overridables
        virtual void examine();
    };

    //=====================================================================
    //= OFormExport
    //=====================================================================
    /** Helper class for handling xml elements representing a form

In opposite to the class <type>OControlExport</type>, OFormExport is unable to export a complete
        form. Instead the client has to care for sub elements of the form itself.

    */
    class OFormExport
                :public OControlElement
                ,public OElementExport
    {
        sal_Bool m_bCreateConnectionResourceElement;
    public:
        /** constructs an object capable of exporting controls
        */
        OFormExport(IFormsExportContext& _rContext,
            const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxForm,
            const ::com::sun::star::uno::Sequence< ::com::sun::star::script::ScriptEventDescriptor >& _rxEvents
            );

    protected:
        virtual const sal_Char* getXMLElementName() const;
        virtual void exportSubTags();
        virtual void exportAttributes();
    };
//.........................................................................
}   // namespace xmloff
//.........................................................................

#endif // _XMLOFF_ELEMENTEXPORT_HXX_

<|endoftext|>


<commit_before>#include "Connection"

using namespace QIRC;

/// \brief Construct from given ServerInfo
Connection::Connection(const ServerInfo& si) :
  m_currentServer(si), m_socket(NULL) {
  if (!setupSocket()) {
    qCritical() << "Connection: Unable to setup m_socket!";
    exit(1);
  }
}

/// \brief Construct from host/port
Connection::Connection(QString h, quint16 p) :
  m_currentServer(h, p), m_socket(NULL) {
  if (!setupSocket()) {
    qCritical() << "Connection: Unable to setup m_socket!";
    exit(1);
  }
}

Connection::~Connection() {
  if (m_socket != NULL) {
    delete m_socket;
  }
}

/// \brief Connect to IRC server
void Connection::connect() {
  Q_ASSERT(m_socket != NULL);
  if (m_socket != NULL) {
    m_socket->connectToHost(m_currentServer.host(), m_currentServer.port());
  }
}

/// \brief Disconnect from IRC server
void Connection::disconnect() {
  Q_ASSERT(m_socket != NULL);
  if (m_socket != NULL) {
    m_socket->disconnectFromHost();
  }
}

/// \brief Access current server for this connection
ServerInfo Connection::server() const {
  return m_currentServer;
}

/// \brief Set current server for this connection
///
/// \attention This method will disconnect from the current
/// server and connect to the new one if they differ.
void Connection::setServer(ServerInfo& si) {
  if (si != m_currentServer) {
    disconnect();
    m_currentServer.setHost(si.host());
    m_currentServer.setPort(si.port());
    connect();
  }
}

/// \brief Set current server for this connection
void Connection::setServer(QString h, quint16 p) {
  ServerInfo si(h, p);
  setServer(si);
}

/// \brief Set up m_socket
///
/// Creates the QTcpSocket instance for m_socket
bool Connection::setupSocket() {
  if (m_socket != NULL) {
    qWarning() << "Called Connection::setupSocket with non-null m_socket!";
    delete m_socket;
  }

  try {
    m_socket = new QTcpSocket(this);
  }

  catch (std::bad_alloc &ex) {
    qCritical() << "Caught std::bad_alloc when trying to setup "
		<< "Connection::m_socket: " << ex.what();
    return false;
  }

  // connect the socket's signals to our slots
  QObject::connect(m_socket, SIGNAL(connected()),
		   this, SLOT(socket_connected()));
  QObject::connect(m_socket, SIGNAL(disconnected()),
		   this, SLOT(socket_disconnected()));
  QObject::connect(m_socket, SIGNAL(error(QAbstractSocket::SocketError)),
		   this, SLOT(socket_error(QAbstractSocket::SocketError)));
  QObject::connect(m_socket, SIGNAL(readyRead()),
		   this, SLOT(socket_readyRead()));

  return true;
}

/// \brief Slot for m_socket::connected()
void Connection::socket_connected() {
  emit connected(m_currentServer);
}

/// \brief Slot for m_socket::disconnected()
void Connection::socket_disconnected() {
  emit disconnected(m_currentServer);
}

/// \brief Slot for m_socket::error()
///
/// This slot is connected to the error() signal of m_socket.
/// It fetches the error message belonging to err and re-emits
/// the signal to the controlling application as
/// socketError().
///
/// \param err Socket error as received from m_socket's error() signal
void Connection::socket_error(QAbstractSocket::SocketError err) {
  QString msg = m_socket->errorString();
  qWarning() << "Connection::m_socket (connected to"
	     << m_currentServer.toString() << ") generated an error: "
	     << msg;
  emit socketError(err, msg);
}

/// \brief Slot for m_socket::readyRead()
void Connection::socket_readyRead() {
  QString line;

  while (m_socket->canReadLine()) {
    line = m_socket->readLine();
    if (!line.isNull()) {
      qDebug() << line;
    }
  }
}

<commit_msg>use new QIRC::ServerInfo assignment operator in Connection::setServer()<commit_after>#include "Connection"

using namespace QIRC;

/// \brief Construct from given ServerInfo
Connection::Connection(const ServerInfo& si) :
  m_currentServer(si), m_socket(NULL) {
  if (!setupSocket()) {
    qCritical() << "Connection: Unable to setup m_socket!";
    exit(1);
  }
}

/// \brief Construct from host/port
Connection::Connection(QString h, quint16 p) :
  m_currentServer(h, p), m_socket(NULL) {
  if (!setupSocket()) {
    qCritical() << "Connection: Unable to setup m_socket!";
    exit(1);
  }
}

Connection::~Connection() {
  if (m_socket != NULL) {
    delete m_socket;
  }
}

/// \brief Connect to IRC server
void Connection::connect() {
  Q_ASSERT(m_socket != NULL);
  if (m_socket != NULL) {
    m_socket->connectToHost(m_currentServer.host(), m_currentServer.port());
  }
}

/// \brief Disconnect from IRC server
void Connection::disconnect() {
  Q_ASSERT(m_socket != NULL);
  if (m_socket != NULL) {
    m_socket->disconnectFromHost();
  }
}

/// \brief Access current server for this connection
ServerInfo Connection::server() const {
  return m_currentServer;
}

/// \brief Set current server for this connection
///
/// \attention This method will disconnect from the current
/// server and connect to the new one if they differ.
void Connection::setServer(ServerInfo& si) {
  if (si != m_currentServer) {
    disconnect();
    m_currentServer = si;
    connect();
  }
}

/// \brief Set current server for this connection
void Connection::setServer(QString h, quint16 p) {
  ServerInfo si(h, p);
  setServer(si);
}

/// \brief Set up m_socket
///
/// Creates the QTcpSocket instance for m_socket
bool Connection::setupSocket() {
  if (m_socket != NULL) {
    qWarning() << "Called Connection::setupSocket with non-null m_socket!";
    delete m_socket;
  }

  try {
    m_socket = new QTcpSocket(this);
  }

  catch (std::bad_alloc &ex) {
    qCritical() << "Caught std::bad_alloc when trying to setup "
		<< "Connection::m_socket: " << ex.what();
    return false;
  }

  // connect the socket's signals to our slots
  QObject::connect(m_socket, SIGNAL(connected()),
		   this, SLOT(socket_connected()));
  QObject::connect(m_socket, SIGNAL(disconnected()),
		   this, SLOT(socket_disconnected()));
  QObject::connect(m_socket, SIGNAL(error(QAbstractSocket::SocketError)),
		   this, SLOT(socket_error(QAbstractSocket::SocketError)));
  QObject::connect(m_socket, SIGNAL(readyRead()),
		   this, SLOT(socket_readyRead()));

  return true;
}

/// \brief Slot for m_socket::connected()
void Connection::socket_connected() {
  emit connected(m_currentServer);
}

/// \brief Slot for m_socket::disconnected()
void Connection::socket_disconnected() {
  emit disconnected(m_currentServer);
}

/// \brief Slot for m_socket::error()
///
/// This slot is connected to the error() signal of m_socket.
/// It fetches the error message belonging to err and re-emits
/// the signal to the controlling application as
/// socketError().
///
/// \param err Socket error as received from m_socket's error() signal
void Connection::socket_error(QAbstractSocket::SocketError err) {
  QString msg = m_socket->errorString();
  qWarning() << "Connection::m_socket (connected to"
	     << m_currentServer.toString() << ") generated an error: "
	     << msg;
  emit socketError(err, msg);
}

/// \brief Slot for m_socket::readyRead()
void Connection::socket_readyRead() {
  QString line;

  while (m_socket->canReadLine()) {
    line = m_socket->readLine();
    if (!line.isNull()) {
      qDebug() << line;
    }
  }
}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: pivotsh.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: dr $ $Date: 2002-05-30 14:33: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_PIVOTSH_HXX
#define SC_PIVOTSH_HXX

#ifndef _SFXMODULE_HXX //autogen
#include <sfx2/module.hxx>
#endif
#ifndef _SFX_SHELL_HXX //autogen
#include <sfx2/shell.hxx>
#endif

#include "shellids.hxx"

class ScTabViewShell;
class ScDPObject;

class ScPivotShell : public SfxShell
{
public:
    TYPEINFO();
    SFX_DECL_INTERFACE(SCID_PIVOT_SHELL);

                    ScPivotShell( ScTabViewShell* pView );
                    ~ScPivotShell();

    void    Execute ( SfxRequest& rReq );
    void    GetState( SfxItemSet& rSet );

private:
    ScTabViewShell* pViewShell;

    ScDPObject*     GetCurrDPObject();
};

#endif

<commit_msg>INTEGRATION: CWS ooo19126 (1.2.906); FILE MERGED 2005/09/05 15:05:41 rt 1.2.906.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: pivotsh.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 21:44:03 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef SC_PIVOTSH_HXX
#define SC_PIVOTSH_HXX

#ifndef _SFXMODULE_HXX //autogen
#include <sfx2/module.hxx>
#endif
#ifndef _SFX_SHELL_HXX //autogen
#include <sfx2/shell.hxx>
#endif

#include "shellids.hxx"

class ScTabViewShell;
class ScDPObject;

class ScPivotShell : public SfxShell
{
public:
    TYPEINFO();
    SFX_DECL_INTERFACE(SCID_PIVOT_SHELL);

                    ScPivotShell( ScTabViewShell* pView );
                    ~ScPivotShell();

    void    Execute ( SfxRequest& rReq );
    void    GetState( SfxItemSet& rSet );

private:
    ScTabViewShell* pViewShell;

    ScDPObject*     GetCurrDPObject();
};

#endif

<|endoftext|>


<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/

#include "makestep.h"

#include "cmakeprojectconstants.h"
#include "cmakeproject.h"
#include "cmaketarget.h"
#include "cmakebuildconfiguration.h"

#include <projectexplorer/buildsteplist.h>
#include <projectexplorer/toolchain.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/gnumakeparser.h>
#include <projectexplorer/projectexplorerconstants.h>

#include <utils/qtcprocess.h>

#include <QFormLayout>
#include <QGroupBox>
#include <QCheckBox>
#include <QLineEdit>
#include <QListWidget>

using namespace CMakeProjectManager;
using namespace CMakeProjectManager::Internal;
using namespace ProjectExplorer;

namespace {
const char * const MS_ID("CMakeProjectManager.MakeStep");

const char * const CLEAN_KEY("CMakeProjectManager.MakeStep.Clean");
const char * const BUILD_TARGETS_KEY("CMakeProjectManager.MakeStep.BuildTargets");
const char * const ADDITIONAL_ARGUMENTS_KEY("CMakeProjectManager.MakeStep.AdditionalArguments");
}

// TODO: Move progress information into an IOutputParser!

MakeStep::MakeStep(BuildStepList *bsl) :
    AbstractProcessStep(bsl, QLatin1String(MS_ID)), m_clean(false),
    m_futureInterface(0)
{
    ctor();
}

MakeStep::MakeStep(BuildStepList *bsl, const QString &id) :
    AbstractProcessStep(bsl, id), m_clean(false),
    m_futureInterface(0)
{
    ctor();
}

MakeStep::MakeStep(BuildStepList *bsl, MakeStep *bs) :
    AbstractProcessStep(bsl, bs),
    m_clean(bs->m_clean),
    m_futureInterface(0),
    m_buildTargets(bs->m_buildTargets),
    m_additionalArguments(Utils::QtcProcess::joinArgs(bs->m_buildTargets))
{
    ctor();
}

void MakeStep::ctor()
{
    m_percentProgress = QRegExp("^\\[\\s*(\\d*)%\\]");
    //: Default display name for the cmake make step.
    setDefaultDisplayName(tr("Make"));
}

MakeStep::~MakeStep()
{
}

CMakeBuildConfiguration *MakeStep::cmakeBuildConfiguration() const
{
    return static_cast<CMakeBuildConfiguration *>(buildConfiguration());
}

void MakeStep::setClean(bool clean)
{
    m_clean = clean;
}

QVariantMap MakeStep::toMap() const
{
    QVariantMap map(AbstractProcessStep::toMap());
    map.insert(QLatin1String(CLEAN_KEY), m_clean);
    map.insert(QLatin1String(BUILD_TARGETS_KEY), m_buildTargets);
    map.insert(QLatin1String(ADDITIONAL_ARGUMENTS_KEY), m_additionalArguments);
    return map;
}

bool MakeStep::fromMap(const QVariantMap &map)
{
    m_clean = map.value(QLatin1String(CLEAN_KEY)).toBool();
    m_buildTargets = map.value(QLatin1String(BUILD_TARGETS_KEY)).toStringList();
    m_additionalArguments = map.value(QLatin1String(ADDITIONAL_ARGUMENTS_KEY)).toString();

    return BuildStep::fromMap(map);
}

bool MakeStep::init()
{
    CMakeBuildConfiguration *bc = cmakeBuildConfiguration();

    QString arguments = Utils::QtcProcess::joinArgs(m_buildTargets);
    Utils::QtcProcess::addArgs(&arguments, additionalArguments());

    setIgnoreReturnValue(m_clean);

    ProcessParameters *pp = processParameters();
    pp->setMacroExpander(bc->macroExpander());
    pp->setEnvironment(bc->environment());
    pp->setWorkingDirectory(bc->buildDirectory());
    if (bc->toolChain())
        pp->setCommand(bc->toolChain()->makeCommand());
    else
        pp->setCommand(QLatin1String("make"));
    pp->setArguments(arguments);

    setOutputParser(new ProjectExplorer::GnuMakeParser());
    if (bc->toolChain())
        appendOutputParser(bc->toolChain()->outputParser());
    outputParser()->setWorkingDirectory(pp->effectiveWorkingDirectory());

    return AbstractProcessStep::init();
}

void MakeStep::run(QFutureInterface<bool> &fi)
{
    m_futureInterface = &fi;
    m_futureInterface->setProgressRange(0, 100);
    AbstractProcessStep::run(fi);
    m_futureInterface->setProgressValue(100);
    m_futureInterface->reportFinished();
    m_futureInterface = 0;
}

BuildStepConfigWidget *MakeStep::createConfigWidget()
{
    return new MakeStepConfigWidget(this);
}

bool MakeStep::immutable() const
{
    return false;
}

void MakeStep::stdOutput(const QString &line)
{
    if (m_percentProgress.indexIn(line) != -1) {
        bool ok = false;
        int percent = m_percentProgress.cap(1).toInt(&ok);;
        if (ok)
            m_futureInterface->setProgressValue(percent);
    }
    AbstractProcessStep::stdOutput(line);
}

QStringList MakeStep::buildTargets() const
{
    return m_buildTargets;
}

bool MakeStep::buildsBuildTarget(const QString &target) const
{
    return m_buildTargets.contains(target);
}

void MakeStep::setBuildTarget(const QString &buildTarget, bool on)
{
    QStringList old = m_buildTargets;
    if (on && !old.contains(buildTarget))
        old << buildTarget;
    else if (!on && old.contains(buildTarget))
        old.removeOne(buildTarget);
    m_buildTargets = old;
}

void MakeStep::setBuildTargets(const QStringList &targets)
{
    m_buildTargets = targets;
}

void MakeStep::clearBuildTargets()
{
    m_buildTargets.clear();
}

QString MakeStep::additionalArguments() const
{
    return m_additionalArguments;
}

void MakeStep::setAdditionalArguments(const QString &list)
{
    m_additionalArguments = list;
}

//
// MakeStepConfigWidget
//

MakeStepConfigWidget::MakeStepConfigWidget(MakeStep *makeStep)
    : m_makeStep(makeStep)
{
    QFormLayout *fl = new QFormLayout(this);
    fl->setMargin(0);
    fl->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
    setLayout(fl);

    m_additionalArguments = new QLineEdit(this);
    fl->addRow(tr("Additional arguments:"), m_additionalArguments);
    m_additionalArguments->setText(m_makeStep->additionalArguments());

    m_buildTargetsList = new QListWidget;
    m_buildTargetsList->setMinimumHeight(200);
    fl->addRow(tr("Targets:"), m_buildTargetsList);

    // TODO update this list also on rescans of the CMakeLists.txt
    // TODO shouldn't be accessing project
    CMakeProject *pro = static_cast<CMakeProject *>(m_makeStep->target()->project());
    foreach (const QString& buildTarget, pro->buildTargetTitles()) {
        QListWidgetItem *item = new QListWidgetItem(buildTarget, m_buildTargetsList);
        item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
        item->setCheckState(m_makeStep->buildsBuildTarget(item->text()) ? Qt::Checked : Qt::Unchecked);
    }

    updateDetails();

    connect(m_additionalArguments, SIGNAL(textEdited(QString)), this, SLOT(additionalArgumentsEdited()));
    connect(m_buildTargetsList, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(itemChanged(QListWidgetItem*)));
    connect(ProjectExplorer::ProjectExplorerPlugin::instance(), SIGNAL(settingsChanged()),
            this, SLOT(updateDetails()));

    connect(pro, SIGNAL(buildTargetsChanged()),
            this, SLOT(buildTargetsChanged()));
}

void MakeStepConfigWidget::additionalArgumentsEdited()
{
    m_makeStep->setAdditionalArguments(m_additionalArguments->text());
    updateDetails();
}

void MakeStepConfigWidget::itemChanged(QListWidgetItem *item)
{
    m_makeStep->setBuildTarget(item->text(), item->checkState() & Qt::Checked);
    updateDetails();
}

QString MakeStepConfigWidget::displayName() const
{
    return tr("Make", "CMakeProjectManager::MakeStepConfigWidget display name.");
}

void MakeStepConfigWidget::buildTargetsChanged()
{
    disconnect(m_buildTargetsList, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(itemChanged(QListWidgetItem*)));
    m_buildTargetsList->clear();
    CMakeProject *pro = static_cast<CMakeProject *>(m_makeStep->target()->project());
    foreach (const QString& buildTarget, pro->buildTargetTitles()) {
        QListWidgetItem *item = new QListWidgetItem(buildTarget, m_buildTargetsList);
        item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
        item->setCheckState(m_makeStep->buildsBuildTarget(item->text()) ? Qt::Checked : Qt::Unchecked);
    }
    connect(m_buildTargetsList, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(itemChanged(QListWidgetItem*)));
    updateSummary();
}

void MakeStepConfigWidget::updateDetails()
{
    CMakeBuildConfiguration *bc = m_makeStep->cmakeBuildConfiguration();
    if (!bc)
        bc = static_cast<CMakeBuildConfiguration *>(m_makeStep->target()->activeBuildConfiguration());
    ProjectExplorer::ToolChain *tc = bc->toolChain();
    if (tc) {
        QString arguments = Utils::QtcProcess::joinArgs(m_makeStep->m_buildTargets);
        Utils::QtcProcess::addArgs(&arguments, m_makeStep->additionalArguments());

        ProcessParameters param;
        param.setMacroExpander(bc->macroExpander());
        param.setEnvironment(bc->environment());
        param.setWorkingDirectory(bc->buildDirectory());
        param.setCommand(tc->makeCommand());
        param.setArguments(arguments);
        m_summaryText = param.summary(displayName());
    } else {
        m_summaryText = tr("<b>Unknown tool chain</b>");
    }
    emit updateSummary();
}

QString MakeStepConfigWidget::summaryText() const
{
    return m_summaryText;
}

//
// MakeStepFactory
//

MakeStepFactory::MakeStepFactory(QObject *parent) :
    ProjectExplorer::IBuildStepFactory(parent)
{
}

MakeStepFactory::~MakeStepFactory()
{
}

bool MakeStepFactory::canCreate(BuildStepList *parent, const QString &id) const
{
    if (parent->target()->project()->id() != QLatin1String(Constants::CMAKEPROJECT_ID))
        return false;
    return QLatin1String(MS_ID) == id;
}

BuildStep *MakeStepFactory::create(BuildStepList *parent, const QString &id)
{
    if (!canCreate(parent, id))
        return 0;
    MakeStep *step = new MakeStep(parent);
    if (parent->id() == ProjectExplorer::Constants::BUILDSTEPS_CLEAN) {
        step->setClean(true);
        step->setAdditionalArguments("clean");
    }
    return step;
}

bool MakeStepFactory::canClone(BuildStepList *parent, BuildStep *source) const
{
    return canCreate(parent, source->id());
}

BuildStep *MakeStepFactory::clone(BuildStepList *parent, BuildStep *source)
{
    if (!canClone(parent, source))
        return 0;
    return new MakeStep(parent, static_cast<MakeStep *>(source));
}

bool MakeStepFactory::canRestore(BuildStepList *parent, const QVariantMap &map) const
{
    QString id(ProjectExplorer::idFromMap(map));
    return canCreate(parent, id);
}

BuildStep *MakeStepFactory::restore(BuildStepList *parent, const QVariantMap &map)
{
    if (!canRestore(parent, map))
        return 0;
    MakeStep *bs(new MakeStep(parent));
    if (bs->fromMap(map))
        return bs;
    delete bs;
    return 0;
}

QStringList MakeStepFactory::availableCreationIds(ProjectExplorer::BuildStepList *parent) const
{
    if (parent->target()->project()->id() == QLatin1String(Constants::CMAKEPROJECT_ID))
        return QStringList() << QLatin1String(MS_ID);
    return QStringList();
}

QString MakeStepFactory::displayNameForId(const QString &id) const
{
    if (id == QLatin1String(MS_ID))
        return tr("Make", "Display name for CMakeProjectManager::MakeStep id.");
    return QString();
}
<commit_msg>CMake: Fix crash in makestep if used in the deploystep list<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/

#include "makestep.h"

#include "cmakeprojectconstants.h"
#include "cmakeproject.h"
#include "cmaketarget.h"
#include "cmakebuildconfiguration.h"

#include <projectexplorer/buildsteplist.h>
#include <projectexplorer/toolchain.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/gnumakeparser.h>
#include <projectexplorer/projectexplorerconstants.h>

#include <utils/qtcprocess.h>

#include <QFormLayout>
#include <QGroupBox>
#include <QCheckBox>
#include <QLineEdit>
#include <QListWidget>

using namespace CMakeProjectManager;
using namespace CMakeProjectManager::Internal;
using namespace ProjectExplorer;

namespace {
const char * const MS_ID("CMakeProjectManager.MakeStep");

const char * const CLEAN_KEY("CMakeProjectManager.MakeStep.Clean");
const char * const BUILD_TARGETS_KEY("CMakeProjectManager.MakeStep.BuildTargets");
const char * const ADDITIONAL_ARGUMENTS_KEY("CMakeProjectManager.MakeStep.AdditionalArguments");
}

// TODO: Move progress information into an IOutputParser!

MakeStep::MakeStep(BuildStepList *bsl) :
    AbstractProcessStep(bsl, QLatin1String(MS_ID)), m_clean(false),
    m_futureInterface(0)
{
    ctor();
}

MakeStep::MakeStep(BuildStepList *bsl, const QString &id) :
    AbstractProcessStep(bsl, id), m_clean(false),
    m_futureInterface(0)
{
    ctor();
}

MakeStep::MakeStep(BuildStepList *bsl, MakeStep *bs) :
    AbstractProcessStep(bsl, bs),
    m_clean(bs->m_clean),
    m_futureInterface(0),
    m_buildTargets(bs->m_buildTargets),
    m_additionalArguments(Utils::QtcProcess::joinArgs(bs->m_buildTargets))
{
    ctor();
}

void MakeStep::ctor()
{
    m_percentProgress = QRegExp("^\\[\\s*(\\d*)%\\]");
    //: Default display name for the cmake make step.
    setDefaultDisplayName(tr("Make"));
}

MakeStep::~MakeStep()
{
}

CMakeBuildConfiguration *MakeStep::cmakeBuildConfiguration() const
{
    return static_cast<CMakeBuildConfiguration *>(buildConfiguration());
}

void MakeStep::setClean(bool clean)
{
    m_clean = clean;
}

QVariantMap MakeStep::toMap() const
{
    QVariantMap map(AbstractProcessStep::toMap());
    map.insert(QLatin1String(CLEAN_KEY), m_clean);
    map.insert(QLatin1String(BUILD_TARGETS_KEY), m_buildTargets);
    map.insert(QLatin1String(ADDITIONAL_ARGUMENTS_KEY), m_additionalArguments);
    return map;
}

bool MakeStep::fromMap(const QVariantMap &map)
{
    m_clean = map.value(QLatin1String(CLEAN_KEY)).toBool();
    m_buildTargets = map.value(QLatin1String(BUILD_TARGETS_KEY)).toStringList();
    m_additionalArguments = map.value(QLatin1String(ADDITIONAL_ARGUMENTS_KEY)).toString();

    return BuildStep::fromMap(map);
}

bool MakeStep::init()
{
    CMakeBuildConfiguration *bc = cmakeBuildConfiguration();
    if (!bc)
        bc = static_cast<CMakeBuildConfiguration *>(target()->activeBuildConfiguration());

    QString arguments = Utils::QtcProcess::joinArgs(m_buildTargets);
    Utils::QtcProcess::addArgs(&arguments, additionalArguments());

    setIgnoreReturnValue(m_clean);

    ProcessParameters *pp = processParameters();
    pp->setMacroExpander(bc->macroExpander());
    pp->setEnvironment(bc->environment());
    pp->setWorkingDirectory(bc->buildDirectory());
    if (bc->toolChain())
        pp->setCommand(bc->toolChain()->makeCommand());
    else
        pp->setCommand(QLatin1String("make"));
    pp->setArguments(arguments);

    setOutputParser(new ProjectExplorer::GnuMakeParser());
    if (bc->toolChain())
        appendOutputParser(bc->toolChain()->outputParser());
    outputParser()->setWorkingDirectory(pp->effectiveWorkingDirectory());

    return AbstractProcessStep::init();
}

void MakeStep::run(QFutureInterface<bool> &fi)
{
    m_futureInterface = &fi;
    m_futureInterface->setProgressRange(0, 100);
    AbstractProcessStep::run(fi);
    m_futureInterface->setProgressValue(100);
    m_futureInterface->reportFinished();
    m_futureInterface = 0;
}

BuildStepConfigWidget *MakeStep::createConfigWidget()
{
    return new MakeStepConfigWidget(this);
}

bool MakeStep::immutable() const
{
    return false;
}

void MakeStep::stdOutput(const QString &line)
{
    if (m_percentProgress.indexIn(line) != -1) {
        bool ok = false;
        int percent = m_percentProgress.cap(1).toInt(&ok);;
        if (ok)
            m_futureInterface->setProgressValue(percent);
    }
    AbstractProcessStep::stdOutput(line);
}

QStringList MakeStep::buildTargets() const
{
    return m_buildTargets;
}

bool MakeStep::buildsBuildTarget(const QString &target) const
{
    return m_buildTargets.contains(target);
}

void MakeStep::setBuildTarget(const QString &buildTarget, bool on)
{
    QStringList old = m_buildTargets;
    if (on && !old.contains(buildTarget))
        old << buildTarget;
    else if (!on && old.contains(buildTarget))
        old.removeOne(buildTarget);
    m_buildTargets = old;
}

void MakeStep::setBuildTargets(const QStringList &targets)
{
    m_buildTargets = targets;
}

void MakeStep::clearBuildTargets()
{
    m_buildTargets.clear();
}

QString MakeStep::additionalArguments() const
{
    return m_additionalArguments;
}

void MakeStep::setAdditionalArguments(const QString &list)
{
    m_additionalArguments = list;
}

//
// MakeStepConfigWidget
//

MakeStepConfigWidget::MakeStepConfigWidget(MakeStep *makeStep)
    : m_makeStep(makeStep)
{
    QFormLayout *fl = new QFormLayout(this);
    fl->setMargin(0);
    fl->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
    setLayout(fl);

    m_additionalArguments = new QLineEdit(this);
    fl->addRow(tr("Additional arguments:"), m_additionalArguments);
    m_additionalArguments->setText(m_makeStep->additionalArguments());

    m_buildTargetsList = new QListWidget;
    m_buildTargetsList->setMinimumHeight(200);
    fl->addRow(tr("Targets:"), m_buildTargetsList);

    // TODO update this list also on rescans of the CMakeLists.txt
    // TODO shouldn't be accessing project
    CMakeProject *pro = static_cast<CMakeProject *>(m_makeStep->target()->project());
    foreach (const QString& buildTarget, pro->buildTargetTitles()) {
        QListWidgetItem *item = new QListWidgetItem(buildTarget, m_buildTargetsList);
        item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
        item->setCheckState(m_makeStep->buildsBuildTarget(item->text()) ? Qt::Checked : Qt::Unchecked);
    }

    updateDetails();

    connect(m_additionalArguments, SIGNAL(textEdited(QString)), this, SLOT(additionalArgumentsEdited()));
    connect(m_buildTargetsList, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(itemChanged(QListWidgetItem*)));
    connect(ProjectExplorer::ProjectExplorerPlugin::instance(), SIGNAL(settingsChanged()),
            this, SLOT(updateDetails()));

    connect(pro, SIGNAL(buildTargetsChanged()),
            this, SLOT(buildTargetsChanged()));
}

void MakeStepConfigWidget::additionalArgumentsEdited()
{
    m_makeStep->setAdditionalArguments(m_additionalArguments->text());
    updateDetails();
}

void MakeStepConfigWidget::itemChanged(QListWidgetItem *item)
{
    m_makeStep->setBuildTarget(item->text(), item->checkState() & Qt::Checked);
    updateDetails();
}

QString MakeStepConfigWidget::displayName() const
{
    return tr("Make", "CMakeProjectManager::MakeStepConfigWidget display name.");
}

void MakeStepConfigWidget::buildTargetsChanged()
{
    disconnect(m_buildTargetsList, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(itemChanged(QListWidgetItem*)));
    m_buildTargetsList->clear();
    CMakeProject *pro = static_cast<CMakeProject *>(m_makeStep->target()->project());
    foreach (const QString& buildTarget, pro->buildTargetTitles()) {
        QListWidgetItem *item = new QListWidgetItem(buildTarget, m_buildTargetsList);
        item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
        item->setCheckState(m_makeStep->buildsBuildTarget(item->text()) ? Qt::Checked : Qt::Unchecked);
    }
    connect(m_buildTargetsList, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(itemChanged(QListWidgetItem*)));
    updateSummary();
}

void MakeStepConfigWidget::updateDetails()
{
    CMakeBuildConfiguration *bc = m_makeStep->cmakeBuildConfiguration();
    if (!bc)
        bc = static_cast<CMakeBuildConfiguration *>(m_makeStep->target()->activeBuildConfiguration());
    ProjectExplorer::ToolChain *tc = bc->toolChain();
    if (tc) {
        QString arguments = Utils::QtcProcess::joinArgs(m_makeStep->m_buildTargets);
        Utils::QtcProcess::addArgs(&arguments, m_makeStep->additionalArguments());

        ProcessParameters param;
        param.setMacroExpander(bc->macroExpander());
        param.setEnvironment(bc->environment());
        param.setWorkingDirectory(bc->buildDirectory());
        param.setCommand(tc->makeCommand());
        param.setArguments(arguments);
        m_summaryText = param.summary(displayName());
    } else {
        m_summaryText = tr("<b>Unknown tool chain</b>");
    }
    emit updateSummary();
}

QString MakeStepConfigWidget::summaryText() const
{
    return m_summaryText;
}

//
// MakeStepFactory
//

MakeStepFactory::MakeStepFactory(QObject *parent) :
    ProjectExplorer::IBuildStepFactory(parent)
{
}

MakeStepFactory::~MakeStepFactory()
{
}

bool MakeStepFactory::canCreate(BuildStepList *parent, const QString &id) const
{
    if (parent->target()->project()->id() != QLatin1String(Constants::CMAKEPROJECT_ID))
        return false;
    return QLatin1String(MS_ID) == id;
}

BuildStep *MakeStepFactory::create(BuildStepList *parent, const QString &id)
{
    if (!canCreate(parent, id))
        return 0;
    MakeStep *step = new MakeStep(parent);
    if (parent->id() == ProjectExplorer::Constants::BUILDSTEPS_CLEAN) {
        step->setClean(true);
        step->setAdditionalArguments("clean");
    }
    return step;
}

bool MakeStepFactory::canClone(BuildStepList *parent, BuildStep *source) const
{
    return canCreate(parent, source->id());
}

BuildStep *MakeStepFactory::clone(BuildStepList *parent, BuildStep *source)
{
    if (!canClone(parent, source))
        return 0;
    return new MakeStep(parent, static_cast<MakeStep *>(source));
}

bool MakeStepFactory::canRestore(BuildStepList *parent, const QVariantMap &map) const
{
    QString id(ProjectExplorer::idFromMap(map));
    return canCreate(parent, id);
}

BuildStep *MakeStepFactory::restore(BuildStepList *parent, const QVariantMap &map)
{
    if (!canRestore(parent, map))
        return 0;
    MakeStep *bs(new MakeStep(parent));
    if (bs->fromMap(map))
        return bs;
    delete bs;
    return 0;
}

QStringList MakeStepFactory::availableCreationIds(ProjectExplorer::BuildStepList *parent) const
{
    if (parent->target()->project()->id() == QLatin1String(Constants::CMAKEPROJECT_ID))
        return QStringList() << QLatin1String(MS_ID);
    return QStringList();
}

QString MakeStepFactory::displayNameForId(const QString &id) const
{
    if (id == QLatin1String(MS_ID))
        return tr("Make", "Display name for CMakeProjectManager::MakeStep id.");
    return QString();
}
<|endoftext|>


<commit_before>#include <pd_view.h>
#include <pd_backend.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

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

const float margins = 5.0f;

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

struct HexMemoryData
{
    unsigned char* data;
    int dataSize;
    int addressSize;
    uint64_t startAddress;
    uint64_t endAddress;
};

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

static void* createInstance(PDUI* uiFuncs, ServiceFunc* serviceFunc)
{
    (void)serviceFunc;
    (void)uiFuncs;

    HexMemoryData* userData = (HexMemoryData*)malloc(sizeof(HexMemoryData));
    userData->data = (unsigned char*)malloc(1024 * 1024);
    userData->startAddress = 0x6000;
    userData->addressSize = 2;

    for (int i = 0; i < 1024 * 1024; ++i)
        userData->data[i] = rand() & 0xff;

    return userData;
}

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

static void destroyInstance(void* userData)
{
    free(userData);
}

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

static void printAddressLine(PDUI* uiFuncs, uint64_t address, int adressSize)
{
    char tempBuffer[128] = { 0 };

    switch (adressSize)
    {
        case 1:
            sprintf(tempBuffer, "0x%02x", (uint8_t)address); break;
        case 2:
            sprintf(tempBuffer, "0x%04x", (uint16_t)address); break;
        case 4:
            sprintf(tempBuffer, "0x%08x", (uint32_t)address); break;
        case 8:
            sprintf(tempBuffer, "0x%16llx", (int64_t)address); break;
    }

    uiFuncs->text(tempBuffer);
}

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

static void drawAddresses(HexMemoryData* data, PDUI* uiFuncs, int lineCount, unsigned int charsPerLine)
{
    uint64_t address = data->startAddress;
    int adressSize = data->addressSize;

    for (int i = 0; i < lineCount; ++i)
    {
        printAddressLine(uiFuncs, address, adressSize);
        address += charsPerLine;
    }
}

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

static void drawNumbers(HexMemoryData* userData, PDUI* uiFuncs, int lineCount, unsigned int charsPerLine, float margin)
{
    const unsigned char* data = userData->data;

    for (int i = 0; i < lineCount; ++i)
    {
        PDVec2 textStart = uiFuncs->getCursorPos();
        textStart.x = margin;

        for (unsigned int p = 0; p < charsPerLine; ++p)
        {
            uiFuncs->setCursorPos(textStart);
            uiFuncs->text("%02x ", *data++);
            textStart.x += 26.0f;
        }
    }
}

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

static void drawChars(HexMemoryData* userData, PDUI* uiFuncs, int lineCount, unsigned int charsPerLine, float margin)
{
    const unsigned char* data = userData->data;

    for (int i = 0; i < lineCount; ++i)
    {
        PDVec2 textStart = uiFuncs->getCursorPos();
        textStart.x = margin;

        for (unsigned int p = 0; p < charsPerLine; ++p)
        {
            unsigned char c = *data++;
            uiFuncs->setCursorPos(textStart);
            if (c >= 32 && c < 128)
                uiFuncs->text("%c", c);
            else
                uiFuncs->text(".", c);
            textStart.x += 10.0f;
        }
    }
}

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

void drawUI(HexMemoryData* data, PDUI* uiFuncs)
{
    PDVec2 textStart = uiFuncs->getCursorPos();
    PDVec2 windowSize = uiFuncs->getWindowSize();
    windowSize.y -= textStart.y;

    if (!data->data)
        return;

    const float fontHeight = uiFuncs->getFontHeight();
    const float fontWidth = uiFuncs->getFontWidth();

    int drawableLineCount = (int)(windowSize.y / fontHeight);
    float drawableChars = (float)(int)(windowSize.x / fontWidth);

    // margins between the rows

    drawableChars -= margins * 3.0f;
    //int addressTextSize = ((int)fontWidth) * (data->addressSize * 2) + 2;

    //printf("%d %d\n", addressTextSize, (int)drawableChars);

    //if (addressTextSize > drawableChars)
    //	return;

    drawAddresses(data, uiFuncs, drawableLineCount, 8);

    uiFuncs->setCursorPos(textStart);

    drawNumbers(data, uiFuncs, drawableLineCount, 8, 76.0f);

    uiFuncs->setCursorPos(textStart);

    drawChars(data, uiFuncs, drawableLineCount, 8, 300.0f);
}

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

static void updateMemory(HexMemoryData* userData, PDReader* reader)
{
    void* data;
    uint64_t size = 0;

    //printf("%s(%d) update memory\n", __FILE__, __LINE__);

    if (PDRead_findData(reader, &data, &size, "data", 0) == PDReadStatus_notFound)
        return;

    printf("%s(%d) update memory\n", __FILE__, __LINE__);

    free(userData->data);

    userData->data = (unsigned char*)malloc((size_t)size);
    memcpy(userData->data, data, (size_t)size);

    printf("updating data %p %d\n", userData->data, (int)size);

    userData->dataSize = (int)size;
    userData->data = (unsigned char*)data;
}

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

static int update(void* userData, PDUI* uiFuncs, PDReader* inEvents, PDWriter* outEvents)
{
    uint32_t event;

    (void)outEvents;

    HexMemoryData* data = (HexMemoryData*)userData;

    /*
       PDVec2 windowSize = uiFuncs->getWindowSize();
       const float fontHeight = uiFuncs->getFontHeight();
       const float fontWidth = uiFuncs->getFontWidth();

       int drawableLineCount = (int)(windowSize.y / fontHeight);
       int drawableChars = (int)(windowSize.x / fontWidth);
     */

    // Loop over all the in events

    while ((event = PDRead_getEvent(inEvents)) != 0)
    {
        switch (event)
        {
            case PDEventType_setMemory:
            {
                updateMemory(data, inEvents);
                break;
            }
        }
    }

    drawUI(data, uiFuncs);

    /*
       PDWrite_eventBegin(outEvents, PDEventType_getMemory);
       PDWrite_u16(outEvents, "address", 0x6000);
       PDWrite_u16(outEvents, "size", (uint16_t)(drawableLineCount * drawableChars));
       PDWrite_eventEnd(outEvents);
     */

    return 0;
}

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

static PDViewPlugin plugin =
{
    "Hex Memory View",
    createInstance,
    destroyInstance,
    update,
};

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

extern "C"
{

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

    PD_EXPORT void InitPlugin(RegisterPlugin* registerPlugin, void* privateData)
    {
        registerPlugin(PD_VIEW_API_VERSION, &plugin, privateData);
    }

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

}

<commit_msg>Work on getting a somewhat working MemoryViewer<commit_after>#include <pd_view.h>
#include <pd_backend.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

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

struct HexMemoryData
{
    unsigned char* data;
    int dataSize;
    int addressSize;
    char startAddress[64];
    char endAddress[64];
    bool requestData;
    uint64_t sa;
    uint64_t ea;
};

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

static void* createInstance(PDUI* uiFuncs, ServiceFunc* serviceFunc)
{
    (void)serviceFunc;
    (void)uiFuncs;

    HexMemoryData* userData = (HexMemoryData*)malloc(sizeof(HexMemoryData));
    memset(userData, 0, sizeof(sizeof(HexMemoryData)));

    strcpy(userData->startAddress, "0x00000000");
    strcpy(userData->endAddress, "0x00001000");

    userData->sa = 0;
    userData->ea = 0x00000fff;

    userData->data = (unsigned char*)malloc(1024 * 1024);
    userData->addressSize = 2;

    for (int i = 0; i < 1024 * 1024; ++i)
        userData->data[i] = rand() & 0xff;

    return userData;
}

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

static void destroyInstance(void* userData)
{
    free(userData);
}

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

static void getAddressLine(char* adressText, uint64_t address, int adressSize)
{
    switch (adressSize)
    {
        case 1:
            sprintf(adressText, "0x%02x", (uint8_t)address); break;
        case 2:
            sprintf(adressText, "0x%04x", (uint16_t)address); break;
        case 4:
            sprintf(adressText, "0x%08x", (uint32_t)address); break;
        case 8:
            sprintf(adressText, "0x%16llx", (int64_t)address); break;
    }
}

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

static void drawData(HexMemoryData* data, PDUI* uiFuncs, int lineCount, int charsPerLine)
{
    uint64_t address = (uint64_t)strtol(data->startAddress, 0, 16);
    int adressSize = data->addressSize;
    uint8_t* memoryData = data->data;

    if (charsPerLine > 1024)
    	charsPerLine = 1024;

    for (int i = 0; i < lineCount; ++i)
    {
    	char addressText[64] = { 0 };
    	char hexData[1024];
    	char charData[1024];

    	char* hexText = hexData;
    	char* charText = charData;

    	// Get Address

		getAddressLine(addressText, address, adressSize);

		// Get Hex and chars

    	for (int p = 0; p < charsPerLine; ++p)
		{
			uint8_t c = memoryData[p];

			sprintf(hexText, "%02x ", c);

            if (c >= 32 && c < 128)
            	*charText++ = (char)c;
            else
            	*charText++ = '.';

			hexText += 3;
		}

		*hexText = 0;
		*charText = 0;

		uiFuncs->text("%s: %s %s", addressText, hexData, charData);

        address += (uint32_t)charsPerLine;
        memoryData += charsPerLine;
    }
}

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

void drawUI(HexMemoryData* data, PDUI* uiFuncs)
{
	uiFuncs->pushItemWidth(100);
    uiFuncs->inputText("Start Address", data->startAddress, sizeof(data->startAddress), PDInputTextFlags_CharsHexadecimal, 0, 0);
    uiFuncs->sameLine(0, -1);
    uiFuncs->inputText("End Address", data->endAddress, sizeof(data->endAddress), 0, 0, 0);
    uiFuncs->popItemWidth();

    PDVec2 size = { 0.0f, 0.0f };

    long startAddress = strtol(data->startAddress, 0, 16);
    long endAddress = strtol(data->endAddress, 0, 16);

    if ((endAddress >= startAddress) && !data->data)
    	return;

	if (data->sa != (uint64_t)startAddress)
	{
		data->requestData = true;
		data->sa = (uint64_t)startAddress;
	}

	if (data->ea != (uint64_t)endAddress)
	{
		data->requestData = true;
		data->ea = (uint64_t)endAddress;
	}

    //PDVec2 textStart = uiFuncs->getCursorPos();
    PDVec2 windowSize = uiFuncs->getWindowSize();

    uiFuncs->beginChild("child", size, false, 0);

    const float fontWidth = uiFuncs->getFontWidth();

    float drawableChars = (float)(int)(windowSize.x / (fontWidth + 23));

    printf("%f\n", drawableChars);

    // margins between the rows

    //int addressTextSize = ((int)fontWidth) * (data->addressSize * 2) + 2;

    //printf("%d %d\n", addressTextSize, (int)drawableChars);

    //if (addressTextSize > drawableChars)
    //	return;

    int drawableLineCount = (int)((endAddress - startAddress) / (int)drawableChars);

    //printf("%d %d %d %d\n", drawableLineCount, (int)endAddress, (int)startAddress, (int)drawableChars);

    drawData(data, uiFuncs, drawableLineCount, (int)drawableChars);

/*
    uiFuncs->setCursorPos(textStart);

    drawNumbers(data, uiFuncs, drawableLineCount, (uint32_t)drawableChars, 76.0f);

    float offset = drawableChars * (fontWidth + 20);

    uiFuncs->setCursorPos(textStart);

    drawChars(data, uiFuncs, drawableLineCount, (uint32_t)drawableChars, offset);

*/
    uiFuncs->endChild();
}

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

static void updateMemory(HexMemoryData* userData, PDReader* reader)
{
    void* data;
    uint64_t size = 0;

    //printf("%s(%d) update memory\n", __FILE__, __LINE__);

    if (PDRead_findData(reader, &data, &size, "data", 0) == PDReadStatus_notFound)
        return;

    printf("%s(%d) update memory\n", __FILE__, __LINE__);

    free(userData->data);

    userData->data = (unsigned char*)malloc((size_t)size);
    memcpy(userData->data, data, (size_t)size);

    printf("updating data %p %d\n", userData->data, (int)size);

    userData->dataSize = (int)size;
    userData->data = (unsigned char*)data;
}

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

static int update(void* userData, PDUI* uiFuncs, PDReader* inEvents, PDWriter* outEvents)
{
    uint32_t event;

    (void)outEvents;

    HexMemoryData* data = (HexMemoryData*)userData;

    /*
       PDVec2 windowSize = uiFuncs->getWindowSize();
       const float fontHeight = uiFuncs->getFontHeight();
       const float fontWidth = uiFuncs->getFontWidth();

       int drawableLineCount = (int)(windowSize.y / fontHeight);
       int drawableChars = (int)(windowSize.x / fontWidth);
     */

    // Loop over all the in events

    while ((event = PDRead_getEvent(inEvents)) != 0)
    {
        switch (event)
        {
            case PDEventType_setMemory:
            {
                updateMemory(data, inEvents);
                break;
            }
        }
    }

    drawUI(data, uiFuncs);

    /*
       PDWrite_eventBegin(outEvents, PDEventType_getMemory);
       PDWrite_u16(outEvents, "address", 0x6000);
       PDWrite_u16(outEvents, "size", (uint16_t)(drawableLineCount * drawableChars));
       PDWrite_eventEnd(outEvents);
     */

    return 0;
}

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

static PDViewPlugin plugin =
{
    "Hex Memory View",
    createInstance,
    destroyInstance,
    update,
};

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

extern "C"
{

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

    PD_EXPORT void InitPlugin(RegisterPlugin* registerPlugin, void* privateData)
    {
        registerPlugin(PD_VIEW_API_VERSION, &plugin, privateData);
    }

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

}

<|endoftext|>


<commit_before>//==============================================================================
// Viewer widget
//==============================================================================

#include "viewerwidget.h"

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

#include <QPainter>
#include <QPaintEvent>

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

namespace OpenCOR {
namespace Viewer {

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

ViewerWidget::ViewerWidget(QWidget *pParent) :
    Widget(pParent),
    mMmlDocument(QtMmlDocument()),
    mOneOverMmlDocumentWidth(0),
    mOneOverMmlDocumentHeight(0),
    mContent(QString())
{
    // Initialise the font of our MathML document

    mMmlDocument.setFontName(QtMmlWidget::NormalFont, "Times New Roman");

//---GRY--- THE BELOW CODE IS JUST FOR TESTING THE WIDGET...
setContent("<math xmlns=\"http://www.w3.org/1998/Math/MathML\"><mrow><msub><mi>i</mi><mi>Na</mi></msub><mo>=</mo><mfrac><mrow><msub><mi>g</mi><mi>Na</mi></msub><mo>·</mo><msup><mi>m</mi><mn>3</mn></msup><mo>·</mo><mi>h</mi><mo>·</mo><msub><mi>Na</mi><mi>o</mi></msub><mo>·</mo><mfrac><msup><mi>F</mi><mn>2</mn></msup><mrow><mi>R</mi><mo>·</mo><mi>T</mi></mrow></mfrac><mo>·</mo><mo>(</mo><mrow><msup><mi>e</mi><mrow><mo>(</mo><mi>V</mi><mo>-</mo><msub><mi>E</mi><mn>Na</mn></msub><mo>)</mo><mo>·</mo><mfrac><mrow><mi>F</mi></mrow><mrow><mi>R</mi><mo>·</mo><mi>T</mi></mrow></mfrac></mrow></msup><mo>-</mo><mn>1</mn></mrow><mo>)</mo></mrow><mrow><msup><mi>e</mi><mrow><mi>V</mi><mo>·</mo><mfrac><mrow><mi>F</mi></mrow><mrow><mi>R</mi><mo>·</mo><mi>T</mi></mrow></mfrac></mrow></msup><mo>-</mo><mn>1</mn></mrow></mfrac><mo>·</mo><mi>V</mi></mrow></math>");
}

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

bool ViewerWidget::setContent(const QString &pContent, QString *pErrorMsg,
                              int *pErrorLine, int *pErrorColumn)
{
    // Keep track of the the MathML equation

    mContent = pContent;

    // Make sure that the base font size is set to 100 pixels and then set the
    // MathML equation
    // Note: when setting the equation, QtMmlDocument recomputes the equation's
    //       layout. Now, because we want the equation to be rendered as
    //       optimally as possible, we use a big font size, so that when we
    //       actually need to render the equation (see paintEvent()), we can
    //       based on the size of the widget use an optimal font size...

    mMmlDocument.setBaseFontPointSize(100);

    bool res = mMmlDocument.setContent(pContent, pErrorMsg, pErrorLine, pErrorColumn);

    // Keep track of the size of the big version of the rendered equation

    QSize mmlDocumentSize = mMmlDocument.size();

    mOneOverMmlDocumentWidth  = 1.0/mmlDocumentSize.width();
    mOneOverMmlDocumentHeight = 1.0/mmlDocumentSize.height();

    // We are all done, so just return the result of setContent()

    return res;
}

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

QSize ViewerWidget::sizeHint() const
{
    // Suggest a default size for the file browser widget
    // Note: this is critical if we want a docked widget, with a file browser
    //       widget on it, to have a decent size when docked to the main window

    return defaultSize(0.1);
}

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

void ViewerWidget::paintEvent(QPaintEvent *pEvent)
{
    QPainter painter(this);

    // Set the base font size value
    // Note: to go for 100% of the 'optimal' size might result in the edges of
    //       the equation being clipped, hence we go for 93% of the 'optimal'
    //       size...

    mMmlDocument.setBaseFontPointSize(qRound(93*qMin((double) width()*mOneOverMmlDocumentWidth,
                                                     (double) height()*mOneOverMmlDocumentHeight)));

    // Clear the background

    painter.fillRect(pEvent->rect(), QColor(palette().color(QPalette::Base)));

    // Render the equation

    QSize mmlDocumentSize = mMmlDocument.size();

    mMmlDocument.paint(&painter, QPoint(0.5*(width()-mmlDocumentSize.width()),
                                        0.5*(height()-mmlDocumentSize.height())));
}

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

}   // namespace Viewer
}   // namespace OpenCOR

//==============================================================================
// End of file
//==============================================================================
<commit_msg>Fixed a small UTF-8 issue.<commit_after>//==============================================================================
// Viewer widget
//==============================================================================

#include "viewerwidget.h"

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

#include <QPainter>
#include <QPaintEvent>

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

namespace OpenCOR {
namespace Viewer {

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

ViewerWidget::ViewerWidget(QWidget *pParent) :
    Widget(pParent),
    mMmlDocument(QtMmlDocument()),
    mOneOverMmlDocumentWidth(0),
    mOneOverMmlDocumentHeight(0),
    mContent(QString())
{
    // Initialise the font of our MathML document

    mMmlDocument.setFontName(QtMmlWidget::NormalFont, "Times New Roman");

//---GRY--- THE BELOW CODE IS JUST FOR TESTING THE WIDGET...
setContent("<math xmlns=\"http://www.w3.org/1998/Math/MathML\"><mrow><msub><mi>i</mi><mi>Na</mi></msub><mo>=</mo><mfrac><mrow><msub><mi>g</mi><mi>Na</mi></msub><mo>·</mo><msup><mi>m</mi><mn>3</mn></msup><mo>·</mo><mi>h</mi><mo>·</mo><msub><mi>Na</mi><mi>o</mi></msub><mo>·</mo><mfrac><msup><mi>F</mi><mn>2</mn></msup><mrow><mi>R</mi><mo>·</mo><mi>T</mi></mrow></mfrac><mo>·</mo><mo>(</mo><mrow><msup><mi>e</mi><mrow><mo>(</mo><mi>V</mi><mo>-</mo><msub><mi>E</mi><mn>Na</mn></msub><mo>)</mo><mo>·</mo><mfrac><mrow><mi>F</mi></mrow><mrow><mi>R</mi><mo>·</mo><mi>T</mi></mrow></mfrac></mrow></msup><mo>-</mo><mn>1</mn></mrow><mo>)</mo></mrow><mrow><msup><mi>e</mi><mrow><mi>V</mi><mo>·</mo><mfrac><mrow><mi>F</mi></mrow><mrow><mi>R</mi><mo>·</mo><mi>T</mi></mrow></mfrac></mrow></msup><mo>-</mo><mn>1</mn></mrow></mfrac><mo>·</mo><mi>V</mi></mrow></math>");
}

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

bool ViewerWidget::setContent(const QString &pContent, QString *pErrorMsg,
                              int *pErrorLine, int *pErrorColumn)
{
    // Keep track of the the MathML equation

    mContent = pContent;

    // Make sure that the base font size is set to 100 pixels and then set the
    // MathML equation
    // Note: when setting the equation, QtMmlDocument recomputes the equation's
    //       layout. Now, because we want the equation to be rendered as
    //       optimally as possible, we use a big font size, so that when we
    //       actually need to render the equation (see paintEvent()), we can
    //       based on the size of the widget use an optimal font size...

    mMmlDocument.setBaseFontPointSize(100);

    bool res = mMmlDocument.setContent(pContent, pErrorMsg, pErrorLine, pErrorColumn);

    // Keep track of the size of the big version of the rendered equation

    QSize mmlDocumentSize = mMmlDocument.size();

    mOneOverMmlDocumentWidth  = 1.0/mmlDocumentSize.width();
    mOneOverMmlDocumentHeight = 1.0/mmlDocumentSize.height();

    // We are all done, so just return the result of setContent()

    return res;
}

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

QSize ViewerWidget::sizeHint() const
{
    // Suggest a default size for the file browser widget
    // Note: this is critical if we want a docked widget, with a file browser
    //       widget on it, to have a decent size when docked to the main window

    return defaultSize(0.1);
}

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

void ViewerWidget::paintEvent(QPaintEvent *pEvent)
{
    QPainter painter(this);

    // Set the base font size value
    // Note: to go for 100% of the 'optimal' size might result in the edges of
    //       the equation being clipped, hence we go for 93% of the 'optimal'
    //       size...

    mMmlDocument.setBaseFontPointSize(qRound(93*qMin((double) width()*mOneOverMmlDocumentWidth,
                                                     (double) height()*mOneOverMmlDocumentHeight)));

    // Clear the background

    painter.fillRect(pEvent->rect(), QColor(palette().color(QPalette::Base)));

    // Render the equation

    QSize mmlDocumentSize = mMmlDocument.size();

    mMmlDocument.paint(&painter, QPoint(0.5*(width()-mmlDocumentSize.width()),
                                        0.5*(height()-mmlDocumentSize.height())));
}

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

}   // namespace Viewer
}   // namespace OpenCOR

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