<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: richtextvclcontrol.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-19 13:01:44 $
 *
 *  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 FORMS_SOURCE_RICHTEXT_RICHTEXTVCLCONTROL_HXX
#include "richtextvclcontrol.hxx"
#endif
#ifndef FORMS_SOURCE_RICHTEXT_RICHTEXTIMPLCONTOL_HXX
#include "richtextimplcontrol.hxx"
#endif

#ifndef _SFXITEMPOOL_HXX
#include <svtools/itempool.hxx>
#endif
#ifndef _SFXITEMSET_HXX
#include <svtools/itemset.hxx>
#endif
#ifndef _SVTOOLS_LANGUAGEOPTIONS_HXX
#include <svtools/languageoptions.hxx>
#endif

#ifndef _SVX_SCRIPTTYPEITEM_HXX
#include <svx/scripttypeitem.hxx>
#endif
#ifndef _MyEDITENG_HXX
#include <svx/editeng.hxx>
#endif
#ifndef _MyEDITVIEW_HXX
#include <svx/editview.hxx>
#endif
#ifndef _EEITEM_HXX
#include <svx/eeitem.hxx>
#endif

#define ITEMID_FONT         EE_CHAR_FONTINFO
#ifndef _SVX_FONTITEM_HXX
#include <svx/fontitem.hxx>
#endif
#define ITEMID_FONTHEIGHT   EE_CHAR_FONTHEIGHT
#ifndef _SVX_FHGTITEM_HXX
#include <svx/fhgtitem.hxx>
#endif

#include <memory>

//........................................................................
namespace frm
{
//........................................................................

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

    //====================================================================
    //= RichTextControl
    //====================================================================
    //--------------------------------------------------------------------
    RichTextControl::RichTextControl( RichTextEngine* _pEngine, Window* _pParent, WinBits _nStyle,
        ITextAttributeListener* _pTextAttribListener, ITextSelectionListener* _pSelectionListener )
        :Control( _pParent, implInitStyle( _nStyle ) )
        ,m_pImpl( NULL )
    {
        implInit( _pEngine, _pTextAttribListener, _pSelectionListener );
    }

    //--------------------------------------------------------------------
    void RichTextControl::implInit( RichTextEngine* _pEngine, ITextAttributeListener* _pTextAttribListener, ITextSelectionListener* _pSelectionListener )
    {
        m_pImpl = new RichTextControlImpl( this, _pEngine, _pTextAttribListener, _pSelectionListener );
        SetCompoundControl( TRUE );
    }

    //--------------------------------------------------------------------
    RichTextControl::~RichTextControl( )
    {
        delete m_pImpl;
    }

    //--------------------------------------------------------------------
    AttributeState RichTextControl::getState( AttributeId _nAttributeId ) const
    {
        return m_pImpl->getAttributeState( _nAttributeId );
    }

    //--------------------------------------------------------------------
    void RichTextControl::executeAttribute( AttributeId _nAttributeId, const SfxPoolItem* _pArgument )
    {
        SfxItemSet aToApplyAttributes( getView().GetEmptyItemSet() );
        if ( !m_pImpl->executeAttribute( getView().GetAttribs(), aToApplyAttributes, _nAttributeId, _pArgument, m_pImpl->getSelectedScriptType() ) )
        {
            OSL_ENSURE( sal_False, "RichTextControl::executeAttribute: cannot handle the given attribute!" );
            return;
        }

        applyAttributes( aToApplyAttributes );
    }

    //--------------------------------------------------------------------
    void RichTextControl::applyAttributes( const SfxItemSet& _rAttributesToApply )
    {
        // apply
        if ( HasChildPathFocus() )
            getView().HideCursor();

        BOOL bOldUpdateMode = getEngine().GetUpdateMode();   // TODO: guard?
        getEngine().SetUpdateMode( FALSE );

        getView().SetAttribs( _rAttributesToApply );

        getEngine().SetUpdateMode( bOldUpdateMode );
        getView().Invalidate();

        if ( HasChildPathFocus() )
            getView().ShowCursor();

        m_pImpl->updateAllAttributes();
            // TODO: maybe we should have a list of attributes which need to be updated
            // (the handler for the just executed attribute should know)
    }

    //--------------------------------------------------------------------
    void RichTextControl::enableAttributeNotification( AttributeId _nAttributeId, ITextAttributeListener* _pListener )
    {
        m_pImpl->enableAttributeNotification( _nAttributeId, _pListener );
    }

    //--------------------------------------------------------------------
    void RichTextControl::disableAttributeNotification( AttributeId _nAttributeId )
    {
        m_pImpl->disableAttributeNotification( _nAttributeId );
    }

    //--------------------------------------------------------------------
    bool RichTextControl::isMappableSlot( SfxSlotId _nSlotId )
    {
        switch ( _nSlotId )
        {
            case SID_ATTR_PARA_ADJUST_LEFT:
            case SID_ATTR_PARA_ADJUST_CENTER:
            case SID_ATTR_PARA_ADJUST_RIGHT:
            case SID_ATTR_PARA_ADJUST_BLOCK:
            case SID_SET_SUPER_SCRIPT:
            case SID_SET_SUB_SCRIPT:
            case SID_ATTR_PARA_LINESPACE_10:
            case SID_ATTR_PARA_LINESPACE_15:
            case SID_ATTR_PARA_LINESPACE_20:
            case SID_ATTR_PARA_LEFT_TO_RIGHT:
            case SID_ATTR_PARA_RIGHT_TO_LEFT:
            case SID_TEXTDIRECTION_TOP_TO_BOTTOM:
            case SID_TEXTDIRECTION_LEFT_TO_RIGHT:
            case SID_ATTR_CHAR_LATIN_FONT:
            case SID_ATTR_CHAR_LATIN_FONTHEIGHT:
            case SID_ATTR_CHAR_LATIN_LANGUAGE:
            case SID_ATTR_CHAR_LATIN_POSTURE:
            case SID_ATTR_CHAR_LATIN_WEIGHT:
                return true;
        }
        return false;
    }

    //--------------------------------------------------------------------
    void RichTextControl::convert( const SfxPoolItem& _rItem, FontDescriptor& _rUnoFont )
    {
        OSL_ENSURE( _rItem.ISA( SvxFontItem ), "RichTextControl::convert: invalid item type!" );

        _rUnoFont.Name    = static_cast< const SvxFontItem& >( _rItem ).GetFamilyName();
        _rUnoFont.Family  = static_cast< const SvxFontItem& >( _rItem ).GetFamily();
        _rUnoFont.Pitch   = static_cast< const SvxFontItem& >( _rItem ).GetPitch();
        _rUnoFont.CharSet = static_cast< const SvxFontItem& >( _rItem ).GetCharSet();
    }

    //--------------------------------------------------------------------
    void RichTextControl::convert( const FontDescriptor& _rUnoFont, SfxPoolItem*& _rpFontItem )
    {
        SvxFontItem* pFontItem = new SvxFontItem( SID_ATTR_CHAR_FONT );
        pFontItem->GetFamilyName() = _rUnoFont.Name;
        pFontItem->GetFamily()     = (FontFamily)_rUnoFont.Family;
        pFontItem->GetPitch()      = (FontPitch)_rUnoFont.Pitch;
        pFontItem->GetCharSet()    = _rUnoFont.CharSet;

        _rpFontItem = pFontItem;
    }

    //--------------------------------------------------------------------
    sal_uInt32 RichTextControl::convertFontHeight( const SfxPoolItem& _rItem )
    {
        OSL_ENSURE( _rItem.ISA( SvxFontHeightItem ), "RichTextControl::convert: invalid item type!" );
        return static_cast< const SvxFontHeightItem& >( _rItem ).GetHeight();
    }

    //--------------------------------------------------------------------
    SfxPoolItem* RichTextControl::convertFontHeight( sal_uInt32 _nUnoFontHeight )
    {
        SvxFontHeightItem* pItem = new SvxFontHeightItem( _nUnoFontHeight );
        pItem->SetProp( 100, SFX_MAPUNIT_POINT );
        return pItem;
    }

    //--------------------------------------------------------------------
    void RichTextControl::Resize()
    {
        m_pImpl->layoutWindow();
        Invalidate();
    }

    //--------------------------------------------------------------------
    void RichTextControl::GetFocus()
    {
        getViewport().GrabFocus();
    }

    //--------------------------------------------------------------------
    WinBits RichTextControl::implInitStyle( WinBits nStyle )
    {
        if ( !( nStyle & WB_NOTABSTOP ) )
            nStyle |= WB_TABSTOP;
        return nStyle;
    }

    //--------------------------------------------------------------------
    void RichTextControl::StateChanged( StateChangedType _nStateChange )
    {
        if ( _nStateChange == STATE_CHANGE_STYLE )
        {
            SetStyle( implInitStyle( GetStyle() ) );
            m_pImpl->notifyStyleChanged();
        }
        else if ( _nStateChange == STATE_CHANGE_ZOOM )
        {
            m_pImpl->notifyZoomChanged();
        }
        else if ( _nStateChange == STATE_CHANGE_INITSHOW )
        {
            m_pImpl->notifyInitShow();
        }
        Control::StateChanged( _nStateChange );
    }

    //--------------------------------------------------------------------
    long RichTextControl::PreNotify( NotifyEvent& _rNEvt )
    {
        if ( IsWindowOrChild( _rNEvt.GetWindow() ) )
        {
            if ( EVENT_KEYINPUT == _rNEvt.GetType() )
            {
                const KeyEvent* pKeyEvent = _rNEvt.GetKeyEvent();

                sal_uInt16 nCode = pKeyEvent->GetKeyCode().GetCode();
                sal_Bool   bShift = pKeyEvent->GetKeyCode().IsShift();
                sal_Bool   bCtrl = pKeyEvent->GetKeyCode().IsMod1();
                sal_Bool   bAlt = pKeyEvent->GetKeyCode().IsMod2();
                if ( ( KEY_TAB == nCode ) && bCtrl && !bAlt )
                {
                    // Ctrl-Tab is used to step out of the control
                    // -> build a new key event without the Ctrl-key, and let the very base class handle it
                    KeyCode aNewCode( KEY_TAB, bShift, sal_False, sal_False );
                    KeyEvent aNewEvent( pKeyEvent->GetCharCode(), aNewCode );
                    Control::KeyInput( aNewEvent );
                    return 1;   // handled
                }
            }
        }
        return Control::PreNotify( _rNEvt );
    }

    //--------------------------------------------------------------------
    long RichTextControl::Notify( NotifyEvent& _rNEvt )
    {
        long nDone = 0;
        if ( _rNEvt.GetType() == EVENT_COMMAND )
        {
            const CommandEvent& rEvent = *_rNEvt.GetCommandEvent();
            nDone = m_pImpl->HandleCommand( rEvent );
        }
        return nDone ? nDone : Control::Notify( _rNEvt );
    }

