<commit_before>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: textparagraphpropertiescontext.cxx,v $
 * $Revision: 1.4 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#include "oox/drawingml/textparagraphpropertiescontext.hxx"

#include <com/sun/star/text/WritingMode.hpp>
#include <com/sun/star/awt/FontDescriptor.hpp>

#include "oox/drawingml/colorchoicecontext.hxx"
#include "oox/drawingml/textcharacterpropertiescontext.hxx"
#include "oox/drawingml/drawingmltypes.hxx"
#include "oox/helper/attributelist.hxx"
#include "oox/core/namespaces.hxx"
#include "textspacingcontext.hxx"
#include "textfontcontext.hxx"
#include "texttabstoplistcontext.hxx"
#include "tokens.hxx"

using ::rtl::OUString;
using namespace ::oox::core;
using ::com::sun::star::awt::FontDescriptor;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::xml::sax;
using namespace ::com::sun::star::style;
using namespace ::com::sun::star::text;

namespace oox { namespace drawingml {

// CT_TextParagraphProperties
TextParagraphPropertiesContext::TextParagraphPropertiesContext( ContextHandler& rParent,
                                                                const Reference< XFastAttributeList >& xAttribs,
                                                                TextParagraphProperties& rTextParagraphProperties )
: ContextHandler( rParent )
, mrTextParagraphProperties( rTextParagraphProperties )
, mrSpaceBefore( rTextParagraphProperties.getParaTopMargin() )
, mrSpaceAfter( rTextParagraphProperties.getParaBottomMargin() )
, mrBulletList( rTextParagraphProperties.getBulletList() )
{
    OUString sValue;
    AttributeList attribs( xAttribs );

    PropertyMap& rPropertyMap( mrTextParagraphProperties.getTextParagraphPropertyMap() );

    // ST_TextAlignType
    if ( xAttribs->hasAttribute( XML_algn ) )
    {
        sal_Int32 nAlign = xAttribs->getOptionalValueToken( XML_algn, XML_l );
        const OUString sParaAdjust( CREATE_OUSTRING( "ParaAdjust" ) );
        rPropertyMap[ sParaAdjust ] <<= GetParaAdjust( nAlign );
    }
//  OSL_TRACE( "OOX: para adjust %d", GetParaAdjust( nAlign ));
    // TODO see to do the same with RubyAdjust

    // ST_Coordinate32
//  sValue = xAttribs->getOptionalValue( XML_defTabSz );    SJ: we need to be able to set the default tab size for each text object,
//                                                          this is possible at the moment only for the whole document.
//  sal_Int32 nDefTabSize = ( sValue.getLength() == 0 ? 0 : GetCoordinate(  sValue ) );
    // TODO

//  bool bEaLineBrk = attribs.getBool( XML_eaLnBrk, true );
    if ( xAttribs->hasAttribute( XML_latinLnBrk ) )
    {
        bool bLatinLineBrk = attribs.getBool( XML_latinLnBrk, true );
        const OUString sParaIsHyphenation( CREATE_OUSTRING( "ParaIsHyphenation" ) );
        rPropertyMap[ sParaIsHyphenation ] <<= bLatinLineBrk;
    }
    // TODO see what to do with Asian hyphenation

    // ST_TextFontAlignType
    // TODO
//  sal_Int32 nFontAlign = xAttribs->getOptionalValueToken( XML_fontAlgn, XML_base );

    if ( xAttribs->hasAttribute( XML_hangingPunct ) )
    {
        bool bHangingPunct = attribs.getBool( XML_hangingPunct, false );
        const OUString sParaIsHangingPunctuation( CREATE_OUSTRING( "ParaIsHangingPunctuation" ) );
        rPropertyMap[ sParaIsHangingPunctuation ] <<= bHangingPunct;
    }

  // ST_Coordinate
    if ( xAttribs->hasAttribute( XML_indent ) )
    {
        sValue = xAttribs->getOptionalValue( XML_indent );
        const OUString sParaFirstLineIndent( CREATE_OUSTRING( "ParaFirstLineIndent" ) );
        rPropertyMap[ sParaFirstLineIndent ] <<= ( sValue.getLength() == 0 ? 0 : GetCoordinate(  sValue ) );
    }

  // ST_TextIndentLevelType
    // -1 is an invalid value and denote the lack of level
    sal_Int32 nLevel = attribs.getInteger( XML_lvl, 0 );
    if( nLevel > 8 || nLevel < 0 )
    {
        nLevel = 0;
    }

    mrTextParagraphProperties.setLevel( static_cast< sal_Int16 >( nLevel ) );

    char name[] = "Outline X";
    name[8] = static_cast<char>( '1' + nLevel );
    const OUString sStyleNameValue( rtl::OUString::createFromAscii( name ) );
    mrBulletList.setStyleName( sStyleNameValue );

    // ST_TextMargin
    // ParaLeftMargin
    if ( xAttribs->hasAttribute( XML_marL ) )
    {
        sValue = xAttribs->getOptionalValue( XML_marL );
        sal_Int32 nMarL = ( sValue.getLength() == 0 ? 0 : GetCoordinate(  sValue ) );
        const OUString sParaLeftMargin( CREATE_OUSTRING( "ParaLeftMargin" ) );
        rPropertyMap[ sParaLeftMargin ] <<= nMarL;
    }

    // ParaRightMargin
    if ( xAttribs->hasAttribute( XML_marR ) )
    {
        sValue = xAttribs->getOptionalValue( XML_marR );
        sal_Int32 nMarR  = ( sValue.getLength() == 0 ? 0 : GetCoordinate( sValue ) );
        const OUString sParaRightMargin( CREATE_OUSTRING( "ParaRightMargin" ) );
        rPropertyMap[ sParaRightMargin ] <<= nMarR;
    }

    if ( xAttribs->hasAttribute( XML_rtl ) )
    {
        bool bRtl = attribs.getBool( XML_rtl, false );
        const OUString sTextWritingMode( CREATE_OUSTRING( "TextWritingMode" ) );
        rPropertyMap[ sTextWritingMode ] <<= ( bRtl ? WritingMode_RL_TB : WritingMode_LR_TB );
    }
}

TextParagraphPropertiesContext::~TextParagraphPropertiesContext()
{
    PropertyMap& rPropertyMap( mrTextParagraphProperties.getTextParagraphPropertyMap() );
    if ( maLineSpacing.bHasValue )
    {
        const OUString sParaLineSpacing( CREATE_OUSTRING( "ParaLineSpacing" ) );
        //OSL_TRACE( "OOX: ParaLineSpacing unit = %d, value = %d", maLineSpacing.nUnit, maLineSpacing.nValue );
        rPropertyMap[ sParaLineSpacing ] <<= maLineSpacing.toLineSpacing();
    }
    ::std::list< TabStop >::size_type nTabCount = maTabList.size();
    if( nTabCount != 0 )
    {
        Sequence< TabStop > aSeq( nTabCount );
        TabStop * aArray = aSeq.getArray();
        OSL_ENSURE( aArray != NULL, "sequence array is NULL" );
        ::std::copy( maTabList.begin(), maTabList.end(), aArray );
        const OUString sParaTabStops( CREATE_OUSTRING( "ParaTabStops" ) );
        rPropertyMap[ sParaTabStops ] <<= aSeq;
    }
    if( mrBulletList.is() )
    {
        const rtl::OUString sIsNumbering( CREATE_OUSTRING( "IsNumbering" ) );
        rPropertyMap[ sIsNumbering ] <<= sal_True;
    }
    sal_Int16 nLevel = mrTextParagraphProperties.getLevel();
//  OSL_TRACE("OOX: numbering level = %d", nLevel );
    const OUString sNumberingLevel( CREATE_OUSTRING( "NumberingLevel" ) );
    rPropertyMap[ sNumberingLevel ] <<= (sal_Int16)nLevel;
    sal_Bool bTmp = sal_True;
    const OUString sNumberingIsNumber( CREATE_OUSTRING( "NumberingIsNumber" ) );
    rPropertyMap[ sNumberingIsNumber ] <<= bTmp;
}

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

void TextParagraphPropertiesContext::endFastElement( sal_Int32 ) throw (SAXException, RuntimeException)
{
}

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

Reference< XFastContextHandler > TextParagraphPropertiesContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& rXAttributes ) throw (SAXException, RuntimeException)
{
    Reference< XFastContextHandler > xRet;
    switch( aElementToken )
    {
        case NMSP_DRAWINGML|XML_lnSpc:          // CT_TextSpacing
            xRet.set( new TextSpacingContext( *this, maLineSpacing ) );
            break;
        case NMSP_DRAWINGML|XML_spcBef:         // CT_TextSpacing
            xRet.set( new TextSpacingContext( *this, mrSpaceBefore ) );
            break;
        case NMSP_DRAWINGML|XML_spcAft:         // CT_TextSpacing
            xRet.set( new TextSpacingContext( *this, mrSpaceAfter ) );
            break;

        // EG_TextBulletColor
        case NMSP_DRAWINGML|XML_buClrTx:        // CT_TextBulletColorFollowText ???
            mrBulletList.mbBulletColorFollowText <<= sal_True;
            break;
        case NMSP_DRAWINGML|XML_buClr:          // CT_Color
            xRet.set( new colorChoiceContext( *this, *mrBulletList.maBulletColorPtr ) );
            break;

        // EG_TextBulletSize
        case NMSP_DRAWINGML|XML_buSzTx:         // CT_TextBulletSizeFollowText
            mrBulletList.setBulletSize(100);
            break;
        case NMSP_DRAWINGML|XML_buSzPct:        // CT_TextBulletSizePercent
            mrBulletList.setBulletSize( static_cast<sal_Int16>( GetPercent( rXAttributes->getOptionalValue( XML_val ) ) / 1000 ) );
            break;
        case NMSP_DRAWINGML|XML_buSzPts:        // CT_TextBulletSizePoint
            mrBulletList.setBulletSize(0);
            mrBulletList.setFontSize( static_cast<sal_Int16>(GetTextSize( rXAttributes->getOptionalValue( XML_val ) ) ) );
            break;

        // EG_TextBulletTypeface
        case NMSP_DRAWINGML|XML_buFontTx:       // CT_TextBulletTypefaceFollowText
            mrBulletList.mbBulletFontFollowText <<= sal_True;
            break;
        case NMSP_DRAWINGML|XML_buFont:         // CT_TextFont
            xRet.set( new TextFontContext( *this, aElementToken, rXAttributes, mrBulletList.maBulletFont ) );
            break;

        // EG_TextBullet
        case NMSP_DRAWINGML|XML_buNone:         // CT_TextNoBullet
            mrBulletList.setNone();
            break;
        case NMSP_DRAWINGML|XML_buAutoNum:      // CT_TextAutonumberBullet
        {
            AttributeList attribs( rXAttributes );
            try {
                sal_Int32 nType = rXAttributes->getValueToken( XML_type );
                sal_Int32 nStartAt = attribs.getInteger( XML_startAt, 1 );
                if( nStartAt > 32767 )
                {
                    nStartAt = 32767;
                }
                else if( nStartAt < 1 )
                {
                    nStartAt = 1;
                }
                mrBulletList.setStartAt( nStartAt );
                mrBulletList.setType( nType );
            }
            catch(SAXException& /* e */ )
            {
                OSL_TRACE("OOX: SAXException in XML_buAutoNum");
            }
            break;
        }
        case NMSP_DRAWINGML|XML_buChar:         // CT_TextCharBullet
            try {
                mrBulletList.setBulletChar( rXAttributes->getValue( XML_char ) );
            }
            catch(SAXException& /* e */)
            {
                OSL_TRACE("OOX: SAXException in XML_buChar");
            }
            break;
        case NMSP_DRAWINGML|XML_buBlip:         // CT_TextBlipBullet
            // TODO
            break;

        case NMSP_DRAWINGML|XML_tabLst:         // CT_TextTabStopList
            xRet.set( new TextTabStopListContext( *this, maTabList ) );
            break;
        case NMSP_DRAWINGML|XML_defRPr:         // CT_TextCharacterProperties
            xRet.set( new TextCharacterPropertiesContext( *this, rXAttributes, *mrTextParagraphProperties.getTextCharacterProperties() ) );
            break;
    }
    if ( !xRet.is() )
        xRet.set( this );
    return xRet;
}

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

} }

