<commit_before>/*************************************************************************
 *
 *  $RCSfile: fmcontrolbordermanager.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: obo $ $Date: 2004-07-05 15:50:06 $
 *
 *  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 SVX_SOURCE_FORM_FMCONTROLBORDERMANAGER_HXX
#include "fmcontrolbordermanager.hxx"
#endif

#ifndef _SVX_FMPROP_HRC
#include "fmprop.hrc"
#endif

/** === begin UNO includes === **/
#ifndef _COM_SUN_STAR_AWT_VISUALEFFECT_HPP_
#include <com/sun/star/awt/VisualEffect.hpp>
#endif
/** === end UNO includes === **/

#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

//........................................................................
namespace svxform
{
//........................................................................

    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::awt;

    //====================================================================
    //= ControlBorderManager
    //====================================================================
    //--------------------------------------------------------------------
    ControlBorderManager::ControlBorderManager()
        :m_bEnabled( false )
        ,m_nFocusColor    ( 0x000000FF )
        ,m_nMouseHoveColor( 0x007098BE )
        ,m_nCombinedColor ( 0x000000FF )
    {
    }

    //--------------------------------------------------------------------
    ControlBorderManager::~ControlBorderManager()
    {
    }

    //--------------------------------------------------------------------
    bool ControlBorderManager::canColorBorder( const Reference< XVclWindowPeer >& _rxPeer )
    {
        OSL_PRECOND( _rxPeer.is(), "ControlBorderManager::canColorBorder: invalid peer!" );
        sal_Int16 nBorderStyle = VisualEffect::NONE;
        OSL_VERIFY( _rxPeer->getProperty( FM_PROP_BORDER ) >>= nBorderStyle );
        return ( nBorderStyle == VisualEffect::FLAT );
    }

    //--------------------------------------------------------------------
    ControlStatus ControlBorderManager::getControlStatus( const Reference< XControl >& _rxControl ) SAL_THROW(())
    {
        ControlStatus nStatus = CONTROL_STATUS_NONE;
        if ( _rxControl.get() == m_aFocusControl.xControl.get() )
            nStatus |= CONTROL_STATUS_FOCUSED;
        if ( _rxControl.get() == m_aMouseHoverControl.xControl.get() )
            nStatus |= CONTROL_STATUS_MOUSE_HOVER;
        return nStatus;
    }

    //--------------------------------------------------------------------
    sal_Int32 ControlBorderManager::getControlColorByStatus( ControlStatus _nStatus )
    {
        switch ( _nStatus )
        {
        case CONTROL_STATUS_FOCUSED:
            return m_nFocusColor;
        case CONTROL_STATUS_BOTH:
            return m_nCombinedColor;
        case CONTROL_STATUS_MOUSE_HOVER:
            return m_nMouseHoveColor;
        }
        OSL_ENSURE( sal_False, "ControlBorderManager::getControlColorByStatus: invalid status!" );
        return 0x00000000;
    }

    //--------------------------------------------------------------------
    void ControlBorderManager::updateControlColor( const Reference< XControl >& _rxControl, const Reference< XVclWindowPeer >& _rxPeer, sal_Int32 _nFallbackColor ) SAL_THROW(())
    {
        OSL_PRECOND( _rxControl.is() && _rxPeer.is(), "ControlBorderManager::updateControlColor: invalid parameters!" );

        ControlStatus nStatus = getControlStatus( _rxControl );
        sal_Int32 nRestoreColor =   ( nStatus == CONTROL_STATUS_NONE )
                                ?   _nFallbackColor
                                :   getControlColorByStatus( nStatus );
        _rxPeer->setProperty( FM_PROP_BORDERCOLOR, makeAny( nRestoreColor ) );
    }

    //--------------------------------------------------------------------
    void ControlBorderManager::controlStatusGained( const Reference< XInterface >& _rxControl, ControlData& _rControlData, const ControlData& _rOppositeStatusData ) SAL_THROW(())
    {
        if ( _rxControl == _rControlData.xControl )
            // nothing to do - though suspicious
            return;

        Reference< XControl > xAsControl( _rxControl, UNO_QUERY );
        DBG_ASSERT( xAsControl.is(), "ControlBorderManager::controlStatusGained: invalid control!" );
        if ( !xAsControl.is() )
            return;

        try
        {
            Reference< XVclWindowPeer > xPeer( xAsControl->getPeer(), UNO_QUERY );
            if ( xPeer.is() && canColorBorder( xPeer ) )
            {
                // remember the control and it's current border color
                _rControlData.xControl = xAsControl;
                if ( _rControlData.xControl == _rOppositeStatusData.xControl )
                {
                    _rControlData.nOriginalColor = _rOppositeStatusData.nOriginalColor;
                }
                else
                {
                    OSL_VERIFY( xPeer->getProperty( FM_PROP_BORDERCOLOR ) >>= _rControlData.nOriginalColor );
                }

                updateControlColor( xAsControl, xPeer, _rControlData.nOriginalColor );
            }
        }
        catch( const Exception& )
        {
            OSL_ENSURE( sal_False, "ControlBorderManager::controlStatusGained: caught an exception!" );
        }
    }

    //--------------------------------------------------------------------
    void ControlBorderManager::controlStatusLost( const Reference< XInterface >& _rxControl, ControlData& _rControlData ) SAL_THROW(())
    {
        if ( _rxControl != _rControlData.xControl )
            // nothing to do
            return;

        OSL_PRECOND( _rControlData.xControl.is(), "ControlBorderManager::controlStatusLost: invalid control data - this will crash!" );
        try
        {
            Reference< XVclWindowPeer > xPeer( _rControlData.xControl->getPeer(), UNO_QUERY );
            if ( xPeer.is() && canColorBorder( xPeer ) )
            {
                ControlData aPreviousStatus( _rControlData );
                _rControlData.clear();
                updateControlColor( aPreviousStatus.xControl, xPeer, aPreviousStatus.nOriginalColor );
            }
        }
        catch( const Exception& )
        {
            OSL_ENSURE( sal_False, "ControlBorderManager::controlStatusLost: caught an exception!" );
        }
    }

    //--------------------------------------------------------------------
    void ControlBorderManager::enableDynamicBorderColor( )
    {
        m_bEnabled = true;
    }

    //--------------------------------------------------------------------
    void ControlBorderManager::disableDynamicBorderColor( )
    {
        m_bEnabled = false;
        restoreAll();
    }

    //--------------------------------------------------------------------
    void ControlBorderManager::setStatusColor( ControlStatus _nStatus, sal_Int32 _nColor )
    {
        switch ( _nStatus )
        {
        case CONTROL_STATUS_FOCUSED:
            m_nFocusColor = _nColor;
            break;
        case CONTROL_STATUS_BOTH:
            m_nCombinedColor = _nColor;
            break;
        case CONTROL_STATUS_MOUSE_HOVER:
            m_nMouseHoveColor = _nColor;
            break;
        default:
            OSL_ENSURE( sal_False, "ControlBorderManager::setStatusColor: invalid status!" );
        }
    }

    //--------------------------------------------------------------------
    void ControlBorderManager::restoreAll()
    {
        if ( m_aFocusControl.xControl.is() )
            controlStatusLost( m_aFocusControl.xControl, m_aFocusControl );
        if ( m_aMouseHoverControl.xControl.is() )
            controlStatusLost( m_aMouseHoverControl.xControl, m_aMouseHoverControl );
    }

    //--------------------------------------------------------------------
    void ControlBorderManager::focusGained( const Reference< XInterface >& _rxControl ) SAL_THROW(())
    {
        if ( m_bEnabled )
            controlStatusGained( _rxControl, m_aFocusControl, m_aMouseHoverControl );
    }

    //--------------------------------------------------------------------
    void ControlBorderManager::focusLost( const Reference< XInterface >& _rxControl ) SAL_THROW(())
    {
        if ( m_bEnabled )
            controlStatusLost( _rxControl, m_aFocusControl );
    }

    //--------------------------------------------------------------------
    void ControlBorderManager::mouseEntered( const Reference< XInterface >& _rxControl ) SAL_THROW(())
    {
        if ( m_bEnabled )
            controlStatusGained( _rxControl, m_aMouseHoverControl, m_aFocusControl );
    }

    //--------------------------------------------------------------------
    void ControlBorderManager::mouseExited( const Reference< XInterface >& _rxControl ) SAL_THROW(())
    {
        if ( m_bEnabled )
            controlStatusLost( _rxControl, m_aMouseHoverControl );
    }

//........................................................................
} // namespace svxform
//........................................................................

<commit_msg>INTEGRATION: CWS eforms2 (1.2.86); FILE MERGED 2004/08/06 11:10:13 fs 1.2.86.5: #i31958# controls whose colors cannot be colored indicate their invalidity with a red text underline now 2004/08/06 10:28:37 fs 1.2.86.4: preparations for dynamic border colors also for 3D borders 2004/08/06 08:28:00 fs 1.2.86.3: #i31958# now also caring for the HelpText of invalid controls 2004/08/05 12:33:37 fs 1.2.86.2: #i31958# restoreAll: also restore control borders of invalid controls 2004/08/05 10:26:57 fs 1.2.86.1: #i31958# indicate the validity of a control/model's value with a red border<commit_after>/*************************************************************************
 *
 *  $RCSfile: fmcontrolbordermanager.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: obo $ $Date: 2004-11-16 11:22:25 $
 *
 *  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 SVX_SOURCE_FORM_FMCONTROLBORDERMANAGER_HXX
#include "fmcontrolbordermanager.hxx"
#endif

#ifndef _SVX_FMPROP_HRC
#include "fmprop.hrc"
#endif

/** === begin UNO includes === **/
#ifndef _COM_SUN_STAR_FORM_VALIDATION_XVALIDATABLEFORMCOMPONENT_HPP_
#include <com/sun/star/form/validation/XValidatableFormComponent.hpp>
#endif
/** === end UNO includes === **/

#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

//........................................................................
namespace svxform
{
//........................................................................

    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::awt;
    using namespace ::com::sun::star::form::validation;