    //--------------------------------------------------------------------
    void RichTextControl::Draw( OutputDevice* _pDev, const Point& _rPos, const Size& _rSize, ULONG _nFlags )
    {
        m_pImpl->Draw( _pDev, _rPos, _rSize, _nFlags );
    }

    //--------------------------------------------------------------------
    EditView& RichTextControl::getView()
    {
        return *m_pImpl->getView( RichTextControlImpl::GrantAccess() );
    }

    //--------------------------------------------------------------------
    const EditView& RichTextControl::getView() const
    {
        return *m_pImpl->getView( RichTextControlImpl::GrantAccess() );
    }

    //--------------------------------------------------------------------
    EditEngine& RichTextControl::getEngine() const
    {
        return *m_pImpl->getEngine( RichTextControlImpl::GrantAccess() );
    }

    //--------------------------------------------------------------------
    Window& RichTextControl::getViewport() const
    {
        return *m_pImpl->getViewport( RichTextControlImpl::GrantAccess() );
    }

    //--------------------------------------------------------------------
    void RichTextControl::SetReadOnly( bool _bReadOnly )
    {
        m_pImpl->SetReadOnly( _bReadOnly );
    }

    //--------------------------------------------------------------------
    bool RichTextControl::IsReadOnly() const
    {
        return m_pImpl->IsReadOnly();
    }

    //--------------------------------------------------------------------
    void RichTextControl::SetBackgroundColor( )
    {
        m_pImpl->SetBackgroundColor( );
    }

    //--------------------------------------------------------------------
    void RichTextControl::SetBackgroundColor( const Color& _rColor )
    {
        m_pImpl->SetBackgroundColor( _rColor );
    }

    //--------------------------------------------------------------------
    void RichTextControl::SetHideInactiveSelection( bool _bHide )
    {
        m_pImpl->SetHideInactiveSelection( _bHide );
    }

    //--------------------------------------------------------------------
    bool RichTextControl::GetHideInactiveSelection() const
    {
        return m_pImpl->GetHideInactiveSelection( );
    }

//........................................................................
}   // namespace frm
//........................................................................

<commit_msg>INTEGRATION: CWS dba30 (1.4.6); FILE MERGED 2006/07/20 13:19:12 fs 1.4.6.3: #i10000# 2006/07/19 10:02:19 fs 1.4.6.2: RESYNC: (1.4-1.5); FILE MERGED 2005/10/10 06:15:43 fs 1.4.6.1: in debug versions, allow saving/loading the EditEngine content to/from a file<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: richtextvclcontrol.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: hr $ $Date: 2006-08-15 10:33:03 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef FORMS_SOURCE_RICHTEXT_RICHTEXTVCLCONTROL_HXX
#include "richtextvclcontrol.hxx"
#endif
#ifndef FORMS_SOURCE_RICHTEXT_RICHTEXTIMPLCONTOL_HXX
#include "richtextimplcontrol.hxx"
#endif

#ifndef _SFXITEMPOOL_HXX
#include <svtools/itempool.hxx>
#endif
#ifndef _SFXITEMSET_HXX
#include <svtools/itemset.hxx>
#endif
#ifndef _SVTOOLS_LANGUAGEOPTIONS_HXX
#include <svtools/languageoptions.hxx>
#endif
#if OSL_DEBUG_LEVEL > 0
    #ifndef _TOOLS_TEMPFILE_HXX
    #include <tools/tempfile.hxx>
    #endif
    #ifndef _UNTOOLS_UCBSTREAMHELPER_HXX
    #include <unotools/ucbstreamhelper.hxx>
    #endif
    #ifndef _SV_MSGBOX_HXX
    #include <vcl/msgbox.hxx>
    #endif
    #ifndef _FILEDLGHELPER_HXX
    #include <sfx2/filedlghelper.hxx>
    #endif
    #ifndef _URLOBJ_HXX
    #include <tools/urlobj.hxx>
    #endif
#endif

#ifndef _SVX_SCRIPTTYPEITEM_HXX
#include <svx/scripttypeitem.hxx>
#endif
#ifndef _MyEDITENG_HXX
#include <svx/editeng.hxx>
#endif
#ifndef _MyEDITVIEW_HXX
#include <svx/editview.hxx>
#endif
#ifndef _EEITEM_HXX
#include <svx/eeitem.hxx>
#endif

#define ITEMID_FONT         EE_CHAR_FONTINFO
#ifndef _SVX_FONTITEM_HXX
#include <svx/fontitem.hxx>
#endif
#define ITEMID_FONTHEIGHT   EE_CHAR_FONTHEIGHT
#ifndef _SVX_FHGTITEM_HXX
#include <svx/fhgtitem.hxx>
#endif

#include <memory>

//........................................................................
namespace frm
{
//........................................................................

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

    //====================================================================
    //= RichTextControl
    //====================================================================
    //--------------------------------------------------------------------
    RichTextControl::RichTextControl( RichTextEngine* _pEngine, Window* _pParent, WinBits _nStyle,
        ITextAttributeListener* _pTextAttribListener, ITextSelectionListener* _pSelectionListener )
        :Control( _pParent, implInitStyle( _nStyle ) )
        ,m_pImpl( NULL )
    {
        implInit( _pEngine, _pTextAttribListener, _pSelectionListener );
    }

    //--------------------------------------------------------------------
    void RichTextControl::implInit( RichTextEngine* _pEngine, ITextAttributeListener* _pTextAttribListener, ITextSelectionListener* _pSelectionListener )
    {
        m_pImpl = new RichTextControlImpl( this, _pEngine, _pTextAttribListener, _pSelectionListener );
        SetCompoundControl( TRUE );
    }

    //--------------------------------------------------------------------
    RichTextControl::~RichTextControl( )
    {
        delete m_pImpl;
    }

    //--------------------------------------------------------------------
    AttributeState RichTextControl::getState( AttributeId _nAttributeId ) const
    {
        return m_pImpl->getAttributeState( _nAttributeId );
    }

    //--------------------------------------------------------------------
    void RichTextControl::executeAttribute( AttributeId _nAttributeId, const SfxPoolItem* _pArgument )
    {
        SfxItemSet aToApplyAttributes( getView().GetEmptyItemSet() );
        if ( !m_pImpl->executeAttribute( getView().GetAttribs(), aToApplyAttributes, _nAttributeId, _pArgument, m_pImpl->getSelectedScriptType() ) )
        {
            OSL_ENSURE( sal_False, "RichTextControl::executeAttribute: cannot handle the given attribute!" );
            return;
        }

        applyAttributes( aToApplyAttributes );
    }

    //--------------------------------------------------------------------
    void RichTextControl::applyAttributes( const SfxItemSet& _rAttributesToApply )
    {
        // apply
        if ( HasChildPathFocus() )
            getView().HideCursor();

        BOOL bOldUpdateMode = getEngine().GetUpdateMode();   // TODO: guard?
        getEngine().SetUpdateMode( FALSE );

        getView().SetAttribs( _rAttributesToApply );

        getEngine().SetUpdateMode( bOldUpdateMode );
        getView().Invalidate();

        if ( HasChildPathFocus() )
            getView().ShowCursor();

        m_pImpl->updateAllAttributes();
            // TODO: maybe we should have a list of attributes which need to be updated
            // (the handler for the just executed attribute should know)
    }

    //--------------------------------------------------------------------
    void RichTextControl::enableAttributeNotification( AttributeId _nAttributeId, ITextAttributeListener* _pListener )
    {
        m_pImpl->enableAttributeNotification( _nAttributeId, _pListener );
    }

    //--------------------------------------------------------------------
    void RichTextControl::disableAttributeNotification( AttributeId _nAttributeId )
    {
        m_pImpl->disableAttributeNotification( _nAttributeId );
    }

    //--------------------------------------------------------------------
    bool RichTextControl::isMappableSlot( SfxSlotId _nSlotId )
    {
        switch ( _nSlotId )
        {
            case SID_ATTR_PARA_ADJUST_LEFT:
            case SID_ATTR_PARA_ADJUST_CENTER:
            case SID_ATTR_PARA_ADJUST_RIGHT:
            case SID_ATTR_PARA_ADJUST_BLOCK:
            case SID_SET_SUPER_SCRIPT:
            case SID_SET_SUB_SCRIPT:
            case SID_ATTR_PARA_LINESPACE_10:
            case SID_ATTR_PARA_LINESPACE_15:
            case SID_ATTR_PARA_LINESPACE_20:
            case SID_ATTR_PARA_LEFT_TO_RIGHT:
            case SID_ATTR_PARA_RIGHT_TO_LEFT:
            case SID_TEXTDIRECTION_TOP_TO_BOTTOM:
            case SID_TEXTDIRECTION_LEFT_TO_RIGHT:
            case SID_ATTR_CHAR_LATIN_FONT:
            case SID_ATTR_CHAR_LATIN_FONTHEIGHT:
            case SID_ATTR_CHAR_LATIN_LANGUAGE:
            case SID_ATTR_CHAR_LATIN_POSTURE:
            case SID_ATTR_CHAR_LATIN_WEIGHT:
                return true;
        }
        return false;
    }

    //--------------------------------------------------------------------
    void RichTextControl::convert( const SfxPoolItem& _rItem, FontDescriptor& _rUnoFont )
    {
        OSL_ENSURE( _rItem.ISA( SvxFontItem ), "RichTextControl::convert: invalid item type!" );

        _rUnoFont.Name    = static_cast< const SvxFontItem& >( _rItem ).GetFamilyName();
        _rUnoFont.Family  = static_cast< const SvxFontItem& >( _rItem ).GetFamily();
        _rUnoFont.Pitch   = static_cast< const SvxFontItem& >( _rItem ).GetPitch();
        _rUnoFont.CharSet = static_cast< const SvxFontItem& >( _rItem ).GetCharSet();
    }

    //--------------------------------------------------------------------
    void RichTextControl::convert( const FontDescriptor& _rUnoFont, SfxPoolItem*& _rpFontItem )
    {
        SvxFontItem* pFontItem = new SvxFontItem( SID_ATTR_CHAR_FONT );
        pFontItem->GetFamilyName() = _rUnoFont.Name;
        pFontItem->GetFamily()     = (FontFamily)_rUnoFont.Family;
        pFontItem->GetPitch()      = (FontPitch)_rUnoFont.Pitch;
        pFontItem->GetCharSet()    = _rUnoFont.CharSet;

        _rpFontItem = pFontItem;
    }

    //--------------------------------------------------------------------
    sal_uInt32 RichTextControl::convertFontHeight( const SfxPoolItem& _rItem )
    {
        OSL_ENSURE( _rItem.ISA( SvxFontHeightItem ), "RichTextControl::convert: invalid item type!" );
        return static_cast< const SvxFontHeightItem& >( _rItem ).GetHeight();
    }