<commit_msg>INTEGRATION: CWS ooxtablefilter (1.3.2); FILE MERGED 2008/06/10 09:52:24 sj 1.3.2.2: RESYNC: (1.3-1.4); FILE MERGED 2008/04/02 17:43:49 sj 1.3.2.1: added table import<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: textparagraphpropertiescontext.cxx,v $
 * $Revision: 1.5 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#include "oox/drawingml/textparagraphpropertiescontext.hxx"

#include <com/sun/star/text/WritingMode.hpp>
#include <com/sun/star/awt/FontDescriptor.hpp>

#include "oox/drawingml/colorchoicecontext.hxx"
#include "oox/drawingml/textcharacterpropertiescontext.hxx"
#include "oox/drawingml/drawingmltypes.hxx"
#include "oox/drawingml/textfontcontext.hxx"
#include "oox/helper/attributelist.hxx"
#include "oox/core/namespaces.hxx"
#include "textspacingcontext.hxx"
#include "texttabstoplistcontext.hxx"
#include "tokens.hxx"

using ::rtl::OUString;
using namespace ::oox::core;
using ::com::sun::star::awt::FontDescriptor;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::xml::sax;
using namespace ::com::sun::star::style;
using namespace ::com::sun::star::text;

namespace oox { namespace drawingml {

// CT_TextParagraphProperties
TextParagraphPropertiesContext::TextParagraphPropertiesContext( ContextHandler& rParent,
                                                                const Reference< XFastAttributeList >& xAttribs,
                                                                TextParagraphProperties& rTextParagraphProperties )
: ContextHandler( rParent )
, mrTextParagraphProperties( rTextParagraphProperties )
, mrSpaceBefore( rTextParagraphProperties.getParaTopMargin() )
, mrSpaceAfter( rTextParagraphProperties.getParaBottomMargin() )
, mrBulletList( rTextParagraphProperties.getBulletList() )
{
    OUString sValue;
    AttributeList attribs( xAttribs );

    PropertyMap& rPropertyMap( mrTextParagraphProperties.getTextParagraphPropertyMap() );

    // ST_TextAlignType
    if ( xAttribs->hasAttribute( XML_algn ) )
    {
        sal_Int32 nAlign = xAttribs->getOptionalValueToken( XML_algn, XML_l );
        const OUString sParaAdjust( CREATE_OUSTRING( "ParaAdjust" ) );
        rPropertyMap[ sParaAdjust ] <<= GetParaAdjust( nAlign );
    }
//  OSL_TRACE( "OOX: para adjust %d", GetParaAdjust( nAlign ));
    // TODO see to do the same with RubyAdjust

    // ST_Coordinate32
//  sValue = xAttribs->getOptionalValue( XML_defTabSz );    SJ: we need to be able to set the default tab size for each text object,
//                                                          this is possible at the moment only for the whole document.
//  sal_Int32 nDefTabSize = ( sValue.getLength() == 0 ? 0 : GetCoordinate(  sValue ) );
    // TODO

//  bool bEaLineBrk = attribs.getBool( XML_eaLnBrk, true );
    if ( xAttribs->hasAttribute( XML_latinLnBrk ) )
    {
        bool bLatinLineBrk = attribs.getBool( XML_latinLnBrk, true );
        const OUString sParaIsHyphenation( CREATE_OUSTRING( "ParaIsHyphenation" ) );
        rPropertyMap[ sParaIsHyphenation ] <<= bLatinLineBrk;
    }
    // TODO see what to do with Asian hyphenation

    // ST_TextFontAlignType
    // TODO
//  sal_Int32 nFontAlign = xAttribs->getOptionalValueToken( XML_fontAlgn, XML_base );

    if ( xAttribs->hasAttribute( XML_hangingPunct ) )
    {
        bool bHangingPunct = attribs.getBool( XML_hangingPunct, false );
        const OUString sParaIsHangingPunctuation( CREATE_OUSTRING( "ParaIsHangingPunctuation" ) );
        rPropertyMap[ sParaIsHangingPunctuation ] <<= bHangingPunct;
    }

  // ST_Coordinate
    if ( xAttribs->hasAttribute( XML_indent ) )
    {
        sValue = xAttribs->getOptionalValue( XML_indent );
        const OUString sParaFirstLineIndent( CREATE_OUSTRING( "ParaFirstLineIndent" ) );
        rPropertyMap[ sParaFirstLineIndent ] <<= ( sValue.getLength() == 0 ? 0 : GetCoordinate(  sValue ) );
    }

  // ST_TextIndentLevelType
    // -1 is an invalid value and denote the lack of level
    sal_Int32 nLevel = attribs.getInteger( XML_lvl, 0 );
    if( nLevel > 8 || nLevel < 0 )
    {
        nLevel = 0;
    }

    mrTextParagraphProperties.setLevel( static_cast< sal_Int16 >( nLevel ) );

    char name[] = "Outline X";
    name[8] = static_cast<char>( '1' + nLevel );
    const OUString sStyleNameValue( rtl::OUString::createFromAscii( name ) );
    mrBulletList.setStyleName( sStyleNameValue );

    // ST_TextMargin
    // ParaLeftMargin
    if ( xAttribs->hasAttribute( XML_marL ) )
    {
        sValue = xAttribs->getOptionalValue( XML_marL );
        sal_Int32 nMarL = ( sValue.getLength() == 0 ? 0 : GetCoordinate(  sValue ) );
        const OUString sParaLeftMargin( CREATE_OUSTRING( "ParaLeftMargin" ) );
        rPropertyMap[ sParaLeftMargin ] <<= nMarL;
    }

    // ParaRightMargin
    if ( xAttribs->hasAttribute( XML_marR ) )
    {
        sValue = xAttribs->getOptionalValue( XML_marR );
        sal_Int32 nMarR  = ( sValue.getLength() == 0 ? 0 : GetCoordinate( sValue ) );
        const OUString sParaRightMargin( CREATE_OUSTRING( "ParaRightMargin" ) );
        rPropertyMap[ sParaRightMargin ] <<= nMarR;
    }

    if ( xAttribs->hasAttribute( XML_rtl ) )
    {
        bool bRtl = attribs.getBool( XML_rtl, false );
        const OUString sTextWritingMode( CREATE_OUSTRING( "TextWritingMode" ) );
        rPropertyMap[ sTextWritingMode ] <<= ( bRtl ? WritingMode_RL_TB : WritingMode_LR_TB );
    }
}

TextParagraphPropertiesContext::~TextParagraphPropertiesContext()
{
    PropertyMap& rPropertyMap( mrTextParagraphProperties.getTextParagraphPropertyMap() );
    if ( maLineSpacing.bHasValue )
    {
        const OUString sParaLineSpacing( CREATE_OUSTRING( "ParaLineSpacing" ) );
        //OSL_TRACE( "OOX: ParaLineSpacing unit = %d, value = %d", maLineSpacing.nUnit, maLineSpacing.nValue );
        rPropertyMap[ sParaLineSpacing ] <<= maLineSpacing.toLineSpacing();
    }
    ::std::list< TabStop >::size_type nTabCount = maTabList.size();
    if( nTabCount != 0 )
    {
        Sequence< TabStop > aSeq( nTabCount );
        TabStop * aArray = aSeq.getArray();
        OSL_ENSURE( aArray != NULL, "sequence array is NULL" );
        ::std::copy( maTabList.begin(), maTabList.end(), aArray );
        const OUString sParaTabStops( CREATE_OUSTRING( "ParaTabStops" ) );
        rPropertyMap[ sParaTabStops ] <<= aSeq;
    }
    if( mrBulletList.is() )
    {
        const rtl::OUString sIsNumbering( CREATE_OUSTRING( "IsNumbering" ) );
        rPropertyMap[ sIsNumbering ] <<= sal_True;
    }
    sal_Int16 nLevel = mrTextParagraphProperties.getLevel();
//  OSL_TRACE("OOX: numbering level = %d", nLevel );
    const OUString sNumberingLevel( CREATE_OUSTRING( "NumberingLevel" ) );
    rPropertyMap[ sNumberingLevel ] <<= (sal_Int16)nLevel;
    sal_Bool bTmp = sal_True;
    const OUString sNumberingIsNumber( CREATE_OUSTRING( "NumberingIsNumber" ) );
    rPropertyMap[ sNumberingIsNumber ] <<= bTmp;
}

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

void TextParagraphPropertiesContext::endFastElement( sal_Int32 ) throw (SAXException, RuntimeException)
{
}

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

Reference< XFastContextHandler > TextParagraphPropertiesContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& rXAttributes ) throw (SAXException, RuntimeException)
{
    Reference< XFastContextHandler > xRet;
    switch( aElementToken )
    {
        case NMSP_DRAWINGML|XML_lnSpc:          // CT_TextSpacing
            xRet.set( new TextSpacingContext( *this, maLineSpacing ) );
            break;
        case NMSP_DRAWINGML|XML_spcBef:         // CT_TextSpacing
            xRet.set( new TextSpacingContext( *this, mrSpaceBefore ) );
            break;
        case NMSP_DRAWINGML|XML_spcAft:         // CT_TextSpacing
            xRet.set( new TextSpacingContext( *this, mrSpaceAfter ) );
            break;

        // EG_TextBulletColor
        case NMSP_DRAWINGML|XML_buClrTx:        // CT_TextBulletColorFollowText ???
            mrBulletList.mbBulletColorFollowText <<= sal_True;
            break;
        case NMSP_DRAWINGML|XML_buClr:          // CT_Color
            xRet.set( new colorChoiceContext( *this, *mrBulletList.maBulletColorPtr ) );
            break;

        // EG_TextBulletSize
        case NMSP_DRAWINGML|XML_buSzTx:         // CT_TextBulletSizeFollowText
            mrBulletList.setBulletSize(100);
            break;
        case NMSP_DRAWINGML|XML_buSzPct:        // CT_TextBulletSizePercent
            mrBulletList.setBulletSize( static_cast<sal_Int16>( GetPercent( rXAttributes->getOptionalValue( XML_val ) ) / 1000 ) );
            break;
        case NMSP_DRAWINGML|XML_buSzPts:        // CT_TextBulletSizePoint
            mrBulletList.setBulletSize(0);
            mrBulletList.setFontSize( static_cast<sal_Int16>(GetTextSize( rXAttributes->getOptionalValue( XML_val ) ) ) );
            break;

        // EG_TextBulletTypeface
        case NMSP_DRAWINGML|XML_buFontTx:       // CT_TextBulletTypefaceFollowText
            mrBulletList.mbBulletFontFollowText <<= sal_True;
            break;
        case NMSP_DRAWINGML|XML_buFont:         // CT_TextFont
            xRet.set( new TextFontContext( *this, aElementToken, rXAttributes, mrBulletList.maBulletFont ) );
            break;

        // EG_TextBullet
        case NMSP_DRAWINGML|XML_buNone:         // CT_TextNoBullet
            mrBulletList.setNone();
            break;
        case NMSP_DRAWINGML|XML_buAutoNum:      // CT_TextAutonumberBullet
        {
            AttributeList attribs( rXAttributes );
            try {
                sal_Int32 nType = rXAttributes->getValueToken( XML_type );
                sal_Int32 nStartAt = attribs.getInteger( XML_startAt, 1 );
                if( nStartAt > 32767 )
                {
                    nStartAt = 32767;
                }
                else if( nStartAt < 1 )
                {
                    nStartAt = 1;
                }
                mrBulletList.setStartAt( nStartAt );
                mrBulletList.setType( nType );
            }
            catch(SAXException& /* e */ )
            {
                OSL_TRACE("OOX: SAXException in XML_buAutoNum");
            }
            break;
        }
        case NMSP_DRAWINGML|XML_buChar:         // CT_TextCharBullet
            try {
                mrBulletList.setBulletChar( rXAttributes->getValue( XML_char ) );
            }
            catch(SAXException& /* e */)
            {
                OSL_TRACE("OOX: SAXException in XML_buChar");
            }
            break;
        case NMSP_DRAWINGML|XML_buBlip:         // CT_TextBlipBullet
            // TODO
            break;

        case NMSP_DRAWINGML|XML_tabLst:         // CT_TextTabStopList
            xRet.set( new TextTabStopListContext( *this, maTabList ) );
            break;
        case NMSP_DRAWINGML|XML_defRPr:         // CT_TextCharacterProperties
            xRet.set( new TextCharacterPropertiesContext( *this, rXAttributes, *mrTextParagraphProperties.getTextCharacterProperties() ) );
            break;
    }
    if ( !xRet.is() )
        xRet.set( this );
    return xRet;
}

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

} }