    //====================================================================
    //= helper
    //====================================================================
    //--------------------------------------------------------------------
    static void setUnderline( const Reference< XVclWindowPeer >& _rxPeer, const UnderlineDescriptor& _rUnderline )
    {
        OSL_ENSURE( _rxPeer.is(), "setUnderline: invalid peer!" );

        // the underline type is an aspect of the font
        FontDescriptor aFont;
        OSL_VERIFY( _rxPeer->getProperty( FM_PROP_FONT ) >>= aFont );
        aFont.Underline = _rUnderline.nUnderlineType;
        _rxPeer->setProperty( FM_PROP_FONT, makeAny( aFont ) );
        // the underline color is a separate property
        _rxPeer->setProperty( FM_PROP_TEXTLINECOLOR, makeAny( _rUnderline.nUnderlineColor ) );
    }

    //--------------------------------------------------------------------
    static void getUnderline( const Reference< XVclWindowPeer >& _rxPeer, UnderlineDescriptor& _rUnderline )
    {
        OSL_ENSURE( _rxPeer.is(), "getUnderline: invalid peer!" );

        FontDescriptor aFont;
        OSL_VERIFY( _rxPeer->getProperty( FM_PROP_FONT ) >>= aFont );
        _rUnderline.nUnderlineType = aFont.Underline;

        OSL_VERIFY( _rxPeer->getProperty( FM_PROP_TEXTLINECOLOR ) >>= _rUnderline.nUnderlineColor );
    }

    //--------------------------------------------------------------------
    static void getBorder( const Reference< XVclWindowPeer >& _rxPeer, BorderDescriptor& _rBoder )
    {
        OSL_ENSURE( _rxPeer.is(), "getBorder: invalid peer!" );

        OSL_VERIFY( _rxPeer->getProperty( FM_PROP_BORDER ) >>= _rBoder.nBorderType );
        OSL_VERIFY( _rxPeer->getProperty( FM_PROP_BORDERCOLOR ) >>= _rBoder.nBorderColor );
    }

    //--------------------------------------------------------------------
    static void setBorder( const Reference< XVclWindowPeer >& _rxPeer, const BorderDescriptor& _rBoder )
    {
        OSL_ENSURE( _rxPeer.is(), "setBorder: invalid peer!" );

        _rxPeer->setProperty( FM_PROP_BORDER, makeAny( _rBoder.nBorderType ) );
        _rxPeer->setProperty( FM_PROP_BORDERCOLOR, makeAny( _rBoder.nBorderColor ) );
    }

    //====================================================================
    //= ControlBorderManager
    //====================================================================
    //--------------------------------------------------------------------
    ControlBorderManager::ControlBorderManager()
        :m_bDynamicBorderColors( false )
        ,m_nFocusColor    ( 0x000000FF )
        ,m_nMouseHoveColor( 0x007098BE )
        ,m_nInvalidColor  ( 0x00FF0000 )
    {
    }

    //--------------------------------------------------------------------
    ControlBorderManager::~ControlBorderManager()
    {
    }

    //--------------------------------------------------------------------
    bool ControlBorderManager::canColorBorder( const Reference< XVclWindowPeer >& _rxPeer )
    {
        OSL_PRECOND( _rxPeer.is(), "ControlBorderManager::canColorBorder: invalid peer!" );
        sal_Int16 nBorderStyle = VisualEffect::NONE;
        OSL_VERIFY( _rxPeer->getProperty( FM_PROP_BORDER ) >>= nBorderStyle );
        return ( nBorderStyle == VisualEffect::FLAT );
            // if you change this to also accept LOOK3D, then this would also work, but look ugly
    }

    //--------------------------------------------------------------------
    ControlStatus ControlBorderManager::getControlStatus( const Reference< XControl >& _rxControl ) SAL_THROW(())
    {
        ControlStatus nStatus = CONTROL_STATUS_NONE;

        if ( _rxControl.get() == m_aFocusControl.xControl.get() )
            nStatus |= CONTROL_STATUS_FOCUSED;

        if ( _rxControl.get() == m_aMouseHoverControl.xControl.get() )
            nStatus |= CONTROL_STATUS_MOUSE_HOVER;

        if ( m_aInvalidControls.find( ControlData( _rxControl ) ) != m_aInvalidControls.end() )
            nStatus |= CONTROL_STATUS_INVALID;

        return nStatus;
    }

    //--------------------------------------------------------------------
    sal_Int32 ControlBorderManager::getControlColorByStatus( ControlStatus _nStatus )
    {
        // "invalid" is ranked highest
        if ( _nStatus & CONTROL_STATUS_INVALID )
            return m_nInvalidColor;

        // then, "focused" is more important than ...
        if ( _nStatus & CONTROL_STATUS_FOCUSED )
            return m_nFocusColor;

        // ... "mouse over"
        if ( _nStatus & CONTROL_STATUS_MOUSE_HOVER )
            return m_nMouseHoveColor;

        OSL_ENSURE( sal_False, "ControlBorderManager::getControlColorByStatus: invalid status!" );
        return 0x00000000;
    }

    //--------------------------------------------------------------------
    void ControlBorderManager::updateBorderStyle( const Reference< XControl >& _rxControl, const Reference< XVclWindowPeer >& _rxPeer, const BorderDescriptor& _rFallback ) SAL_THROW(())
    {
        OSL_PRECOND( _rxControl.is() && _rxPeer.is(), "ControlBorderManager::updateBorderStyle: invalid parameters!" );

        ControlStatus nStatus = getControlStatus( _rxControl );
        BorderDescriptor aBorder;
        aBorder.nBorderType =   ( nStatus == CONTROL_STATUS_NONE )
                            ?   _rFallback.nBorderType
                            :   VisualEffect::FLAT;
        aBorder.nBorderColor =   ( nStatus == CONTROL_STATUS_NONE )
                             ?   _rFallback.nBorderColor
                             :   getControlColorByStatus( nStatus );
        setBorder( _rxPeer, aBorder );
    }

    //--------------------------------------------------------------------
    void ControlBorderManager::determineOriginalBorderStyle( const Reference< XControl >& _rxControl, BorderDescriptor& _rData ) const
    {
        _rData = ControlData();
        if ( m_aFocusControl.xControl.get() == _rxControl.get() )
        {
            _rData = m_aFocusControl;
        }
        else if ( m_aMouseHoverControl.xControl.get() == _rxControl.get() )
        {
            _rData = m_aMouseHoverControl;
        }
        else
        {
            ControlBag::const_iterator aPos = m_aInvalidControls.find( _rxControl );
            if ( aPos != m_aInvalidControls.end() )
            {
                _rData = *aPos;
            }
            else
            {
                Reference< XVclWindowPeer > xPeer( _rxControl->getPeer(), UNO_QUERY );
                getBorder( xPeer, _rData );
            }
        }
    }

    //--------------------------------------------------------------------
    void ControlBorderManager::controlStatusGained( const Reference< XInterface >& _rxControl, ControlData& _rControlData ) SAL_THROW(())
    {
        if ( _rxControl == _rControlData.xControl )
            // nothing to do - though suspicious
            return;

        Reference< XControl > xAsControl( _rxControl, UNO_QUERY );
        DBG_ASSERT( xAsControl.is(), "ControlBorderManager::controlStatusGained: invalid control!" );
        if ( !xAsControl.is() )
            return;

        try
        {
            Reference< XVclWindowPeer > xPeer( xAsControl->getPeer(), UNO_QUERY );
            if ( xPeer.is() && canColorBorder( xPeer ) )
            {
                // remember the control and it's current border color
                _rControlData.xControl.clear(); // so determineOriginalBorderStyle doesn't get confused

                determineOriginalBorderStyle( xAsControl, _rControlData );

                _rControlData.xControl = xAsControl;

                updateBorderStyle( xAsControl, xPeer, _rControlData );
            }
        }
        catch( const Exception& )
        {
            OSL_ENSURE( sal_False, "ControlBorderManager::controlStatusGained: caught an exception!" );
        }
    }

    //--------------------------------------------------------------------
    void ControlBorderManager::controlStatusLost( const Reference< XInterface >& _rxControl, ControlData& _rControlData ) SAL_THROW(())
    {
        if ( _rxControl != _rControlData.xControl )
            // nothing to do
            return;

        OSL_PRECOND( _rControlData.xControl.is(), "ControlBorderManager::controlStatusLost: invalid control data - this will crash!" );
        try
        {
            Reference< XVclWindowPeer > xPeer( _rControlData.xControl->getPeer(), UNO_QUERY );
            if ( xPeer.is() && canColorBorder( xPeer ) )
            {
                ControlData aPreviousStatus( _rControlData );
                _rControlData = ControlData();
                updateBorderStyle( aPreviousStatus.xControl, xPeer, aPreviousStatus );
            }
        }
        catch( const Exception& )
        {
            OSL_ENSURE( sal_False, "ControlBorderManager::controlStatusLost: caught an exception!" );
        }
    }

    //--------------------------------------------------------------------
    void ControlBorderManager::enableDynamicBorderColor( )
    {
        m_bDynamicBorderColors = true;
    }

    //--------------------------------------------------------------------
    void ControlBorderManager::disableDynamicBorderColor( )
    {
        m_bDynamicBorderColors = false;
        restoreAll();
    }

    //--------------------------------------------------------------------
    void ControlBorderManager::setStatusColor( ControlStatus _nStatus, sal_Int32 _nColor )
    {
        switch ( _nStatus )
        {
        case CONTROL_STATUS_FOCUSED:
            m_nFocusColor = _nColor;
            break;
        case CONTROL_STATUS_MOUSE_HOVER:
            m_nMouseHoveColor = _nColor;
            break;
        case CONTROL_STATUS_INVALID:
            m_nInvalidColor = _nColor;
            break;
        default:
            OSL_ENSURE( sal_False, "ControlBorderManager::setStatusColor: invalid status!" );
        }
    }

    //--------------------------------------------------------------------
    void ControlBorderManager::restoreAll()
    {
        if ( m_aFocusControl.xControl.is() )
            controlStatusLost( m_aFocusControl.xControl, m_aFocusControl );
        if ( m_aMouseHoverControl.xControl.is() )
            controlStatusLost( m_aMouseHoverControl.xControl, m_aMouseHoverControl );

        ControlBag aInvalidControls;
        m_aInvalidControls.swap( aInvalidControls );

        for ( ControlBag::const_iterator loop = aInvalidControls.begin();
              loop != aInvalidControls.end();
              ++loop
            )
        {
            Reference< XVclWindowPeer > xPeer( loop->xControl->getPeer(), UNO_QUERY );
            if ( xPeer.is() )
            {
                updateBorderStyle( loop->xControl, xPeer, *loop );
                xPeer->setProperty( FM_PROP_HELPTEXT, makeAny( loop->sOriginalHelpText ) );
                setUnderline( xPeer, *loop );
            }
        }
    }