    //--------------------------------------------------------------------
    SfxPoolItem* RichTextControl::convertFontHeight( sal_uInt32 _nUnoFontHeight )
    {
        SvxFontHeightItem* pItem = new SvxFontHeightItem( _nUnoFontHeight );
        pItem->SetProp( 100, SFX_MAPUNIT_POINT );
        return pItem;
    }

    //--------------------------------------------------------------------
    void RichTextControl::Resize()
    {
        m_pImpl->layoutWindow();
        Invalidate();
    }

    //--------------------------------------------------------------------
    void RichTextControl::GetFocus()
    {
        getViewport().GrabFocus();
    }

    //--------------------------------------------------------------------
    WinBits RichTextControl::implInitStyle( WinBits nStyle )
    {
        if ( !( nStyle & WB_NOTABSTOP ) )
            nStyle |= WB_TABSTOP;
        return nStyle;
    }

    //--------------------------------------------------------------------
    void RichTextControl::StateChanged( StateChangedType _nStateChange )
    {
        if ( _nStateChange == STATE_CHANGE_STYLE )
        {
            SetStyle( implInitStyle( GetStyle() ) );
            m_pImpl->notifyStyleChanged();
        }
        else if ( _nStateChange == STATE_CHANGE_ZOOM )
        {
            m_pImpl->notifyZoomChanged();
        }
        else if ( _nStateChange == STATE_CHANGE_INITSHOW )
        {
            m_pImpl->notifyInitShow();
        }
        Control::StateChanged( _nStateChange );
    }

    //--------------------------------------------------------------------
    long RichTextControl::PreNotify( NotifyEvent& _rNEvt )
    {
        if ( IsWindowOrChild( _rNEvt.GetWindow() ) )
        {
            if ( EVENT_KEYINPUT == _rNEvt.GetType() )
            {
                const KeyEvent* pKeyEvent = _rNEvt.GetKeyEvent();

                sal_uInt16 nCode = pKeyEvent->GetKeyCode().GetCode();
                sal_Bool   bShift = pKeyEvent->GetKeyCode().IsShift();
                sal_Bool   bCtrl = pKeyEvent->GetKeyCode().IsMod1();
                sal_Bool   bAlt = pKeyEvent->GetKeyCode().IsMod2();
                if ( ( KEY_TAB == nCode ) && bCtrl && !bAlt )
                {
                    // Ctrl-Tab is used to step out of the control
                    // -> build a new key event without the Ctrl-key, and let the very base class handle it
                    KeyCode aNewCode( KEY_TAB, bShift, sal_False, sal_False );
                    KeyEvent aNewEvent( pKeyEvent->GetCharCode(), aNewCode );
                    Control::KeyInput( aNewEvent );
                    return 1;   // handled
                }

#if OSL_DEBUG_LEVEL > 0
                if  (   (   ( KEY_F12 == nCode )
                        ||  ( KEY_F11 == nCode )
                        )
                    &&  bCtrl
                    &&  bAlt
                    )
                {
                    bool bLoad = KEY_F11 == nCode;
                    struct
                    {
                        const sal_Char* pDescription;
                        const sal_Char* pExtension;
                        EETextFormat    eFormat;
                    } aExportFormats[] =
                    {
                        { "OASIS OpenDocument (*.xml)", "*.xml", EE_FORMAT_XML },
                        { "HyperText Markup Language (*.html)", "*.html", EE_FORMAT_HTML },
                        { "Rich Text format (*.rtf)", "*.rtf", EE_FORMAT_RTF },
                        { "Text (*.txt)", "*.txt", EE_FORMAT_TEXT }
                    };

                    ::sfx2::FileDialogHelper aFP( bLoad ? ::sfx2::FILEOPEN_SIMPLE : ::sfx2::FILESAVE_AUTOEXTENSION, 0, this );

                    for ( size_t i = 0; i < sizeof( aExportFormats ) / sizeof( aExportFormats[ 0 ] ); ++i )
                    {
                        aFP.AddFilter(
                            String::CreateFromAscii( aExportFormats[i].pDescription ),
                            String::CreateFromAscii( aExportFormats[i].pExtension ) );
                    }
                    ErrCode nResult = aFP.Execute();
                    if ( nResult == 0 )
                    {
                        String sFileName = aFP.GetPath();
                        SvStream* pStream = ::utl::UcbStreamHelper::CreateStream(
                            sFileName, ( bLoad ? STREAM_READ : STREAM_WRITE | STREAM_TRUNC ) | STREAM_SHARE_DENYALL
                        );
                        if ( pStream )
                        {
                            EETextFormat eFormat = EE_FORMAT_XML;
                            String sFilter = aFP.GetCurrentFilter();
                            for ( size_t i = 0; i < sizeof( aExportFormats ) / sizeof( aExportFormats[ 0 ] ); ++i )
                            {
                                if ( sFilter.EqualsAscii( aExportFormats[i].pDescription ) )
                                {
                                    eFormat = aExportFormats[i].eFormat;
                                    break;
                                }
                            }
                            if ( bLoad )
                            {
                                INetURLObject aURL( sFileName );
                                aURL.removeSegment();
                                getEngine().Read( *pStream, aURL.GetMainURL( INetURLObject::NO_DECODE ), eFormat );
                            }
                            else
                            {
                                getEngine().Write( *pStream, eFormat );
                            }
                        }
                        DELETEZ( pStream );
                    }
                    return 1;   // handled
                }
#endif
            }
        }
        return Control::PreNotify( _rNEvt );
    }

    //--------------------------------------------------------------------
    long RichTextControl::Notify( NotifyEvent& _rNEvt )
    {
        long nDone = 0;
        if ( _rNEvt.GetType() == EVENT_COMMAND )
        {
            const CommandEvent& rEvent = *_rNEvt.GetCommandEvent();
            nDone = m_pImpl->HandleCommand( rEvent );
        }
        return nDone ? nDone : Control::Notify( _rNEvt );
    }

    //--------------------------------------------------------------------
    void RichTextControl::Draw( OutputDevice* _pDev, const Point& _rPos, const Size& _rSize, ULONG _nFlags )
    {
        m_pImpl->Draw( _pDev, _rPos, _rSize, _nFlags );
    }

    //--------------------------------------------------------------------
    EditView& RichTextControl::getView()
    {
        return *m_pImpl->getView( RichTextControlImpl::GrantAccess() );
    }

    //--------------------------------------------------------------------
    const EditView& RichTextControl::getView() const
    {
        return *m_pImpl->getView( RichTextControlImpl::GrantAccess() );
    }

    //--------------------------------------------------------------------
    EditEngine& RichTextControl::getEngine() const
    {
        return *m_pImpl->getEngine( RichTextControlImpl::GrantAccess() );
    }

    //--------------------------------------------------------------------
    Window& RichTextControl::getViewport() const
    {
        return *m_pImpl->getViewport( RichTextControlImpl::GrantAccess() );
    }

    //--------------------------------------------------------------------
    void RichTextControl::SetReadOnly( bool _bReadOnly )
    {
        m_pImpl->SetReadOnly( _bReadOnly );
    }

    //--------------------------------------------------------------------
    bool RichTextControl::IsReadOnly() const
    {
        return m_pImpl->IsReadOnly();
    }

    //--------------------------------------------------------------------
    void RichTextControl::SetBackgroundColor( )
    {
        m_pImpl->SetBackgroundColor( );
    }

    //--------------------------------------------------------------------
    void RichTextControl::SetBackgroundColor( const Color& _rColor )
    {
        m_pImpl->SetBackgroundColor( _rColor );
    }

    //--------------------------------------------------------------------
    void RichTextControl::SetHideInactiveSelection( bool _bHide )
    {
        m_pImpl->SetHideInactiveSelection( _bHide );
    }

    //--------------------------------------------------------------------
    bool RichTextControl::GetHideInactiveSelection() const
    {
        return m_pImpl->GetHideInactiveSelection( );
    }

//........................................................................
}   // namespace frm
//........................................................................

<|endoftext|>


<commit_before>#include "JobHandler/PathPlanningHandler.h"
#include <cmath>
using namespace std;

bool PathPlanningHandler::registered = JobHandler::RegisterJobHandler("path-planning", [](string command) {
	return (ptr<JobHandler>) std::make_shared<PathPlanningHandler>();
});

PathPlanningHandler::PathPlanningHandler()
{
	g = Grid(1000, 1000, 13, 13, 13, 0);
	shortPath = Dijkstra(500, 500);
	path = Path();
	track = 0;
}

PathPlanningHandler::PathPlanningHandler(float w, float h, float scal, float startx, float starty, float startAngle, float goalx, float goaly)
{
	g = Grid(w, h, scal, startx, starty, startAngle);
	shortPath = Dijkstra(goalx, goaly);
	path = Path();
	track = 0;
}

PathPlanningHandler::~PathPlanningHandler()
{
}

void PathPlanningHandler::execute(deque<Job>& jobs, SensorData & data, ControllerData & outputs)
{
	Obstacle newObs;
	auto usInfo = data.find("ULTRASOUNDF");
	if (usInfo != data.end()) {
		for (int i = 1; i <= 7; i++) {
			float inches = static_pointer_cast<UltrasoundData>(usInfo->second)->distance[i - 1];
			newObs = Obstacle(g.R2Pos.x, g.R2Pos.y, g.r2Angle, 3.14159265/4, inches);
			g.addObstacle(newObs);
		}
		path = shortPath.calcPath(&g);
		track = 0;
	}
	else {
		Coord moveTo = path.path[track];
		float xdist = moveTo.x - g.R2Pos.x;
		float ydist = moveTo.y - g.R2Pos.y;
		float radius = sqrt(pow(xdist, 2) + pow(ydist, 2));
		float angle = atan2(ydist, xdist) - g.r2Angle;
		int l = (int)(radius * cos(angle));
		int r = (int)(radius * sin(angle));
		track++;
		g.updatePos(moveTo.x, moveTo.y);
		ptr<MotorData> output = std::make_shared<MotorData>();
		output->leftMotor = l;
		output->rightMotor = r;
		outputs["MOTOR"] = output;

	}
}
<commit_msg>Added stopping motors when destination reached<commit_after>#include "JobHandler/PathPlanningHandler.h"
#include <cmath>
using namespace std;

bool PathPlanningHandler::registered = JobHandler::RegisterJobHandler("path-planning", [](string command) {
	return (ptr<JobHandler>) std::make_shared<PathPlanningHandler>();
});

PathPlanningHandler::PathPlanningHandler()
{
	g = Grid(1000, 1000, 13, 13, 13, 0);
	shortPath = Dijkstra(500, 500);
	path = Path();
	track = 0;
}