<|endoftext|>


<commit_before>#include "RendererBase.hpp"

#include <iostream>
#include <sstream>
#include <thread>
#include <mutex>
#include <unordered_map>

#include <gtkmm.h>
#include <GL/gl.h>
#include <GL/glu.h>

#include <lcm/lcm-cpp.hpp>
#include <drc_utils/Clock.hpp>

#include <lcmtypes/drc/data_request_list_t.hpp>
#include <lcmtypes/drc/twist_timed_t.hpp>
#include <lcmtypes/drc/map_image_t.hpp>

#include <bot_vis/viewer.h>

// TODO: slow sweep commands

using namespace maps;

class DataControlRenderer : public RendererBase {
protected:
  enum ChannelType {
    ChannelTypeAnonymous,
    ChannelTypeDepthImage,
  };

  struct RequestControl {
    const int mId;
    bool mEnabled;
    double mPeriod;
    typedef std::shared_ptr<RequestControl> Ptr;
  };

  struct TimeKeeper {
    int64_t mLastUpdateTime;
    Gtk::Label* mLabel;
    TimeKeeper() : mLastUpdateTime(-1), mLabel(NULL) {}
  };

  struct LastUpdateChecker {
    DataControlRenderer* mRenderer;
    std::thread mThread;
    bool mIsRunning;

    LastUpdateChecker(DataControlRenderer* iRenderer) : mRenderer(iRenderer) {
      mThread = std::thread(std::ref(*this));
    }

    ~LastUpdateChecker() {
      mIsRunning = false;
      mThread.join();
    }

    void operator()() {
      mIsRunning = true;
      while (mIsRunning) {
        int64_t currentTime = drc::Clock::instance()->getCurrentWallTime();
        std::unordered_map<std::string, TimeKeeper>::const_iterator iter;
        {
          std::lock_guard<std::mutex> lock(mRenderer->mTimeKeepersMutex);
          for (iter = mRenderer->mTimeKeepers.begin();
               iter != mRenderer->mTimeKeepers.end(); ++iter) {
            int64_t lastUpdateTime = iter->second.mLastUpdateTime;
            if (lastUpdateTime < 0) continue;
            int dtSec = (currentTime - lastUpdateTime)/1000000;
            if (dtSec > 0) {
              std::string text = static_cast<std::ostringstream*>
                (&(std::ostringstream() << dtSec) )->str();
              text = "(" + text + "s)";
              iter->second.mLabel->set_text(text);
            }
          }
        }
        std::this_thread::sleep_for(std::chrono::milliseconds(500));
      }
    }
  };

protected:
  Gtk::VBox* mRequestControlBox;
  std::unordered_map<int, RequestControl::Ptr> mRequestControls;
  int mSpinRate;

  std::shared_ptr<LastUpdateChecker> mUpdateChecker;
  std::unordered_map<std::string, ChannelType> mChannels;
  std::unordered_map<std::string, TimeKeeper> mTimeKeepers;
  std::mutex mTimeKeepersMutex;

public:

  DataControlRenderer(BotViewer* iViewer, const int iPriority,
                      const lcm_t* iLcm,
                      const BotParam* iParam, const BotFrames* iFrames)
    : RendererBase("Data Control", iViewer, iPriority, iLcm,
                   iParam, iFrames, 0) {

    // set up robot time clock
    drc::Clock::instance()->setLcm(getLcm());
    drc::Clock::instance()->setVerbose(false);

    // create and show ui widgets
    setupWidgets();

    // create update timers
    mUpdateChecker.reset(new LastUpdateChecker(this));
  }

  ~DataControlRenderer() {
    mUpdateChecker->mIsRunning = false;
    mUpdateChecker.reset();
  }

  void onMessage(const lcm::ReceiveBuffer* iBuf, const std::string& iChannel) {
    std::unordered_map<std::string, ChannelType>::const_iterator channelItem =
      mChannels.find(iChannel);
    if (channelItem == mChannels.end()) return;
    std::string key = iChannel;
    if (channelItem->second == ChannelTypeDepthImage) {
      drc::map_image_t msg;
      if (msg.decode(iBuf->data, 0, iBuf->data_size) < 0) {
        std::cout << "Error decoding " << iChannel << std::endl;
        return;
      }
      key += static_cast<std::ostringstream*>
        (&(std::ostringstream() << msg.view_id) )->str();
    }
    else {
    }
    {
      std::lock_guard<std::mutex> lock(mTimeKeepersMutex);
      mTimeKeepers[key].mLastUpdateTime =
        drc::Clock::instance()->getCurrentWallTime();
      mTimeKeepers[key].mLabel->set_text("");
    }
  }

  void setupWidgets() {
    Gtk::Container* container = getGtkContainer();

    Gtk::Notebook* notebook = Gtk::manage(new Gtk::Notebook());

    // for data requests
    mRequestControlBox = Gtk::manage(new Gtk::VBox());
    typedef drc::data_request_t dr;
    addControl(drc::data_request_t::CAMERA_IMAGE, "Camera Image",
               "CAMERALEFT_COMPRESSED", ChannelTypeAnonymous);
    addControl(drc::data_request_t::MINIMAL_ROBOT_STATE, "Robot State",
               "EST_ROBOT_STATE", ChannelTypeAnonymous);
    addControl(drc::data_request_t::AFFORDANCE_LIST, "Affordance List",
               "AFFORDANCE_LIST", ChannelTypeAnonymous);
    addControl(drc::data_request_t::MAP_CATALOG, "Map Catalog",
               "MAP_CATALOG", ChannelTypeAnonymous);
    addControl(drc::data_request_t::OCTREE_SCENE, "Scene Octree",
               "MAP_OCTREE", ChannelTypeAnonymous);
    addControl(drc::data_request_t::HEIGHT_MAP_SCENE, "Scene Height",
               "MAP_DEPTH", ChannelTypeDepthImage);
    addControl(drc::data_request_t::HEIGHT_MAP_CORRIDOR, "Corridor Height",
               "MAP_DEPTH", ChannelTypeDepthImage);
    addControl(drc::data_request_t::DEPTH_MAP_SCENE, "Scene Depth",
               "MAP_DEPTH", ChannelTypeDepthImage);
    addControl(drc::data_request_t::DEPTH_MAP_WORKSPACE, "Workspace Depth",
               "MAP_DEPTH", ChannelTypeDepthImage);
    Gtk::Button* button = Gtk::manage(new Gtk::Button("Submit Request"));
    button->signal_clicked().connect
      (sigc::mem_fun(*this, &DataControlRenderer::onDataRequestButton));
    mRequestControlBox->add(*button);
    notebook->append_page(*mRequestControlBox, "Data");

    // for sensor control
    Gtk::VBox* sensorControlBox = Gtk::manage(new Gtk::VBox());
    mSpinRate = 15;
    addSpin("Spin Rate (rpm)", mSpinRate, 0, 60, 1, sensorControlBox);
    button = Gtk::manage(new Gtk::Button("Submit Rate"));
    button->signal_clicked().connect
      (sigc::mem_fun(*this, &DataControlRenderer::onRateControlButton));
    sensorControlBox->pack_start(*button, false, false);
    notebook->append_page(*sensorControlBox, "Sensor");

    container->add(*notebook);
    container->show_all();
  }

  void addControl(const int iId, const std::string& iLabel,
                  const std::string& iChannel, const ChannelType iChannelType) {
    Gtk::HBox* box = Gtk::manage(new Gtk::HBox());
    Gtk::CheckButton* check = Gtk::manage(new Gtk::CheckButton());
    Gtk::Label* label = Gtk::manage(new Gtk::Label(iLabel));
    Gtk::SpinButton* spin = Gtk::manage(new Gtk::SpinButton());
    Gtk::Label* ageLabel = Gtk::manage(new Gtk::Label(" "));
    spin->set_range(0, 10);
    spin->set_increments(1, 2);
    spin->set_digits(0);
    box->add(*check);
    box->add(*label);
    box->add(*ageLabel);
    box->add(*spin);
    RequestControl::Ptr group(new RequestControl());
    group->mEnabled = false;
    group->mPeriod = 0;
    bind(check, iLabel + " enable", group->mEnabled);
    bind(spin, iLabel + " period", group->mPeriod);
    mRequestControlBox->add(*box);
    mRequestControls[iId] = group;

    std::string key = iChannel;
    if (iChannelType == ChannelTypeDepthImage) {
      key += static_cast<std::ostringstream*>
        (&(std::ostringstream() << iId) )->str();
    }
    TimeKeeper timeKeeper;
    timeKeeper.mLabel = ageLabel;
    timeKeeper.mLastUpdateTime = -1;
    {
      std::lock_guard<std::mutex> lock(mTimeKeepersMutex);
      mTimeKeepers[key] = timeKeeper;
    }

    if (mChannels.find(iChannel) == mChannels.end()) {
      add(getLcm()->subscribe(iChannel, &DataControlRenderer::onMessage, this));
      mChannels[iChannel] = iChannelType;
    }
  }

  void onDataRequestButton() {
    drc::data_request_list_t msg;
    msg.utime = drc::Clock::instance()->getCurrentTime();
    std::unordered_map<int,RequestControl::Ptr>::const_iterator iter;
    for (iter = mRequestControls.begin();
         iter != mRequestControls.end(); ++iter) {
      if (!iter->second->mEnabled) continue;
      drc::data_request_t req;
      req.type = iter->first;
      req.period = (int)(iter->second->mPeriod*10);
      msg.requests.push_back(req);
    }
    msg.num_requests = msg.requests.size();
    if (msg.num_requests > 0) {
      getLcm()->publish("DATA_REQUEST", &msg);
    }
  }

  void onRateControlButton() {
    const double kPi = 4*atan(1);
    double radiansPerSecond = (double)mSpinRate/60*2*kPi;
    drc::twist_timed_t rate;
    rate.utime = drc::Clock::instance()->getCurrentTime();
    rate.angular_velocity.x = radiansPerSecond;
    rate.angular_velocity.y = 0.0;
    rate.angular_velocity.z = 0.0;
    rate.linear_velocity.x = 0.0;
    rate.linear_velocity.y = 0.0;
    rate.linear_velocity.z = 0.0;
    getLcm()->publish("SCAN_RATE_CMD", &rate);
  }

  void draw() {
    // intentionally left blank
  }
};

// this is the single setup method exposed for integration with the viewer
void data_control_renderer_setup(BotViewer* iViewer,
                                 const int iPriority,
                                 const lcm_t* iLcm,
                                 const BotParam* iParam,
                                 const BotFrames* iFrames) {
  new DataControlRenderer(iViewer, iPriority, iLcm, iParam, iFrames);
}
<commit_msg>moved widget update to main thread<commit_after>#include "RendererBase.hpp"