    //--------------------------------------------------------------------
    void ControlBorderManager::focusGained( const Reference< XInterface >& _rxControl ) SAL_THROW(())
    {
        if ( m_bDynamicBorderColors )
            controlStatusGained( _rxControl, m_aFocusControl );
    }

    //--------------------------------------------------------------------
    void ControlBorderManager::focusLost( const Reference< XInterface >& _rxControl ) SAL_THROW(())
    {
        if ( m_bDynamicBorderColors )
            controlStatusLost( _rxControl, m_aFocusControl );
    }

    //--------------------------------------------------------------------
    void ControlBorderManager::mouseEntered( const Reference< XInterface >& _rxControl ) SAL_THROW(())
    {
        if ( m_bDynamicBorderColors )
            controlStatusGained( _rxControl, m_aMouseHoverControl );
    }

    //--------------------------------------------------------------------
    void ControlBorderManager::mouseExited( const Reference< XInterface >& _rxControl ) SAL_THROW(())
    {
        if ( m_bDynamicBorderColors )
            controlStatusLost( _rxControl, m_aMouseHoverControl );
    }

    //--------------------------------------------------------------------
    void ControlBorderManager::validityChanged( const Reference< XControl >& _rxControl, const Reference< XValidatableFormComponent >& _rxValidatable ) SAL_THROW(())
    {
        try
        {
            Reference< XVclWindowPeer > xPeer( _rxControl.is() ? _rxControl->getPeer() : Reference< XWindowPeer >(), UNO_QUERY );
            OSL_ENSURE( xPeer.is(), "ControlBorderManager::validityChanged: invalid control/peer!" );
            OSL_ENSURE( _rxValidatable.is(), "ControlBorderManager::validityChanged: invalid validatable!" );

            if ( !xPeer.is() || !_rxValidatable.is() )
                return;

            ControlData aData( _rxControl );

            if ( _rxValidatable->isValid() )
            {
                ControlBag::iterator aPos = m_aInvalidControls.find( aData );
                if ( aPos != m_aInvalidControls.end() )
                {   // invalid before, valid now
                    ControlData aOriginalLayout( *aPos );
                    m_aInvalidControls.erase( aPos );

                    // restore all the things we used to indicate invalidity
                    if ( m_bDynamicBorderColors )
                        updateBorderStyle( _rxControl, xPeer, aOriginalLayout );
                    xPeer->setProperty( FM_PROP_HELPTEXT, makeAny( aOriginalLayout.sOriginalHelpText ) );
                    setUnderline( xPeer, aOriginalLayout );
                }
                return;
            }

            // we're here in the INVALID case
            if ( m_aInvalidControls.find( _rxControl ) == m_aInvalidControls.end() )
            {   // valid before, invalid now

                // remember the current border
                determineOriginalBorderStyle( _rxControl, aData );
                // and tool tip
                xPeer->getProperty( FM_PROP_HELPTEXT ) >>= aData.sOriginalHelpText;
                // and font
                getUnderline( xPeer, aData );

                m_aInvalidControls.insert( aData );

                // update the border to the new invalidity
                if ( m_bDynamicBorderColors && canColorBorder( xPeer ) )
                    updateBorderStyle( _rxControl, xPeer, aData );
                else
                {
                    // and also the new font
                    setUnderline( xPeer, UnderlineDescriptor( FontUnderline::WAVE, m_nInvalidColor ) );
                }
            }

            // update the explanation for invalidity (this is always done, even if the validity did not change)
            Reference< XValidator > xValidator = _rxValidatable->getValidator();
            OSL_ENSURE( xValidator.is(), "ControlBorderManager::validityChanged: invalid, but no validator?" );
            ::rtl::OUString sExplainInvalidity = xValidator.is() ? xValidator->explainInvalid( _rxValidatable->getCurrentValue() ) : ::rtl::OUString();
            xPeer->setProperty( FM_PROP_HELPTEXT, makeAny( sExplainInvalidity ) );
        }
        catch( const Exception& )
        {
            OSL_ENSURE( sal_False, "ControlBorderManager::validityChanged: caught an exception!" );
        }
    }

//........................................................................
} // namespace svxform
//........................................................................

<|endoftext|>


<commit_before>/** @file
    @brief Implementation

    @date 2014

    @author
    Ryan Pavlik
    <ryan@sensics.com>
    <http://sensics.com>

*/

// Copyright 2014 Sensics, Inc.
//
// All rights reserved.
//
// (Final version intended to be licensed under
// the Apache License, Version 2.0)

// Internal Includes
#include <ogvr/PluginKit/PluginRegistrationC.h>
#include <ogvr/Util/Verbosity.h>

// Library/third-party includes
// - none

// Standard includes
// - none

OGVR_PluginReturnCode
ogvrPluginRegisterHardwarePollCallback(OGVR_PluginRegContext ctx,
                                       OGVRHardwarePollCallback pollCallback,
                                       void *userData) {
    /// @todo implement - replace stub
    OGVR_DEV_VERBOSE("In ogvrPluginRegisterHardwarePollCallback");
    return OGVR_PLUGIN_SUCCESS;
}

OGVR_PluginReturnCode ogvrPluginRegisterDataWithDeleteCallback(
    OGVR_PluginRegContext ctx, OGVR_PluginDataDeleteCallback deleteCallback,
    void *pluginData) {
    /// @todo implement - replace stub
    OGVR_DEV_VERBOSE("In ogvrPluginRegisterHardwarePollCallback");
    return OGVR_PLUGIN_SUCCESS;
}
<commit_msg>Register data delete callbacks go all the way through.<commit_after>/** @file
    @brief Implementation

    @date 2014

    @author
    Ryan Pavlik
    <ryan@sensics.com>
    <http://sensics.com>

*/

// Copyright 2014 Sensics, Inc.
//
// All rights reserved.
//
// (Final version intended to be licensed under
// the Apache License, Version 2.0)

// Internal Includes
#include <ogvr/PluginKit/PluginRegistrationC.h>
#include <ogvr/Util/Verbosity.h>

// Library/third-party includes
// - none

// Standard includes
// - none

OGVR_PluginReturnCode
ogvrPluginRegisterHardwarePollCallback(OGVR_PluginRegContext ctx,
                                       OGVRHardwarePollCallback pollCallback,
                                       void *userData) {
    /// @todo implement - replace stub
    OGVR_DEV_VERBOSE("In ogvrPluginRegisterHardwarePollCallback");
    return OGVR_PLUGIN_SUCCESS;
}