PathPlanningHandler::PathPlanningHandler(float w, float h, float scal, float startx, float starty, float startAngle, float goalx, float goaly)
{
	g = Grid(w, h, scal, startx, starty, startAngle);
	shortPath = Dijkstra(goalx, goaly);
	path = Path();
	track = 0;
}

PathPlanningHandler::~PathPlanningHandler()
{
}

void PathPlanningHandler::execute(deque<Job>& jobs, SensorData & data, ControllerData & outputs)
{
	Obstacle newObs;
	auto usInfo = data.find("ULTRASOUNDF");
	if (usInfo != data.end()) {
		//Add obstacle information to grid
		for (int i = 1; i <= 7; i++) {
			float inches = static_pointer_cast<UltrasoundData>(usInfo->second)->distance[i - 1];
			newObs = Obstacle(g.R2Pos.x, g.R2Pos.y, g.r2Angle, 3.14159265/4, inches);
			g.addObstacle(newObs);
		}
		//Recalculate path
		path = shortPath.calcPath(&g);
		track = 0;
	}
	else if(track < path.path.size()){
		//Extract next coordinate from shortest path and calculate motor commands
		Coord moveTo = path.path[track];
		float xdist = moveTo.x - g.R2Pos.x;
		float ydist = moveTo.y - g.R2Pos.y;
		float radius = sqrt(pow(xdist, 2) + pow(ydist, 2));
		float angle = atan2(ydist, xdist) - g.r2Angle;
		int l = (int)(radius * cos(angle));
		int r = (int)(radius * sin(angle));
		track++;
		g.updatePos(moveTo.x, moveTo.y);
		ptr<MotorData> output = std::make_shared<MotorData>();
		output->leftMotor = l;
		output->rightMotor = r;
		outputs["MOTOR"] = output;
	}
	else {
		//Stop motors if no path or goal reached
		ptr<MotorData> output = std::make_shared<MotorData>();
		output->leftMotor = 0;
		output->rightMotor = 0;
		outputs["MOTOR"] = output;
	}

}
<|endoftext|>


<commit_before>void SETUP()
{
   // Load some Root libraries needed by STEERBase
   gSystem->Load("libVMC");
   gSystem->Load("libNet");
   gSystem->Load("libTree");
   gSystem->Load("libPhysics");

   // Load the STEERBase library
   gSystem->Load("libSTEERBase");

   // Set the include paths
   gROOT->ProcessLine(".include STEERBase");

   // Set our location, so that other packages can find us
   gSystem->Setenv("STEERBase_INCLUDE", "STEERBase");
}
<commit_msg>Root does not give precedence anymore to current directory in the dynamic library search path. In case of usage of par files, this leads to loading the libraries in aliroot libdir instead of the compiled ones. This fix adds . in the search path at the profit of all libs loaded after STEERBase.<commit_after>void SETUP()
{
   // Load some Root libraries needed by STEERBase
   gSystem->Load("libVMC");
   gSystem->Load("libNet");
   gSystem->Load("libTree");
   gSystem->Load("libPhysics");

   // Load the STEERBase library
   TString dypath = gSystem->GetDynamicPath();
   dypath.Prepend(".:");
   gSystem->SetDynamicPath(dypath);
   gSystem->Load("libSTEERBase");

   // Set the include paths
   gROOT->ProcessLine(".include STEERBase");

   // Set our location, so that other packages can find us
   gSystem->Setenv("STEERBase_INCLUDE", "STEERBase");
}
<|endoftext|>


<commit_before>
#include <iostream>
#include <thread>
#include <deque>
#include <exception>
#include <mutex>
#include <chrono>

// #include <condition_variable>

bool WAITFOREXIT = true;
bool NOWAITFOREXIT = false;

void busywait(int lmax) {
    for(int i=0; i<lmax; i++) {
        for(int j=0; j<lmax; j++) {
            for(int k=0; k<lmax; k++) {
            }
        }
    }
}

class EmptyQueue: public std::exception {
    virtual const char* what() const throw() {
        return "EmptyQueue";
    }
};

class EmptyQueueTimeout: public std::exception {
    virtual const char* what() const throw() {
        return "EmptyQueueTimeout";
    }
};

using namespace std::chrono_literals;

template <class T>
class Queue {
    std::deque<T> m_queue;
    std::mutex m_mutex;
public:

    void put(T item) {
        m_mutex.lock();
        m_queue.push_back(item);
        m_mutex.unlock();
    }

    T get_nowait() {
        T result;
        m_mutex.lock();
        if (m_queue.empty()) {
            m_mutex.unlock();
            throw EmptyQueue();
        }
        result = m_queue.front();
        m_queue.pop_front();
        m_mutex.unlock();
        return result;
    }

    T get() {
        return get_timeout(0);
    }

    T get_timeout(int timeout_ms) {
        int so_far_ms = 0;
        T result;
        while (true) {
            m_mutex.lock();
            if (!m_queue.empty()) {
                break;
            }
            m_mutex.unlock();
            std::this_thread::sleep_for(2ms);
            so_far_ms += 2;
            if (timeout_ms and so_far_ms > timeout_ms) {
                throw EmptyQueueTimeout();
            }
            std::this_thread::yield();
        }

        result = m_queue.front();
        m_queue.pop_front();
        m_mutex.unlock();
        return result;
    }
};

class Actor { // I know this is bad practice. This is a sketch remember?
public:
    std::thread m_Thread;
    bool m_let_me_finish;

protected:
    virtual void main() {
        for(int i=0; i<20; i++) {
            busywait(350);
            std::cout << "              Actor::main " << std::this_thread::get_id() << " Executing:" << i << std::endl;
        }
    }

public:
    Actor(): m_Thread(), m_let_me_finish(false) { };
    Actor(bool X): m_Thread(), m_let_me_finish(X) { };
    void run() {
        m_Thread = std::thread(&Actor::main, this);
        if (!m_let_me_finish) {
            m_Thread.detach();
        }
    }
    ~Actor() {
        if (m_let_me_finish) {
            m_Thread.join(); // Appropriate?
        }
    }
};

class Producer : public Actor {
public:
    std::string m_tag;
    Queue<int> * q;

    Producer(std::string name): Actor(), m_tag(name) {}
    Producer(std::string name, Queue<int> * Q): Actor(), m_tag(name), q(Q) {}
    void set_outbox(Queue<int> * Q) {
        q = Q;
    }
    void main() {
        for(int i=0; i<20; i++) {
            busywait(95);
            q->put(i);
        }
        q->put(-1);
    }
};

class Consumer : public Actor {
public:
    std::string m_tag;
    Queue<int> * q;

    Consumer(std::string name): Actor(), m_tag(name) {}
    Consumer(std::string name, Queue<int> * Q): Actor(), m_tag(name), q(Q) {}
    void set_inbox(Queue<int> * Q) {
        q = Q;
    }
    void main() {
        while(true) {
            int result;
            busywait(105);
            try {
                result = q->get_timeout(10);
            } catch (EmptyQueueTimeout& e) {
                break;
            }
            std::cout << "CONSUMER " << m_tag << " " << result << std::endl;
        }
        std::cout << "CONSUMER " << m_tag << " exitting" << std::endl;
    }
};

int main(int argc, char *argv[]) {
    Queue<int> q;

    Producer P1("P1", &q);
    Producer P2("P2");
    Consumer C1("C1", &q);
    P2.set_outbox(&q);

    P1.run();
    P2.run();
    C1.run();

    for(int i=0; i<10; i++) {
            busywait(200);
    }

    std::cout<<"Exit of Main function"<<std::endl;

    return 0;
}
<commit_msg>Add comment<commit_after>
#include <iostream>
#include <thread>
#include <deque>
#include <exception>
#include <mutex>
#include <chrono>

// #include <condition_variable>

bool WAITFOREXIT = true;
bool NOWAITFOREXIT = false;

void busywait(int lmax) {
    for(int i=0; i<lmax; i++) {
        for(int j=0; j<lmax; j++) {
            for(int k=0; k<lmax; k++) {
            }
        }
    }
}

class EmptyQueue: public std::exception {
    virtual const char* what() const throw() {
        return "EmptyQueue";
    }
};

class EmptyQueueTimeout: public std::exception {
    virtual const char* what() const throw() {
        return "EmptyQueueTimeout";
    }
};

using namespace std::chrono_literals;

template <class T>
class Queue {
    std::deque<T> m_queue;
    std::mutex m_mutex;
public:

    void put(T item) {
        m_mutex.lock();
        m_queue.push_back(item);
        m_mutex.unlock();
    }

    T get_nowait() {
        T result;
        m_mutex.lock();
        if (m_queue.empty()) {
            m_mutex.unlock();
            throw EmptyQueue();
        }
        result = m_queue.front();
        m_queue.pop_front();
        m_mutex.unlock();
        return result;
    }

    T get() {
        return get_timeout(0);
    }

    T get_timeout(int timeout_ms) {
        int so_far_ms = 0;
        T result;
        while (true) {
            m_mutex.lock();
            if (!m_queue.empty()) {
                break;
            }
            m_mutex.unlock();
            std::this_thread::sleep_for(2ms);
            so_far_ms += 2;
            if (timeout_ms and so_far_ms > timeout_ms) {
                throw EmptyQueueTimeout();
            }
            std::this_thread::yield(); // be nice to other threads
        }

        result = m_queue.front();
        m_queue.pop_front();
        m_mutex.unlock();
        return result;
    }
};

class Actor { // I know this is bad practice. This is a sketch remember?
public:
    std::thread m_Thread;
    bool m_let_me_finish;

protected:
    virtual void main() {
        for(int i=0; i<20; i++) {
            busywait(350);
            std::cout << "              Actor::main " << std::this_thread::get_id() << " Executing:" << i << std::endl;
        }
    }

public:
    Actor(): m_Thread(), m_let_me_finish(false) { };
    Actor(bool X): m_Thread(), m_let_me_finish(X) { };
    void run() {
        m_Thread = std::thread(&Actor::main, this);
        if (!m_let_me_finish) {
            m_Thread.detach();
        }
    }
    ~Actor() {
        if (m_let_me_finish) {
            m_Thread.join(); // Appropriate?
        }
    }
};

class Producer : public Actor {
public:
    std::string m_tag;
    Queue<int> * q;

    Producer(std::string name): Actor(), m_tag(name) {}
    Producer(std::string name, Queue<int> * Q): Actor(), m_tag(name), q(Q) {}
    void set_outbox(Queue<int> * Q) {
        q = Q;
    }
    void main() {
        for(int i=0; i<20; i++) {
            busywait(95);
            q->put(i);
        }
        q->put(-1);
    }
};

class Consumer : public Actor {
public:
    std::string m_tag;
    Queue<int> * q;