#include <iostream>
#include <sstream>
#include <thread>
#include <mutex>
#include <unordered_map>

#include <gtkmm.h>
#include <GL/gl.h>
#include <GL/glu.h>

#include <lcm/lcm-cpp.hpp>
#include <drc_utils/Clock.hpp>

#include <lcmtypes/drc/data_request_list_t.hpp>
#include <lcmtypes/drc/twist_timed_t.hpp>
#include <lcmtypes/drc/map_image_t.hpp>

#include <bot_vis/viewer.h>

// TODO: slow sweep commands

using namespace maps;

class DataControlRenderer : public RendererBase {
protected:
  enum ChannelType {
    ChannelTypeAnonymous,
    ChannelTypeDepthImage,
  };

  struct RequestControl {
    const int mId;
    bool mEnabled;
    double mPeriod;
    typedef std::shared_ptr<RequestControl> Ptr;
  };

  struct TimeKeeper {
    int64_t mLastUpdateTime;
    Gtk::Label* mLabel;
    TimeKeeper() : mLastUpdateTime(-1), mLabel(NULL) {}
  };

protected:
  Gtk::VBox* mRequestControlBox;
  std::unordered_map<int, RequestControl::Ptr> mRequestControls;
  int mSpinRate;

  std::unordered_map<std::string, ChannelType> mChannels;
  std::unordered_map<std::string, TimeKeeper> mTimeKeepers;
  std::mutex mTimeKeepersMutex;

public:

  DataControlRenderer(BotViewer* iViewer, const int iPriority,
                      const lcm_t* iLcm,
                      const BotParam* iParam, const BotFrames* iFrames)
    : RendererBase("Data Control", iViewer, iPriority, iLcm,
                   iParam, iFrames, 0) {

    // set up robot time clock
    drc::Clock::instance()->setLcm(getLcm());
    drc::Clock::instance()->setVerbose(false);

    // create and show ui widgets
    setupWidgets();

    // create update timer
    Glib::signal_timeout().connect
      (sigc::mem_fun(*this, &DataControlRenderer::checkTimers), 500);
  }

  ~DataControlRenderer() {
  }

  bool checkTimers() {
    int64_t currentTime = drc::Clock::instance()->getCurrentWallTime();
    std::unordered_map<std::string, TimeKeeper>::const_iterator iter;
    {
      std::lock_guard<std::mutex> lock(mTimeKeepersMutex);
      for (iter = mTimeKeepers.begin(); iter != mTimeKeepers.end(); ++iter) {
	int64_t lastUpdateTime = iter->second.mLastUpdateTime;
	if (lastUpdateTime < 0) continue;
	int dtSec = (currentTime - lastUpdateTime)/1000000;
	if (dtSec > 0) {
	  std::string text = static_cast<std::ostringstream*>
	    (&(std::ostringstream() << dtSec) )->str();
	  text = "(" + text + "s)";
	  iter->second.mLabel->set_text(text);
	}
      }
    }
    return true;
  }

  void onMessage(const lcm::ReceiveBuffer* iBuf, const std::string& iChannel) {
    std::unordered_map<std::string, ChannelType>::const_iterator channelItem =
      mChannels.find(iChannel);
    if (channelItem == mChannels.end()) return;
    std::string key = iChannel;
    if (channelItem->second == ChannelTypeDepthImage) {
      drc::map_image_t msg;
      if (msg.decode(iBuf->data, 0, iBuf->data_size) < 0) {
        std::cout << "Error decoding " << iChannel << std::endl;
        return;
      }
      key += static_cast<std::ostringstream*>
        (&(std::ostringstream() << msg.view_id) )->str();
    }
    else {
    }
    {
      std::lock_guard<std::mutex> lock(mTimeKeepersMutex);
      mTimeKeepers[key].mLastUpdateTime =
        drc::Clock::instance()->getCurrentWallTime();
      mTimeKeepers[key].mLabel->set_text("");
    }
  }

  void setupWidgets() {
    Gtk::Container* container = getGtkContainer();

    Gtk::Notebook* notebook = Gtk::manage(new Gtk::Notebook());

    // for data requests
    mRequestControlBox = Gtk::manage(new Gtk::VBox());
    typedef drc::data_request_t dr;
    addControl(drc::data_request_t::CAMERA_IMAGE, "Camera Image",
               "CAMERALEFT_COMPRESSED", ChannelTypeAnonymous);
    addControl(drc::data_request_t::MINIMAL_ROBOT_STATE, "Robot State",
               "EST_ROBOT_STATE", ChannelTypeAnonymous);
    addControl(drc::data_request_t::AFFORDANCE_LIST, "Affordance List",
               "AFFORDANCE_LIST", ChannelTypeAnonymous);
    addControl(drc::data_request_t::MAP_CATALOG, "Map Catalog",
               "MAP_CATALOG", ChannelTypeAnonymous);
    addControl(drc::data_request_t::OCTREE_SCENE, "Scene Octree",
               "MAP_OCTREE", ChannelTypeAnonymous);
    addControl(drc::data_request_t::HEIGHT_MAP_SCENE, "Scene Height",
               "MAP_DEPTH", ChannelTypeDepthImage);
    addControl(drc::data_request_t::HEIGHT_MAP_CORRIDOR, "Corridor Height",
               "MAP_DEPTH", ChannelTypeDepthImage);
    addControl(drc::data_request_t::DEPTH_MAP_SCENE, "Scene Depth",
               "MAP_DEPTH", ChannelTypeDepthImage);
    addControl(drc::data_request_t::DEPTH_MAP_WORKSPACE, "Workspace Depth",
               "MAP_DEPTH", ChannelTypeDepthImage);
    Gtk::Button* button = Gtk::manage(new Gtk::Button("Submit Request"));
    button->signal_clicked().connect
      (sigc::mem_fun(*this, &DataControlRenderer::onDataRequestButton));
    mRequestControlBox->add(*button);
    notebook->append_page(*mRequestControlBox, "Data");

    // for sensor control
    Gtk::VBox* sensorControlBox = Gtk::manage(new Gtk::VBox());
    mSpinRate = 15;
    addSpin("Spin Rate (rpm)", mSpinRate, 0, 60, 1, sensorControlBox);
    button = Gtk::manage(new Gtk::Button("Submit Rate"));
    button->signal_clicked().connect
      (sigc::mem_fun(*this, &DataControlRenderer::onRateControlButton));
    sensorControlBox->pack_start(*button, false, false);
    notebook->append_page(*sensorControlBox, "Sensor");

    container->add(*notebook);
    container->show_all();
  }

  void addControl(const int iId, const std::string& iLabel,
                  const std::string& iChannel, const ChannelType iChannelType) {
    Gtk::HBox* box = Gtk::manage(new Gtk::HBox());
    Gtk::CheckButton* check = Gtk::manage(new Gtk::CheckButton());
    Gtk::Label* label = Gtk::manage(new Gtk::Label(iLabel));
    Gtk::SpinButton* spin = Gtk::manage(new Gtk::SpinButton());
    Gtk::Label* ageLabel = Gtk::manage(new Gtk::Label(" "));
    spin->set_range(0, 10);
    spin->set_increments(1, 2);
    spin->set_digits(0);
    box->add(*check);
    box->add(*label);
    box->add(*ageLabel);
    box->add(*spin);
    RequestControl::Ptr group(new RequestControl());
    group->mEnabled = false;
    group->mPeriod = 0;
    bind(check, iLabel + " enable", group->mEnabled);
    bind(spin, iLabel + " period", group->mPeriod);
    mRequestControlBox->add(*box);
    mRequestControls[iId] = group;

    std::string key = iChannel;
    if (iChannelType == ChannelTypeDepthImage) {
      key += static_cast<std::ostringstream*>
        (&(std::ostringstream() << iId) )->str();
    }
    TimeKeeper timeKeeper;
    timeKeeper.mLabel = ageLabel;
    timeKeeper.mLastUpdateTime = -1;
    {
      std::lock_guard<std::mutex> lock(mTimeKeepersMutex);
      mTimeKeepers[key] = timeKeeper;
    }

    if (mChannels.find(iChannel) == mChannels.end()) {
      add(getLcm()->subscribe(iChannel, &DataControlRenderer::onMessage, this));
      mChannels[iChannel] = iChannelType;
    }
  }

  void onDataRequestButton() {
    drc::data_request_list_t msg;
    msg.utime = drc::Clock::instance()->getCurrentTime();
    std::unordered_map<int,RequestControl::Ptr>::const_iterator iter;
    for (iter = mRequestControls.begin();
         iter != mRequestControls.end(); ++iter) {
      if (!iter->second->mEnabled) continue;
      drc::data_request_t req;
      req.type = iter->first;
      req.period = (int)(iter->second->mPeriod*10);
      msg.requests.push_back(req);
    }
    msg.num_requests = msg.requests.size();
    if (msg.num_requests > 0) {
      getLcm()->publish("DATA_REQUEST", &msg);
    }
  }

  void onRateControlButton() {
    const double kPi = 4*atan(1);
    double radiansPerSecond = (double)mSpinRate/60*2*kPi;
    drc::twist_timed_t rate;
    rate.utime = drc::Clock::instance()->getCurrentTime();
    rate.angular_velocity.x = radiansPerSecond;
    rate.angular_velocity.y = 0.0;
    rate.angular_velocity.z = 0.0;
    rate.linear_velocity.x = 0.0;
    rate.linear_velocity.y = 0.0;
    rate.linear_velocity.z = 0.0;
    getLcm()->publish("SCAN_RATE_CMD", &rate);
  }

  void draw() {
    // intentionally left blank
  }
};

// this is the single setup method exposed for integration with the viewer
void data_control_renderer_setup(BotViewer* iViewer,
                                 const int iPriority,
                                 const lcm_t* iLcm,
                                 const BotParam* iParam,
                                 const BotFrames* iFrames) {
  new DataControlRenderer(iViewer, iPriority, iLcm, iParam, iFrames);
}
<|endoftext|>


<commit_before>// Copyright (c) 2013 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "atom/browser/browser.h"

#include <atlbase.h>
#include <propkey.h>
#include <windows.h>
#include <shlobj.h>
#include <shobjidl.h>

#include "base/base_paths.h"
#include "base/file_version_info.h"
#include "base/files/file_path.h"
#include "base/memory/scoped_ptr.h"
#include "base/path_service.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/win/win_util.h"
#include "base/win/registry.h"
#include "base/win/windows_version.h"
#include "atom/common/atom_version.h"