OGVR_PluginReturnCode ogvrPluginRegisterDataWithDeleteCallback(
    OGVR_PluginRegContext ctx, OGVR_PluginDataDeleteCallback deleteCallback,
    void *pluginData) {
    assert(ctx);
    ogvr::PluginSpecificRegistrationContext *context =
        static_cast<ogvr::PluginSpecificRegistrationContext *>(ctx);
    context->registerDataWithDeleteCallback(deleteCallback, pluginData);
    return OGVR_PLUGIN_SUCCESS;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: dlg_ChartType.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: bm $ $Date: 2004-01-26 09:12:02 $
 *
 *  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: 2003 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _CHART2_DLG_CHARTTYPE_HXX
#define _CHART2_DLG_CHARTTYPE_HXX

/*
#ifndef _SCH_DIAGRTYP_HXX_
#define _SCH_DIAGRTYP_HXX_

#ifndef _SV_BUTTON_HXX //autogen
#include <vcl/button.hxx>
#endif
#ifndef _SV_FIXED_HXX //autogen
#include <vcl/fixed.hxx>
#endif
#ifndef _SV_FIELD_HXX //autogen
#include <vcl/field.hxx>
#endif
#ifndef _VALUESET_HXX //autogen
#include <svtools/valueset.hxx>
#endif
#ifndef _SV_DIALOG_HXX //autogen
#include <vcl/dialog.hxx>
#endif
#ifndef _SFXITEMSET_HXX //autogen
#include <svtools/itemset.hxx>
#endif
*/

// header for class ModalDialog
#ifndef _SV_DIALOG_HXX
#include <vcl/dialog.hxx>
#endif
// header for class RadioButton
#ifndef _SV_BUTTON_HXX
#include <vcl/button.hxx>
#endif
// header for class FixedLine
#ifndef _SV_FIXED_HXX
#include <vcl/fixed.hxx>
#endif
// header for class MetricField
#ifndef _SV_FIELD_HXX
#include <vcl/field.hxx>
#endif
// header for class ValueSet
#ifndef _VALUESET_HXX
#include <svtools/valueset.hxx>
#endif
// header for class SfxItemSet
#ifndef _SFXITEMSET_HXX
#include <svtools/itemset.hxx>
#endif
// header for SvxChartStyle
#ifndef _SVX_CHRTITEM_HXX
#include <svx/chrtitem.hxx>
#endif

#ifndef _COM_SUN_STAR_CHART2_XDIAGRAM_HPP_
#include <com/sun/star/chart2/XDiagram.hpp>
#endif
#ifndef _COM_SUN_STAR_CHART2_XCHARTTYPETEMPLATE_HPP_
#include <com/sun/star/chart2/XChartTypeTemplate.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif

//.............................................................................
namespace chart
{
//.............................................................................

enum ChartDimension
{
    CHDIM_2D,
    CHDIM_3D
};

#define CHDIM_COUNT (CHDIM_3D + 1)

/*************************************************************************
|*
|* Dialog zur Auswahl eines Diagrammtyps
|*
\************************************************************************/
class SchDiagramTypeDlg : public ModalDialog
{
private:
    long            n3DGeometry;
    RadioButton     aRbt2D;
    RadioButton     aRbt3D;
    FixedLine       aFlDimension;
    FixedText       aFtDeep;
    MetricField     aMtrFldDeep;
    FixedText       aFtGran;
    MetricField     aMtrFldGran;
    FixedText       aFtNumLines;
    MetricField     aMtrFldNumLines;

    FixedText       aFtType;
    ValueSet        aCtlType;
    FixedText       aFtVariant;
    ValueSet        aCtlVariant;
    OKButton        aBtnOK;
    CancelButton    aBtnCancel;
    HelpButton      aBtnHelp;
    ChartDimension  eDimension;

    ::com::sun::star::uno::Reference<
            ::com::sun::star::chart2::XDiagram > m_xDiagram;
    ::com::sun::star::uno::Reference<
            ::com::sun::star::lang::XMultiServiceFactory > m_xTemplateManager;

    void Reset();

    void FillTypeSet(ChartDimension eDim, bool bForce=false);
    void FillVariantSet(USHORT nType);

    DECL_LINK(SelectDimensionHdl, void*);
    DECL_LINK(SelectTypeHdl, void*);
    DECL_LINK(DoubleClickHdl, void*);
    DECL_LINK(ClickHdl, void*);

    void SwitchDepth( SvxChartStyle eID );

    /** Hides/Shows the controls for line/bar combination chart according to the
        chart type id given as nID.
     */
    void SwitchNumLines( SvxChartStyle eID );

    void FillValueSets();

public:
    SchDiagramTypeDlg(
        Window* pWindow,
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::chart2::XDiagram > & xDiagram,
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::lang::XMultiServiceFactory > & xTemplateManager );
    virtual ~SchDiagramTypeDlg();

     sal_Int32 GetDepth() const;
    void      SetDepth( sal_Int32 nDeep );

     sal_Int32 GetGranularity() const;
     void      SetGranularity( sal_Int32 nGranularity );

    /** The value set here determines the maximum number of lines in a line/bar
        combination chart.  This should usually be one less than the number of
        series, such that at least one series remains a bar.
     */
    void    SetMaximumNumberOfLines( sal_Int32 nMaxLines );
    /** set the current number of lines that are used in a line/bar combination
        chart.
     */
//     void    SetNumberOfLines( long nLines );
    /** get the number of lines that should be used for a line/bar combination
        chart.  This has to be set before to be meaningful
     */
    sal_Int32  GetNumberOfLines() const;

    virtual void    DataChanged( const DataChangedEvent& rDCEvt );

    ::com::sun::star::uno::Reference<
            ::com::sun::star::chart2::XChartTypeTemplate >
        getTemplate() const;

    bool HasChanged() const;
};

//.............................................................................
} //namespace chart
//.............................................................................

#endif

<commit_msg>INTEGRATION: CWS ooo19126 (1.5.110); FILE MERGED 2005/09/05 18:42:36 rt 1.5.110.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: dlg_ChartType.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 00:26:34 $
 *
 *  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 _CHART2_DLG_CHARTTYPE_HXX
#define _CHART2_DLG_CHARTTYPE_HXX

/*
#ifndef _SCH_DIAGRTYP_HXX_
#define _SCH_DIAGRTYP_HXX_

#ifndef _SV_BUTTON_HXX //autogen
#include <vcl/button.hxx>
#endif
#ifndef _SV_FIXED_HXX //autogen
#include <vcl/fixed.hxx>
#endif
#ifndef _SV_FIELD_HXX //autogen
#include <vcl/field.hxx>
#endif
#ifndef _VALUESET_HXX //autogen
#include <svtools/valueset.hxx>
#endif
#ifndef _SV_DIALOG_HXX //autogen
#include <vcl/dialog.hxx>
#endif
#ifndef _SFXITEMSET_HXX //autogen
#include <svtools/itemset.hxx>
#endif
*/

// header for class ModalDialog
#ifndef _SV_DIALOG_HXX
#include <vcl/dialog.hxx>
#endif
// header for class RadioButton
#ifndef _SV_BUTTON_HXX
#include <vcl/button.hxx>
#endif
// header for class FixedLine
#ifndef _SV_FIXED_HXX
#include <vcl/fixed.hxx>
#endif
// header for class MetricField
#ifndef _SV_FIELD_HXX
#include <vcl/field.hxx>
#endif
// header for class ValueSet
#ifndef _VALUESET_HXX
#include <svtools/valueset.hxx>
#endif
// header for class SfxItemSet
#ifndef _SFXITEMSET_HXX
#include <svtools/itemset.hxx>
#endif
// header for SvxChartStyle
#ifndef _SVX_CHRTITEM_HXX
#include <svx/chrtitem.hxx>
#endif

#ifndef _COM_SUN_STAR_CHART2_XDIAGRAM_HPP_
#include <com/sun/star/chart2/XDiagram.hpp>
#endif
#ifndef _COM_SUN_STAR_CHART2_XCHARTTYPETEMPLATE_HPP_
#include <com/sun/star/chart2/XChartTypeTemplate.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif

//.............................................................................
namespace chart
{
//.............................................................................

enum ChartDimension
{
    CHDIM_2D,
    CHDIM_3D
};

#define CHDIM_COUNT (CHDIM_3D + 1)

/*************************************************************************
|*
|* Dialog zur Auswahl eines Diagrammtyps
|*
\************************************************************************/
class SchDiagramTypeDlg : public ModalDialog
{
private:
    long            n3DGeometry;
    RadioButton     aRbt2D;
    RadioButton     aRbt3D;
    FixedLine       aFlDimension;
    FixedText       aFtDeep;
    MetricField     aMtrFldDeep;
    FixedText       aFtGran;
    MetricField     aMtrFldGran;
    FixedText       aFtNumLines;
    MetricField     aMtrFldNumLines;

    FixedText       aFtType;
    ValueSet        aCtlType;
    FixedText       aFtVariant;
    ValueSet        aCtlVariant;
    OKButton        aBtnOK;
    CancelButton    aBtnCancel;
    HelpButton      aBtnHelp;
    ChartDimension  eDimension;

    ::com::sun::star::uno::Reference<
            ::com::sun::star::chart2::XDiagram > m_xDiagram;
    ::com::sun::star::uno::Reference<
            ::com::sun::star::lang::XMultiServiceFactory > m_xTemplateManager;

    void Reset();

    void FillTypeSet(ChartDimension eDim, bool bForce=false);
    void FillVariantSet(USHORT nType);

    DECL_LINK(SelectDimensionHdl, void*);
    DECL_LINK(SelectTypeHdl, void*);
    DECL_LINK(DoubleClickHdl, void*);
    DECL_LINK(ClickHdl, void*);

    void SwitchDepth( SvxChartStyle eID );

    /** Hides/Shows the controls for line/bar combination chart according to the
        chart type id given as nID.
     */
    void SwitchNumLines( SvxChartStyle eID );

    void FillValueSets();

public:
    SchDiagramTypeDlg(
        Window* pWindow,
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::chart2::XDiagram > & xDiagram,
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::lang::XMultiServiceFactory > & xTemplateManager );
    virtual ~SchDiagramTypeDlg();

     sal_Int32 GetDepth() const;
    void      SetDepth( sal_Int32 nDeep );

     sal_Int32 GetGranularity() const;
     void      SetGranularity( sal_Int32 nGranularity );

    /** The value set here determines the maximum number of lines in a line/bar
        combination chart.  This should usually be one less than the number of
        series, such that at least one series remains a bar.
     */
    void    SetMaximumNumberOfLines( sal_Int32 nMaxLines );
    /** set the current number of lines that are used in a line/bar combination
        chart.
     */
//     void    SetNumberOfLines( long nLines );
    /** get the number of lines that should be used for a line/bar combination
        chart.  This has to be set before to be meaningful
     */
    sal_Int32  GetNumberOfLines() const;

    virtual void    DataChanged( const DataChangedEvent& rDCEvt );

    ::com::sun::star::uno::Reference<
            ::com::sun::star::chart2::XChartTypeTemplate >
        getTemplate() const;

    bool HasChanged() const;
};

//.............................................................................
} //namespace chart
//.............................................................................

#endif

<|endoftext|>


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

#include "chrome/browser/bookmarks/bookmark_drag_data.h"

// TODO(port): Port this file.
#if defined(TOOLKIT_VIEWS)
#include "app/os_exchange_data.h"
#else
#include "chrome/common/temp_scaffolding_stubs.h"
#endif
#include "base/basictypes.h"
#include "base/pickle.h"
#include "base/string_util.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/browser/profile.h"
#include "chrome/common/url_constants.h"

#if defined(OS_WIN)
static CLIPFORMAT clipboard_format = 0;

static void RegisterFormat() {
  if (clipboard_format == 0) {
    clipboard_format = RegisterClipboardFormat(L"chrome/x-bookmark-entries");
    DCHECK(clipboard_format);
  }
}
#endif

BookmarkDragData::Element::Element(BookmarkNode* node)
    : is_url(node->is_url()),
      url(node->GetURL()),
      title(node->GetTitle()),
      id_(node->id()) {
  for (int i = 0; i < node->GetChildCount(); ++i)
    children.push_back(Element(node->GetChild(i)));
}

void BookmarkDragData::Element::WriteToPickle(Pickle* pickle) const {
  pickle->WriteBool(is_url);
  pickle->WriteString(url.spec());
  pickle->WriteWString(title);
  pickle->WriteInt(id_);
  if (!is_url) {
    pickle->WriteSize(children.size());
    for (std::vector<Element>::const_iterator i = children.begin();
         i != children.end(); ++i) {
      i->WriteToPickle(pickle);
    }
  }
}

bool BookmarkDragData::Element::ReadFromPickle(Pickle* pickle,
                                               void** iterator) {
  std::string url_spec;
  if (!pickle->ReadBool(iterator, &is_url) ||
      !pickle->ReadString(iterator, &url_spec) ||
      !pickle->ReadWString(iterator, &title) ||
      !pickle->ReadInt(iterator, &id_)) {
    return false;
  }
  url = GURL(url_spec);
  children.clear();
  if (!is_url) {
    size_t children_count;
    if (!pickle->ReadSize(iterator, &children_count))
      return false;
    children.resize(children_count);
    for (std::vector<Element>::iterator i = children.begin();
         i != children.end(); ++i) {
      if (!i->ReadFromPickle(pickle, iterator))
        return false;
    }
  }
  return true;
}

BookmarkDragData::BookmarkDragData(BookmarkNode* node) {
  elements.push_back(Element(node));
}

BookmarkDragData::BookmarkDragData(const std::vector<BookmarkNode*>& nodes) {
  for (size_t i = 0; i < nodes.size(); ++i)
    elements.push_back(Element(nodes[i]));
}

#if defined(OS_WIN)
void BookmarkDragData::Write(Profile* profile, OSExchangeData* data) const {
  RegisterFormat();

  DCHECK(data);

  // If there is only one element and it is a URL, write the URL to the
  // clipboard.
  if (elements.size() == 1 && elements[0].is_url) {
    if (elements[0].url.SchemeIs(chrome::kJavaScriptScheme)) {
      data->SetString(ASCIIToWide(elements[0].url.spec()));
    } else {
      data->SetURL(elements[0].url, elements[0].title);
    }
  }

  Pickle data_pickle;
  WriteToPickle(profile, &data_pickle);

  data->SetPickledData(clipboard_format, data_pickle);
}

bool BookmarkDragData::Read(const OSExchangeData& data) {
  RegisterFormat();

  elements.clear();

  profile_path_.clear();

  if (data.HasFormat(clipboard_format)) {
    Pickle drag_data_pickle;
    if (data.GetPickledData(clipboard_format, &drag_data_pickle)) {
      if (!ReadFromPickle(&drag_data_pickle))
        return false;
    }
  } else {
    // See if there is a URL on the clipboard.
    Element element;
    if (data.GetURLAndTitle(&element.url, &element.title) &&
        element.url.is_valid()) {
      element.is_url = true;
      elements.push_back(element);
    }
  }

  return is_valid();
}
#endif

void BookmarkDragData::WriteToPickle(Profile* profile, Pickle* pickle) const {
#if defined(WCHAR_T_IS_UTF16)
  pickle->WriteWString(
      profile ? profile->GetPath().ToWStringHack() : std::wstring());
#elif defined(WCHAR_T_IS_UTF32)
  pickle->WriteString(
      profile ? profile->GetPath().value() : std::string());
#else
  NOTIMPLEMENTED() << "Impossible encoding situation!";
#endif

  pickle->WriteSize(elements.size());

  for (size_t i = 0; i < elements.size(); ++i)
    elements[i].WriteToPickle(pickle);
}

bool BookmarkDragData::ReadFromPickle(Pickle* pickle) {
  void* data_iterator = NULL;
  size_t element_count;
#if defined(WCHAR_T_IS_UTF16)
  if (pickle->ReadWString(&data_iterator, &profile_path_) &&
#elif defined(WCHAR_T_IS_UTF32)
  if (pickle->ReadString(&data_iterator, &profile_path_) &&
#else
  NOTIMPLEMENTED() << "Impossible encoding situation!";
  if (false &&
#endif
      pickle->ReadSize(&data_iterator, &element_count)) {
    std::vector<Element> tmp_elements;
    tmp_elements.resize(element_count);
    for (size_t i = 0; i < element_count; ++i) {
      if (!tmp_elements[i].ReadFromPickle(pickle, &data_iterator)) {
        return false;
      }
    }
    elements.swap(tmp_elements);
  }

  return true;
}

std::vector<BookmarkNode*> BookmarkDragData::GetNodes(Profile* profile) const {
  std::vector<BookmarkNode*> nodes;

  if (!IsFromProfile(profile))
    return nodes;

  for (size_t i = 0; i < elements.size(); ++i) {
    BookmarkNode* node =
        profile->GetBookmarkModel()->GetNodeByID(elements[i].id_);
    if (!node) {
      nodes.clear();
      return nodes;
    }
    nodes.push_back(node);
  }
  return nodes;
}

BookmarkNode* BookmarkDragData::GetFirstNode(Profile* profile) const {
  std::vector<BookmarkNode*> nodes = GetNodes(profile);
  return nodes.size() == 1 ? nodes[0] : NULL;
}

bool BookmarkDragData::IsFromProfile(Profile* profile) const {
  // An empty path means the data is not associated with any profile.
  return (!profile_path_.empty() &&
#if defined(WCHAR_T_IS_UTF16)
      profile->GetPath().ToWStringHack() == profile_path_);
#elif defined(WCHAR_T_IS_UTF32)
      profile->GetPath().value() == profile_path_);
#endif
}
<commit_msg>Stub out a couple of methods in BookmarkDragData.<commit_after>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/bookmarks/bookmark_drag_data.h"

// TODO(port): Port this file.
#if defined(TOOLKIT_VIEWS)
#include "app/os_exchange_data.h"
#else
#include "chrome/common/temp_scaffolding_stubs.h"
#endif
#include "base/basictypes.h"
#include "base/pickle.h"
#include "base/string_util.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/browser/profile.h"
#include "chrome/common/url_constants.h"

#if defined(OS_WIN)
static CLIPFORMAT clipboard_format = 0;

static void RegisterFormat() {
  if (clipboard_format == 0) {
    clipboard_format = RegisterClipboardFormat(L"chrome/x-bookmark-entries");
    DCHECK(clipboard_format);
  }
}
#endif

BookmarkDragData::Element::Element(BookmarkNode* node)
    : is_url(node->is_url()),
      url(node->GetURL()),
      title(node->GetTitle()),
      id_(node->id()) {
  for (int i = 0; i < node->GetChildCount(); ++i)
    children.push_back(Element(node->GetChild(i)));
}

void BookmarkDragData::Element::WriteToPickle(Pickle* pickle) const {
  pickle->WriteBool(is_url);
  pickle->WriteString(url.spec());
  pickle->WriteWString(title);
  pickle->WriteInt(id_);
  if (!is_url) {
    pickle->WriteSize(children.size());
    for (std::vector<Element>::const_iterator i = children.begin();
         i != children.end(); ++i) {
      i->WriteToPickle(pickle);
    }
  }
}

bool BookmarkDragData::Element::ReadFromPickle(Pickle* pickle,
                                               void** iterator) {
  std::string url_spec;
  if (!pickle->ReadBool(iterator, &is_url) ||
      !pickle->ReadString(iterator, &url_spec) ||
      !pickle->ReadWString(iterator, &title) ||
      !pickle->ReadInt(iterator, &id_)) {
    return false;
  }
  url = GURL(url_spec);
  children.clear();
  if (!is_url) {
    size_t children_count;
    if (!pickle->ReadSize(iterator, &children_count))
      return false;
    children.resize(children_count);
    for (std::vector<Element>::iterator i = children.begin();
         i != children.end(); ++i) {
      if (!i->ReadFromPickle(pickle, iterator))
        return false;
    }
  }
  return true;
}

BookmarkDragData::BookmarkDragData(BookmarkNode* node) {
  elements.push_back(Element(node));
}

BookmarkDragData::BookmarkDragData(const std::vector<BookmarkNode*>& nodes) {
  for (size_t i = 0; i < nodes.size(); ++i)
    elements.push_back(Element(nodes[i]));
}

#if defined(OS_WIN)
void BookmarkDragData::Write(Profile* profile, OSExchangeData* data) const {
  RegisterFormat();

  DCHECK(data);

  // If there is only one element and it is a URL, write the URL to the
  // clipboard.
  if (elements.size() == 1 && elements[0].is_url) {
    if (elements[0].url.SchemeIs(chrome::kJavaScriptScheme)) {
      data->SetString(ASCIIToWide(elements[0].url.spec()));
    } else {
      data->SetURL(elements[0].url, elements[0].title);
    }
  }

  Pickle data_pickle;
  WriteToPickle(profile, &data_pickle);

  data->SetPickledData(clipboard_format, data_pickle);
}

bool BookmarkDragData::Read(const OSExchangeData& data) {
  RegisterFormat();

  elements.clear();

  profile_path_.clear();

  if (data.HasFormat(clipboard_format)) {
    Pickle drag_data_pickle;
    if (data.GetPickledData(clipboard_format, &drag_data_pickle)) {
      if (!ReadFromPickle(&drag_data_pickle))
        return false;
    }
  } else {
    // See if there is a URL on the clipboard.
    Element element;
    if (data.GetURLAndTitle(&element.url, &element.title) &&
        element.url.is_valid()) {
      element.is_url = true;
      elements.push_back(element);
    }
  }

  return is_valid();
}
#elif defined(TOOLKIT_VIEWS)
void BookmarkDragData::Write(Profile* profile, OSExchangeData* data) const {
  NOTIMPLEMENTED();
}

bool BookmarkDragData::Read(const OSExchangeData& data) {
  NOTIMPLEMENTED();
  return false;
}
#endif

void BookmarkDragData::WriteToPickle(Profile* profile, Pickle* pickle) const {
#if defined(WCHAR_T_IS_UTF16)
  pickle->WriteWString(
      profile ? profile->GetPath().ToWStringHack() : std::wstring());
#elif defined(WCHAR_T_IS_UTF32)
  pickle->WriteString(
      profile ? profile->GetPath().value() : std::string());
#else
  NOTIMPLEMENTED() << "Impossible encoding situation!";
#endif

  pickle->WriteSize(elements.size());

  for (size_t i = 0; i < elements.size(); ++i)
    elements[i].WriteToPickle(pickle);
}

bool BookmarkDragData::ReadFromPickle(Pickle* pickle) {
  void* data_iterator = NULL;
  size_t element_count;
#if defined(WCHAR_T_IS_UTF16)
  if (pickle->ReadWString(&data_iterator, &profile_path_) &&
#elif defined(WCHAR_T_IS_UTF32)
  if (pickle->ReadString(&data_iterator, &profile_path_) &&
#else
  NOTIMPLEMENTED() << "Impossible encoding situation!";
  if (false &&
#endif
      pickle->ReadSize(&data_iterator, &element_count)) {
    std::vector<Element> tmp_elements;
    tmp_elements.resize(element_count);
    for (size_t i = 0; i < element_count; ++i) {
      if (!tmp_elements[i].ReadFromPickle(pickle, &data_iterator)) {
        return false;
      }
    }
    elements.swap(tmp_elements);
  }

  return true;
}

std::vector<BookmarkNode*> BookmarkDragData::GetNodes(Profile* profile) const {
  std::vector<BookmarkNode*> nodes;

  if (!IsFromProfile(profile))
    return nodes;

  for (size_t i = 0; i < elements.size(); ++i) {
    BookmarkNode* node =
        profile->GetBookmarkModel()->GetNodeByID(elements[i].id_);
    if (!node) {
      nodes.clear();
      return nodes;
    }
    nodes.push_back(node);
  }
  return nodes;
}

BookmarkNode* BookmarkDragData::GetFirstNode(Profile* profile) const {
  std::vector<BookmarkNode*> nodes = GetNodes(profile);
  return nodes.size() == 1 ? nodes[0] : NULL;
}

bool BookmarkDragData::IsFromProfile(Profile* profile) const {
  // An empty path means the data is not associated with any profile.
  return (!profile_path_.empty() &&
#if defined(WCHAR_T_IS_UTF16)
      profile->GetPath().ToWStringHack() == profile_path_);
#elif defined(WCHAR_T_IS_UTF32)
      profile->GetPath().value() == profile_path_);
#endif
}
<|endoftext|>


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

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

#include "app/resource_bundle.h"
#include "base/callback.h"
#include "chrome/browser/browser_thread.h"
#include "chrome/browser/profile.h"
#include "chrome/common/url_constants.h"
#include "grit/app_resources.h"

DOMUIFavIconSource::DOMUIFavIconSource(Profile* profile)
    : DataSource(chrome::kChromeUIFavIconHost, MessageLoop::current()),
      profile_(profile) {
}

DOMUIFavIconSource::~DOMUIFavIconSource() {
}

void DOMUIFavIconSource::StartDataRequest(const std::string& path,
                                          bool is_off_the_record,
                                          int request_id) {
  FaviconService* favicon_service =
      profile_->GetFaviconService(Profile::EXPLICIT_ACCESS);
  if (favicon_service) {
    FaviconService::Handle handle;
    if (path.empty()) {
      SendDefaultResponse(request_id);
      return;
    }

    if (path.size() > 8 && path.substr(0, 8) == "iconurl/") {
      handle = favicon_service->GetFavicon(
          GURL(path.substr(8)),
          &cancelable_consumer_,
          NewCallback(this, &DOMUIFavIconSource::OnFavIconDataAvailable));
    } else {
      handle = favicon_service->GetFaviconForURL(
          GURL(path),
          &cancelable_consumer_,
          NewCallback(this, &DOMUIFavIconSource::OnFavIconDataAvailable));
    }
    // Attach the ChromeURLDataManager request ID to the history request.
    cancelable_consumer_.SetClientData(favicon_service, handle, request_id);
  } else {
    SendResponse(request_id, NULL);
  }
}

std::string DOMUIFavIconSource::GetMimeType(const std::string&) const {
  // We need to explicitly return a mime type, otherwise if the user tries to
  // drag the image they get no extension.
  return "image/png";
}

void DOMUIFavIconSource::OnFavIconDataAvailable(
    FaviconService::Handle request_handle,
    bool know_favicon,
    scoped_refptr<RefCountedMemory> data,
    bool expired,
    GURL icon_url) {
  FaviconService* favicon_service =
      profile_->GetFaviconService(Profile::EXPLICIT_ACCESS);
  int request_id = cancelable_consumer_.GetClientData(favicon_service,
                                                      request_handle);

  if (know_favicon && data.get() && data->size()) {
    // Forward the data along to the networking system.
    SendResponse(request_id, data);
  } else {
    SendDefaultResponse(request_id);
  }
}

void DOMUIFavIconSource::SendDefaultResponse(int request_id) {
  if (!default_favicon_.get()) {
    default_favicon_ =
        ResourceBundle::GetSharedInstance().LoadDataResourceBytes(
            IDR_DEFAULT_FAVICON);
  }

  SendResponse(request_id, default_favicon_);
}
<commit_msg>DOMUIFavIconSource should use original profile since the incognito profile might go away.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

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

#include "app/resource_bundle.h"
#include "base/callback.h"
#include "chrome/browser/browser_thread.h"
#include "chrome/browser/profile.h"
#include "chrome/common/url_constants.h"
#include "grit/app_resources.h"

DOMUIFavIconSource::DOMUIFavIconSource(Profile* profile)
    : DataSource(chrome::kChromeUIFavIconHost, MessageLoop::current()),
      profile_(profile->GetOriginalProfile()) {
}

DOMUIFavIconSource::~DOMUIFavIconSource() {
}

void DOMUIFavIconSource::StartDataRequest(const std::string& path,
                                          bool is_off_the_record,
                                          int request_id) {
  FaviconService* favicon_service =
      profile_->GetFaviconService(Profile::EXPLICIT_ACCESS);
  if (favicon_service) {
    FaviconService::Handle handle;
    if (path.empty()) {
      SendDefaultResponse(request_id);
      return;
    }

    if (path.size() > 8 && path.substr(0, 8) == "iconurl/") {
      handle = favicon_service->GetFavicon(
          GURL(path.substr(8)),
          &cancelable_consumer_,
          NewCallback(this, &DOMUIFavIconSource::OnFavIconDataAvailable));
    } else {
      handle = favicon_service->GetFaviconForURL(
          GURL(path),
          &cancelable_consumer_,
          NewCallback(this, &DOMUIFavIconSource::OnFavIconDataAvailable));
    }
    // Attach the ChromeURLDataManager request ID to the history request.
    cancelable_consumer_.SetClientData(favicon_service, handle, request_id);
  } else {
    SendResponse(request_id, NULL);
  }
}

std::string DOMUIFavIconSource::GetMimeType(const std::string&) const {
  // We need to explicitly return a mime type, otherwise if the user tries to
  // drag the image they get no extension.
  return "image/png";
}

void DOMUIFavIconSource::OnFavIconDataAvailable(
    FaviconService::Handle request_handle,
    bool know_favicon,
    scoped_refptr<RefCountedMemory> data,
    bool expired,
    GURL icon_url) {
  FaviconService* favicon_service =
      profile_->GetFaviconService(Profile::EXPLICIT_ACCESS);
  int request_id = cancelable_consumer_.GetClientData(favicon_service,
                                                      request_handle);

  if (know_favicon && data.get() && data->size()) {
    // Forward the data along to the networking system.
    SendResponse(request_id, data);
  } else {
    SendDefaultResponse(request_id);
  }
}

void DOMUIFavIconSource::SendDefaultResponse(int request_id) {
  if (!default_favicon_.get()) {
    default_favicon_ =
        ResourceBundle::GetSharedInstance().LoadDataResourceBytes(
            IDR_DEFAULT_FAVICON);
  }

  SendResponse(request_id, default_favicon_);
}
<|endoftext|>


<commit_before>class MyCls {
  void in_foo() {
    vec.x = 0;
  }
  void out_foo();

  struct Vec { int x, y; };
  Vec vec;
};

void MyCls::out_foo() {
  vec.x = 0;
}

// RUN: c-index-test -code-completion-at=%s:3:9 %s | FileCheck %s
// RUN: c-index-test -code-completion-at=%s:12:7 %s | FileCheck %s
// CHECK:      CXXMethod:{ResultType MyCls::Vec &}{TypedText operator=}{LeftParen (}{Placeholder const MyCls::Vec &}{RightParen )} (34)
// CHECK-NEXT: StructDecl:{TypedText Vec}{Text ::} (75)
// CHECK-NEXT: FieldDecl:{ResultType int}{TypedText x} (35)
// CHECK-NEXT: FieldDecl:{ResultType int}{TypedText y} (35)
// CHECK-NEXT: CXXDestructor:{ResultType void}{TypedText ~Vec}{LeftParen (}{RightParen )} (34)
// CHECK-NEXT: Completion contexts:
// CHECK-NEXT: Dot member access
// CHECK-NEXT: Container Kind: StructDecl
<commit_msg>Test code completion for constructor initializers within the class definition. This already worked; <rdar://problem/10208871>.<commit_after>class MyCls {
  void in_foo() {
    vec.x = 0;
  }
  void out_foo();

  struct Vec { int x, y; };
  Vec vec;
};

void MyCls::out_foo() {
  vec.x = 0;
}

class OtherClass : public MyCls {
public:
  OtherClass(const OtherClass &other) : MyCls(other), value(value) { }

private:
  int value;
  MyCls *object;
};

// RUN: c-index-test -code-completion-at=%s:3:9 %s | FileCheck %s
// RUN: c-index-test -code-completion-at=%s:12:7 %s | FileCheck %s
// CHECK:      CXXMethod:{ResultType MyCls::Vec &}{TypedText operator=}{LeftParen (}{Placeholder const MyCls::Vec &}{RightParen )} (34)
// CHECK-NEXT: StructDecl:{TypedText Vec}{Text ::} (75)
// CHECK-NEXT: FieldDecl:{ResultType int}{TypedText x} (35)
// CHECK-NEXT: FieldDecl:{ResultType int}{TypedText y} (35)
// CHECK-NEXT: CXXDestructor:{ResultType void}{TypedText ~Vec}{LeftParen (}{RightParen )} (34)
// CHECK-NEXT: Completion contexts:
// CHECK-NEXT: Dot member access
// CHECK-NEXT: Container Kind: StructDecl

// RUN: c-index-test -code-completion-at=%s:17:41 %s | FileCheck -check-prefix=CHECK-CTOR-INIT %s
// CHECK-CTOR-INIT: NotImplemented:{TypedText MyCls}{LeftParen (}{Placeholder args}{RightParen )} (7)
// CHECK-CTOR-INIT: MemberRef:{TypedText object}{LeftParen (}{Placeholder args}{RightParen )} (35)
// CHECK-CTOR-INIT: MemberRef:{TypedText value}{LeftParen (}{Placeholder args}{RightParen )} (35)
// RUN: c-index-test -code-completion-at=%s:17:55 %s | FileCheck -check-prefix=CHECK-CTOR-INIT-2 %s
// CHECK-CTOR-INIT-2-NOT: NotImplemented:{TypedText MyCls}{LeftParen (}{Placeholder args}{RightParen )}
// CHECK-CTOR-INIT-2: MemberRef:{TypedText object}{LeftParen (}{Placeholder args}{RightParen )} (35)
// CHECK-CTOR-INIT-2: MemberRef:{TypedText value}{LeftParen (}{Placeholder args}{RightParen )} (7)
<|endoftext|>


<commit_before>#include "TrackedPoint.h"
#include "PointProcessor.h"
#include "Segmentation.h"

namespace sensekit { namespace plugins { namespace hand {

    PointProcessor::PointProcessor(const ScalingCoordinateMapper& mapper) :
        m_mapper(mapper),
        m_trackingBandwidthDepth(150),  //mm
        m_initialBandwidthDepth(450),   //mm
        m_maxMatchDistLostActive(500),  //mm
        m_maxMatchDistDefault(200),     //mm
        m_iterationMaxInitial(1),
        m_iterationMaxTracking(1),
        m_minArea(5000),            //mm^2
        m_maxArea(20000),           //mm^2
        m_areaBandwidth(150),       //mm
        m_areaBandwidthDepth(100)   //mm
    {}

    PointProcessor::~PointProcessor()
    {}

    void PointProcessor::updateTrackedPoints(TrackingMatrices& matrices)
    {
        for (auto iter = m_trackedPoints.begin(); iter != m_trackedPoints.end(); ++iter)
        {
            //TODO take this and make it a method on TrackedPoint
            TrackedPoint& trackedPoint = *iter;
            updateTrackedPoint(matrices, trackedPoint);
        }
    }

    void PointProcessor::reset()
    {
        m_trackedPoints.clear();
        m_nextTrackingId = 0;
    }

    void PointProcessor::updateTrackedPoint(TrackingMatrices& matrices, TrackedPoint& trackedPoint)
    {
        const float width = matrices.depth.cols;
        const float height = matrices.depth.rows;

        trackedPoint.m_inactiveFrameCount++;

        cv::Point seedPosition = trackedPoint.m_position;
        float referenceDepth = trackedPoint.m_worldPosition.z;

        TrackingData updateTrackingData(matrices, seedPosition, referenceDepth, m_trackingBandwidthDepth, trackedPoint.m_type, m_iterationMaxTracking);

        cv::Point newTargetPoint = segmentation::converge_track_point_from_seed(updateTrackingData);

        validateAndUpdateTrackedPoint(matrices, trackedPoint, newTargetPoint);

        //lost a tracked point, try to guess the position using previous position delta for second chance to recover

        if (trackedPoint.m_status != TrackingStatus::Tracking && cv::norm(trackedPoint.m_worldDeltaPosition) > 0)
        {
            auto estimatedWorldPosition = trackedPoint.m_worldPosition + trackedPoint.m_worldDeltaPosition;

            cv::Point3f estimatedPosition = m_mapper.convert_world_to_depth(estimatedWorldPosition);

            seedPosition.x = MAX(0, MIN(width - 1, static_cast<int>(estimatedPosition.x)));
            seedPosition.y = MAX(0, MIN(height - 1, static_cast<int>(estimatedPosition.y)));
            referenceDepth = estimatedPosition.z;

            TrackingData recoverTrackingData(matrices, seedPosition, referenceDepth, m_initialBandwidthDepth, trackedPoint.m_type, m_iterationMaxTracking);

            newTargetPoint = segmentation::converge_track_point_from_seed(recoverTrackingData);
            validateAndUpdateTrackedPoint(matrices, trackedPoint, newTargetPoint);

            if (trackedPoint.m_status == TrackingStatus::Tracking)
            {
                printf("Recovered point %d\n", trackedPoint.m_trackingId);
            }
            else
            {
                /*tracked.m_position = seedPosition;
                  tracked.m_worldPosition = estimatedWorldPosition;
                  tracked.m_worldDeltaPosition = cv::Point3f();*/
            }
        }
    }

    void PointProcessor::validateAndUpdateTrackedPoint(TrackingMatrices& matrices,
                                                       TrackedPoint& trackedPoint,
                                                       const cv::Point& newTargetPoint)
    {
        bool updatedPoint = false;
        const float steadyDist = 150; //mm
        const float maxJumpDist = 450; //mm

        if (newTargetPoint.x != -1 && newTargetPoint.y != -1)
        {
            float depth = matrices.depth.at<float>(newTargetPoint);

            cv::Point3f worldPosition = m_mapper.convert_depth_to_world(newTargetPoint.x, newTargetPoint.y, depth);

            auto dist = cv::norm(worldPosition - trackedPoint.m_worldPosition);
            auto deadbandDist = cv::norm(worldPosition - trackedPoint.m_steadyWorldPosition);

            float area = segmentation::count_neighborhood_area(matrices.layerSegmentation,
                                                               matrices.depth,
                                                               matrices.area,
                                                               newTargetPoint,
                                                               m_areaBandwidth,
                                                               m_areaBandwidthDepth,
                                                               m_mapper);

            if (dist < maxJumpDist && area > m_minArea && area < m_maxArea)
            {
                updatedPoint = true;
                cv::Point3f deltaPosition = worldPosition - trackedPoint.m_worldPosition;
                trackedPoint.m_worldPosition = worldPosition;
                trackedPoint.m_worldDeltaPosition = deltaPosition;

                trackedPoint.m_position = newTargetPoint;
                if (deadbandDist > steadyDist)
                {
                    trackedPoint.m_steadyWorldPosition = worldPosition;
                    trackedPoint.m_inactiveFrameCount = 0;
                }

                if (trackedPoint.m_inactiveFrameCount < 10)
                {
                    trackedPoint.m_activeFrameCount++;
                    if (trackedPoint.m_activeFrameCount > 120)
                    {
                        trackedPoint.m_type = TrackedPointType::ActivePoint;
                    }
                }
            }
        }

        if (trackedPoint.m_status != TrackingStatus::Dead)
        {
            if (updatedPoint)
            {
                trackedPoint.m_status = TrackingStatus::Tracking;
            }
            else
            {
                trackedPoint.m_status = TrackingStatus::Lost;
            }
        }
    }

    bool PointProcessor::isValidPointArea(TrackingMatrices& matrices, cv::Point targetPoint)
    {
        bool validPointArea = false;
        if (targetPoint.x != -1 && targetPoint.y != -1)
        {
            float area = segmentation::count_neighborhood_area(matrices.layerSegmentation,
                                                               matrices.depth,
                                                               matrices.area,
                                                               targetPoint,
                                                               m_areaBandwidth,
                                                               m_areaBandwidthDepth,
                                                               m_mapper);

            if (area > m_minArea && area < m_maxArea)
            {
                validPointArea = true;
            }
        }
        return validPointArea;
    }

    void PointProcessor::removeDuplicatePoints()
    {
        for (auto iter = m_trackedPoints.begin(); iter != m_trackedPoints.end(); ++iter)
        {
            TrackedPoint& tracked = *iter;
            for (auto otherIter = m_trackedPoints.begin(); otherIter != m_trackedPoints.end(); ++otherIter)
            {
                TrackedPoint& otherTracked = *otherIter;
                bool bothNotDead = tracked.m_status != TrackingStatus::Dead && otherTracked.m_status != TrackingStatus::Dead;
                if (tracked.m_trackingId != otherTracked.m_trackingId && bothNotDead && tracked.m_position == otherTracked.m_position)
                {
                    tracked.m_activeFrameCount = MAX(tracked.m_activeFrameCount, otherTracked.m_activeFrameCount);
                    tracked.m_inactiveFrameCount = MIN(tracked.m_inactiveFrameCount, otherTracked.m_inactiveFrameCount);
                    if (otherTracked.m_type == TrackedPointType::ActivePoint && tracked.m_type != TrackedPointType::ActivePoint)
                    {
                        tracked.m_trackingId = otherTracked.m_trackingId;
                        tracked.m_type = TrackedPointType::ActivePoint;
                    }
                    otherTracked.m_status = TrackingStatus::Dead;
                }
            }
        }
    }

    void PointProcessor::removeOldOrDeadPoints()
    {
        const int maxInactiveFrames = 60;
        const int maxInactiveFramesForLostPoints = 240;
        const int maxInactiveFramesForActivePoints = 480;

        for (auto iter = m_trackedPoints.begin(); iter != m_trackedPoints.end();)
        {
            TrackedPoint& tracked = *iter;

            int max = maxInactiveFrames;
            if (tracked.m_type == TrackedPointType::ActivePoint)
            {
                if (tracked.m_status == TrackingStatus::Lost)
                {
                    max = maxInactiveFramesForLostPoints;
                }
                else
                {
                    max = maxInactiveFramesForActivePoints;
                }
            }
            //if inactive for more than a certain number of frames, or dead, remove point
            if (tracked.m_inactiveFrameCount > max || tracked.m_status == TrackingStatus::Dead)
            {
                iter = m_trackedPoints.erase(iter);
            }
            else
            {
                ++iter;
            }
        }
    }

    void PointProcessor::updateTrackedPointOrCreateNewPointFromSeedPosition(TrackingMatrices& matrices,
                                                                            const cv::Point& seedPosition)
    {
        float seedDepth = matrices.depth.at<float>(seedPosition);
        TrackingData trackingData(matrices, seedPosition, seedDepth, m_initialBandwidthDepth, TrackedPointType::CandidatePoint, m_iterationMaxInitial);

        cv::Point targetPoint = segmentation::converge_track_point_from_seed(trackingData);

        bool validPointArea = isValidPointArea(matrices, targetPoint);

        if (validPointArea)
        {
            bool existingPoint = false;

            for (auto iter = m_trackedPoints.begin(); iter != m_trackedPoints.end(); ++iter)
            {
                TrackedPoint& tracked = *iter;
                if (tracked.m_status != TrackingStatus::Dead)
                {
                    float dist = cv::norm(tracked.m_position - targetPoint);
                    float maxDist = m_maxMatchDistDefault;
                    if (tracked.m_type == TrackedPointType::ActivePoint && tracked.m_status == TrackingStatus::Lost)
                    {
                        maxDist = m_maxMatchDistLostActive;
                    }
                    if (dist < maxDist)
                    {
                        tracked.m_inactiveFrameCount = 0;
                        tracked.m_status = TrackingStatus::Tracking;
                        existingPoint = true;
                        break;
                    }
                }
            }
            if (!existingPoint)
            {
                float depth = matrices.depth.at<float>(targetPoint);

                cv::Point3f worldPosition = m_mapper.convert_depth_to_world(targetPoint.x, targetPoint.y, depth);

                TrackedPoint newPoint(targetPoint, worldPosition, m_nextTrackingId);
                newPoint.m_type = TrackedPointType::CandidatePoint;
                newPoint.m_status = TrackingStatus::Tracking;
                ++m_nextTrackingId;
                m_trackedPoints.push_back(newPoint);
            }
        }
    }
}}}
<commit_msg>Fixed major bug in hand tracker -- need to compare world position distances for new points instead of image positions<commit_after>#include "TrackedPoint.h"
#include "PointProcessor.h"
#include "Segmentation.h"

namespace sensekit { namespace plugins { namespace hand {

    PointProcessor::PointProcessor(const ScalingCoordinateMapper& mapper) :
        m_mapper(mapper),
        m_trackingBandwidthDepth(150),  //mm
        m_initialBandwidthDepth(450),   //mm
        m_maxMatchDistLostActive(500),  //mm
        m_maxMatchDistDefault(200),     //mm
        m_iterationMaxInitial(1),
        m_iterationMaxTracking(1),
        m_minArea(5000),            //mm^2
        m_maxArea(20000),           //mm^2
        m_areaBandwidth(150),       //mm
        m_areaBandwidthDepth(100)   //mm
    {}

    PointProcessor::~PointProcessor()
    {}

    void PointProcessor::updateTrackedPoints(TrackingMatrices& matrices)
    {
        for (auto iter = m_trackedPoints.begin(); iter != m_trackedPoints.end(); ++iter)
        {
            //TODO take this and make it a method on TrackedPoint
            TrackedPoint& trackedPoint = *iter;
            updateTrackedPoint(matrices, trackedPoint);
        }
    }

    void PointProcessor::reset()
    {
        m_trackedPoints.clear();
        m_nextTrackingId = 0;
    }

    void PointProcessor::updateTrackedPoint(TrackingMatrices& matrices, TrackedPoint& trackedPoint)
    {
        const float width = matrices.depth.cols;
        const float height = matrices.depth.rows;

        trackedPoint.m_inactiveFrameCount++;

        cv::Point seedPosition = trackedPoint.m_position;
        float referenceDepth = trackedPoint.m_worldPosition.z;

        TrackingData updateTrackingData(matrices, seedPosition, referenceDepth, m_trackingBandwidthDepth, trackedPoint.m_type, m_iterationMaxTracking);

        cv::Point newTargetPoint = segmentation::converge_track_point_from_seed(updateTrackingData);

        validateAndUpdateTrackedPoint(matrices, trackedPoint, newTargetPoint);

        //lost a tracked point, try to guess the position using previous position delta for second chance to recover

        if (trackedPoint.m_status != TrackingStatus::Tracking && cv::norm(trackedPoint.m_worldDeltaPosition) > 0)
        {
            auto estimatedWorldPosition = trackedPoint.m_worldPosition + trackedPoint.m_worldDeltaPosition;

            cv::Point3f estimatedPosition = m_mapper.convert_world_to_depth(estimatedWorldPosition);

            seedPosition.x = MAX(0, MIN(width - 1, static_cast<int>(estimatedPosition.x)));
            seedPosition.y = MAX(0, MIN(height - 1, static_cast<int>(estimatedPosition.y)));
            referenceDepth = estimatedPosition.z;

            TrackingData recoverTrackingData(matrices, seedPosition, referenceDepth, m_initialBandwidthDepth, trackedPoint.m_type, m_iterationMaxTracking);

            newTargetPoint = segmentation::converge_track_point_from_seed(recoverTrackingData);
            validateAndUpdateTrackedPoint(matrices, trackedPoint, newTargetPoint);

            if (trackedPoint.m_status == TrackingStatus::Tracking)
            {
                printf("Recovered point %d\n", trackedPoint.m_trackingId);
            }
            else
            {
                /*tracked.m_position = seedPosition;
                  tracked.m_worldPosition = estimatedWorldPosition;
                  tracked.m_worldDeltaPosition = cv::Point3f();*/
            }
        }
    }

    void PointProcessor::validateAndUpdateTrackedPoint(TrackingMatrices& matrices,
                                                       TrackedPoint& trackedPoint,
                                                       const cv::Point& newTargetPoint)
    {
        bool updatedPoint = false;
        const float steadyDist = 150; //mm
        const float maxJumpDist = 450; //mm

        if (newTargetPoint.x != -1 && newTargetPoint.y != -1)
        {
            float depth = matrices.depth.at<float>(newTargetPoint);

            cv::Point3f worldPosition = m_mapper.convert_depth_to_world(newTargetPoint.x, newTargetPoint.y, depth);

            auto dist = cv::norm(worldPosition - trackedPoint.m_worldPosition);
            auto deadbandDist = cv::norm(worldPosition - trackedPoint.m_steadyWorldPosition);

            float area = segmentation::count_neighborhood_area(matrices.layerSegmentation,
                                                               matrices.depth,
                                                               matrices.area,
                                                               newTargetPoint,
                                                               m_areaBandwidth,
                                                               m_areaBandwidthDepth,
                                                               m_mapper);

            if (dist < maxJumpDist && area > m_minArea && area < m_maxArea)
            {
                updatedPoint = true;
                cv::Point3f deltaPosition = worldPosition - trackedPoint.m_worldPosition;
                trackedPoint.m_worldPosition = worldPosition;
                trackedPoint.m_worldDeltaPosition = deltaPosition;

                trackedPoint.m_position = newTargetPoint;
                if (deadbandDist > steadyDist)
                {
                    trackedPoint.m_steadyWorldPosition = worldPosition;
                    trackedPoint.m_inactiveFrameCount = 0;
                }

                if (trackedPoint.m_inactiveFrameCount < 10)
                {
                    trackedPoint.m_activeFrameCount++;
                    if (trackedPoint.m_activeFrameCount > 120)
                    {
                        trackedPoint.m_type = TrackedPointType::ActivePoint;
                    }
                }
            }
        }

        if (trackedPoint.m_status != TrackingStatus::Dead)
        {
            if (updatedPoint)
            {
                trackedPoint.m_status = TrackingStatus::Tracking;
            }
            else
            {
                trackedPoint.m_status = TrackingStatus::Lost;
            }
        }
    }

    bool PointProcessor::isValidPointArea(TrackingMatrices& matrices, cv::Point targetPoint)
    {
        bool validPointArea = false;
        if (targetPoint.x != -1 && targetPoint.y != -1)
        {
            float area = segmentation::count_neighborhood_area(matrices.layerSegmentation,
                                                               matrices.depth,
                                                               matrices.area,
                                                               targetPoint,
                                                               m_areaBandwidth,
                                                               m_areaBandwidthDepth,
                                                               m_mapper);

            if (area > m_minArea && area < m_maxArea)
            {
                validPointArea = true;
            }
        }
        return validPointArea;
    }

    void PointProcessor::removeDuplicatePoints()
    {
        for (auto iter = m_trackedPoints.begin(); iter != m_trackedPoints.end(); ++iter)
        {
            TrackedPoint& tracked = *iter;
            for (auto otherIter = m_trackedPoints.begin(); otherIter != m_trackedPoints.end(); ++otherIter)
            {
                TrackedPoint& otherTracked = *otherIter;
                bool bothNotDead = tracked.m_status != TrackingStatus::Dead && otherTracked.m_status != TrackingStatus::Dead;
                if (tracked.m_trackingId != otherTracked.m_trackingId && bothNotDead && tracked.m_position == otherTracked.m_position)
                {
                    tracked.m_activeFrameCount = MAX(tracked.m_activeFrameCount, otherTracked.m_activeFrameCount);
                    tracked.m_inactiveFrameCount = MIN(tracked.m_inactiveFrameCount, otherTracked.m_inactiveFrameCount);
                    if (otherTracked.m_type == TrackedPointType::ActivePoint && tracked.m_type != TrackedPointType::ActivePoint)
                    {
                        tracked.m_trackingId = otherTracked.m_trackingId;
                        tracked.m_type = TrackedPointType::ActivePoint;
                    }
                    otherTracked.m_status = TrackingStatus::Dead;
                }
            }
        }
    }

    void PointProcessor::removeOldOrDeadPoints()
    {
        const int maxInactiveFrames = 60;
        const int maxInactiveFramesForLostPoints = 240;
        const int maxInactiveFramesForActivePoints = 480;

        for (auto iter = m_trackedPoints.begin(); iter != m_trackedPoints.end();)
        {
            TrackedPoint& tracked = *iter;

            int max = maxInactiveFrames;
            if (tracked.m_type == TrackedPointType::ActivePoint)
            {
                if (tracked.m_status == TrackingStatus::Lost)
                {
                    max = maxInactiveFramesForLostPoints;
                }
                else
                {
                    max = maxInactiveFramesForActivePoints;
                }
            }
            //if inactive for more than a certain number of frames, or dead, remove point
            if (tracked.m_inactiveFrameCount > max || tracked.m_status == TrackingStatus::Dead)
            {
                iter = m_trackedPoints.erase(iter);
            }
            else
            {
                ++iter;
            }
        }
    }

    void PointProcessor::updateTrackedPointOrCreateNewPointFromSeedPosition(TrackingMatrices& matrices,
                                                                            const cv::Point& seedPosition)
    {
        float seedDepth = matrices.depth.at<float>(seedPosition);
        TrackingData trackingData(matrices, seedPosition, seedDepth, m_initialBandwidthDepth, TrackedPointType::CandidatePoint, m_iterationMaxInitial);

        cv::Point targetPoint = segmentation::converge_track_point_from_seed(trackingData);

        bool validPointArea = isValidPointArea(matrices, targetPoint);

        if (targetPoint.x != -1 && targetPoint.y != -1 && validPointArea)
        {
            bool existingPoint = false;

            float depth = matrices.depth.at<float>(targetPoint);

            cv::Point3f worldPosition = m_mapper.convert_depth_to_world(targetPoint.x,
                                                                                targetPoint.y,
                                                                                depth);

            for (auto iter = m_trackedPoints.begin(); iter != m_trackedPoints.end(); ++iter)
            {
                TrackedPoint& tracked = *iter;
                if (tracked.m_status != TrackingStatus::Dead)
                {
                    float dist = cv::norm(tracked.m_worldPosition - worldPosition);
                    float maxDist = m_maxMatchDistDefault;
                    if (tracked.m_type == TrackedPointType::ActivePoint && tracked.m_status == TrackingStatus::Lost)
                    {
                        maxDist = m_maxMatchDistLostActive;
                    }
                    if (dist < maxDist)
                    {
                        tracked.m_inactiveFrameCount = 0;
                        tracked.m_status = TrackingStatus::Tracking;
                        existingPoint = true;
                        break;
                    }
                }
            }
            if (!existingPoint)
            {
                TrackedPoint newPoint(targetPoint, worldPosition, m_nextTrackingId);
                newPoint.m_type = TrackedPointType::CandidatePoint;
                newPoint.m_status = TrackingStatus::Tracking;
                ++m_nextTrackingId;
                m_trackedPoints.push_back(newPoint);
            }
        }
    }
}}}
<|endoftext|>