    Consumer(std::string name): Actor(), m_tag(name) {}
    Consumer(std::string name, Queue<int> * Q): Actor(), m_tag(name), q(Q) {}
    void set_inbox(Queue<int> * Q) {
        q = Q;
    }
    void main() {
        while(true) {
            int result;
            busywait(105);
            try {
                result = q->get_timeout(10);
            } catch (EmptyQueueTimeout& e) {
                break;
            }
            std::cout << "CONSUMER " << m_tag << " " << result << std::endl;
        }
        std::cout << "CONSUMER " << m_tag << " exitting" << std::endl;
    }
};

int main(int argc, char *argv[]) {
    Queue<int> q;

    Producer P1("P1", &q);
    Producer P2("P2");
    Consumer C1("C1", &q);
    P2.set_outbox(&q);

    P1.run();
    P2.run();
    C1.run();

    for(int i=0; i<10; i++) {
            busywait(200);
    }

    std::cout<<"Exit of Main function"<<std::endl;

    return 0;
}
<|endoftext|>


<commit_before>// GUI of MediaInfo
// Copyright (C) 2011-2012 MediaArea.net SARL, Info@MediaArea.net
//
// This program is free software: you can redistribute it and/or modify it
// under the terms of the GNU Library General Public License as published by
// the Free Software Foundation, either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

#include "columneditsheet.h"
#include "sheet.h"
#include <QtGui/QLineEdit>
#include <QtGui/QSpinBox>
#include <QtGui/QComboBox>
#include <QtGui/QToolButton>
#include "translate.h"

#include <ZenLib/Ztring.h>
using namespace ZenLib;
#define wstring2QString(_DATA) \
    QString::fromUtf8(Ztring(_DATA).To_UTF8().c_str())
#define QString2wstring(_DATA) \
    Ztring().From_UTF8(_DATA.toUtf8())

ColumnEditSheet::ColumnEditSheet(column c, int pos, int nb, Core* C, QWidget *parent) :
    QHBoxLayout(parent)
{
    this->pos = pos;
    this->C = C;
    this->col = c;

    QLineEdit* lineedit = new QLineEdit(c.name);
    this->addWidget(lineedit);
    spinbox = new QSpinBox();
    spinbox->setMinimum(0);
    spinbox->setMaximum(500);
    spinbox->setValue(c.width);
    this->addWidget(spinbox);
    stream = new QComboBox();
    for (int streamKind=(int)Stream_General; streamKind<(int)Stream_Max; streamKind++)
    {
        if(streamKind==Stream_Other)
            continue;
        stream->addItem(wstring2QString(C->StreamName((stream_t)streamKind)),streamKind);
    }
    stream->setCurrentIndex(c.stream);
    this->addWidget(stream);
    combobox = new QComboBox();
    combobox->addItem(c.key,c.key);
    this->addWidget(combobox);
    up = new QToolButton();
    up->setArrowType(Qt::UpArrow);
    //up->setSizePolicy(QSizePolicy::Minimum);
    this->addWidget(up);
    down = new QToolButton();
    down->setArrowType(Qt::DownArrow);
    down->setBaseSize(480,480);
    down->setMaximumHeight(spinbox->height());
    this->addWidget(down);
    minus = new QToolButton();
    minus->setText("-");
    this->addWidget(minus);

    connect(lineedit,SIGNAL(textChanged(QString)),SLOT(contentChanged()));
    connect(spinbox,SIGNAL(valueChanged(int)),SLOT(contentChanged()));
    connect(up,SIGNAL(clicked()),SLOT(upButton()));
    connect(down,SIGNAL(clicked()),SLOT(downButton()));
    connect(minus,SIGNAL(clicked()),SLOT(minusButton()));
    connect(stream,SIGNAL(currentIndexChanged(int)),SLOT(fillCombobox()));

    fillCombobox();

    posChanged(nb);
}

ColumnEditSheet::~ColumnEditSheet() {
    while (QLayoutItem* i = takeAt(0)) {
        delete i->widget();
    }
}

void ColumnEditSheet::fillCombobox() {
    combobox->clear();
    QString s = wstring2QString(C->Parameters());
    s.replace("\r\n","\n").replace("\r","\n");
    s.remove(0,s.indexOf(stream->currentText()+"\n"));
    s.truncate((s.indexOf("\n\n")==-1?s.size():s.indexOf("\n\n")));
    QStringList sl = s.split("\n");
    sl.removeAt(0);
    sl.replaceInStrings(QRegExp(";(.*)"),"");
    for (int i=0; i<sl.size(); ++i)
        combobox->addItem(sl.at(i),sl.at(i));
    if(stream->itemData(stream->currentIndex()).toInt()==col.stream)
        combobox->setCurrentIndex(sl.indexOf(col.key));
}

void ColumnEditSheet::contentChanged() {
    emit somethingChanged();
}

void ColumnEditSheet::upButton() {
    emit moveMeUp(pos);
}

void ColumnEditSheet::downButton() {
    emit moveMeDown(pos);
}

void ColumnEditSheet::minusButton() {
    emit removeMe(pos);
}

void ColumnEditSheet::posSwitched(int p1, int p2, int nb) {
    if(pos==p1)
        pos=p2;
    else if(pos==p2)
        pos=p1;
    posChanged(nb);
}

void ColumnEditSheet::posRemoved(int p, int nb) {
    if(pos>p)
        pos--;
    posChanged(nb);
}

void ColumnEditSheet::posChanged(int nb) {
    up->setEnabled(pos!=0);
    down->setEnabled(pos!=(nb-1));
    minus->setEnabled(nb>1);
    emit somethingChanged();
}
<commit_msg>+ Running tabspace. Thanks to XhmikosR<commit_after>// GUI of MediaInfo
// Copyright (C) 2011-2012 MediaArea.net SARL, Info@MediaArea.net
//
// This program is free software: you can redistribute it and/or modify it
// under the terms of the GNU Library General Public License as published by
// the Free Software Foundation, either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

#include "columneditsheet.h"
#include "sheet.h"
#include <QtGui/QLineEdit>
#include <QtGui/QSpinBox>
#include <QtGui/QComboBox>
#include <QtGui/QToolButton>
#include "translate.h"

#include <ZenLib/Ztring.h>
using namespace ZenLib;

#define wstring2QString(_DATA)  QString::fromUtf8(Ztring(_DATA).To_UTF8().c_str())
#define QString2wstring(_DATA)  Ztring().From_UTF8(_DATA.toUtf8())

ColumnEditSheet::ColumnEditSheet(column c, int pos, int nb, Core* C, QWidget *parent) :
    QHBoxLayout(parent)
{
    this->pos = pos;
    this->C = C;
    this->col = c;

    QLineEdit* lineedit = new QLineEdit(c.name);
    this->addWidget(lineedit);
    spinbox = new QSpinBox();
    spinbox->setMinimum(0);
    spinbox->setMaximum(500);
    spinbox->setValue(c.width);
    this->addWidget(spinbox);
    stream = new QComboBox();
    for (int streamKind=(int)Stream_General; streamKind<(int)Stream_Max; streamKind++)
    {
        if(streamKind==Stream_Other)
            continue;
        stream->addItem(wstring2QString(C->StreamName((stream_t)streamKind)),streamKind);
    }
    stream->setCurrentIndex(c.stream);
    this->addWidget(stream);
    combobox = new QComboBox();
    combobox->addItem(c.key,c.key);
    this->addWidget(combobox);
    up = new QToolButton();
    up->setArrowType(Qt::UpArrow);
    //up->setSizePolicy(QSizePolicy::Minimum);
    this->addWidget(up);
    down = new QToolButton();
    down->setArrowType(Qt::DownArrow);
    down->setBaseSize(480,480);
    down->setMaximumHeight(spinbox->height());
    this->addWidget(down);
    minus = new QToolButton();
    minus->setText("-");
    this->addWidget(minus);

    connect(lineedit,SIGNAL(textChanged(QString)),SLOT(contentChanged()));
    connect(spinbox,SIGNAL(valueChanged(int)),SLOT(contentChanged()));
    connect(up,SIGNAL(clicked()),SLOT(upButton()));
    connect(down,SIGNAL(clicked()),SLOT(downButton()));
    connect(minus,SIGNAL(clicked()),SLOT(minusButton()));
    connect(stream,SIGNAL(currentIndexChanged(int)),SLOT(fillCombobox()));

    fillCombobox();

    posChanged(nb);
}

ColumnEditSheet::~ColumnEditSheet() {
    while (QLayoutItem* i = takeAt(0)) {
        delete i->widget();
    }
}

void ColumnEditSheet::fillCombobox() {
    combobox->clear();
    QString s = wstring2QString(C->Parameters());
    s.replace("\r\n","\n").replace("\r","\n");
    s.remove(0,s.indexOf(stream->currentText()+"\n"));
    s.truncate((s.indexOf("\n\n")==-1?s.size():s.indexOf("\n\n")));
    QStringList sl = s.split("\n");
    sl.removeAt(0);
    sl.replaceInStrings(QRegExp(";(.*)"),"");
    for (int i=0; i<sl.size(); ++i)
        combobox->addItem(sl.at(i),sl.at(i));
    if(stream->itemData(stream->currentIndex()).toInt()==col.stream)
        combobox->setCurrentIndex(sl.indexOf(col.key));
}

void ColumnEditSheet::contentChanged() {
    emit somethingChanged();
}

void ColumnEditSheet::upButton() {
    emit moveMeUp(pos);
}

void ColumnEditSheet::downButton() {
    emit moveMeDown(pos);
}

void ColumnEditSheet::minusButton() {
    emit removeMe(pos);
}

void ColumnEditSheet::posSwitched(int p1, int p2, int nb) {
    if(pos==p1)
        pos=p2;
    else if(pos==p2)
        pos=p1;
    posChanged(nb);
}

void ColumnEditSheet::posRemoved(int p, int nb) {
    if(pos>p)
        pos--;
    posChanged(nb);
}

void ColumnEditSheet::posChanged(int nb) {
    up->setEnabled(pos!=0);
    down->setEnabled(pos!=(nb-1));
    minus->setEnabled(nb>1);
    emit somethingChanged();
}
<|endoftext|>


<commit_before>/*
 *  qmcdespot.cpp
 *
 *  Created by Tobias Wood on 03/06/2015.
 *  Copyright (c) 2015 Tobias Wood.
 *
 *  This Source Code Form is subject to the terms of the Mozilla Public
 *  License, v. 2.0. If a copy of the MPL was not distributed with this
 *  file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 */

#include <iostream>
#include <Eigen/Dense>
#include <unsupported/Eigen/LevenbergMarquardt>
#include <unsupported/Eigen/NumericalDiff>

#include "itkTimeProbe.h"