namespace atom {

namespace {

const wchar_t kAppUserModelIDFormat[] = L"electron.app.$1";

BOOL CALLBACK WindowsEnumerationHandler(HWND hwnd, LPARAM param) {
  DWORD target_process_id = *reinterpret_cast<DWORD*>(param);
  DWORD process_id = 0;

  GetWindowThreadProcessId(hwnd, &process_id);
  if (process_id == target_process_id) {
    SetFocus(hwnd);
    return FALSE;
  }

  return TRUE;
}

}  // namespace

void Browser::Focus() {
  // On Windows we just focus on the first window found for this process.
  DWORD pid = GetCurrentProcessId();
  EnumWindows(&WindowsEnumerationHandler, reinterpret_cast<LPARAM>(&pid));
}

void Browser::AddRecentDocument(const base::FilePath& path) {
  if (base::win::GetVersion() < base::win::VERSION_WIN7)
    return;

  CComPtr<IShellItem> item;
  HRESULT hr = SHCreateItemFromParsingName(
      path.value().c_str(), NULL, IID_PPV_ARGS(&item));
  if (SUCCEEDED(hr)) {
    SHARDAPPIDINFO info;
    info.psi = item;
    info.pszAppID = GetAppUserModelID();
    SHAddToRecentDocs(SHARD_APPIDINFO, &info);
  }
}

void Browser::ClearRecentDocuments() {
  CComPtr<IApplicationDestinations> destinations;
  if (FAILED(destinations.CoCreateInstance(CLSID_ApplicationDestinations,
                                           NULL, CLSCTX_INPROC_SERVER)))
    return;
  if (FAILED(destinations->SetAppID(GetAppUserModelID())))
    return;
  destinations->RemoveAllDestinations();
}

void Browser::SetAppUserModelID(const base::string16& name) {
  app_user_model_id_ = name;
  SetCurrentProcessExplicitAppUserModelID(app_user_model_id_.c_str());
}

void Browser::SetUserTasks(const std::vector<UserTask>& tasks) {
  CComPtr<ICustomDestinationList> destinations;
  if (FAILED(destinations.CoCreateInstance(CLSID_DestinationList)))
    return;
  if (FAILED(destinations->SetAppID(GetAppUserModelID())))
    return;

  // Start a transaction that updates the JumpList of this application.
  UINT max_slots;
  CComPtr<IObjectArray> removed;
  if (FAILED(destinations->BeginList(&max_slots, IID_PPV_ARGS(&removed))))
    return;

  CComPtr<IObjectCollection> collection;
  if (FAILED(collection.CoCreateInstance(CLSID_EnumerableObjectCollection)))
    return;

  for (auto& task : tasks) {
    CComPtr<IShellLink> link;
    if (FAILED(link.CoCreateInstance(CLSID_ShellLink)) ||
        FAILED(link->SetPath(task.program.value().c_str())) ||
        FAILED(link->SetArguments(task.arguments.c_str())) ||
        FAILED(link->SetDescription(task.description.c_str())))
      return;

    if (!task.icon_path.empty() &&
        FAILED(link->SetIconLocation(task.icon_path.value().c_str(),
                                     task.icon_index)))
      return;

    CComQIPtr<IPropertyStore> property_store = link;
    if (!base::win::SetStringValueForPropertyStore(property_store, PKEY_Title,
                                                   task.title.c_str()))
      return;

    if (FAILED(collection->AddObject(link)))
      return;
  }

  // When the list is empty "AddUserTasks" could fail, so we don't check return
  // value for it.
  CComQIPtr<IObjectArray> task_array = collection;
  destinations->AddUserTasks(task_array);
  destinations->CommitList();
}

bool Browser::RemoveAsDefaultProtocolClient(const std::string& protocol) {
  if (protocol.empty())
    return false;

  base::FilePath path;
  if (!PathService::Get(base::FILE_EXE, &path)) {
    LOG(ERROR) << "Error getting app exe path";
    return false;
  }

  // Main Registry Key
  HKEY root = HKEY_CURRENT_USER;
  std::string keyPathStr = "Software\\Classes\\" + protocol;
  std::wstring keyPath = std::wstring(keyPathStr.begin(), keyPathStr.end());

  // Command Key
  std::string cmdPathStr = keyPathStr + "\\shell\\open\\command";
  std::wstring cmdPath = std::wstring(cmdPathStr.begin(), cmdPathStr.end());

  base::win::RegKey key;
  base::win::RegKey commandKey;
  if (FAILED(key.Open(root, keyPath.c_str(), KEY_ALL_ACCESS)))
    // Key doesn't even exist, we can confirm that it is not set
    return true;

  if (FAILED(commandKey.Open(root, cmdPath.c_str(), KEY_ALL_ACCESS)))
    // Key doesn't even exist, we can confirm that it is not set
    return true;

  std::wstring keyVal;
  if (FAILED(commandKey.ReadValue(L"", &keyVal)))
    // Default value not set, we can confirm that it is not set
    return true;

  std::wstring exePath(path.value());
  std::wstring exe = L"\"" + exePath + L"\" \"%1\"";
  if (keyVal == exe) {
    // Let's kill the key
    if (FAILED(key.DeleteKey(L"shell")))
      return false;

    return true;
  } else {
    return true;
  }
}

bool Browser::SetAsDefaultProtocolClient(const std::string& protocol) {
  // HKEY_CLASSES_ROOT
  //    $PROTOCOL
  //       (Default) = "URL:$NAME"
  //       URL Protocol = ""
  //       shell
  //          open
  //             command
  //                (Default) = "$COMMAND" "%1"
  //
  // However, the "HKEY_CLASSES_ROOT" key can only be written by the
  // Administrator user. So, we instead write to "HKEY_CURRENT_USER\
  // Software\Classes", which is inherited by "HKEY_CLASSES_ROOT"
  // anyway, and can be written by unprivileged users.

  if (protocol.empty())
    return false;

  base::FilePath path;
  if (!PathService::Get(base::FILE_EXE, &path)) {
    LOG(ERROR) << "Error getting app exe path";
    return false;
  }

  // Main Registry Key
  HKEY root = HKEY_CURRENT_USER;
  std::string keyPathStr = "Software\\Classes\\" + protocol;
  std::wstring keyPath = std::wstring(keyPathStr.begin(), keyPathStr.end());
  std::string urlDeclStr = "URL:" + protocol;
  std::wstring urlDecl = std::wstring(urlDeclStr.begin(), urlDeclStr.end());

  // Command Key
  std::string cmdPathStr = keyPathStr + "\\shell\\open\\command";
  std::wstring cmdPath = std::wstring(cmdPathStr.begin(), cmdPathStr.end());

  // Executable Path
  std::wstring exePath(path.value());
  std::wstring exe = L"\"" + exePath + L"\" \"%1\"";

  // Write information to registry
  base::win::RegKey key(root, keyPath.c_str(), KEY_ALL_ACCESS);
  if (FAILED(key.WriteValue(L"URL Protocol", L"")) ||
      FAILED(key.WriteValue(L"", urlDecl.c_str())))
    return false;

  base::win::RegKey commandKey(root, cmdPath.c_str(), KEY_ALL_ACCESS);
  if (FAILED(commandKey.WriteValue(L"", exe.c_str())))
    return false;

  return true;
}

bool Browser::IsDefaultProtocolClient(const std::string& protocol) {
  if (protocol.empty())
    return false;

  base::FilePath path;
  if (!PathService::Get(base::FILE_EXE, &path)) {
    LOG(ERROR) << "Error getting app exe path";
    return false;
  }

  // Main Registry Key
  HKEY root = HKEY_CURRENT_USER;
  std::string keyPathStr = "Software\\Classes\\" + protocol;
  std::wstring keyPath = std::wstring(keyPathStr.begin(), keyPathStr.end());

  // Command Key
  std::string cmdPathStr = keyPathStr + "\\shell\\open\\command";
  std::wstring cmdPath = std::wstring(cmdPathStr.begin(), cmdPathStr.end());

  base::win::RegKey key;
  base::win::RegKey commandKey;
  if (FAILED(key.Open(root, keyPath.c_str(), KEY_ALL_ACCESS)))
    // Key doesn't exist, we can confirm that it is not set
    return false;

  if (FAILED(commandKey.Open(root, cmdPath.c_str(), KEY_ALL_ACCESS)))
    // Key doesn't exist, we can confirm that it is not set
    return false;

  std::wstring keyVal;
  if (FAILED(commandKey.ReadValue(L"", &keyVal)))
    // Default value not set, we can confirm that it is not set
    return false;

  std::wstring exePath(path.value());
  std::wstring exe = L"\"" + exePath + L"\" \"%1\"";
  if (keyVal == exe) {
    // Default value is the same as current file path
    return true;
  } else {
    return false;
  }
}

bool Browser::SetBadgeCount(int count) {
  return false;
}

void Browser::SetLoginItemSettings(LoginItemSettings settings) {
}

LoginItemSettings Browser::GetLoginItemSettings() {
  return LoginItemSettings();
}

PCWSTR Browser::GetAppUserModelID() {
  if (app_user_model_id_.empty()) {
    SetAppUserModelID(base::ReplaceStringPlaceholders(
        kAppUserModelIDFormat, base::UTF8ToUTF16(GetName()), nullptr));
  }

  return app_user_model_id_.c_str();
}

std::string Browser::GetExecutableFileVersion() const {
  base::FilePath path;
  if (PathService::Get(base::FILE_EXE, &path)) {
    std::unique_ptr<FileVersionInfo> version_info(
        FileVersionInfo::CreateFileVersionInfo(path));
    return base::UTF16ToUTF8(version_info->product_version());
  }

  return ATOM_VERSION_STRING;
}

std::string Browser::GetExecutableFileProductName() const {
  base::FilePath path;
  if (PathService::Get(base::FILE_EXE, &path)) {
    std::unique_ptr<FileVersionInfo> version_info(
        FileVersionInfo::CreateFileVersionInfo(path));
    return base::UTF16ToUTF8(version_info->product_name());
  }

  return ATOM_PRODUCT_NAME;
}

}  // namespace atom
<commit_msg>Add initial windows login item implementation<commit_after>// Copyright (c) 2013 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "atom/browser/browser.h"

#include <atlbase.h>
#include <propkey.h>
#include <windows.h>
#include <shlobj.h>
#include <shobjidl.h>

#include "base/base_paths.h"
#include "base/file_version_info.h"
#include "base/files/file_path.h"
#include "base/memory/scoped_ptr.h"
#include "base/path_service.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/win/win_util.h"
#include "base/win/registry.h"
#include "base/win/windows_version.h"
#include "atom/common/atom_version.h"

namespace atom {

namespace {

const wchar_t kAppUserModelIDFormat[] = L"electron.app.$1";

BOOL CALLBACK WindowsEnumerationHandler(HWND hwnd, LPARAM param) {
  DWORD target_process_id = *reinterpret_cast<DWORD*>(param);
  DWORD process_id = 0;

  GetWindowThreadProcessId(hwnd, &process_id);
  if (process_id == target_process_id) {
    SetFocus(hwnd);
    return FALSE;
  }

  return TRUE;
}

}  // namespace

void Browser::Focus() {
  // On Windows we just focus on the first window found for this process.
  DWORD pid = GetCurrentProcessId();
  EnumWindows(&WindowsEnumerationHandler, reinterpret_cast<LPARAM>(&pid));
}

void Browser::AddRecentDocument(const base::FilePath& path) {
  if (base::win::GetVersion() < base::win::VERSION_WIN7)
    return;

  CComPtr<IShellItem> item;
  HRESULT hr = SHCreateItemFromParsingName(
      path.value().c_str(), NULL, IID_PPV_ARGS(&item));
  if (SUCCEEDED(hr)) {
    SHARDAPPIDINFO info;
    info.psi = item;
    info.pszAppID = GetAppUserModelID();
    SHAddToRecentDocs(SHARD_APPIDINFO, &info);
  }
}

void Browser::ClearRecentDocuments() {
  CComPtr<IApplicationDestinations> destinations;
  if (FAILED(destinations.CoCreateInstance(CLSID_ApplicationDestinations,
                                           NULL, CLSCTX_INPROC_SERVER)))
    return;
  if (FAILED(destinations->SetAppID(GetAppUserModelID())))
    return;
  destinations->RemoveAllDestinations();
}

void Browser::SetAppUserModelID(const base::string16& name) {
  app_user_model_id_ = name;
  SetCurrentProcessExplicitAppUserModelID(app_user_model_id_.c_str());
}

void Browser::SetUserTasks(const std::vector<UserTask>& tasks) {
  CComPtr<ICustomDestinationList> destinations;
  if (FAILED(destinations.CoCreateInstance(CLSID_DestinationList)))
    return;
  if (FAILED(destinations->SetAppID(GetAppUserModelID())))
    return;

  // Start a transaction that updates the JumpList of this application.
  UINT max_slots;
  CComPtr<IObjectArray> removed;
  if (FAILED(destinations->BeginList(&max_slots, IID_PPV_ARGS(&removed))))
    return;

  CComPtr<IObjectCollection> collection;
  if (FAILED(collection.CoCreateInstance(CLSID_EnumerableObjectCollection)))
    return;

  for (auto& task : tasks) {
    CComPtr<IShellLink> link;
    if (FAILED(link.CoCreateInstance(CLSID_ShellLink)) ||
        FAILED(link->SetPath(task.program.value().c_str())) ||
        FAILED(link->SetArguments(task.arguments.c_str())) ||
        FAILED(link->SetDescription(task.description.c_str())))
      return;

    if (!task.icon_path.empty() &&
        FAILED(link->SetIconLocation(task.icon_path.value().c_str(),
                                     task.icon_index)))
      return;

    CComQIPtr<IPropertyStore> property_store = link;
    if (!base::win::SetStringValueForPropertyStore(property_store, PKEY_Title,
                                                   task.title.c_str()))
      return;

    if (FAILED(collection->AddObject(link)))
      return;
  }

  // When the list is empty "AddUserTasks" could fail, so we don't check return
  // value for it.
  CComQIPtr<IObjectArray> task_array = collection;
  destinations->AddUserTasks(task_array);
  destinations->CommitList();
}

bool Browser::RemoveAsDefaultProtocolClient(const std::string& protocol) {
  if (protocol.empty())
    return false;

  base::FilePath path;
  if (!PathService::Get(base::FILE_EXE, &path)) {
    LOG(ERROR) << "Error getting app exe path";
    return false;
  }

  // Main Registry Key
  HKEY root = HKEY_CURRENT_USER;
  std::string keyPathStr = "Software\\Classes\\" + protocol;
  std::wstring keyPath = std::wstring(keyPathStr.begin(), keyPathStr.end());

  // Command Key
  std::string cmdPathStr = keyPathStr + "\\shell\\open\\command";
  std::wstring cmdPath = std::wstring(cmdPathStr.begin(), cmdPathStr.end());

  base::win::RegKey key;
  base::win::RegKey commandKey;
  if (FAILED(key.Open(root, keyPath.c_str(), KEY_ALL_ACCESS)))
    // Key doesn't even exist, we can confirm that it is not set
    return true;

  if (FAILED(commandKey.Open(root, cmdPath.c_str(), KEY_ALL_ACCESS)))
    // Key doesn't even exist, we can confirm that it is not set
    return true;

  std::wstring keyVal;
  if (FAILED(commandKey.ReadValue(L"", &keyVal)))
    // Default value not set, we can confirm that it is not set
    return true;

  std::wstring exePath(path.value());
  std::wstring exe = L"\"" + exePath + L"\" \"%1\"";
  if (keyVal == exe) {
    // Let's kill the key
    if (FAILED(key.DeleteKey(L"shell")))
      return false;

    return true;
  } else {
    return true;
  }
}

bool Browser::SetAsDefaultProtocolClient(const std::string& protocol) {
  // HKEY_CLASSES_ROOT
  //    $PROTOCOL
  //       (Default) = "URL:$NAME"
  //       URL Protocol = ""
  //       shell
  //          open
  //             command
  //                (Default) = "$COMMAND" "%1"
  //
  // However, the "HKEY_CLASSES_ROOT" key can only be written by the
  // Administrator user. So, we instead write to "HKEY_CURRENT_USER\
  // Software\Classes", which is inherited by "HKEY_CLASSES_ROOT"
  // anyway, and can be written by unprivileged users.

  if (protocol.empty())
    return false;

  base::FilePath path;
  if (!PathService::Get(base::FILE_EXE, &path)) {
    LOG(ERROR) << "Error getting app exe path";
    return false;
  }

  // Main Registry Key
  HKEY root = HKEY_CURRENT_USER;
  std::string keyPathStr = "Software\\Classes\\" + protocol;
  std::wstring keyPath = std::wstring(keyPathStr.begin(), keyPathStr.end());
  std::string urlDeclStr = "URL:" + protocol;
  std::wstring urlDecl = std::wstring(urlDeclStr.begin(), urlDeclStr.end());

  // Command Key
  std::string cmdPathStr = keyPathStr + "\\shell\\open\\command";
  std::wstring cmdPath = std::wstring(cmdPathStr.begin(), cmdPathStr.end());

  // Executable Path
  std::wstring exePath(path.value());
  std::wstring exe = L"\"" + exePath + L"\" \"%1\"";

  // Write information to registry
  base::win::RegKey key(root, keyPath.c_str(), KEY_ALL_ACCESS);
  if (FAILED(key.WriteValue(L"URL Protocol", L"")) ||
      FAILED(key.WriteValue(L"", urlDecl.c_str())))
    return false;

  base::win::RegKey commandKey(root, cmdPath.c_str(), KEY_ALL_ACCESS);
  if (FAILED(commandKey.WriteValue(L"", exe.c_str())))
    return false;

  return true;
}

bool Browser::IsDefaultProtocolClient(const std::string& protocol) {
  if (protocol.empty())
    return false;

  base::FilePath path;
  if (!PathService::Get(base::FILE_EXE, &path)) {
    LOG(ERROR) << "Error getting app exe path";
    return false;
  }

  // Main Registry Key
  HKEY root = HKEY_CURRENT_USER;
  std::string keyPathStr = "Software\\Classes\\" + protocol;
  std::wstring keyPath = std::wstring(keyPathStr.begin(), keyPathStr.end());

  // Command Key
  std::string cmdPathStr = keyPathStr + "\\shell\\open\\command";
  std::wstring cmdPath = std::wstring(cmdPathStr.begin(), cmdPathStr.end());

  base::win::RegKey key;
  base::win::RegKey commandKey;
  if (FAILED(key.Open(root, keyPath.c_str(), KEY_ALL_ACCESS)))
    // Key doesn't exist, we can confirm that it is not set
    return false;

  if (FAILED(commandKey.Open(root, cmdPath.c_str(), KEY_ALL_ACCESS)))
    // Key doesn't exist, we can confirm that it is not set
    return false;

  std::wstring keyVal;
  if (FAILED(commandKey.ReadValue(L"", &keyVal)))
    // Default value not set, we can confirm that it is not set
    return false;

  std::wstring exePath(path.value());
  std::wstring exe = L"\"" + exePath + L"\" \"%1\"";
  if (keyVal == exe) {
    // Default value is the same as current file path
    return true;
  } else {
    return false;
  }
}

bool Browser::SetBadgeCount(int count) {
  return false;
}

void Browser::SetLoginItemSettings(LoginItemSettings settings) {
  base::FilePath path;
  if (!PathService::Get(base::FILE_EXE, &path)) {
    LOG(ERROR) << "Error getting app exe path";
    return;
  }

  // Main Registry Key
  HKEY root = HKEY_CURRENT_USER;
  std::string keyPathStr = "Software\\Microsoft\\Windows\\CurrentVersion\\Run";
  std::wstring keyPath = std::wstring(keyPathStr.begin(), keyPathStr.end());

  // Executable Path
  std::wstring exePath(path.value());
  base::win::RegKey key(root, keyPath.c_str(), KEY_ALL_ACCESS);

  if (settings.open_at_login)
    key.WriteValue(GetAppUserModelID(), exePath.c_str());
  else {
    key.DeleteValue(GetAppUserModelID())
  }
}

LoginItemSettings Browser::GetLoginItemSettings() {
  LoginItemSettings settings;

  base::FilePath path;
  if (!PathService::Get(base::FILE_EXE, &path)) {
    LOG(ERROR) << "Error getting app exe path";
    return;
  }

  // Main Registry Key
  HKEY root = HKEY_CURRENT_USER;
  std::string keyPathStr = "Software\\Microsoft\\Windows\\CurrentVersion\\Run";
  std::wstring keyPath = std::wstring(keyPathStr.begin(), keyPathStr.end());

  // Executable Path
  std::wstring exePath(path.value());
  base::win::RegKey key(root, keyPath.c_str(), KEY_ALL_ACCESS);

  settings.open_at_login = key.HasValue(GetAppUserModelID());
}

PCWSTR Browser::GetAppUserModelID() {
  if (app_user_model_id_.empty()) {
    SetAppUserModelID(base::ReplaceStringPlaceholders(
        kAppUserModelIDFormat, base::UTF8ToUTF16(GetName()), nullptr));
  }

  return app_user_model_id_.c_str();
}

std::string Browser::GetExecutableFileVersion() const {
  base::FilePath path;
  if (PathService::Get(base::FILE_EXE, &path)) {
    std::unique_ptr<FileVersionInfo> version_info(
        FileVersionInfo::CreateFileVersionInfo(path));
    return base::UTF16ToUTF8(version_info->product_version());
  }

  return ATOM_VERSION_STRING;
}

std::string Browser::GetExecutableFileProductName() const {
  base::FilePath path;
  if (PathService::Get(base::FILE_EXE, &path)) {
    std::unique_ptr<FileVersionInfo> version_info(
        FileVersionInfo::CreateFileVersionInfo(path));
    return base::UTF16ToUTF8(version_info->product_name());
  }

  return ATOM_PRODUCT_NAME;
}

}  // namespace atom
<|endoftext|>


<commit_before>#include "MeshPrimitives.hpp"
#include <Core/Mesh/MeshUtils.hpp>
#include <Core/String/StringUtils.hpp>

namespace Ra {
namespace Core {
namespace MeshUtils {

template <uint U, uint V>
TriangleMesh makeParametricSphere( Scalar radius ) {
    constexpr uint slices = U;
    constexpr uint stacks = V;

    TriangleMesh result;
    result.m_vertices.reserve(2+slices*(stacks-1));
    result.m_normals.reserve(2+slices*(stacks-1));
    result.m_triangles.reserve(2*slices*(stacks-1));

    for ( uint u = 0; u < slices; ++u )
    {
        const Scalar theta = Scalar( 2 * u ) * Core::Math::Pi / Scalar( slices );
        for ( uint v = 1; v < stacks; ++v )
        {
            // Regular vertices on the sphere.
            const Scalar phi = Scalar( v ) * Core::Math::Pi / Scalar( stacks );
            result.m_vertices.push_back( Vector3( radius * std::cos( theta ) * std::sin( phi ),
                                                  radius * std::sin( theta ) * std::sin( phi ),
                                                  radius * std::cos( phi ) ) );
            // Regular triangles
            if ( v > 1 )
            {
                const uint nextSlice = ( ( u + 1 ) % slices ) * ( stacks - 1 );
                const uint baseSlice = u * ( stacks - 1 );
                result.m_triangles.push_back(
                    Triangle( baseSlice + v - 2, baseSlice + v - 1, nextSlice + v - 1 ) );
                result.m_triangles.push_back(
                    Triangle( baseSlice + v - 2, nextSlice + v - 1, nextSlice + v - 2 ) );
            }
        }
    }

    // Add the pole vertices.
    uint northPoleIdx = result.m_vertices.size();
    result.m_vertices.push_back( Vector3( 0, 0, radius ) );
    uint southPoleIdx = result.m_vertices.size();
    result.m_vertices.push_back( Vector3( 0, 0, -radius ) );

    // Add the polar caps triangles.
    for ( uint u = 0; u < slices; ++u )
    {
        const uint nextSlice = ( ( u + 1 ) % slices ) * ( stacks - 1 );
        const uint baseSlice = u * ( stacks - 1 );
        result.m_triangles.push_back( Triangle( northPoleIdx, baseSlice, nextSlice ) );
        result.m_triangles.push_back(
            Triangle( southPoleIdx, nextSlice + stacks - 2, baseSlice + stacks - 2 ) );
    }

    // Compute normals.
    for ( const auto v : result.m_vertices )
    {
        const Vector3 n = v.normalized();
        result.m_normals.push_back( n );
    }
    checkConsistency( result );
    return result;
}

template <uint U, uint V>
TriangleMesh makeParametricTorus( Scalar majorRadius, Scalar minorRadius ) {
    TriangleMesh result;

    for ( uint iu = 0; iu < U; ++iu )
    {
        Scalar u = Scalar( iu ) * Core::Math::PiMul2 / Scalar( U );
        Core::Vector3 circleCenter( majorRadius * std::cos( u ), majorRadius * std::sin( u ), 0.f );

        for ( uint iv = 0; iv < V; ++iv )
        {
            Scalar v = Scalar( iv ) * Core::Math::PiMul2 / Scalar( V );

            Core::Vector3 vertex( ( majorRadius + minorRadius * std::cos( v ) ) * std::cos( u ),
                                  ( majorRadius + minorRadius * std::cos( v ) ) * std::sin( u ),
                                  minorRadius * std::sin( v ) );

            result.m_vertices.push_back( vertex );
            result.m_normals.push_back( ( vertex - circleCenter ).normalized() );

            result.m_triangles.push_back(
                Triangle( iu * V + iv, ( ( iu + 1 ) % U ) * V + iv, iu * V + ( ( iv + 1 ) % V ) ) );
            result.m_triangles.push_back( Triangle( ( ( iu + 1 ) % U ) * V + iv,
                                                    ( ( iu + 1 ) % U ) * V + ( ( iv + 1 ) % V ),
                                                    iu * V + ( ( iv + 1 ) % V ) ) );
        }
    }
    checkConsistency( result );
    return result;
}
} // namespace MeshUtils
} // namespace Core
} // namespace Ra
<commit_msg>avoid loop for normals of parametric sphere<commit_after>#include "MeshPrimitives.hpp"
#include <Core/Mesh/MeshUtils.hpp>
#include <Core/String/StringUtils.hpp>