#include "Types.h"
#include "Util.h"
#include "Args.h"
#include "IO.h"
#include "Model.h"
#include "Sequences.h"
#include "RegionContraction.h"
#include "ApplyAlgorithmFilter.h"
#include "ReorderVectorFilter.h"

/*
 * Read in all required files and data from cin
 */
void parseInput(std::shared_ptr<QI::SequenceGroup> seq, std::vector<typename QI::VectorVolumeF::Pointer> &images,
                bool verbose, bool prompt);
void parseInput(std::shared_ptr<QI::SequenceGroup> seq, std::vector<typename QI::VectorVolumeF::Pointer> &images,
                bool verbose, bool prompt)
{
    std::string path;
    if (prompt) std::cout << "Enter input filename: " << std::flush;
    while (QI::Read(std::cin, path) && (path != "END") && (path != "")) {
        if (verbose) std::cout << "Reading file: " << path << std::endl;
        auto image = QI::ReadVectorImage<float>(path);
        seq->addSequence(QI::ReadSequence(std::cin, prompt));
        image->DisconnectPipeline(); // This step is really important.
        images.push_back(image);
        if (prompt) std::cout << "Enter next filename (END to finish input): " << std::flush;
    }
}

class MCDAlgo : public QI::ApplyF::Algorithm {
protected:
    Eigen::ArrayXXd m_bounds;
    std::shared_ptr<QI::Model> m_model = nullptr;
    std::shared_ptr<QI::SequenceGroup> m_sequence = nullptr;
    QI::FieldStrength m_tesla = QI::FieldStrength::Three;
    int m_iterations = 0;

public:
    MCDAlgo(std::shared_ptr<QI::Model>&m, Eigen::ArrayXXd &b,
            std::shared_ptr<QI::SequenceGroup> s, int mi) :
        m_model(m), m_bounds(b), m_sequence(s), m_iterations(mi)
    {}

    size_t numInputs() const override  { return m_sequence->count(); }
    size_t numOutputs() const override { return m_model->nParameters(); }
    size_t dataSize() const override   { return m_sequence->size(); }

    void setModel(std::shared_ptr<QI::Model> &m) { m_model = m; }
    void setSequence(std::shared_ptr<QI::SequenceGroup> &s) { m_sequence = s; }
    void setBounds(Eigen::ArrayXXd &b) { m_bounds = b; }
    void setIterations(const int i) { m_iterations = i; }
    float zero() const override { return 0.f; }
};

class MCDSRCFunctor {
    public:
        const std::shared_ptr<QI::SequenceGroup> m_sequence;
        const Eigen::ArrayXd m_data, m_weights;
        const std::shared_ptr<QI::Model> m_model;

        MCDSRCFunctor(std::shared_ptr<QI::Model> m, std::shared_ptr<QI::SequenceGroup> s,
                      const Eigen::ArrayXd &d, const Eigen::ArrayXd &w) :
            m_sequence(s), m_data(d), m_model(m), m_weights(w)
        {
            assert(static_cast<size_t>(m_data.rows()) == m_sequence->size());
        }

        int inputs() const { return m_model->nParameters(); }
        int values() const { return m_sequence->size(); }

        const bool constraint(const Eigen::VectorXd &params) const {
            return m_model->ValidParameters(params);
        }

        Eigen::ArrayXd residuals(const Eigen::Ref<Eigen::VectorXd> &params) const {
            const Eigen::ArrayXd s = (m_sequence->signal(m_model, params)).abs();
            return m_data - s;
        }
        double operator()(const Eigen::Ref<Eigen::VectorXd> &params) const {
            return (residuals(params) * m_weights).square().sum();
        }
};

class SRCAlgo : public MCDAlgo {
using MCDAlgo::MCDAlgo;

private:
    size_t m_samples = 5000, m_retain = 50;
    bool m_gauss = true;

public:
    void setGauss(bool g) { m_gauss = g; }

    size_t numConsts() const override  { return 2; }
    std::vector<float> defaultConsts() const override {
        std::vector<float> def(2);
        def[0] = NAN; def[1] = 1.0f; // f0, B1
        return def;
    }

bool apply(const std::vector<TInput> &inputs, const std::vector<TConst> &consts,
           std::vector<TOutput> &outputs, TConst &residual,
           TInput &resids, TIters &its) const override
    {
        Eigen::ArrayXd data(dataSize());
        int dataIndex = 0;
        for (int i = 0; i < inputs.size(); i++) {
            Eigen::Map<const Eigen::ArrayXf> this_data(inputs[i].GetDataPointer(), inputs[i].Size());
            if (m_model->scaleToMean()) {
                data.segment(dataIndex, this_data.rows()) = this_data.cast<double>() / this_data.abs().mean();
            } else {
                data.segment(dataIndex, this_data.rows()) = this_data.cast<double>();
            }
            dataIndex += this_data.rows();
        }
        Eigen::ArrayXd thresh(m_model->nParameters()); thresh.setConstant(0.05);
        const double f0 = consts[0];
        const double B1 = consts[1];
        Eigen::ArrayXXd localBounds = m_bounds;
        Eigen::ArrayXd weights = Eigen::ArrayXd::Ones(m_sequence->size());
        if (isfinite(f0)) { // We have an f0 map, add it to the fitting bounds
            localBounds.row(m_model->ParameterIndex("f0")) += f0;
            weights = m_sequence->weights(f0);
        }
        localBounds.row(m_model->ParameterIndex("B1")).setConstant(B1);
        MCDSRCFunctor func(m_model, m_sequence, data, weights);
        QI::RegionContraction<MCDSRCFunctor> rc(func, localBounds, thresh, m_samples, m_retain, m_iterations, 0.02, m_gauss, false);
        Eigen::ArrayXd pars(m_model->nParameters());
        rc.optimise(pars);
        for (int i = 0; i < m_model->nParameters(); i++) {
            outputs[i] = pars[i];
        }
        Eigen::ArrayXf r = func.residuals(pars).cast<float>();
        residual = sqrt(r.square().sum() / r.rows());
        resids = itk::VariableLengthVector<float>(r.data(), r.rows());
        its = rc.contractions();
        return true;
    }
};

//******************************************************************************
// Main
//******************************************************************************
int main(int argc, char **argv) {
    Eigen::initParallel();
    args::ArgumentParser parser("Calculates MWF & other parameter maps from mcDESPOT data\n"
                                "All times (e.g. T1, TR) are in SECONDS. All angles are in degrees.\n"
                                "http://github.com/spinicist/QUIT");
    args::HelpFlag help(parser, "HELP", "Show this help message", {'h', "help"});
    args::Flag     verbose(parser, "VERBOSE", "Print more information", {'v', "verbose"});
    args::Flag     noprompt(parser, "NOPROMPT", "Suppress input prompts", {'n', "no-prompt"});
    args::ValueFlag<int> threads(parser, "THREADS", "Use N threads (default=4, 0=hardware limit)", {'T', "threads"}, 4);
    args::ValueFlag<std::string> outarg(parser, "OUTPREFIX", "Add a prefix to output filenames", {'o', "out"});
    args::ValueFlag<std::string> f0(parser, "f0", "f0 map (Hertz)", {'f', "f0"});
    args::ValueFlag<std::string> B1(parser, "B1", "B1 map (ratio)", {'b', "B1"});
    args::ValueFlag<std::string> mask(parser, "MASK", "Only process voxels within the mask", {'m', "mask"});
    args::ValueFlag<std::string> subregion(parser, "SUBREGION", "Process subregion starting at voxel I,J,K with size SI,SJ,SK", {'s', "subregion"});
    args::Flag resids(parser, "RESIDS", "Write out residuals for each data-point", {'r', "resids"});
    args::ValueFlag<std::string> modelarg(parser, "MODEL", "Select model to fit - 1/2/2nex/3/3_f0/3nex, default 3", {'m', "model"}, "3");
    args::Flag scale(parser, "SCALE", "Normalize signals to mean (a good idea)", {'S', "scale"});
    args::ValueFlag<char> algorithm(parser, "ALGO", "Select (S)tochastic or (G)aussian Region Contraction", {'a', "algo"}, 'G');
    args::ValueFlag<int> its(parser, "ITERS", "Max iterations, default 4", {'i',"its"}, 4);
    args::ValueFlag<char> field(parser, "FIELD STRENGTH", "Specify field-strength for fitting regions - 3/7/u for user input", {'t', "tesla"}, '3');
    QI::ParseArgs(parser, argc, argv);
    bool prompt = !noprompt;

    std::shared_ptr<QI::Model> model = nullptr;
    if (modelarg.Get() == "1")         { model = std::make_shared<QI::SCD>(); }
    else if (modelarg.Get() == "2")    { model = std::make_shared<QI::MCD2>(); }
    else if (modelarg.Get() == "2nex") { model = std::make_shared<QI::MCD2_NoEx>(); }
    else if (modelarg.Get() == "3")    { model = std::make_shared<QI::MCD3>(); }
    else if (modelarg.Get() == "3_f0") { model = std::make_shared<QI::MCD3_f0>(); }
    else if (modelarg.Get() == "3nex") { model = std::make_shared<QI::MCD3_NoEx>(); }
    else {
        std::cerr << "Invalid model " << modelarg.Get() << " specified." << std::endl;
        return EXIT_FAILURE;
    }
    if (verbose) std::cout << "Using " << model->Name() << " model." << std::endl;
    if (verbose && scale) std::cout << "Mean-scaling selected" << std::endl;
    model->setScaleToMean(scale);

    Eigen::ArrayXXd bounds;
    Eigen::ArrayXd start;
    switch (field.Get()) {
        case '3':
            bounds = model->Bounds(QI::FieldStrength::Three);
            start = model->Default(QI::FieldStrength::Three);
            break;
        case '7':
            bounds = model->Bounds(QI::FieldStrength::Seven);
            start = model->Bounds(QI::FieldStrength::Seven);
            break;
        case 'u': {
            Eigen::ArrayXd temp;
            if (prompt) std::cout << "Enter lower bounds" << std::endl;
            QI::ReadArray(std::cin, temp);
            bounds.col(0) = temp;
            if (prompt) std::cout << "Enter upper bounds" << std::endl;
            QI::ReadArray(std::cin, temp);
            bounds.col(1) = temp;
        } break;
    default:
        std::cerr << "Unknown boundaries type " << field.Get() << std::endl;
        return EXIT_FAILURE;
        break;
    }

    if (prompt) {
        std::cout << "Starting qimcdespot\n"
                     "Run with -h switch to see usage" << std::endl;
    }

    std::shared_ptr<QI::SequenceGroup> sequences = std::make_shared<QI::SequenceGroup>();
    std::vector<QI::VectorVolumeF::Pointer> images;
    parseInput(sequences, images, verbose, prompt);
    auto apply = QI::ApplyF::New();
    switch (algorithm.Get()) {
        case 'S': {
            if (verbose) std::cout << "Using SRC algorithm" << std::endl;
            std::shared_ptr<SRCAlgo> algo = std::make_shared<SRCAlgo>(model, bounds, sequences, its.Get());
            algo->setGauss(false);
            apply->SetAlgorithm(algo);
        } break;
        case 'G': {
            if (verbose) std::cout << "Using GRC algorithm" << std::endl;
            std::shared_ptr<SRCAlgo> algo = std::make_shared<SRCAlgo>(model, bounds, sequences, its.Get());
            algo->setGauss(true);
            apply->SetAlgorithm(algo);
        } break;
        default:
            std::cerr << "Unknown algorithm type " << algorithm.Get() << std::endl;
            return EXIT_FAILURE;
    }
    apply->SetOutputAllResiduals(resids);
    apply->SetVerbose(verbose);
    apply->SetPoolsize(threads.Get());
    apply->SetSplitsPerThread(threads.Get()); // mcdespot with a mask & threads is a very unbalanced algorithm
    for (int i = 0; i < images.size(); i++) {
        apply->SetInput(i, images[i]);
    }
    if (f0) apply->SetConst(0, QI::ReadImage(f0.Get()));
    if (B1) apply->SetConst(1, QI::ReadImage(B1.Get()));
    if (mask) apply->SetMask(QI::ReadImage(mask.Get()));
    if (subregion) apply->SetSubregion(QI::RegionArg(args::get(subregion)));

    // Need this here so the bounds.txt file will have the correct prefix
    std::string outPrefix = outarg.Get() + model->Name() + "_";
    if (verbose) {
        std::cout << *sequences;
        std::cout << "Bounds:\n" <<  bounds.transpose() << std::endl;
        std::ofstream boundsFile(outPrefix + "bounds.txt");
        boundsFile << "Names: ";
        for (size_t p = 0; p < model->nParameters(); p++) {
            boundsFile << model->ParameterNames()[p] << "\t";
        }
        boundsFile << std::endl << "Bounds:\n" << bounds.transpose() << std::endl;
        boundsFile.close();
    }

    if (verbose) {
        std::cout << "Processing" << std::endl;
        auto monitor = QI::GenericMonitor::New();
        apply->AddObserver(itk::ProgressEvent(), monitor);
    }
    apply->Update();
    if (verbose) {
        std::cout << "Elapsed time was " << apply->GetTotalTime() << "s" << std::endl;
        std::cout << "Writing results files." << std::endl;
    }
    for (int i = 0; i < model->nParameters(); i++) {
        QI::WriteImage(apply->GetOutput(i), outPrefix + model->ParameterNames()[i] + QI::OutExt());
    }
    QI::WriteScaledImage(apply->GetResidualOutput(), apply->GetOutput(0), outPrefix + "residual" + QI::OutExt());
    if (resids) {
        QI::WriteScaledVectorImage(apply->GetAllResidualsOutput(), apply->GetOutput(0), outPrefix + "all_residuals" + QI::OutExt());
    }
    QI::WriteImage(apply->GetIterationsOutput(), outPrefix + "iterations" + QI::OutExt());
    return EXIT_SUCCESS;
}