namespace Ra {
namespace Core {
namespace MeshUtils {

template <uint U, uint V>
TriangleMesh makeParametricSphere( Scalar radius ) {
    constexpr uint slices = U;
    constexpr uint stacks = V;

    TriangleMesh result;
    result.m_vertices.reserve(2+slices*(stacks-1));
    result.m_normals.reserve(2+slices*(stacks-1));
    result.m_triangles.reserve(2*slices*(stacks-1));

    for ( uint u = 0; u < slices; ++u )
    {
        const Scalar theta = Scalar( 2 * u ) * Core::Math::Pi / Scalar( slices );
        for ( uint v = 1; v < stacks; ++v )
        {
            // Regular vertices on the sphere.
            const Scalar phi = Scalar( v ) * Core::Math::Pi / Scalar( stacks );
            result.m_vertices.push_back( Vector3( radius * std::cos( theta ) * std::sin( phi ),
                                                  radius * std::sin( theta ) * std::sin( phi ),
                                                  radius * std::cos( phi ) ) );
            result.m_normals.push_back(result.m_vertices.back().normalized());

            // Regular triangles
            if ( v > 1 )
            {
                const uint nextSlice = ( ( u + 1 ) % slices ) * ( stacks - 1 );
                const uint baseSlice = u * ( stacks - 1 );
                result.m_triangles.push_back(
                    Triangle( baseSlice + v - 2, baseSlice + v - 1, nextSlice + v - 1 ) );
                result.m_triangles.push_back(
                    Triangle( baseSlice + v - 2, nextSlice + v - 1, nextSlice + v - 2 ) );
            }
        }
    }

    // Add the pole vertices.
    uint northPoleIdx = result.m_vertices.size();
    result.m_vertices.push_back( Vector3( 0, 0, radius ) );
    result.m_normals.push_back( Vector3( 0, 0, 1 ) );
    uint southPoleIdx = result.m_vertices.size();
    result.m_vertices.push_back( Vector3( 0, 0, -radius ) );
    result.m_normals.push_back( Vector3( 0, 0, -1 ) );

    // Add the polar caps triangles.
    for ( uint u = 0; u < slices; ++u )
    {
        const uint nextSlice = ( ( u + 1 ) % slices ) * ( stacks - 1 );
        const uint baseSlice = u * ( stacks - 1 );
        result.m_triangles.push_back( Triangle( northPoleIdx, baseSlice, nextSlice ) );
        result.m_triangles.push_back(
            Triangle( southPoleIdx, nextSlice + stacks - 2, baseSlice + stacks - 2 ) );
    }

    checkConsistency( result );
    return result;
}

template <uint U, uint V>
TriangleMesh makeParametricTorus( Scalar majorRadius, Scalar minorRadius ) {
    TriangleMesh result;

    for ( uint iu = 0; iu < U; ++iu )
    {
        Scalar u = Scalar( iu ) * Core::Math::PiMul2 / Scalar( U );
        Core::Vector3 circleCenter( majorRadius * std::cos( u ), majorRadius * std::sin( u ), 0.f );

        for ( uint iv = 0; iv < V; ++iv )
        {
            Scalar v = Scalar( iv ) * Core::Math::PiMul2 / Scalar( V );

            Core::Vector3 vertex( ( majorRadius + minorRadius * std::cos( v ) ) * std::cos( u ),
                                  ( majorRadius + minorRadius * std::cos( v ) ) * std::sin( u ),
                                  minorRadius * std::sin( v ) );

            result.m_vertices.push_back( vertex );
            result.m_normals.push_back( ( vertex - circleCenter ).normalized() );

            result.m_triangles.push_back(
                Triangle( iu * V + iv, ( ( iu + 1 ) % U ) * V + iv, iu * V + ( ( iv + 1 ) % V ) ) );
            result.m_triangles.push_back( Triangle( ( ( iu + 1 ) % U ) * V + iv,
                                                    ( ( iu + 1 ) % U ) * V + ( ( iv + 1 ) % V ),
                                                    iu * V + ( ( iv + 1 ) % V ) ) );
        }
    }
    checkConsistency( result );
    return result;
}
} // namespace MeshUtils
} // namespace Core
} // namespace Ra
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2015 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <sys/types.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "killaction.h"

KillAction::KillAction() {
   signal = SIGKILL;
}

void KillAction::act(JNIEnv* jniEnv, jint resourceExhaustionFlags) {
	fprintf(stderr, "killing current process\n");
    kill(getpid(), signal);
}

void KillAction::setSignal(int sig) {
   signal = sig;
}
<commit_msg>Improve formatting of "killing current process"<commit_after>/*
 * Copyright (c) 2015 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <sys/types.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "killaction.h"

KillAction::KillAction() {
   signal = SIGKILL;
}

void KillAction::act(JNIEnv* jniEnv, jint resourceExhaustionFlags) {
	fprintf(stderr, "\nKilling current process\n");
    kill(getpid(), signal);
}

void KillAction::setSignal(int sig) {
   signal = sig;
}
<|endoftext|>


<commit_before>#include "PresetChooser.hpp"
#include "misc_ui.hpp"

namespace Slic3r { namespace GUI {

PresetChooser::PresetChooser(wxWindow* parent, std::weak_ptr<Print> print) : PresetChooser(parent, print, SLIC3RAPP->settings(), SLIC3RAPP->presets) {}

PresetChooser::PresetChooser(wxWindow* parent, std::weak_ptr<Print> print, Settings* external_settings, preset_store& external_presets) :
    wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL, ""),
    _local_sizer(new wxFlexGridSizer(3,3,1,2)), _parent(parent), _settings(external_settings), _print(print), _presets(external_presets)
{
    _local_sizer->AddGrowableCol(1, 1);
    _local_sizer->SetFlexibleDirection(wxHORIZONTAL);

    for (auto group : { preset_t::Print, preset_t::Material, preset_t::Printer }) {
        wxString name = "";
        switch(group) {
            case preset_t::Print:
                name << _("Print settings:");
                break;
            case preset_t::Material:
                name << _("Material:");
                break;
            case preset_t::Printer:
                name << _("Printer:");
                break;
            default:
                break;
        }
        auto* text {new wxStaticText(this, wxID_ANY, name, wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT)};
        text->SetFont(_settings->small_font());

        auto* choice {new wxBitmapComboBox(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, 0, nullptr, wxCB_READONLY)};
        this->preset_choosers[get_preset(group)].push_back(choice);

        // Settings button
        auto* settings_btn {new wxBitmapButton(this, wxID_ANY, wxBitmap(var("cog.png"), wxBITMAP_TYPE_PNG), wxDefaultPosition, wxDefaultSize, wxBORDER_NONE)};

        this->_local_sizer->Add(text, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL | wxRIGHT, 4);
        this->_local_sizer->Add(choice, 1, wxALIGN_CENTER_VERTICAL | wxEXPAND | wxBOTTOM, 0);
        this->_local_sizer->Add(settings_btn, 0, wxALIGN_CENTER_VERTICAL | wxEXPAND | wxLEFT, 3);

        // setup listener.
        // On a combobox event, puts a call to _on_change_combobox() on the evt_idle stack.
        choice->Bind(wxEVT_COMBOBOX,
            [=](wxCommandEvent& e) {
                wxTheApp->CallAfter([=]() { this->_on_change_combobox(group, choice);} );
            });
    }

    this->SetSizer(_local_sizer);
}

void PresetChooser::load(std::array<Presets, preset_types> presets) {

    wxString selected_printer_name {""};
    for (const auto& group : { preset_t::Printer, preset_t::Material, preset_t::Print }) {
        auto current_list = presets.at(get_preset(group));
        // Filter out profiles not compatible with this printer
        if (group != preset_t::Printer) {
            current_list = grep(presets.at(get_preset(group)), [selected_printer_name] (const Preset& x) -> bool { return x.compatible(selected_printer_name); });
        }

        // show default names if no other presets visible.
        if (current_list.size() > 1) {
            current_list = grep(current_list, [] (const Preset& x) -> bool { return !x.default_preset; });
        }

        // # Read the current defaults from the settings file
        const auto& settings_defaults {_settings->default_presets.at(get_preset(group))};

        size_t i {0};
        std::vector<std::string> preset_names {};
        __chooser_names[get_preset(group)].clear();
        // populate the chooser
        for (auto* chooser : this->preset_choosers[get_preset(group)]) {
            chooser->Clear();
            assert(chooser->GetCount() == 0);
            for (auto preset : current_list) {
                wxBitmap bitmap;
                switch (group) {
                    case preset_t::Print:
                        bitmap = wxBitmap(var("cog.png"), wxBITMAP_TYPE_PNG);
                        break;
                    case preset_t::Material:
                        if (auto config =  preset.config().lock()) {
                            if (preset.default_preset || !config->has("filament_colour"))
                                bitmap = wxBitmap(var("spool.png"), wxBITMAP_TYPE_PNG);
                        } else { // fall back if for some reason the config is dead.
                            bitmap = wxBitmap(var("spool.png"), wxBITMAP_TYPE_PNG);
                        }
                        break;
                    case preset_t::Printer:
                        bitmap = wxBitmap(var("printer_empty.png"), wxBITMAP_TYPE_PNG);
                        break;
                    default: break;
                }
                chooser->Append(preset.name, bitmap);
                __chooser_names[get_preset(group)].push_back(preset.name);
            }
            assert(chooser->GetCount() == current_list.size());

            // Apply default options from settings
            bool updated_from_settings = false;
            if (settings_defaults.size() > i) { // only apply if there is a value from Settings
                updated_from_settings = this->select_preset_by_name(settings_defaults.at(i), chooser);
            }

            if (!updated_from_settings) // default
                chooser->SetSelection(0);

            wxString selected_preset { chooser->GetString(chooser->GetSelection()) };
            if (group == preset_t::Printer) {
                selected_printer_name = selected_preset;
            }

            ++i;
        }
        this->_update_preset_settings(group);
    }
}

bool PresetChooser::select_preset_by_name(wxString name, preset_t group, size_t index = 0) {
    auto& ps_list = this->preset_choosers.at(get_preset(group));
    bool updated = false;
    if (ps_list.size() > index) {
        updated = select_preset_by_name(name, ps_list.at(index));
    }
    if (updated)
        this->_on_select_preset(group);
    return updated;
}

bool PresetChooser::select_preset_by_name(wxString name, wxBitmapComboBox* chooser) {
    auto index { chooser->FindString(name) };
    if (index != wxNOT_FOUND) {
        chooser->SetSelection(index);
        return true;
    }
    return false;
}

void PresetChooser::_update_preset_settings(preset_t preset) {
    auto& settings_presets {_settings->default_presets.at(get_preset(preset))};
    settings_presets.clear(); // make sure previous contents are deconstructed
    settings_presets = this->_get_selected_presets(preset);

}

void PresetChooser::_on_select_preset(preset_t preset) {
    // update settings store
    this->_update_preset_settings(preset);
    // save settings
    _settings->save_settings();
    if (preset == preset_t::Printer) {
        this->load(); // reload print/filament settings to honor compatible printers
    }
}

bool PresetChooser::prompt_unsaved_changes() {
    return true;
}

std::vector<wxString> PresetChooser::_get_selected_presets(preset_t group) const {
        const auto& choosers { this->preset_choosers[get_preset(group)] };
        std::vector<wxString> selected;
        selected.reserve(choosers.size());

        for (auto* chooser :  choosers) {
            selected.push_back(chooser->GetString(chooser->GetSelection()));
        }
        return selected;
}

wxString PresetChooser::_get_selected_preset(preset_t group, size_t index) const {
    auto selected { this->_get_selected_presets(group) };
    if (index > selected.size()) { return wxString(""); }
    return selected.at(index);
}
void PresetChooser::_on_change_combobox(preset_t preset, wxBitmapComboBox* choice) {

    // Prompt for unsaved changes and undo selections if cancelled and return early
    // Callback to close preset editor tab, close editor tabs, reload presets.
    //
    if (!this->prompt_unsaved_changes()) return;
    wxTheApp->CallAfter([this,preset]()
    {
        this->_on_select_preset(preset);
        // reload presets; removes the modified mark
        this->load();
    });
    /*
    sub _on_change_combobox {
    my ($self, $group, $choice) = @_;

    if (0) {
        # This code is disabled because wxPerl doesn't provide GetCurrentSelection
        my $current_name = $self->{preset_choosers_names}{$choice}[$choice->GetCurrentSelection];
        my $current = first { $_->name eq $current_name } @{wxTheApp->presets->{$group}};
        if (!$current->prompt_unsaved_changes($self)) {
            # Restore the previous one
            $choice->SetSelection($choice->GetCurrentSelection);
            return;
        }
    } else {
        return 0 if !$self->prompt_unsaved_changes;
    }
    wxTheApp->CallAfter(sub {
        # Close the preset editor tab if any
        if (exists $self->GetFrame->{preset_editor_tabs}{$group}) {
            my $tabpanel = $self->GetFrame->{tabpanel};
            $tabpanel->DeletePage($tabpanel->GetPageIndex($self->GetFrame->{preset_editor_tabs}{$group}));
            delete $self->GetFrame->{preset_editor_tabs}{$group};
            $tabpanel->SetSelection(0); # without this, a newly created tab will not be selected by wx
        }

        $self->_on_select_preset($group);

        # This will remove the "(modified)" mark from any dirty preset handled here.
        $self->load_presets;
    });
}
*/
}

}} // Slic3r::GUI
<commit_msg>comment update<commit_after>#include "PresetChooser.hpp"
#include "misc_ui.hpp"

namespace Slic3r { namespace GUI {

PresetChooser::PresetChooser(wxWindow* parent, std::weak_ptr<Print> print) : PresetChooser(parent, print, SLIC3RAPP->settings(), SLIC3RAPP->presets) {}

PresetChooser::PresetChooser(wxWindow* parent, std::weak_ptr<Print> print, Settings* external_settings, preset_store& external_presets) :
    wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL, ""),
    _local_sizer(new wxFlexGridSizer(3,3,1,2)), _parent(parent), _settings(external_settings), _print(print), _presets(external_presets)
{
    _local_sizer->AddGrowableCol(1, 1);
    _local_sizer->SetFlexibleDirection(wxHORIZONTAL);

    for (auto group : { preset_t::Print, preset_t::Material, preset_t::Printer }) {
        wxString name = "";
        switch(group) {
            case preset_t::Print:
                name << _("Print settings:");
                break;
            case preset_t::Material:
                name << _("Material:");
                break;
            case preset_t::Printer:
                name << _("Printer:");
                break;
            default:
                break;
        }
        auto* text {new wxStaticText(this, wxID_ANY, name, wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT)};
        text->SetFont(_settings->small_font());

        auto* choice {new wxBitmapComboBox(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, 0, nullptr, wxCB_READONLY)};
        this->preset_choosers[get_preset(group)].push_back(choice);

        // Settings button
        auto* settings_btn {new wxBitmapButton(this, wxID_ANY, wxBitmap(var("cog.png"), wxBITMAP_TYPE_PNG), wxDefaultPosition, wxDefaultSize, wxBORDER_NONE)};

        this->_local_sizer->Add(text, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL | wxRIGHT, 4);
        this->_local_sizer->Add(choice, 1, wxALIGN_CENTER_VERTICAL | wxEXPAND | wxBOTTOM, 0);
        this->_local_sizer->Add(settings_btn, 0, wxALIGN_CENTER_VERTICAL | wxEXPAND | wxLEFT, 3);

        // setup listener.
        // On a combobox event, puts a call to _on_change_combobox() on the evt_idle stack.
        choice->Bind(wxEVT_COMBOBOX,
            [=](wxCommandEvent& e) {
                wxTheApp->CallAfter([=]() { this->_on_change_combobox(group, choice);} );
            });
    }

    this->SetSizer(_local_sizer);
}

void PresetChooser::load(std::array<Presets, preset_types> presets) {

    wxString selected_printer_name {""};
    for (const auto& group : { preset_t::Printer, preset_t::Material, preset_t::Print }) {
        auto current_list = presets.at(get_preset(group));
        // Filter out profiles not compatible with this printer
        if (group != preset_t::Printer) {
            current_list = grep(presets.at(get_preset(group)), [selected_printer_name] (const Preset& x) -> bool { return x.compatible(selected_printer_name); });
        }

        // show default names if no other presets visible.
        if (current_list.size() > 1) {
            current_list = grep(current_list, [] (const Preset& x) -> bool { return !x.default_preset; });
        }

        // Read the current defaults from the settings file
        const auto& settings_defaults {_settings->default_presets.at(get_preset(group))};

        size_t i {0};
        std::vector<std::string> preset_names {};
        __chooser_names[get_preset(group)].clear();
        // populate the chooser
        for (auto* chooser : this->preset_choosers[get_preset(group)]) {
            chooser->Clear();
            assert(chooser->GetCount() == 0);
            for (auto preset : current_list) {
                wxBitmap bitmap;
                switch (group) {
                    case preset_t::Print:
                        bitmap = wxBitmap(var("cog.png"), wxBITMAP_TYPE_PNG);
                        break;
                    case preset_t::Material:
                        if (auto config =  preset.config().lock()) {
                            if (preset.default_preset || !config->has("filament_colour"))
                                bitmap = wxBitmap(var("spool.png"), wxBITMAP_TYPE_PNG);
                        } else { // fall back if for some reason the config is dead.
                            bitmap = wxBitmap(var("spool.png"), wxBITMAP_TYPE_PNG);
                        }
                        break;
                    case preset_t::Printer:
                        bitmap = wxBitmap(var("printer_empty.png"), wxBITMAP_TYPE_PNG);
                        break;
                    default: break;
                }
                chooser->Append(preset.name, bitmap);
                __chooser_names[get_preset(group)].push_back(preset.name);
            }
            assert(chooser->GetCount() == current_list.size());

            // Apply default options from settings
            bool updated_from_settings = false;
            if (settings_defaults.size() > i) { // only apply if there is a value from Settings
                updated_from_settings = this->select_preset_by_name(settings_defaults.at(i), chooser);
            }

            if (!updated_from_settings) // default
                chooser->SetSelection(0);

            wxString selected_preset { chooser->GetString(chooser->GetSelection()) };
            if (group == preset_t::Printer) {
                selected_printer_name = selected_preset;
            }

            ++i;
        }
        this->_update_preset_settings(group);
    }
}

bool PresetChooser::select_preset_by_name(wxString name, preset_t group, size_t index = 0) {
    auto& ps_list = this->preset_choosers.at(get_preset(group));
    bool updated = false;
    if (ps_list.size() > index) {
        updated = select_preset_by_name(name, ps_list.at(index));
    }
    if (updated)
        this->_on_select_preset(group);
    return updated;
}

bool PresetChooser::select_preset_by_name(wxString name, wxBitmapComboBox* chooser) {
    auto index { chooser->FindString(name) };
    if (index != wxNOT_FOUND) {
        chooser->SetSelection(index);
        return true;
    }
    return false;
}

void PresetChooser::_update_preset_settings(preset_t preset) {
    auto& settings_presets {_settings->default_presets.at(get_preset(preset))};
    settings_presets.clear(); // make sure previous contents are deconstructed
    settings_presets = this->_get_selected_presets(preset);

}

void PresetChooser::_on_select_preset(preset_t preset) {
    // update settings store
    this->_update_preset_settings(preset);
    // save settings
    _settings->save_settings();
    if (preset == preset_t::Printer) {
        this->load(); // reload print/filament settings to honor compatible printers
    }
}

bool PresetChooser::prompt_unsaved_changes() {
    return true;
}

std::vector<wxString> PresetChooser::_get_selected_presets(preset_t group) const {
        const auto& choosers { this->preset_choosers[get_preset(group)] };
        std::vector<wxString> selected;
        selected.reserve(choosers.size());

        for (auto* chooser :  choosers) {
            selected.push_back(chooser->GetString(chooser->GetSelection()));
        }
        return selected;
}

wxString PresetChooser::_get_selected_preset(preset_t group, size_t index) const {
    auto selected { this->_get_selected_presets(group) };
    if (index > selected.size()) { return wxString(""); }
    return selected.at(index);
}
void PresetChooser::_on_change_combobox(preset_t preset, wxBitmapComboBox* choice) {

    // Prompt for unsaved changes and undo selections if cancelled and return early
    // Callback to close preset editor tab, close editor tabs, reload presets.
    //
    if (!this->prompt_unsaved_changes()) return;
    wxTheApp->CallAfter([this,preset]()
    {
        this->_on_select_preset(preset);
        // reload presets; removes the modified mark
        this->load();
    });
    /*
    sub _on_change_combobox {
    my ($self, $group, $choice) = @_;

    if (0) {
        # This code is disabled because wxPerl doesn't provide GetCurrentSelection
        my $current_name = $self->{preset_choosers_names}{$choice}[$choice->GetCurrentSelection];
        my $current = first { $_->name eq $current_name } @{wxTheApp->presets->{$group}};
        if (!$current->prompt_unsaved_changes($self)) {
            # Restore the previous one
            $choice->SetSelection($choice->GetCurrentSelection);
            return;
        }
    } else {
        return 0 if !$self->prompt_unsaved_changes;
    }
    wxTheApp->CallAfter(sub {
        # Close the preset editor tab if any
        if (exists $self->GetFrame->{preset_editor_tabs}{$group}) {
            my $tabpanel = $self->GetFrame->{tabpanel};
            $tabpanel->DeletePage($tabpanel->GetPageIndex($self->GetFrame->{preset_editor_tabs}{$group}));
            delete $self->GetFrame->{preset_editor_tabs}{$group};
            $tabpanel->SetSelection(0); # without this, a newly created tab will not be selected by wx
        }

        $self->_on_select_preset($group);

        # This will remove the "(modified)" mark from any dirty preset handled here.
        $self->load_presets;
    });
}
*/
}

}} // Slic3r::GUI
<|endoftext|>