<commit_msg>BUG: Incorrect argument specifier<commit_after>/*
 *  qmcdespot.cpp
 *
 *  Created by Tobias Wood on 03/06/2015.
 *  Copyright (c) 2015 Tobias Wood.
 *
 *  This Source Code Form is subject to the terms of the Mozilla Public
 *  License, v. 2.0. If a copy of the MPL was not distributed with this
 *  file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 */

#include <iostream>
#include <Eigen/Dense>
#include <unsupported/Eigen/LevenbergMarquardt>
#include <unsupported/Eigen/NumericalDiff>

#include "itkTimeProbe.h"

#include "Types.h"
#include "Util.h"
#include "Args.h"
#include "IO.h"
#include "Model.h"
#include "Sequences.h"
#include "RegionContraction.h"
#include "ApplyAlgorithmFilter.h"
#include "ReorderVectorFilter.h"

/*
 * Read in all required files and data from cin
 */
void parseInput(std::shared_ptr<QI::SequenceGroup> seq, std::vector<typename QI::VectorVolumeF::Pointer> &images,
                bool verbose, bool prompt);
void parseInput(std::shared_ptr<QI::SequenceGroup> seq, std::vector<typename QI::VectorVolumeF::Pointer> &images,
                bool verbose, bool prompt)
{
    std::string path;
    if (prompt) std::cout << "Enter input filename: " << std::flush;
    while (QI::Read(std::cin, path) && (path != "END") && (path != "")) {
        if (verbose) std::cout << "Reading file: " << path << std::endl;
        auto image = QI::ReadVectorImage<float>(path);
        seq->addSequence(QI::ReadSequence(std::cin, prompt));
        image->DisconnectPipeline(); // This step is really important.
        images.push_back(image);
        if (prompt) std::cout << "Enter next filename (END to finish input): " << std::flush;
    }
}

class MCDAlgo : public QI::ApplyF::Algorithm {
protected:
    Eigen::ArrayXXd m_bounds;
    std::shared_ptr<QI::Model> m_model = nullptr;
    std::shared_ptr<QI::SequenceGroup> m_sequence = nullptr;
    QI::FieldStrength m_tesla = QI::FieldStrength::Three;
    int m_iterations = 0;

public:
    MCDAlgo(std::shared_ptr<QI::Model>&m, Eigen::ArrayXXd &b,
            std::shared_ptr<QI::SequenceGroup> s, int mi) :
        m_model(m), m_bounds(b), m_sequence(s), m_iterations(mi)
    {}

    size_t numInputs() const override  { return m_sequence->count(); }
    size_t numOutputs() const override { return m_model->nParameters(); }
    size_t dataSize() const override   { return m_sequence->size(); }

    void setModel(std::shared_ptr<QI::Model> &m) { m_model = m; }
    void setSequence(std::shared_ptr<QI::SequenceGroup> &s) { m_sequence = s; }
    void setBounds(Eigen::ArrayXXd &b) { m_bounds = b; }
    void setIterations(const int i) { m_iterations = i; }
    float zero() const override { return 0.f; }
};

class MCDSRCFunctor {
    public:
        const std::shared_ptr<QI::SequenceGroup> m_sequence;
        const Eigen::ArrayXd m_data, m_weights;
        const std::shared_ptr<QI::Model> m_model;

        MCDSRCFunctor(std::shared_ptr<QI::Model> m, std::shared_ptr<QI::SequenceGroup> s,
                      const Eigen::ArrayXd &d, const Eigen::ArrayXd &w) :
            m_sequence(s), m_data(d), m_model(m), m_weights(w)
        {
            assert(static_cast<size_t>(m_data.rows()) == m_sequence->size());
        }

        int inputs() const { return m_model->nParameters(); }
        int values() const { return m_sequence->size(); }

        const bool constraint(const Eigen::VectorXd &params) const {
            return m_model->ValidParameters(params);
        }

        Eigen::ArrayXd residuals(const Eigen::Ref<Eigen::VectorXd> &params) const {
            const Eigen::ArrayXd s = (m_sequence->signal(m_model, params)).abs();
            return m_data - s;
        }
        double operator()(const Eigen::Ref<Eigen::VectorXd> &params) const {
            return (residuals(params) * m_weights).square().sum();
        }
};

class SRCAlgo : public MCDAlgo {
using MCDAlgo::MCDAlgo;

private:
    size_t m_samples = 5000, m_retain = 50;
    bool m_gauss = true;

public:
    void setGauss(bool g) { m_gauss = g; }

    size_t numConsts() const override  { return 2; }
    std::vector<float> defaultConsts() const override {
        std::vector<float> def(2);
        def[0] = NAN; def[1] = 1.0f; // f0, B1
        return def;
    }

bool apply(const std::vector<TInput> &inputs, const std::vector<TConst> &consts,
           std::vector<TOutput> &outputs, TConst &residual,
           TInput &resids, TIters &its) const override
    {
        Eigen::ArrayXd data(dataSize());
        int dataIndex = 0;
        for (int i = 0; i < inputs.size(); i++) {
            Eigen::Map<const Eigen::ArrayXf> this_data(inputs[i].GetDataPointer(), inputs[i].Size());
            if (m_model->scaleToMean()) {
                data.segment(dataIndex, this_data.rows()) = this_data.cast<double>() / this_data.abs().mean();
            } else {
                data.segment(dataIndex, this_data.rows()) = this_data.cast<double>();
            }
            dataIndex += this_data.rows();
        }
        Eigen::ArrayXd thresh(m_model->nParameters()); thresh.setConstant(0.05);
        const double f0 = consts[0];
        const double B1 = consts[1];
        Eigen::ArrayXXd localBounds = m_bounds;
        Eigen::ArrayXd weights = Eigen::ArrayXd::Ones(m_sequence->size());
        if (isfinite(f0)) { // We have an f0 map, add it to the fitting bounds
            localBounds.row(m_model->ParameterIndex("f0")) += f0;
            weights = m_sequence->weights(f0);
        }
        localBounds.row(m_model->ParameterIndex("B1")).setConstant(B1);
        MCDSRCFunctor func(m_model, m_sequence, data, weights);
        QI::RegionContraction<MCDSRCFunctor> rc(func, localBounds, thresh, m_samples, m_retain, m_iterations, 0.02, m_gauss, false);
        Eigen::ArrayXd pars(m_model->nParameters());
        rc.optimise(pars);
        for (int i = 0; i < m_model->nParameters(); i++) {
            outputs[i] = pars[i];
        }
        Eigen::ArrayXf r = func.residuals(pars).cast<float>();
        residual = sqrt(r.square().sum() / r.rows());
        resids = itk::VariableLengthVector<float>(r.data(), r.rows());
        its = rc.contractions();
        return true;
    }
};

//******************************************************************************
// Main
//******************************************************************************
int main(int argc, char **argv) {
    Eigen::initParallel();
    args::ArgumentParser parser("Calculates MWF & other parameter maps from mcDESPOT data\n"
                                "All times (e.g. T1, TR) are in SECONDS. All angles are in degrees.\n"
                                "http://github.com/spinicist/QUIT");
    args::HelpFlag help(parser, "HELP", "Show this help message", {'h', "help"});
    args::Flag     verbose(parser, "VERBOSE", "Print more information", {'v', "verbose"});
    args::Flag     noprompt(parser, "NOPROMPT", "Suppress input prompts", {'n', "no-prompt"});
    args::ValueFlag<int> threads(parser, "THREADS", "Use N threads (default=4, 0=hardware limit)", {'T', "threads"}, 4);
    args::ValueFlag<std::string> outarg(parser, "OUTPREFIX", "Add a prefix to output filenames", {'o', "out"});
    args::ValueFlag<std::string> f0(parser, "f0", "f0 map (Hertz)", {'f', "f0"});
    args::ValueFlag<std::string> B1(parser, "B1", "B1 map (ratio)", {'b', "B1"});
    args::ValueFlag<std::string> mask(parser, "MASK", "Only process voxels within the mask", {'m', "mask"});
    args::ValueFlag<std::string> subregion(parser, "SUBREGION", "Process subregion starting at voxel I,J,K with size SI,SJ,SK", {'s', "subregion"});
    args::Flag resids(parser, "RESIDS", "Write out residuals for each data-point", {'r', "resids"});
    args::ValueFlag<std::string> modelarg(parser, "MODEL", "Select model to fit - 1/2/2nex/3/3_f0/3nex, default 3", {'M', "model"}, "3");
    args::Flag scale(parser, "SCALE", "Normalize signals to mean (a good idea)", {'S', "scale"});
    args::ValueFlag<char> algorithm(parser, "ALGO", "Select (S)tochastic or (G)aussian Region Contraction", {'a', "algo"}, 'G');
    args::ValueFlag<int> its(parser, "ITERS", "Max iterations, default 4", {'i',"its"}, 4);
    args::ValueFlag<char> field(parser, "FIELD STRENGTH", "Specify field-strength for fitting regions - 3/7/u for user input", {'t', "tesla"}, '3');
    QI::ParseArgs(parser, argc, argv);
    bool prompt = !noprompt;

    std::shared_ptr<QI::Model> model = nullptr;
    if (modelarg.Get() == "1")         { model = std::make_shared<QI::SCD>(); }
    else if (modelarg.Get() == "2")    { model = std::make_shared<QI::MCD2>(); }
    else if (modelarg.Get() == "2nex") { model = std::make_shared<QI::MCD2_NoEx>(); }
    else if (modelarg.Get() == "3")    { model = std::make_shared<QI::MCD3>(); }
    else if (modelarg.Get() == "3_f0") { model = std::make_shared<QI::MCD3_f0>(); }
    else if (modelarg.Get() == "3nex") { model = std::make_shared<QI::MCD3_NoEx>(); }
    else {
        std::cerr << "Invalid model " << modelarg.Get() << " specified." << std::endl;
        return EXIT_FAILURE;
    }
    if (verbose) std::cout << "Using " << model->Name() << " model." << std::endl;
    if (verbose && scale) std::cout << "Mean-scaling selected" << std::endl;
    model->setScaleToMean(scale);

    Eigen::ArrayXXd bounds;
    Eigen::ArrayXd start;
    switch (field.Get()) {
        case '3':
            bounds = model->Bounds(QI::FieldStrength::Three);
            start = model->Default(QI::FieldStrength::Three);
            break;
        case '7':
            bounds = model->Bounds(QI::FieldStrength::Seven);
            start = model->Bounds(QI::FieldStrength::Seven);
            break;
        case 'u': {
            Eigen::ArrayXd temp;
            if (prompt) std::cout << "Enter lower bounds" << std::endl;
            QI::ReadArray(std::cin, temp);
            bounds.col(0) = temp;
            if (prompt) std::cout << "Enter upper bounds" << std::endl;
            QI::ReadArray(std::cin, temp);
            bounds.col(1) = temp;
        } break;
    default:
        std::cerr << "Unknown boundaries type " << field.Get() << std::endl;
        return EXIT_FAILURE;
        break;
    }

    if (prompt) {
        std::cout << "Starting qimcdespot\n"
                     "Run with -h switch to see usage" << std::endl;
    }

    std::shared_ptr<QI::SequenceGroup> sequences = std::make_shared<QI::SequenceGroup>();
    std::vector<QI::VectorVolumeF::Pointer> images;
    parseInput(sequences, images, verbose, prompt);
    auto apply = QI::ApplyF::New();
    switch (algorithm.Get()) {
        case 'S': {
            if (verbose) std::cout << "Using SRC algorithm" << std::endl;
            std::shared_ptr<SRCAlgo> algo = std::make_shared<SRCAlgo>(model, bounds, sequences, its.Get());
            algo->setGauss(false);
            apply->SetAlgorithm(algo);
        } break;
        case 'G': {
            if (verbose) std::cout << "Using GRC algorithm" << std::endl;
            std::shared_ptr<SRCAlgo> algo = std::make_shared<SRCAlgo>(model, bounds, sequences, its.Get());
            algo->setGauss(true);
            apply->SetAlgorithm(algo);
        } break;
        default:
            std::cerr << "Unknown algorithm type " << algorithm.Get() << std::endl;
            return EXIT_FAILURE;
    }
    apply->SetOutputAllResiduals(resids);
    apply->SetVerbose(verbose);
    apply->SetPoolsize(threads.Get());
    apply->SetSplitsPerThread(threads.Get()); // mcdespot with a mask & threads is a very unbalanced algorithm
    for (int i = 0; i < images.size(); i++) {
        apply->SetInput(i, images[i]);
    }
    if (f0) apply->SetConst(0, QI::ReadImage(f0.Get()));
    if (B1) apply->SetConst(1, QI::ReadImage(B1.Get()));
    if (mask) apply->SetMask(QI::ReadImage(mask.Get()));
    if (subregion) apply->SetSubregion(QI::RegionArg(args::get(subregion)));

    // Need this here so the bounds.txt file will have the correct prefix
    std::string outPrefix = outarg.Get() + model->Name() + "_";
    if (verbose) {
        std::cout << *sequences;
        std::cout << "Bounds:\n" <<  bounds.transpose() << std::endl;
        std::ofstream boundsFile(outPrefix + "bounds.txt");
        boundsFile << "Names: ";
        for (size_t p = 0; p < model->nParameters(); p++) {
            boundsFile << model->ParameterNames()[p] << "\t";
        }
        boundsFile << std::endl << "Bounds:\n" << bounds.transpose() << std::endl;
        boundsFile.close();
    }

    if (verbose) {
        std::cout << "Processing" << std::endl;
        auto monitor = QI::GenericMonitor::New();
        apply->AddObserver(itk::ProgressEvent(), monitor);
    }
    apply->Update();
    if (verbose) {
        std::cout << "Elapsed time was " << apply->GetTotalTime() << "s" << std::endl;
        std::cout << "Writing results files." << std::endl;
    }
    for (int i = 0; i < model->nParameters(); i++) {
        QI::WriteImage(apply->GetOutput(i), outPrefix + model->ParameterNames()[i] + QI::OutExt());
    }
    QI::WriteScaledImage(apply->GetResidualOutput(), apply->GetOutput(0), outPrefix + "residual" + QI::OutExt());
    if (resids) {
        QI::WriteScaledVectorImage(apply->GetAllResidualsOutput(), apply->GetOutput(0), outPrefix + "all_residuals" + QI::OutExt());
    }
    QI::WriteImage(apply->GetIterationsOutput(), outPrefix + "iterations" + QI::OutExt());
    return EXIT_SUCCESS;
}

<|endoftext|>


<commit_before><commit_msg>ThirdParty: Fix imprecise mouse dragging.<commit_after><|endoftext|>


<commit_before>/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "wtf/SpinLock.h"

#include "platform/Task.h"
#include "public/platform/Platform.h"
#include "public/platform/WebThread.h"
#include "wtf/OwnPtr.h"
#include "wtf/PassOwnPtr.h"

#include <gtest/gtest.h>

using WebCore::Task;

namespace {

static const size_t bufferSize = 16;

static int lock = 0;

static void fillBuffer(volatile char* buffer, char fillPattern)
{
    for (size_t i = 0; i < bufferSize; ++i)
        buffer[i] = fillPattern;
}

static void changeAndCheckBuffer(volatile char* buffer)
{
    fillBuffer(buffer, '\0');
    int total = 0;
    for (size_t i = 0; i < bufferSize; ++i)
        total += buffer[i];

    EXPECT_EQ(0, total);

    // This will mess with the other thread's calculation if we accidentally get
    // concurrency.
    fillBuffer(buffer, '!');
}

static void threadMain(volatile char* buffer)
{
    for (int i = 0; i < 500000; ++i) {
        spinLockLock(&lock);
        changeAndCheckBuffer(buffer);
        spinLockUnlock(&lock);
    }
}

TEST(WTF_SpinLock, Torture)
{
    char sharedBuffer[bufferSize];

    OwnPtr<WebKit::WebThread> thread1 = adoptPtr(WebKit::Platform::current()->createThread("thread1"));
    OwnPtr<WebKit::WebThread> thread2 = adoptPtr(WebKit::Platform::current()->createThread("thread2"));

    thread1->postTask(new Task(WTF::bind(&threadMain, static_cast<char*>(sharedBuffer))));
    thread2->postTask(new Task(WTF::bind(&threadMain, static_cast<char*>(sharedBuffer))));

    thread1.clear();
    thread2.clear();
}

} // namespace
<commit_msg>Rename WebKit namespace to blink<commit_after>/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "wtf/SpinLock.h"

#include "platform/Task.h"
#include "public/platform/Platform.h"
#include "public/platform/WebThread.h"
#include "wtf/OwnPtr.h"
#include "wtf/PassOwnPtr.h"

#include <gtest/gtest.h>

using WebCore::Task;

namespace {

static const size_t bufferSize = 16;

static int lock = 0;

static void fillBuffer(volatile char* buffer, char fillPattern)
{
    for (size_t i = 0; i < bufferSize; ++i)
        buffer[i] = fillPattern;
}

static void changeAndCheckBuffer(volatile char* buffer)
{
    fillBuffer(buffer, '\0');
    int total = 0;
    for (size_t i = 0; i < bufferSize; ++i)
        total += buffer[i];

    EXPECT_EQ(0, total);

    // This will mess with the other thread's calculation if we accidentally get
    // concurrency.
    fillBuffer(buffer, '!');
}

static void threadMain(volatile char* buffer)
{
    for (int i = 0; i < 500000; ++i) {
        spinLockLock(&lock);
        changeAndCheckBuffer(buffer);
        spinLockUnlock(&lock);
    }
}

TEST(WTF_SpinLock, Torture)
{
    char sharedBuffer[bufferSize];

    OwnPtr<blink::WebThread> thread1 = adoptPtr(blink::Platform::current()->createThread("thread1"));
    OwnPtr<blink::WebThread> thread2 = adoptPtr(blink::Platform::current()->createThread("thread2"));

    thread1->postTask(new Task(WTF::bind(&threadMain, static_cast<char*>(sharedBuffer))));
    thread2->postTask(new Task(WTF::bind(&threadMain, static_cast<char*>(sharedBuffer))));

    thread1.clear();
    thread2.clear();
}

} // namespace
<|endoftext|>