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

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_xmloff.hxx"

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

#ifndef _XMLOFF_XMLTOKEN_HXX
#include "xmltoken.hxx"
#endif
#ifndef _XMLOFF_XMLNMSPE_HXX
#include "xmlnmspe.hxx"
#endif
#ifndef _XMLOFF_XMLMETAI_HXX
#include "xmlmetai.hxx"
#endif
#ifndef _XMLOFF_XMLSTYLE_HXX
#include "xmlstyle.hxx"
#endif
#ifndef SCH_XMLIMPORT_HXX_
#include "SchXMLImport.hxx"
#endif

//  #ifndef _XMLOFF_XMLCHARTSTYLECONTEXT_HXX_
//  #include "XMLChartStyleContext.hxx"
//  #endif

#ifndef _COM_SUN_STAR_CHART_XCHARTDOCUMENT_HPP_
#include <com/sun/star/chart/XChartDocument.hpp>
#endif
#ifndef _COM_SUN_STAR_CHART_XCHARTDATAARRAY_HPP_
#include <com/sun/star/chart/XChartDataArray.hpp>
#endif
#ifndef _COM_SUN_STAR_CHART_CHARTDATAROWSOURCE_HPP_
#include <com/sun/star/chart/ChartDataRowSource.hpp>
#endif

#include "contexts.hxx"
#include "SchXMLChartContext.hxx"

using namespace com::sun::star;
using namespace ::xmloff::token;

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

class SchXMLBodyContext_Impl : public SvXMLImportContext
{
private:
    SchXMLImportHelper& mrImportHelper;

public:

    SchXMLBodyContext_Impl( SchXMLImportHelper& rImpHelper,
                SvXMLImport& rImport, sal_uInt16 nPrfx,
                const ::rtl::OUString& rLName );
    virtual ~SchXMLBodyContext_Impl();

    virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
            const ::rtl::OUString& rLocalName,
                const uno::Reference< xml::sax::XAttributeList > & xAttrList );
};

SchXMLBodyContext_Impl::SchXMLBodyContext_Impl(
        SchXMLImportHelper& rImpHelper, SvXMLImport& rImport,
        sal_uInt16 nPrfx, const ::rtl::OUString& rLName ) :
    SvXMLImportContext( rImport, nPrfx, rLName ),
    mrImportHelper( rImpHelper )
{
}

SchXMLBodyContext_Impl::~SchXMLBodyContext_Impl()
{
}

SvXMLImportContext *SchXMLBodyContext_Impl::CreateChildContext(
        sal_uInt16 nPrefix,
        const ::rtl::OUString& rLocalName,
        const uno::Reference< xml::sax::XAttributeList > & )
{
    return new SchXMLBodyContext( mrImportHelper, GetImport(), nPrefix,
                                  rLocalName );
}

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

SchXMLDocContext::SchXMLDocContext( SchXMLImportHelper& rImpHelper,
                                    SvXMLImport& rImport,
                                    USHORT nPrefix,
                                    const rtl::OUString& rLName ) :
        SvXMLImportContext( rImport, nPrefix, rLName ),
        mrImportHelper( rImpHelper )
{
    DBG_ASSERT( XML_NAMESPACE_OFFICE == nPrefix &&
        ( IsXMLToken( rLName, XML_DOCUMENT ) ||
          IsXMLToken( rLName, XML_DOCUMENT_META) ||
          IsXMLToken( rLName, XML_DOCUMENT_STYLES) ||
          IsXMLToken( rLName, XML_DOCUMENT_CONTENT) ),
                "SchXMLDocContext instanciated with no <office:document> element" );
}

SchXMLDocContext::~SchXMLDocContext()
{}

TYPEINIT1( SchXMLDocContext, SvXMLImportContext );

SvXMLImportContext* SchXMLDocContext::CreateChildContext(
    sal_uInt16 nPrefix,
    const ::rtl::OUString& rLocalName,
    const uno::Reference< xml::sax::XAttributeList >& xAttrList )
{
    SvXMLImportContext* pContext = 0;
    const SvXMLTokenMap& rTokenMap = mrImportHelper.GetDocElemTokenMap();
    sal_uInt16 nFlags = GetImport().getImportFlags();

    switch( rTokenMap.Get( nPrefix, rLocalName ))
    {
        case XML_TOK_DOC_AUTOSTYLES:
            if( nFlags & IMPORT_AUTOSTYLES )
                // not nice, but this is safe, as the SchXMLDocContext class can only by
                // instantiated by the chart import class SchXMLImport (header is not exported)
                pContext =
                    static_cast< SchXMLImport& >( GetImport() ).CreateStylesContext( rLocalName, xAttrList );
            break;
        case XML_TOK_DOC_STYLES:
            // for draw styles containing gradients/hatches/markers and dashes
            if( nFlags & IMPORT_STYLES )
                pContext = new SvXMLStylesContext( GetImport(), nPrefix, rLocalName, xAttrList );
            break;
        case XML_TOK_DOC_META:
            if( nFlags & IMPORT_META )
                pContext = new SfxXMLMetaContext( GetImport(), nPrefix, rLocalName, GetImport().GetModel());
            break;
        case XML_TOK_DOC_BODY:
            if( nFlags & IMPORT_CONTENT )
                pContext = new SchXMLBodyContext_Impl( mrImportHelper, GetImport(), nPrefix, rLocalName );
            break;
    }

    // call parent when no own context was created
    if( ! pContext )
        pContext = SvXMLImportContext::CreateChildContext( nPrefix, rLocalName, xAttrList );

    return pContext;
}

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

SchXMLBodyContext::SchXMLBodyContext( SchXMLImportHelper& rImpHelper,
                                      SvXMLImport& rImport,
                                      USHORT nPrefix,
                                      const rtl::OUString& rLName ) :
        SvXMLImportContext( rImport, nPrefix, rLName ),
        mrImportHelper( rImpHelper )
{
    DBG_ASSERT( XML_NAMESPACE_OFFICE == nPrefix &&
                IsXMLToken( rLName, XML_CHART ),
                "SchXMLBodyContext instanciated with no <office:chart> element" );
}

SchXMLBodyContext::~SchXMLBodyContext()
{}

void SchXMLBodyContext::EndElement()
{
}

SvXMLImportContext* SchXMLBodyContext::CreateChildContext(
    sal_uInt16 nPrefix,
    const rtl::OUString& rLocalName,
    const uno::Reference< xml::sax::XAttributeList >& xAttrList )
{
    SvXMLImportContext* pContext = 0;

    // <chart:chart> element
    if( nPrefix == XML_NAMESPACE_CHART &&
        IsXMLToken( rLocalName, XML_CHART ) )
    {
        pContext = mrImportHelper.CreateChartContext( GetImport(),
                                                      nPrefix, rLocalName,
                                                      GetImport().GetModel(),
                                                      xAttrList );
    }
    else
    {
        pContext = SvXMLImportContext::CreateChildContext( nPrefix, rLocalName, xAttrList );
    }

    return pContext;
}

<commit_msg>INTEGRATION: CWS vgbugs07 (1.11.124); FILE MERGED 2007/06/04 13:23:20 vg 1.11.124.1: #i76605# Remove -I .../inc/module hack introduced by hedaburemove01<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: contexts.cxx,v $
 *
 *  $Revision: 1.12 $
 *
 *  last change: $Author: hr $ $Date: 2007-06-27 14:53:20 $
 *
 *  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
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_xmloff.hxx"

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

#ifndef _XMLOFF_XMLTOKEN_HXX
#include <xmloff/xmltoken.hxx>
#endif
#ifndef _XMLOFF_XMLNMSPE_HXX
#include "xmlnmspe.hxx"
#endif
#ifndef _XMLOFF_XMLMETAI_HXX
#include <xmloff/xmlmetai.hxx>
#endif
#ifndef _XMLOFF_XMLSTYLE_HXX
#include <xmloff/xmlstyle.hxx>
#endif
#ifndef SCH_XMLIMPORT_HXX_
#include "SchXMLImport.hxx"
#endif

//  #ifndef _XMLOFF_XMLCHARTSTYLECONTEXT_HXX_
//  #include "XMLChartStyleContext.hxx"
//  #endif

#ifndef _COM_SUN_STAR_CHART_XCHARTDOCUMENT_HPP_
#include <com/sun/star/chart/XChartDocument.hpp>
#endif
#ifndef _COM_SUN_STAR_CHART_XCHARTDATAARRAY_HPP_
#include <com/sun/star/chart/XChartDataArray.hpp>
#endif
#ifndef _COM_SUN_STAR_CHART_CHARTDATAROWSOURCE_HPP_
#include <com/sun/star/chart/ChartDataRowSource.hpp>
#endif

#include "contexts.hxx"
#include "SchXMLChartContext.hxx"

using namespace com::sun::star;
using namespace ::xmloff::token;

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

class SchXMLBodyContext_Impl : public SvXMLImportContext
{
private:
    SchXMLImportHelper& mrImportHelper;

public:

    SchXMLBodyContext_Impl( SchXMLImportHelper& rImpHelper,
                SvXMLImport& rImport, sal_uInt16 nPrfx,
                const ::rtl::OUString& rLName );
    virtual ~SchXMLBodyContext_Impl();

    virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
            const ::rtl::OUString& rLocalName,
                const uno::Reference< xml::sax::XAttributeList > & xAttrList );
};

SchXMLBodyContext_Impl::SchXMLBodyContext_Impl(
        SchXMLImportHelper& rImpHelper, SvXMLImport& rImport,
        sal_uInt16 nPrfx, const ::rtl::OUString& rLName ) :
    SvXMLImportContext( rImport, nPrfx, rLName ),
    mrImportHelper( rImpHelper )
{
}

SchXMLBodyContext_Impl::~SchXMLBodyContext_Impl()
{
}

SvXMLImportContext *SchXMLBodyContext_Impl::CreateChildContext(
        sal_uInt16 nPrefix,
        const ::rtl::OUString& rLocalName,
        const uno::Reference< xml::sax::XAttributeList > & )
{
    return new SchXMLBodyContext( mrImportHelper, GetImport(), nPrefix,
                                  rLocalName );
}

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

SchXMLDocContext::SchXMLDocContext( SchXMLImportHelper& rImpHelper,
                                    SvXMLImport& rImport,
                                    USHORT nPrefix,
                                    const rtl::OUString& rLName ) :
        SvXMLImportContext( rImport, nPrefix, rLName ),
        mrImportHelper( rImpHelper )
{
    DBG_ASSERT( XML_NAMESPACE_OFFICE == nPrefix &&
        ( IsXMLToken( rLName, XML_DOCUMENT ) ||
          IsXMLToken( rLName, XML_DOCUMENT_META) ||
          IsXMLToken( rLName, XML_DOCUMENT_STYLES) ||
          IsXMLToken( rLName, XML_DOCUMENT_CONTENT) ),
                "SchXMLDocContext instanciated with no <office:document> element" );
}

SchXMLDocContext::~SchXMLDocContext()
{}

TYPEINIT1( SchXMLDocContext, SvXMLImportContext );

SvXMLImportContext* SchXMLDocContext::CreateChildContext(
    sal_uInt16 nPrefix,
    const ::rtl::OUString& rLocalName,
    const uno::Reference< xml::sax::XAttributeList >& xAttrList )
{
    SvXMLImportContext* pContext = 0;
    const SvXMLTokenMap& rTokenMap = mrImportHelper.GetDocElemTokenMap();
    sal_uInt16 nFlags = GetImport().getImportFlags();

    switch( rTokenMap.Get( nPrefix, rLocalName ))
    {
        case XML_TOK_DOC_AUTOSTYLES:
            if( nFlags & IMPORT_AUTOSTYLES )
                // not nice, but this is safe, as the SchXMLDocContext class can only by
                // instantiated by the chart import class SchXMLImport (header is not exported)
                pContext =
                    static_cast< SchXMLImport& >( GetImport() ).CreateStylesContext( rLocalName, xAttrList );
            break;
        case XML_TOK_DOC_STYLES:
            // for draw styles containing gradients/hatches/markers and dashes
            if( nFlags & IMPORT_STYLES )
                pContext = new SvXMLStylesContext( GetImport(), nPrefix, rLocalName, xAttrList );
            break;
        case XML_TOK_DOC_META:
            if( nFlags & IMPORT_META )
                pContext = new SfxXMLMetaContext( GetImport(), nPrefix, rLocalName, GetImport().GetModel());
            break;
        case XML_TOK_DOC_BODY:
            if( nFlags & IMPORT_CONTENT )
                pContext = new SchXMLBodyContext_Impl( mrImportHelper, GetImport(), nPrefix, rLocalName );
            break;
    }

    // call parent when no own context was created
    if( ! pContext )
        pContext = SvXMLImportContext::CreateChildContext( nPrefix, rLocalName, xAttrList );

    return pContext;
}

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

SchXMLBodyContext::SchXMLBodyContext( SchXMLImportHelper& rImpHelper,
                                      SvXMLImport& rImport,
                                      USHORT nPrefix,
                                      const rtl::OUString& rLName ) :
        SvXMLImportContext( rImport, nPrefix, rLName ),
        mrImportHelper( rImpHelper )
{
    DBG_ASSERT( XML_NAMESPACE_OFFICE == nPrefix &&
                IsXMLToken( rLName, XML_CHART ),
                "SchXMLBodyContext instanciated with no <office:chart> element" );
}

SchXMLBodyContext::~SchXMLBodyContext()
{}

void SchXMLBodyContext::EndElement()
{
}

SvXMLImportContext* SchXMLBodyContext::CreateChildContext(
    sal_uInt16 nPrefix,
    const rtl::OUString& rLocalName,
    const uno::Reference< xml::sax::XAttributeList >& xAttrList )
{
    SvXMLImportContext* pContext = 0;

    // <chart:chart> element
    if( nPrefix == XML_NAMESPACE_CHART &&
        IsXMLToken( rLocalName, XML_CHART ) )
    {
        pContext = mrImportHelper.CreateChartContext( GetImport(),
                                                      nPrefix, rLocalName,
                                                      GetImport().GetModel(),
                                                      xAttrList );
    }
    else
    {
        pContext = SvXMLImportContext::CreateChildContext( nPrefix, rLocalName, xAttrList );
    }

    return pContext;
}

<|endoftext|>


<commit_before>/***********************************
 Copyright 2017 Ravishankar Mathur

 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 <OpenFrames/OpenVRDevice.hpp>
#include <OpenFrames/ReferenceFrame.hpp>
#include <osg/Matrixd>
#include <osg/Notify>
#include <osg/MatrixTransform>

// Assume 3 stub tracked devices here: HMD + 2 base stations
const unsigned int numTrackedDevices = 3;

namespace OpenFrames{

  /*************************************************************/
  OpenVREvent::VREvent::VREvent()
  : _ovrEvent(NULL), _controllerState(NULL)
  {}

  /*************************************************************/
  OpenVREvent::VREvent::~VREvent()
  {}

  /*************************************************************/
  bool OpenVRDevice::initVR()
  {
    osg::notify(osg::NOTICE) << "Using OpenVR stub" << std::endl;

    // Set texture size similar to what OpenVR would return
    _width = 1512;  // 1.4*1080
    _height = 1680; // 1.4*1200
    osg::notify(osg::NOTICE) << "VR eye texture width = " << _width << ", height = " << _height << std::endl;

    // Update the per-eye projection matrices
    // The view offset matrices will be computed per-frame since IPD can change
    updateProjectionMatrices();

    // Allocate render data for each possible tracked device
    // The render data struct is a light wrapper, so there is no size concern here
    _deviceIDToModel.resize(numTrackedDevices);

    // Get render models for controllers and other devices
    updateDeviceRenderModels();

    return (_isInitialized = true);
  }

  /*************************************************************/
  void OpenVRDevice::shutdownVR()
  {
    _deviceNameToGeode.clear();
    _deviceIDToModel.clear();
    _deviceModels->removeChildren(0, _deviceModels->getNumChildren());
    _isInitialized = false;
  }

  /*************************************************************/
  void OpenVRDevice::updateDeviceRenderModels()
  {
    // Loop through all possible tracked devices except the HMD (already loaded)
    for(unsigned int deviceID = 0; deviceID < numTrackedDevices; ++deviceID)
    {
      // Set up device render model
      setupRenderModelForTrackedDevice(deviceID);
    }
  }

  /*************************************************************/
  void OpenVRDevice::setupRenderModelForTrackedDevice(uint32_t deviceID)
  {
    // Get name of tracked device
    std::string deviceName;
    if(deviceID == 0) deviceName = "HMD_Stub";
    else deviceName = "BaseStation_Stub";

    // Find device data by name
    DeviceGeodeMap::iterator i = _deviceNameToGeode.find(deviceName);

    // If not found, then load device data
    if(i == _deviceNameToGeode.end())
    {
      osg::notify(osg::NOTICE) << "OpenFrames::OpenVRDeviceStub: Setting up render data for device " << deviceName << std::endl;

      float radius = 0.1f;
      float height = 0.2f;

      // Create device model's render model and add it to the render group
      osg::Geode *geode = new osg::Geode;
      geode->addDrawable(new osg::ShapeDrawable(new osg::Capsule(osg::Vec3(),radius, height)));
      _deviceNameToGeode[deviceName] = geode;
    }

    // Set up device model if needed
    if(_deviceIDToModel[deviceID]._modelTransform->getNumChildren() == 0)
    {
      osg::notify(osg::NOTICE) << "OpenFrames::OpenVRDeviceStub: Setting up transform for device " << deviceName << deviceID << std::endl;

      // Add device model's transform to the group of all rendered devices
      _deviceIDToModel[deviceID]._modelTransform->addChild(_deviceNameToGeode[deviceName]);
      _deviceModels->addChild(_deviceIDToModel[deviceID]._modelTransform);

      // Set device class
      if(deviceID == 0) _deviceIDToModel[deviceID]._class = HMD;
      else _deviceIDToModel[deviceID]._class = BASESTATION;
    }
  }

  /*************************************************************/
  void OpenVRDevice::updateProjectionMatrices()
  {
    // Create right/left/center projection matrices. Using unit depth minimizes
    // precision losses in the projection matrix
    _rightEyeProj.makePerspective(110.0, (double)_width/(double)_height, 1.0, 2.0);
    _leftEyeProj.makePerspective(110.0, (double)_width/(double)_height, 1.0, 2.0);

    // Center projection is average of right and left
    // OSG doesn't have a matrix addition for Matrixd (facepalm)
    osg::Matrixf rightEyeProjf = _rightEyeProj;
    osg::Matrixf leftEyeProjf = _leftEyeProj;
    _centerProj = (rightEyeProjf + leftEyeProjf)*0.5;
  }

  /*************************************************************/
  void OpenVRDevice::updateViewOffsets()
  {
    // Simulate raw left/right eye vectors relative to HMD origin
    osg::Vec3d rightEyeRaw(0.03, 0.01, -0.01);
    osg::Vec3d leftEyeRaw(-0.03, 0.01, -0.01);

    // Compute view offsets from raw offset vectors
    computeViewOffsets(rightEyeRaw, leftEyeRaw);
  }

  /*************************************************************/
  void OpenVRDevice::waitGetPoses()
  {
    osg::Matrixf matDeviceToWorld; // Device to World transform

    // Simulate poses for all VR devices
    for(unsigned int i = 0; i < numTrackedDevices; ++i)
    {
      _deviceIDToModel[i]._valid = true; // Always valid

      // Set simulated HMD or base station pose in meters
      if(i == 0)
      {
        matDeviceToWorld.makeIdentity();
        matDeviceToWorld(3, 1) = 1.6764; // 5'6" simulated user height in meters
      }
      else if(i == 1)
      {
        matDeviceToWorld.makeRotate(osg::Quat(10.0, osg::Vec3d(1, 0, 0)));
        matDeviceToWorld.postMultTranslate(osg::Vec3d(-3, 3, -3));
      }
      else if(i == 2)
      {
        matDeviceToWorld.makeRotate(osg::Quat(10.0, osg::Vec3d(0, 1, 0)));
        matDeviceToWorld.postMultTranslate(osg::Vec3d(2, 3, -2));
      }

      matDeviceToWorld(3, 1) -= _userHeight; // Subtract user's height, OpenVR world is Y-up
      _deviceIDToModel[i]._rawDeviceToWorld = matDeviceToWorld;

      // Enable device model's transform so that it will be rendered
      // Only enable base stations, since we don't want to render anything else
      if(_deviceIDToModel[i]._class == BASESTATION)
        _deviceIDToModel[i]._modelTransform->setNodeMask(0xffffffff);
      else
        _deviceIDToModel[i]._modelTransform->setNodeMask(0x0);
    }

    // Compute device transforms from raw poses
    computeDeviceTransforms();
  }

  /*************************************************************/
  void OpenVRDevice::submitFrame(GLuint rightEyeTexName, GLuint leftEyeTexName)
  {
    // Nothing to do here
  }

  /*************************************************************/
  bool OpenVRDevice::pollNextEvent(OpenVREvent *event)
  {
    // Nothing to do here
    return false;
  }

  /*************************************************************/
  bool OpenVREventDevice::checkEvents()
  {
    // Nothing to do here
    return false;
  }

  /*************************************************************/
  bool OpenVRTrackball::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us)
  {
    // Just call parent trackball handler
    return FollowingTrackball::handle(ea, us);
  }

} // !namespace OpenFrames
<commit_msg>Update Stub VR with new VR code organization<commit_after>/***********************************
 Copyright 2017 Ravishankar Mathur

 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 <OpenFrames/OpenVRDevice.hpp>
#include <OpenFrames/ReferenceFrame.hpp>
#include <osg/Matrixd>
#include <osg/Notify>
#include <osg/MatrixTransform>

// Assume 3 stub tracked devices here: HMD + 2 base stations
const unsigned int numTrackedDevices = 3;

namespace OpenFrames{

  /*************************************************************/
  OpenVREvent::VREvent::VREvent()
  : _ovrEvent(NULL), _controllerState(NULL)
  {}

  /*************************************************************/
  OpenVREvent::VREvent::~VREvent()
  {}

  /*************************************************************/
  bool OpenVRDevice::initVR()
  {
    osg::notify(osg::NOTICE) << "Using OpenVR stub" << std::endl;

    // Set texture size similar to what OpenVR would return
    _width = 1512;  // 1.4*1080
    _height = 1680; // 1.4*1200
    osg::notify(osg::NOTICE) << "VR eye texture width = " << _width << ", height = " << _height << std::endl;

    // Update the per-eye projection matrices
    // The view offset matrices will be computed per-frame since IPD can change
    updateProjectionMatrices();

    // Allocate render data for each possible tracked device
    // The render data struct is a light wrapper, so there is no size concern here
    _deviceIDToModel.resize(numTrackedDevices);

    // Get render models for controllers and other devices
    updateDeviceRenderModels();

    return (_isInitialized = true);
  }

  /*************************************************************/
  void OpenVRDevice::shutdownVR()
  {
    _deviceNameToGeode.clear();
    _deviceIDToModel.clear();
    _deviceModels->removeChildren(0, _deviceModels->getNumChildren());
    _isInitialized = false;
  }

  /*************************************************************/
  void OpenVRDevice::updateDeviceRenderModels()
  {
    // Loop through all possible tracked devices except the HMD (already loaded)
    for(unsigned int deviceID = 0; deviceID < numTrackedDevices; ++deviceID)
    {
      // Set up device render model
      setupRenderModelForTrackedDevice(deviceID);
    }
  }

  /*************************************************************/
  void OpenVRDevice::setupRenderModelForTrackedDevice(uint32_t deviceID)
  {
    // Get name of tracked device
    std::string deviceName;
    if(deviceID == 0) deviceName = "HMD_Stub";
    else deviceName = "BaseStation_Stub";

    // Find device data by name
    DeviceGeodeMap::iterator i = _deviceNameToGeode.find(deviceName);

    // If not found, then load device data
    if(i == _deviceNameToGeode.end())
    {
      osg::notify(osg::NOTICE) << "OpenFrames::OpenVRDeviceStub: Setting up render data for device " << deviceName << std::endl;

      float radius = 0.1f;
      float height = 0.2f;

      // Create device model's render model and add it to the render group
      osg::Geode *geode = new osg::Geode;
      geode->addDrawable(new osg::ShapeDrawable(new osg::Capsule(osg::Vec3(),radius, height)));
      _deviceNameToGeode[deviceName] = geode;
    }

    // Set up device model if needed
    if(_deviceIDToModel[deviceID]._modelTransform->getNumChildren() == 0)
    {
      osg::notify(osg::NOTICE) << "OpenFrames::OpenVRDeviceStub: Setting up transform for device " << deviceName << deviceID << std::endl;

      // Add device model's transform to the group of all rendered devices
      _deviceIDToModel[deviceID]._modelTransform->addChild(_deviceNameToGeode[deviceName]);
      _deviceModels->addChild(_deviceIDToModel[deviceID]._modelTransform);

      // Set device class
      if(deviceID == 0) _deviceIDToModel[deviceID]._class = HMD;
      else _deviceIDToModel[deviceID]._class = BASESTATION;
    }
  }

  /*************************************************************/
  void OpenVRDevice::updateProjectionMatrices()
  {
    // Create right/left/center projection matrices. Using unit depth minimizes
    // precision losses in the projection matrix
    _rightEyeProj.makePerspective(110.0, (double)_width/(double)_height, 1.0, 2.0);
    _leftEyeProj.makePerspective(110.0, (double)_width/(double)_height, 1.0, 2.0);

    // Center projection is average of right and left
    // OSG doesn't have a matrix addition for Matrixd (facepalm)
    osg::Matrixf rightEyeProjf = _rightEyeProj;
    osg::Matrixf leftEyeProjf = _leftEyeProj;
    _centerProj = (rightEyeProjf + leftEyeProjf)*0.5;
  }

  /*************************************************************/
  void OpenVRDevice::updateViewOffsets()
  {
    // Simulate raw left/right eye vectors relative to HMD origin
    _rightEyeViewOffsetRaw.set(0.03, 0.01, -0.01);
    _leftEyeViewOffsetRaw.set(-0.03, 0.01, -0.01);

    // Compute HMD center view offset vector (Eye to Head transform)
    _centerViewOffsetRaw = (_rightEyeViewOffsetRaw + _leftEyeViewOffsetRaw)*0.5;
    _rightEyeViewOffsetRaw -= _centerViewOffsetRaw;
    _leftEyeViewOffsetRaw -= _centerViewOffsetRaw;

    // Print new IPD value if needed
    double ipd = (_rightEyeViewOffsetRaw - _leftEyeViewOffsetRaw).length();
    if (ipd != _ipd)
    {
      osg::notify(osg::ALWAYS) << "VR Interpupillary Distance: " << ipd * 1000.0f << "mm" << std::endl;
      _ipd = ipd;
    }
  }

  /*************************************************************/
  void OpenVRDevice::waitGetPoses()
  {
    osg::Matrixf matDeviceToWorld; // Device to World transform

    // Simulate poses for all VR devices
    for(unsigned int i = 0; i < numTrackedDevices; ++i)
    {
      _deviceIDToModel[i]._valid = true; // Always valid

      // Set simulated HMD or base station pose in meters
      if(i == 0)
      {
        matDeviceToWorld.makeIdentity();
        matDeviceToWorld(3, 1) = 1.6764; // 5'6" simulated user height in meters
      }
      else if(i == 1)
      {
        matDeviceToWorld.makeRotate(osg::Quat(10.0, osg::Vec3d(1, 0, 0)));
        matDeviceToWorld.postMultTranslate(osg::Vec3d(-3, 3, -3));
      }
      else if(i == 2)
      {
        matDeviceToWorld.makeRotate(osg::Quat(10.0, osg::Vec3d(0, 1, 0)));
        matDeviceToWorld.postMultTranslate(osg::Vec3d(2, 3, -2));
      }

      matDeviceToWorld(3, 1) -= _userHeight; // Subtract user's height, OpenVR world is Y-up
      _deviceIDToModel[i]._rawDeviceToWorld = matDeviceToWorld;

      // Enable device model's transform so that it will be rendered
      // Only enable base stations, since we don't want to render anything else
      if(_deviceIDToModel[i]._class == BASESTATION)
        _deviceIDToModel[i]._modelTransform->setNodeMask(0xffffffff);
      else
        _deviceIDToModel[i]._modelTransform->setNodeMask(0x0);
    }

    // Update the HMD->Eye view offset vectors
    updateViewOffsets();
  }

  /*************************************************************/
  void OpenVRDevice::submitFrame(GLuint rightEyeTexName, GLuint leftEyeTexName)
  {
    // Nothing to do here
  }

  /*************************************************************/
  bool OpenVRDevice::pollNextEvent(OpenVREvent *event)
  {
    // Nothing to do here
    return false;
  }

  /*************************************************************/
  bool OpenVREventDevice::checkEvents()
  {
    // Nothing to do here
    return false;
  }

  /*************************************************************/
  bool OpenVRTrackball::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us)
  {
    // Compute new motion-based view at each frame
    if (ea.getEventType() == osgGA::GUIEventAdapter::FRAME)
      processMotion();

    // Just call parent trackball handler
    return FollowingTrackball::handle(ea, us);
  }

} // !namespace OpenFrames
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: xmlprmap.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: dvo $ $Date: 2001-07-25 13:55:54 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

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

#ifndef _XMLOFF_PROPERTYHANDLERBASE_HXX
#include "xmlprhdl.hxx"
#endif

#ifndef _XMLOFF_PROPERTYHANDLER_BASICTYPES_HXX
#include "xmlbahdl.hxx"
#endif

#ifndef _XMLOFF_PROPERTYSETMAPPER_HXX
#include "xmlprmap.hxx"
#endif

#ifndef _XMLOFF_XMLTYPES_HXX
#include "xmltypes.hxx"
#endif

#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif

#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSTATE_HPP_
#include <com/sun/star/beans/XPropertyState.hpp>
#endif

#ifndef _COM_SUN_STAR_UNO_ANY_HXX_
#include <com/sun/star/uno/Any.hxx>
#endif

#ifndef _XMLOFF_XMLTOKEN_HXX
#include "xmltoken.hxx"
#endif

using namespace ::std;
using namespace ::rtl;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
using ::xmloff::token::GetXMLToken;

XMLPropertySetMapperEntry_Impl::XMLPropertySetMapperEntry_Impl(
    const XMLPropertyMapEntry& rMapEntry,
    const UniReference< XMLPropertyHandlerFactory >& rFactory ) :
    sXMLAttributeName( GetXMLToken(rMapEntry.meXMLName) ),
    sAPIPropertyName( OUString(rMapEntry.msApiName, rMapEntry.nApiNameLength,
                               RTL_TEXTENCODING_ASCII_US ) ),
    nXMLNameSpace( rMapEntry.mnNameSpace ),
    nType( rMapEntry.mnType ),
    nContextId( rMapEntry.mnContextId ),
    pHdl( rFactory->GetPropertyHandler( rMapEntry.mnType & MID_FLAG_MASK ) )
{
}

XMLPropertySetMapperEntry_Impl::XMLPropertySetMapperEntry_Impl(
        const XMLPropertySetMapperEntry_Impl& rEntry ) :
    sXMLAttributeName( rEntry.sXMLAttributeName),
    sAPIPropertyName( rEntry.sAPIPropertyName),
    nXMLNameSpace( rEntry.nXMLNameSpace),
    nType( rEntry.nType),
    nContextId( rEntry.nContextId),
    pHdl( rEntry.pHdl)
{
    DBG_ASSERT( pHdl, "Unknown XML property type handler!" );
}

///////////////////////////////////////////////////////////////////////////
//
// Ctor
//
XMLPropertySetMapper::XMLPropertySetMapper(
        const XMLPropertyMapEntry* pEntries,
        const UniReference< XMLPropertyHandlerFactory >& rFactory )
{
    aHdlFactories.push_back( rFactory );
    if( pEntries )
    {
        const XMLPropertyMapEntry* pIter = pEntries;

        // count entries
        while( pIter->msApiName )
        {
            XMLPropertySetMapperEntry_Impl aEntry( *pIter, rFactory );
            aMapEntries.push_back( aEntry );
            pIter++;
        }
    }
}

XMLPropertySetMapper::~XMLPropertySetMapper()
{
}

void XMLPropertySetMapper::AddMapperEntry(
    const UniReference < XMLPropertySetMapper >& rMapper )
{
    for( vector < UniReference < XMLPropertyHandlerFactory > >::iterator
            aFIter = rMapper->aHdlFactories.begin();
         aFIter != rMapper->aHdlFactories.end();
         aFIter++ )
    {
        aHdlFactories.push_back( *aFIter );
    }

    for( vector < XMLPropertySetMapperEntry_Impl >::iterator
            aEIter = rMapper->aMapEntries.begin();
         aEIter != rMapper->aMapEntries.end();
         aEIter++ )
    {
        aMapEntries.push_back( *aEIter );
    }
}

///////////////////////////////////////////////////////////////////////////
//
// Export a Property
//
sal_Bool XMLPropertySetMapper::exportXML(
        OUString& rStrExpValue,
        const XMLPropertyState& rProperty,
        const SvXMLUnitConverter& rUnitConverter ) const
{
    sal_Bool bRet = sal_False;

    const XMLPropertyHandler* pHdl = GetPropertyHandler( rProperty.mnIndex );

    DBG_ASSERT( pHdl, "Unknown XML Type!" );
    if( pHdl )
        bRet = pHdl->exportXML( rStrExpValue, rProperty.maValue,
                                rUnitConverter );

    return bRet;
}

///////////////////////////////////////////////////////////////////////////
//
// Import a Property
//
sal_Bool XMLPropertySetMapper::importXML(
        const OUString& rStrImpValue,
        XMLPropertyState& rProperty,
        const SvXMLUnitConverter& rUnitConverter ) const
{
    sal_Bool bRet = sal_False;

    const XMLPropertyHandler* pHdl = GetPropertyHandler( rProperty.mnIndex );

    if( pHdl )
        bRet = pHdl->importXML( rStrImpValue, rProperty.maValue,
                                rUnitConverter );

    return bRet;
}

///////////////////////////////////////////////////////////////////////////
//
// Search for the given name and the namespace in the list and return
// the index of the entry
// If there is no matching entry the method returns -1
//
const sal_Int32 XMLPropertySetMapper::GetEntryIndex(
        sal_uInt16 nNamespace,
        const OUString& rStrName,
        sal_Int32 nStartAt /* = -1 */ ) const
{
    sal_Int32 nEntries = GetEntryCount();
    sal_Int32 nIndex= nStartAt == - 1? 0 : nStartAt+1;

    do
    {
        const XMLPropertySetMapperEntry_Impl& rEntry = aMapEntries[nIndex];
        if( rEntry.nXMLNameSpace == nNamespace &&
            rStrName == rEntry.sXMLAttributeName )
            return nIndex;
        else
            nIndex++;

    } while( nIndex<nEntries );

    return -1;
}

/** searches for an entry that matches the given api name, namespace and local name or -1 if nothing found */
sal_Int32 XMLPropertySetMapper::FindEntryIndex(
        const sal_Char* sApiName,
        sal_uInt16 nNameSpace,
        const OUString& sXMLName ) const
{
    sal_Int32 nIndex = 0;
    sal_Int32 nEntries = GetEntryCount();

    do
    {
        const XMLPropertySetMapperEntry_Impl& rEntry = aMapEntries[nIndex];
        if( rEntry.nXMLNameSpace == nNameSpace &&
            rEntry.sXMLAttributeName.equals( sXMLName ) &&
            0 == rEntry.sAPIPropertyName.compareToAscii( sApiName ) )
            return nIndex;
        else
            nIndex++;

    } while( nIndex < nEntries );

    return -1;
}

sal_Int32 XMLPropertySetMapper::FindEntryIndex( const sal_Int16 nContextId ) const
{
    sal_Int32 nIndex = 0;
    sal_Int32 nEntries = GetEntryCount();

    do
    {
        const XMLPropertySetMapperEntry_Impl& rEntry = aMapEntries[nIndex];
        if( rEntry.nContextId == nContextId )
            return nIndex;
        else
            nIndex++;

    } while( nIndex < nEntries );

    return -1;
}
<commit_msg>INTEGRATION: CWS oasis (1.5.276); FILE MERGED 2004/04/21 07:27:25 mib 1.5.276.1: - separated attribute lists for <*-properties> elements on import (#i20153#) - replaced "style:text-backgroubnd-color" with "fo:background-color"<commit_after>/*************************************************************************
 *
 *  $RCSfile: xmlprmap.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: rt $ $Date: 2004-07-13 08:28:32 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

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

#ifndef _XMLOFF_PROPERTYHANDLERBASE_HXX
#include "xmlprhdl.hxx"
#endif

#ifndef _XMLOFF_PROPERTYHANDLER_BASICTYPES_HXX
#include "xmlbahdl.hxx"
#endif

#ifndef _XMLOFF_PROPERTYSETMAPPER_HXX
#include "xmlprmap.hxx"
#endif

#ifndef _XMLOFF_XMLTYPES_HXX
#include "xmltypes.hxx"
#endif

#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif

#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSTATE_HPP_
#include <com/sun/star/beans/XPropertyState.hpp>
#endif

#ifndef _COM_SUN_STAR_UNO_ANY_HXX_
#include <com/sun/star/uno/Any.hxx>
#endif

#ifndef _XMLOFF_XMLTOKEN_HXX
#include "xmltoken.hxx"
#endif

using namespace ::std;
using namespace ::rtl;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
using ::xmloff::token::GetXMLToken;

XMLPropertySetMapperEntry_Impl::XMLPropertySetMapperEntry_Impl(
    const XMLPropertyMapEntry& rMapEntry,
    const UniReference< XMLPropertyHandlerFactory >& rFactory ) :
    sXMLAttributeName( GetXMLToken(rMapEntry.meXMLName) ),
    sAPIPropertyName( OUString(rMapEntry.msApiName, rMapEntry.nApiNameLength,
                               RTL_TEXTENCODING_ASCII_US ) ),
    nXMLNameSpace( rMapEntry.mnNameSpace ),
    nType( rMapEntry.mnType ),
    nContextId( rMapEntry.mnContextId ),
    pHdl( rFactory->GetPropertyHandler( rMapEntry.mnType & MID_FLAG_MASK ) )
{
}

XMLPropertySetMapperEntry_Impl::XMLPropertySetMapperEntry_Impl(
        const XMLPropertySetMapperEntry_Impl& rEntry ) :
    sXMLAttributeName( rEntry.sXMLAttributeName),
    sAPIPropertyName( rEntry.sAPIPropertyName),
    nXMLNameSpace( rEntry.nXMLNameSpace),
    nType( rEntry.nType),
    nContextId( rEntry.nContextId),
    pHdl( rEntry.pHdl)
{
    DBG_ASSERT( pHdl, "Unknown XML property type handler!" );
}

///////////////////////////////////////////////////////////////////////////
//
// Ctor
//
XMLPropertySetMapper::XMLPropertySetMapper(
        const XMLPropertyMapEntry* pEntries,
        const UniReference< XMLPropertyHandlerFactory >& rFactory )
{
    aHdlFactories.push_back( rFactory );
    if( pEntries )
    {
        const XMLPropertyMapEntry* pIter = pEntries;

        // count entries
        while( pIter->msApiName )
        {
            XMLPropertySetMapperEntry_Impl aEntry( *pIter, rFactory );
            aMapEntries.push_back( aEntry );
            pIter++;
        }
    }
}

XMLPropertySetMapper::~XMLPropertySetMapper()
{
}

void XMLPropertySetMapper::AddMapperEntry(
    const UniReference < XMLPropertySetMapper >& rMapper )
{
    for( vector < UniReference < XMLPropertyHandlerFactory > >::iterator
            aFIter = rMapper->aHdlFactories.begin();
         aFIter != rMapper->aHdlFactories.end();
         aFIter++ )
    {
        aHdlFactories.push_back( *aFIter );
    }

    for( vector < XMLPropertySetMapperEntry_Impl >::iterator
            aEIter = rMapper->aMapEntries.begin();
         aEIter != rMapper->aMapEntries.end();
         aEIter++ )
    {
        aMapEntries.push_back( *aEIter );
    }
}

///////////////////////////////////////////////////////////////////////////
//
// Export a Property
//
sal_Bool XMLPropertySetMapper::exportXML(
        OUString& rStrExpValue,
        const XMLPropertyState& rProperty,
        const SvXMLUnitConverter& rUnitConverter ) const
{
    sal_Bool bRet = sal_False;

    const XMLPropertyHandler* pHdl = GetPropertyHandler( rProperty.mnIndex );

    DBG_ASSERT( pHdl, "Unknown XML Type!" );
    if( pHdl )
        bRet = pHdl->exportXML( rStrExpValue, rProperty.maValue,
                                rUnitConverter );

    return bRet;
}

///////////////////////////////////////////////////////////////////////////
//
// Import a Property
//
sal_Bool XMLPropertySetMapper::importXML(
        const OUString& rStrImpValue,
        XMLPropertyState& rProperty,
        const SvXMLUnitConverter& rUnitConverter ) const
{
    sal_Bool bRet = sal_False;

    const XMLPropertyHandler* pHdl = GetPropertyHandler( rProperty.mnIndex );

    if( pHdl )
        bRet = pHdl->importXML( rStrImpValue, rProperty.maValue,
                                rUnitConverter );

    return bRet;
}

///////////////////////////////////////////////////////////////////////////
//
// Search for the given name and the namespace in the list and return
// the index of the entry
// If there is no matching entry the method returns -1
//
const sal_Int32 XMLPropertySetMapper::GetEntryIndex(
        sal_uInt16 nNamespace,
        const OUString& rStrName,
        sal_uInt32 nPropType,
        sal_Int32 nStartAt /* = -1 */ ) const
{
    sal_Int32 nEntries = GetEntryCount();
    sal_Int32 nIndex= nStartAt == - 1? 0 : nStartAt+1;

    do
    {
        const XMLPropertySetMapperEntry_Impl& rEntry = aMapEntries[nIndex];
        if( (!nPropType || nPropType == rEntry.GetPropType()) &&
            rEntry.nXMLNameSpace == nNamespace &&
            rStrName == rEntry.sXMLAttributeName )
            return nIndex;
        else
            nIndex++;

    } while( nIndex<nEntries );

    return -1;
}

/** searches for an entry that matches the given api name, namespace and local name or -1 if nothing found */
sal_Int32 XMLPropertySetMapper::FindEntryIndex(
        const sal_Char* sApiName,
        sal_uInt16 nNameSpace,
        const OUString& sXMLName ) const
{
    sal_Int32 nIndex = 0;
    sal_Int32 nEntries = GetEntryCount();

    do
    {
        const XMLPropertySetMapperEntry_Impl& rEntry = aMapEntries[nIndex];
        if( rEntry.nXMLNameSpace == nNameSpace &&
            rEntry.sXMLAttributeName.equals( sXMLName ) &&
            0 == rEntry.sAPIPropertyName.compareToAscii( sApiName ) )
            return nIndex;
        else
            nIndex++;

    } while( nIndex < nEntries );

    return -1;
}

sal_Int32 XMLPropertySetMapper::FindEntryIndex( const sal_Int16 nContextId ) const
{
    sal_Int32 nIndex = 0;
    sal_Int32 nEntries = GetEntryCount();

    do
    {
        const XMLPropertySetMapperEntry_Impl& rEntry = aMapEntries[nIndex];
        if( rEntry.nContextId == nContextId )
            return nIndex;
        else
            nIndex++;

    } while( nIndex < nEntries );

    return -1;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <iterator>

using std::begin; using std::end; using std::cout; using std::endl;

int main()
{
    int arr[10];
    int *b = begin(arr);
    int *e = end(arr);

    for (int *i = b; i != e; ++i)
      *i = 0;

    for (auto i : arr)
      cout << i << " ";
    cout << endl;

    return 0;
}
<commit_msg>Update ex3_35.cpp<commit_after>#include <iostream>
using std::cout; using std::endl;

int main()
{
    int arr[10];
    for (auto ptr = arr; ptr != arr + 10; ++ptr) *ptr = 0;

    for (auto i : arr) cout << i << " ";
    cout << endl;

    return 0;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <string>
using std::cout; using std::cin; using std::endl; using std::string;

int main()
{
    string read, tmp;
    while (cin >> read)
        if (read == tmp) break; else tmp = read;

    if (cin.eof())  cout << "no word was repeated." << endl;
    else            cout << read << " occurs twice in succession." << endl;

    return 0;
}
<commit_msg>Update ex5_20.cpp<commit_after>#include <iostream>
#include <string>
using std::cout; using std::cin; using std::endl; using std::string;

int main()
{
    string read, tmp;
    while (cin >> read)
        if (read == tmp) break; tmp = read;

    if (cin.eof())  cout << "no word was repeated." << endl;
    else            cout << read << " occurs twice in succession." << endl;

    return 0;
}
<|endoftext|>


<commit_before>//
//  ex8_05.cpp
//  Exercise 8.5
//
//  Created by pezy on 11/9/14.
//  Copyright (c) 2014 pezy. All rights reserved.
//
//  @Brief  Rewrite the previous program to store each word in a separate
//  element.
//  @See    ex8_04.cpp

#include <fstream>
#include <string>
#include <vector>
#include <iostream>

using std::vector;
using std::string;
using std::ifstream;
using std::cout;
using std::endl;

void ReadFileToVec(const string& fileName, vector<string>& vec)
{
    ifstream ifs(fileName);
    if (ifs) {
        string buf;
        while (ifs >> buf) vec.push_back(buf);
    }
}

int main()
{
    vector<string> vec;
    ReadFileToVec("../data/book.txt", vec);
    for (const auto& str : vec) cout << str << endl;
    return 0;
}
<commit_msg>Update ex8_05.cpp<commit_after>//
//  ex8_05.cpp
//  Exercise 8.5
//
//  Created by pezy on 11/9/14.
//  Copyright (c) 2014 pezy. All rights reserved.
//
//  @Brief  Rewrite the previous program to store each word in a separate element
//  @See    ex8_04.cpp

#include <fstream>
#include <string>
#include <vector>
#include <iostream>

using std::vector;
using std::string;
using std::ifstream;
using std::cout;
using std::endl;

void ReadFileToVec(const string& fileName, vector<string>& vec)
{
    ifstream ifs(fileName);
    if (ifs) {
        string buf;
        while (ifs >> buf) vec.push_back(buf);
    }
}

int main()
{
    vector<string> vec;
    ReadFileToVec("../data/book.txt", vec);
    for (const auto& str : vec) cout << str << endl;
    return 0;
}
<|endoftext|>


<commit_before>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

//misc
#define _USE_MATH_DEFINES
#include <math.h>

// Blueberry
#include <berryISelectionService.h>
#include <berryIWorkbenchWindow.h>

// Qmitk
#include "QmitkDiffusionRegistrationView.h"

// MITK
#include <mitkImageCast.h>
#include <mitkImageToItk.h>
#include <mitkImageAccessByItk.h>
#include <mitkProgressBar.h>
#include <mitkIOUtil.h>
#include <mitkDiffusionPropertyHelper.h>

// Qt
#include <QMessageBox>
#include <QFileDialog>
#include <QDir>
#include <QDirIterator>
#include <QTimer>

#include <mitkDWIHeadMotionCorrectionFilter.h>

#define _USE_MATH_DEFINES
#include <math.h>

QmitkRegistrationWorker::QmitkRegistrationWorker(QmitkDiffusionRegistrationView* view)
  : m_View(view)
{

}

void QmitkRegistrationWorker::run()
{

  typedef mitk::DiffusionPropertyHelper::BValueMapType BValueMap;

  unsigned int totalImagesCount;
  if( !m_View->m_IsBatch )
  {
    totalImagesCount = m_View->m_SelectedDiffusionNodes.size();
  }
  else
  {
    totalImagesCount = m_View->m_BatchList.size();
  }
  m_View->m_TotalFiles = totalImagesCount;

  QString inputPath = m_View->m_Controls->m_InputFolderTextbox->text();
  QString outputPath = m_View->m_Controls->m_OutputFolderTextbox->text();

  for(unsigned int i=0; i< totalImagesCount; i++)
  {
    if(m_View->m_IsAborted){
      m_View->m_RegistrationThread.quit();
      return;
    }

    m_View->m_CurrentFile = i+1;
    m_View->m_GlobalRegisterer = QmitkDiffusionRegistrationView::DWIHeadMotionCorrectionFilterType::New();

    //mitk::DataNode::Pointer node = m_View->m_SelectedDiffusionNodes.at(i);
    mitk::Image::Pointer inImage;
    mitk::DataNode::Pointer node;

    if( !m_View->m_IsBatch )
    {
      node = m_View->m_SelectedDiffusionNodes.at(i);
      inImage = dynamic_cast<mitk::Image*>(node->GetData());
    }
    else
    {
      mitk::Image::Pointer inImage = dynamic_cast<mitk::Image*>(mitk::IOUtil::Load( m_View->m_BatchList.at(i).toStdString() )[0].GetPointer());
      mitk::GradientDirectionsProperty::Pointer gradDir = static_cast<mitk::GradientDirectionsProperty*>(inImage->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer());
    }

    bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage( inImage ) );

    if(!isDiffusionImage)
    {
      MITK_ERROR << "Error occured: can't get input image. \nAborting";
      return;
    }

    m_View->m_GlobalRegisterer->SetInput(inImage);

    try
    {
      m_View->m_GlobalRegisterer->Update();
    }
    catch( mitk::Exception e )
    {
      MITK_ERROR << "Internal error occured: " <<  e.what() << "\nAborting";
    }

    if( m_View->m_GlobalRegisterer->GetIsInValidState() )
    {
      if(! m_View->m_IsBatch)
      {
        mitk::Image::Pointer image = m_View->m_GlobalRegisterer->GetOutput();
        mitk::DataNode::Pointer imageNode = mitk::DataNode::New();
        imageNode->SetData( image );
        QString name = node->GetName().c_str();
        imageNode->SetName((name+"_MC").toStdString().c_str());
        m_View->GetDataStorage()->Add(imageNode);
      }
      else
      {
        QString name = m_View->m_BatchList.at(i);
        name = name.replace(".dwi", "_MC.dwi", Qt::CaseInsensitive);
        name = name.replace(inputPath, outputPath, Qt::CaseInsensitive);

        try
        {
          mitk::IOUtil::Save(m_View->m_GlobalRegisterer->GetOutput(), name.toStdString().c_str());
        }
        catch( const itk::ExceptionObject& e)
        {
          MITK_ERROR << "Catched exception: " << e.what();
          mitkThrow() << "Failed with exception from subprocess!";
        }
      }
    }

  }
  m_View->m_RegistrationThread.quit();
}

const std::string QmitkDiffusionRegistrationView::VIEW_ID = "org.mitk.views.diffusionregistrationview";

QmitkDiffusionRegistrationView::QmitkDiffusionRegistrationView()
  : QmitkAbstractView()
  , m_Controls( 0 )
  , m_DiffusionImage( nullptr )
  , m_ThreadIsRunning(false)
  , m_Steps(100)
  , m_LastStep(0)
  , m_GlobalRegisterer(nullptr)
  , m_RegistrationWorker(this)

{

  m_RegistrationWorker.moveToThread(&m_RegistrationThread);
  connect(&m_RegistrationThread, SIGNAL(started()), this, SLOT(BeforeThread()));
  connect(&m_RegistrationThread, SIGNAL(started()), &m_RegistrationWorker, SLOT(run()));
  connect(&m_RegistrationThread, SIGNAL(finished()), this, SLOT(AfterThread()));
  connect(&m_RegistrationThread, SIGNAL(terminated()), this, SLOT(AfterThread()));
  m_RegistrationTimer = new QTimer(this);

}

// Destructor
QmitkDiffusionRegistrationView::~QmitkDiffusionRegistrationView()
{
  delete m_RegistrationTimer;
}

// update Registration status and generate fiber bundle
void QmitkDiffusionRegistrationView::TimerUpdate()
{
  int currentStep = m_GlobalRegisterer->GetCurrentStep();

  mitk::ProgressBar::GetInstance()->Progress(currentStep-m_LastStep);
  UpdateRegistrationStatus();

  m_LastStep = currentStep;
}

// update gui elements after registration is finished
void QmitkDiffusionRegistrationView::AfterThread()
{

  m_ThreadIsRunning = false;
  m_RegistrationTimer->stop();

  mitk::ProgressBar::GetInstance()->Progress(m_GlobalRegisterer->GetSteps()-m_LastStep+1);
  UpdateGUI();

  if( !m_GlobalRegisterer->GetIsInValidState() )
  {
    QMessageBox::critical( nullptr,  "Registration", "An internal error occured, or user canceled the Registration.\n Please check the log for details." );
    return;
  }

  UpdateRegistrationStatus();

  m_GlobalRegisterer = 0;

}

// start Registration timer and update gui elements before Registration is started
void QmitkDiffusionRegistrationView::BeforeThread()
{
  m_ThreadIsRunning = true;
  m_RegistrationTime = QTime::currentTime();
  m_ElapsedTime = 0;
  m_RegistrationTimer->start(1000);
  m_LastStep = 0;

  UpdateGUI();
}

void QmitkDiffusionRegistrationView::CreateQtPartControl( QWidget *parent )
{
  // build up qt view, unless already done
  if ( !m_Controls )
  {
    // create GUI widgets from the Qt Designer's .ui file
    m_Controls = new Ui::QmitkDiffusionRegistrationViewControls;
    m_Controls->setupUi( parent );

    AdvancedSettings();

    connect( m_RegistrationTimer, SIGNAL(timeout()), this, SLOT(TimerUpdate()) );
    connect( m_Controls->m_RegistrationStopButton, SIGNAL(clicked()), this, SLOT(StopRegistration()) );
    connect( m_Controls->m_RegistrationStartButton, SIGNAL(clicked()), this, SLOT(StartRegistration()) );
    connect( m_Controls->m_AdvancedSettingsCheckbox, SIGNAL(clicked()), this, SLOT(AdvancedSettings()) );
    connect( m_Controls->m_SelectInputButton, SIGNAL(clicked()), this, SLOT(AddInputFolderName()) );
    connect( m_Controls->m_SelectOutputButton, SIGNAL(clicked()), this, SLOT(AddOutputFolderName()) );
    connect( m_Controls->m_StartBatchButton, SIGNAL(clicked()), this, SLOT(StartBatch()) );

    this->m_Parent = parent;
  }
}

// show/hide advanced settings frame
void QmitkDiffusionRegistrationView::AdvancedSettings()
{
  m_Controls->m_AdvancedFrame->setVisible(m_Controls->m_AdvancedSettingsCheckbox->isChecked());
}

void QmitkDiffusionRegistrationView::OnSelectionChanged(berry::IWorkbenchPart::Pointer, const QList<mitk::DataNode::Pointer>& nodes)
{

  if (m_ThreadIsRunning)
    return;

  bool foundDwiVolume = false;
  QString tempSelectedNames = "";
  m_DiffusionImage = nullptr;
  m_SelectedDiffusionNodes.clear();

  // iterate selection
  for (mitk::DataNode::Pointer node: nodes)
  {
    bool isDiffusionImage(false);
    if( node.IsNotNull() )
    {
      isDiffusionImage = mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage( dynamic_cast<mitk::Image *>(node->GetData()));
    }

    if( isDiffusionImage )
    {
      foundDwiVolume = true;
      m_SelectedDiffusionNodes.push_back(node);

      if(m_SelectedDiffusionNodes.size() > 0){tempSelectedNames += "\n";}
      tempSelectedNames += (node->GetName().c_str());
    }

  }

  m_Controls->m_RegistrationStartButton->setEnabled(foundDwiVolume);

  if (foundDwiVolume)
  {
    m_Controls->m_DiffusionImageLabel->setText(tempSelectedNames);
    m_Controls->m_InputData->setTitle("Input Data");
  }
  else
  {
    m_Controls->m_DiffusionImageLabel->setText("mandatory");
    m_Controls->m_InputData->setTitle("Please Select Input Data");
  }

  UpdateGUI();

}

// update gui elements displaying Registrations status
void QmitkDiffusionRegistrationView::UpdateRegistrationStatus()
{
  if (m_GlobalRegisterer.IsNull())
    return;

  m_ElapsedTime += m_RegistrationTime.elapsed()/1000;
  m_RegistrationTime.restart();
  unsigned long hours = m_ElapsedTime/3600;
  unsigned long minutes = (m_ElapsedTime%3600)/60;
  unsigned long seconds = m_ElapsedTime%60;

  m_Controls->m_RegistrationTimeLabel->setText( QString::number(hours)+QString("h ")+QString::number(minutes)+QString("m ")+QString::number(seconds)+QString("s") );
  m_Controls->m_CurrentStepLabel->setText( QString::number((int)(100*(float)(m_GlobalRegisterer->GetCurrentStep()-1)/m_GlobalRegisterer->GetSteps()))+"%" );
  m_Controls->m_CurrentFileLabel->setText( QString::number(m_CurrentFile)+" / "+QString::number(m_TotalFiles) );
}

void QmitkDiffusionRegistrationView::UpdateGUI()
{

  if (!m_ThreadIsRunning && (m_SelectedDiffusionNodes.size() > 0) )
  {
    m_Controls->m_RegistrationStopButton->setEnabled(false);
    m_Controls->m_RegistrationStartButton->setEnabled(true);
    m_Controls->m_StartBatchButton->setEnabled(true);
    m_Controls->m_AdvancedFrame->setEnabled(true);
    m_Controls->m_RegistrationStopButton->setText("Stop");
    m_Controls->m_RegistrationStartButton->setToolTip("Start Registration");
    m_Controls->m_RegistrationStopButton->setToolTip("");
  }
  else if (!m_ThreadIsRunning)
  {
    m_Controls->m_RegistrationStopButton->setEnabled(false);
    m_Controls->m_RegistrationStartButton->setEnabled(false);
    m_Controls->m_StartBatchButton->setEnabled(true);
    m_Controls->m_AdvancedFrame->setEnabled(true);
    m_Controls->m_RegistrationStopButton->setText("Stop");
    m_Controls->m_RegistrationStartButton->setToolTip("No Diffusion image selected.");
    m_Controls->m_RegistrationStopButton->setToolTip("");
  }
  else
  {
    m_Controls->m_RegistrationStopButton->setEnabled(true);
    m_Controls->m_RegistrationStartButton->setEnabled(false);
    m_Controls->m_StartBatchButton->setEnabled(false);
    m_Controls->m_AdvancedFrame->setEnabled(false);
    m_Controls->m_RegistrationStartButton->setToolTip("Registration in progress.");
    m_Controls->m_RegistrationStopButton->setToolTip("Cancel Registration");
  }

}

void QmitkDiffusionRegistrationView::SetFocus()
{
  m_Controls->m_RegistrationStartButton->setFocus();
}

void QmitkDiffusionRegistrationView::StartRegistration()
{

  if(m_ThreadIsRunning)
  {
    MITK_WARN("QmitkDiffusionRegistrationView")<<"Thread already running!";
    return;
  }
  m_GlobalRegisterer = nullptr;

  if (m_SelectedDiffusionNodes.size()<1)
  {
    QMessageBox::information( nullptr, "Warning", "Please load and select a diffusion image before starting image processing.");
    return;
  }

  m_IsBatch = false;
  m_IsAborted = false;

  m_Controls->m_RegistrationStartButton->setEnabled(false);
  m_Controls->m_StartBatchButton->setEnabled(false);

  // start worker thread
  m_RegistrationThread.start(QThread::NormalPriority);

  return;
}

void QmitkDiffusionRegistrationView::StopRegistration()
{

  if (m_GlobalRegisterer.IsNull())
    return;

  m_IsAborted = true;
  m_GlobalRegisterer->SetAbortRegistration(true);
  m_Controls->m_RegistrationStopButton->setEnabled(false);
  m_Controls->m_RegistrationStopButton->setText("Stopping ...");

  return;
}

void QmitkDiffusionRegistrationView::AddInputFolderName()
{

  // SELECT FOLDER DIALOG
  QFileDialog* w = new QFileDialog( m_Parent, QString("Select the input folder with DWI files within") );
  w->setFileMode( QFileDialog::Directory );

  // RETRIEVE SELECTION
  if ( w->exec() != QDialog::Accepted )
    return;

  m_Controls->m_InputFolderTextbox->setText(w->selectedFiles()[0]);
}

void QmitkDiffusionRegistrationView::AddOutputFolderName()
{
  // SELECT FOLDER DIALOG
  QFileDialog* w = new QFileDialog( m_Parent, QString("Select the output folder") );
  w->setFileMode( QFileDialog::Directory );

  // RETRIEVE SELECTION
  if ( w->exec() != QDialog::Accepted )
    return;

  m_Controls->m_OutputFolderTextbox->setText(w->selectedFiles()[0]);
}

void QmitkDiffusionRegistrationView::StartBatch()
{
  QString inputPath = m_Controls->m_InputFolderTextbox->text();
  QString outputPath = m_Controls->m_OutputFolderTextbox->text();

  if(inputPath == outputPath){
    QMessageBox::information( nullptr, "Error", "Input and Output folders can't be the same");
    return;
  }

  QStringList list, filters;
  filters<<"*.dwi";
  QDirIterator dirIterator(inputPath,
                           filters,
                           QDir::Files|QDir::NoSymLinks);

  while (dirIterator.hasNext())
  {
    dirIterator.next();

    list.append(dirIterator.fileInfo().absoluteFilePath());
    std::cout << dirIterator.fileInfo().absoluteFilePath().toStdString() << endl;
    m_BatchList = list;

    m_IsBatch = true;
    m_IsAborted = false;

    if(m_ThreadIsRunning)
    {
      MITK_WARN("QmitkDiffusionRegistrationView")<<"Thread already running!";
      return;
    }
    m_GlobalRegisterer = nullptr;

    if (m_BatchList.size()<1)
    {
      QMessageBox::information( nullptr, "Error", "No diffusion images were found in the selected input folder.");
      return;
    }

    m_Controls->m_RegistrationStartButton->setEnabled(false);
    m_Controls->m_StartBatchButton->setEnabled(false);

    // start worker thread
    m_RegistrationThread.start(QThread::NormalPriority);
  }
}
<commit_msg>Add missing std namespace to endl<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

//misc
#define _USE_MATH_DEFINES
#include <math.h>

// Blueberry
#include <berryISelectionService.h>
#include <berryIWorkbenchWindow.h>

// Qmitk
#include "QmitkDiffusionRegistrationView.h"

// MITK
#include <mitkImageCast.h>
#include <mitkImageToItk.h>
#include <mitkImageAccessByItk.h>
#include <mitkProgressBar.h>
#include <mitkIOUtil.h>
#include <mitkDiffusionPropertyHelper.h>

// Qt
#include <QMessageBox>
#include <QFileDialog>
#include <QDir>
#include <QDirIterator>
#include <QTimer>

#include <mitkDWIHeadMotionCorrectionFilter.h>

#define _USE_MATH_DEFINES
#include <math.h>

QmitkRegistrationWorker::QmitkRegistrationWorker(QmitkDiffusionRegistrationView* view)
  : m_View(view)
{

}

void QmitkRegistrationWorker::run()
{

  typedef mitk::DiffusionPropertyHelper::BValueMapType BValueMap;

  unsigned int totalImagesCount;
  if( !m_View->m_IsBatch )
  {
    totalImagesCount = m_View->m_SelectedDiffusionNodes.size();
  }
  else
  {
    totalImagesCount = m_View->m_BatchList.size();
  }
  m_View->m_TotalFiles = totalImagesCount;

  QString inputPath = m_View->m_Controls->m_InputFolderTextbox->text();
  QString outputPath = m_View->m_Controls->m_OutputFolderTextbox->text();

  for(unsigned int i=0; i< totalImagesCount; i++)
  {
    if(m_View->m_IsAborted){
      m_View->m_RegistrationThread.quit();
      return;
    }

    m_View->m_CurrentFile = i+1;
    m_View->m_GlobalRegisterer = QmitkDiffusionRegistrationView::DWIHeadMotionCorrectionFilterType::New();

    //mitk::DataNode::Pointer node = m_View->m_SelectedDiffusionNodes.at(i);
    mitk::Image::Pointer inImage;
    mitk::DataNode::Pointer node;

    if( !m_View->m_IsBatch )
    {
      node = m_View->m_SelectedDiffusionNodes.at(i);
      inImage = dynamic_cast<mitk::Image*>(node->GetData());
    }
    else
    {
      mitk::Image::Pointer inImage = dynamic_cast<mitk::Image*>(mitk::IOUtil::Load( m_View->m_BatchList.at(i).toStdString() )[0].GetPointer());
      mitk::GradientDirectionsProperty::Pointer gradDir = static_cast<mitk::GradientDirectionsProperty*>(inImage->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer());
    }

    bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage( inImage ) );

    if(!isDiffusionImage)
    {
      MITK_ERROR << "Error occured: can't get input image. \nAborting";
      return;
    }

    m_View->m_GlobalRegisterer->SetInput(inImage);

    try
    {
      m_View->m_GlobalRegisterer->Update();
    }
    catch( mitk::Exception e )
    {
      MITK_ERROR << "Internal error occured: " <<  e.what() << "\nAborting";
    }

    if( m_View->m_GlobalRegisterer->GetIsInValidState() )
    {
      if(! m_View->m_IsBatch)
      {
        mitk::Image::Pointer image = m_View->m_GlobalRegisterer->GetOutput();
        mitk::DataNode::Pointer imageNode = mitk::DataNode::New();
        imageNode->SetData( image );
        QString name = node->GetName().c_str();
        imageNode->SetName((name+"_MC").toStdString().c_str());
        m_View->GetDataStorage()->Add(imageNode);
      }
      else
      {
        QString name = m_View->m_BatchList.at(i);
        name = name.replace(".dwi", "_MC.dwi", Qt::CaseInsensitive);
        name = name.replace(inputPath, outputPath, Qt::CaseInsensitive);

        try
        {
          mitk::IOUtil::Save(m_View->m_GlobalRegisterer->GetOutput(), name.toStdString().c_str());
        }
        catch( const itk::ExceptionObject& e)
        {
          MITK_ERROR << "Catched exception: " << e.what();
          mitkThrow() << "Failed with exception from subprocess!";
        }
      }
    }

  }
  m_View->m_RegistrationThread.quit();
}

const std::string QmitkDiffusionRegistrationView::VIEW_ID = "org.mitk.views.diffusionregistrationview";

QmitkDiffusionRegistrationView::QmitkDiffusionRegistrationView()
  : QmitkAbstractView()
  , m_Controls( 0 )
  , m_DiffusionImage( nullptr )
  , m_ThreadIsRunning(false)
  , m_Steps(100)
  , m_LastStep(0)
  , m_GlobalRegisterer(nullptr)
  , m_RegistrationWorker(this)

{

  m_RegistrationWorker.moveToThread(&m_RegistrationThread);
  connect(&m_RegistrationThread, SIGNAL(started()), this, SLOT(BeforeThread()));
  connect(&m_RegistrationThread, SIGNAL(started()), &m_RegistrationWorker, SLOT(run()));
  connect(&m_RegistrationThread, SIGNAL(finished()), this, SLOT(AfterThread()));
  connect(&m_RegistrationThread, SIGNAL(terminated()), this, SLOT(AfterThread()));
  m_RegistrationTimer = new QTimer(this);

}

// Destructor
QmitkDiffusionRegistrationView::~QmitkDiffusionRegistrationView()
{
  delete m_RegistrationTimer;
}

// update Registration status and generate fiber bundle
void QmitkDiffusionRegistrationView::TimerUpdate()
{
  int currentStep = m_GlobalRegisterer->GetCurrentStep();

  mitk::ProgressBar::GetInstance()->Progress(currentStep-m_LastStep);
  UpdateRegistrationStatus();

  m_LastStep = currentStep;
}

// update gui elements after registration is finished
void QmitkDiffusionRegistrationView::AfterThread()
{

  m_ThreadIsRunning = false;
  m_RegistrationTimer->stop();

  mitk::ProgressBar::GetInstance()->Progress(m_GlobalRegisterer->GetSteps()-m_LastStep+1);
  UpdateGUI();

  if( !m_GlobalRegisterer->GetIsInValidState() )
  {
    QMessageBox::critical( nullptr,  "Registration", "An internal error occured, or user canceled the Registration.\n Please check the log for details." );
    return;
  }

  UpdateRegistrationStatus();

  m_GlobalRegisterer = 0;

}

// start Registration timer and update gui elements before Registration is started
void QmitkDiffusionRegistrationView::BeforeThread()
{
  m_ThreadIsRunning = true;
  m_RegistrationTime = QTime::currentTime();
  m_ElapsedTime = 0;
  m_RegistrationTimer->start(1000);
  m_LastStep = 0;

  UpdateGUI();
}

void QmitkDiffusionRegistrationView::CreateQtPartControl( QWidget *parent )
{
  // build up qt view, unless already done
  if ( !m_Controls )
  {
    // create GUI widgets from the Qt Designer's .ui file
    m_Controls = new Ui::QmitkDiffusionRegistrationViewControls;
    m_Controls->setupUi( parent );

    AdvancedSettings();

    connect( m_RegistrationTimer, SIGNAL(timeout()), this, SLOT(TimerUpdate()) );
    connect( m_Controls->m_RegistrationStopButton, SIGNAL(clicked()), this, SLOT(StopRegistration()) );
    connect( m_Controls->m_RegistrationStartButton, SIGNAL(clicked()), this, SLOT(StartRegistration()) );
    connect( m_Controls->m_AdvancedSettingsCheckbox, SIGNAL(clicked()), this, SLOT(AdvancedSettings()) );
    connect( m_Controls->m_SelectInputButton, SIGNAL(clicked()), this, SLOT(AddInputFolderName()) );
    connect( m_Controls->m_SelectOutputButton, SIGNAL(clicked()), this, SLOT(AddOutputFolderName()) );
    connect( m_Controls->m_StartBatchButton, SIGNAL(clicked()), this, SLOT(StartBatch()) );

    this->m_Parent = parent;
  }
}

// show/hide advanced settings frame
void QmitkDiffusionRegistrationView::AdvancedSettings()
{
  m_Controls->m_AdvancedFrame->setVisible(m_Controls->m_AdvancedSettingsCheckbox->isChecked());
}

void QmitkDiffusionRegistrationView::OnSelectionChanged(berry::IWorkbenchPart::Pointer, const QList<mitk::DataNode::Pointer>& nodes)
{

  if (m_ThreadIsRunning)
    return;

  bool foundDwiVolume = false;
  QString tempSelectedNames = "";
  m_DiffusionImage = nullptr;
  m_SelectedDiffusionNodes.clear();

  // iterate selection
  for (mitk::DataNode::Pointer node: nodes)
  {
    bool isDiffusionImage(false);
    if( node.IsNotNull() )
    {
      isDiffusionImage = mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage( dynamic_cast<mitk::Image *>(node->GetData()));
    }

    if( isDiffusionImage )
    {
      foundDwiVolume = true;
      m_SelectedDiffusionNodes.push_back(node);

      if(m_SelectedDiffusionNodes.size() > 0){tempSelectedNames += "\n";}
      tempSelectedNames += (node->GetName().c_str());
    }

  }

  m_Controls->m_RegistrationStartButton->setEnabled(foundDwiVolume);

  if (foundDwiVolume)
  {
    m_Controls->m_DiffusionImageLabel->setText(tempSelectedNames);
    m_Controls->m_InputData->setTitle("Input Data");
  }
  else
  {
    m_Controls->m_DiffusionImageLabel->setText("mandatory");
    m_Controls->m_InputData->setTitle("Please Select Input Data");
  }

  UpdateGUI();

}

// update gui elements displaying Registrations status
void QmitkDiffusionRegistrationView::UpdateRegistrationStatus()
{
  if (m_GlobalRegisterer.IsNull())
    return;

  m_ElapsedTime += m_RegistrationTime.elapsed()/1000;
  m_RegistrationTime.restart();
  unsigned long hours = m_ElapsedTime/3600;
  unsigned long minutes = (m_ElapsedTime%3600)/60;
  unsigned long seconds = m_ElapsedTime%60;

  m_Controls->m_RegistrationTimeLabel->setText( QString::number(hours)+QString("h ")+QString::number(minutes)+QString("m ")+QString::number(seconds)+QString("s") );
  m_Controls->m_CurrentStepLabel->setText( QString::number((int)(100*(float)(m_GlobalRegisterer->GetCurrentStep()-1)/m_GlobalRegisterer->GetSteps()))+"%" );
  m_Controls->m_CurrentFileLabel->setText( QString::number(m_CurrentFile)+" / "+QString::number(m_TotalFiles) );
}

void QmitkDiffusionRegistrationView::UpdateGUI()
{

  if (!m_ThreadIsRunning && (m_SelectedDiffusionNodes.size() > 0) )
  {
    m_Controls->m_RegistrationStopButton->setEnabled(false);
    m_Controls->m_RegistrationStartButton->setEnabled(true);
    m_Controls->m_StartBatchButton->setEnabled(true);
    m_Controls->m_AdvancedFrame->setEnabled(true);
    m_Controls->m_RegistrationStopButton->setText("Stop");
    m_Controls->m_RegistrationStartButton->setToolTip("Start Registration");
    m_Controls->m_RegistrationStopButton->setToolTip("");
  }
  else if (!m_ThreadIsRunning)
  {
    m_Controls->m_RegistrationStopButton->setEnabled(false);
    m_Controls->m_RegistrationStartButton->setEnabled(false);
    m_Controls->m_StartBatchButton->setEnabled(true);
    m_Controls->m_AdvancedFrame->setEnabled(true);
    m_Controls->m_RegistrationStopButton->setText("Stop");
    m_Controls->m_RegistrationStartButton->setToolTip("No Diffusion image selected.");
    m_Controls->m_RegistrationStopButton->setToolTip("");
  }
  else
  {
    m_Controls->m_RegistrationStopButton->setEnabled(true);
    m_Controls->m_RegistrationStartButton->setEnabled(false);
    m_Controls->m_StartBatchButton->setEnabled(false);
    m_Controls->m_AdvancedFrame->setEnabled(false);
    m_Controls->m_RegistrationStartButton->setToolTip("Registration in progress.");
    m_Controls->m_RegistrationStopButton->setToolTip("Cancel Registration");
  }

}

void QmitkDiffusionRegistrationView::SetFocus()
{
  m_Controls->m_RegistrationStartButton->setFocus();
}

void QmitkDiffusionRegistrationView::StartRegistration()
{

  if(m_ThreadIsRunning)
  {
    MITK_WARN("QmitkDiffusionRegistrationView")<<"Thread already running!";
    return;
  }
  m_GlobalRegisterer = nullptr;

  if (m_SelectedDiffusionNodes.size()<1)
  {
    QMessageBox::information( nullptr, "Warning", "Please load and select a diffusion image before starting image processing.");
    return;
  }

  m_IsBatch = false;
  m_IsAborted = false;

  m_Controls->m_RegistrationStartButton->setEnabled(false);
  m_Controls->m_StartBatchButton->setEnabled(false);

  // start worker thread
  m_RegistrationThread.start(QThread::NormalPriority);

  return;
}

void QmitkDiffusionRegistrationView::StopRegistration()
{

  if (m_GlobalRegisterer.IsNull())
    return;

  m_IsAborted = true;
  m_GlobalRegisterer->SetAbortRegistration(true);
  m_Controls->m_RegistrationStopButton->setEnabled(false);
  m_Controls->m_RegistrationStopButton->setText("Stopping ...");

  return;
}

void QmitkDiffusionRegistrationView::AddInputFolderName()
{

  // SELECT FOLDER DIALOG
  QFileDialog* w = new QFileDialog( m_Parent, QString("Select the input folder with DWI files within") );
  w->setFileMode( QFileDialog::Directory );

  // RETRIEVE SELECTION
  if ( w->exec() != QDialog::Accepted )
    return;

  m_Controls->m_InputFolderTextbox->setText(w->selectedFiles()[0]);
}

void QmitkDiffusionRegistrationView::AddOutputFolderName()
{
  // SELECT FOLDER DIALOG
  QFileDialog* w = new QFileDialog( m_Parent, QString("Select the output folder") );
  w->setFileMode( QFileDialog::Directory );

  // RETRIEVE SELECTION
  if ( w->exec() != QDialog::Accepted )
    return;

  m_Controls->m_OutputFolderTextbox->setText(w->selectedFiles()[0]);
}

void QmitkDiffusionRegistrationView::StartBatch()
{
  QString inputPath = m_Controls->m_InputFolderTextbox->text();
  QString outputPath = m_Controls->m_OutputFolderTextbox->text();

  if(inputPath == outputPath){
    QMessageBox::information( nullptr, "Error", "Input and Output folders can't be the same");
    return;
  }

  QStringList list, filters;
  filters<<"*.dwi";
  QDirIterator dirIterator(inputPath,
                           filters,
                           QDir::Files|QDir::NoSymLinks);

  while (dirIterator.hasNext())
  {
    dirIterator.next();

    list.append(dirIterator.fileInfo().absoluteFilePath());
    std::cout << dirIterator.fileInfo().absoluteFilePath().toStdString() << std::endl;
    m_BatchList = list;

    m_IsBatch = true;
    m_IsAborted = false;

    if(m_ThreadIsRunning)
    {
      MITK_WARN("QmitkDiffusionRegistrationView")<<"Thread already running!";
      return;
    }
    m_GlobalRegisterer = nullptr;

    if (m_BatchList.size()<1)
    {
      QMessageBox::information( nullptr, "Error", "No diffusion images were found in the selected input folder.");
      return;
    }

    m_Controls->m_RegistrationStartButton->setEnabled(false);
    m_Controls->m_StartBatchButton->setEnabled(false);

    // start worker thread
    m_RegistrationThread.start(QThread::NormalPriority);
  }
}
<|endoftext|>


<commit_before>/*
   This file is part of the clang-lazy static checker.

  Copyright (C) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
  Author: Sérgio Martins <sergio.martins@kdab.com>

  Copyright (C) 2015 Sergio Martins <smartins@kde.org>

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

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

  You should have received a copy of the GNU General Public License along
  with this program; if not, write to the Free Software Foundation, Inc.,
  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

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

#include "functionargsbyref.h"
#include "Utils.h"
#include "FixItUtils.h"
#include "checkmanager.h"

#include <clang/AST/AST.h>
#include <clang/Lex/Lexer.h>

using namespace clang;
using namespace std;

enum Fixit {
    FixitNone = 0,
    FixitAll = 0x1 // More granularity isn't needed I guess
};

static bool shouldIgnoreClass(CXXRecordDecl *record)
{
    if (!record)
        return false;

    if (Utils::isSharedPointer(record))
        return true;

    static const vector<string> ignoreList = {"QDebug", // Too many warnings
                                              "QGenericReturnArgument",
                                              "QColor", // TODO: Remove in Qt6
                                              "QStringRef", // TODO: Remove in Qt6
                                              "QList::const_iterator", // TODO: Remove in Qt6
                                              "QJsonArray::const_iterator", // TODO: Remove in Qt6
                                              "QList<QString>::const_iterator",  // TODO: Remove in Qt6
                                              "QtMetaTypePrivate::QSequentialIterableImpl",
                                              "QtMetaTypePrivate::QAssociativeIterableImpl",
                                              "QVariantComparisonHelper",
                                              "QHashDummyValue", "QCharRef", "QString::Null"
                                             };
    return std::find(ignoreList.cbegin(), ignoreList.cend(), record->getQualifiedNameAsString()) != ignoreList.cend();
}

static bool shouldIgnoreFunction(clang::FunctionDecl *function)
{
    // Too many warnings in operator<<
    static const vector<string> ignoreList = {"operator<<"};
    static const vector<string> qualifiedIgnoreList = {"QDBusMessage::createErrorReply", // Fixed in Qt6
                                                       "QMenu::exec", // Fixed in Qt6
                                                       "QTextFrame::iterator" // Fixed in Qt6
                                                      };
    if (std::find(ignoreList.cbegin(), ignoreList.cend(), function->getNameAsString()) != ignoreList.cend())
        return true;

    return std::find(qualifiedIgnoreList.cbegin(), qualifiedIgnoreList.cend(), function->getQualifiedNameAsString()) != qualifiedIgnoreList.cend();
}

FunctionArgsByRef::FunctionArgsByRef(const std::string &name)
    : CheckBase(name)
{
}

std::vector<string> FunctionArgsByRef::filesToIgnore() const
{
    return {"/c++/",
        "qimage.cpp", // TODO: Uncomment in Qt6
        "qimage.h",    // TODO: Uncomment in Qt6
        "qevent.h", // TODO: Uncomment in Qt6
        "avxintrin.h",
        "avx2intrin.h",
        "qnoncontiguousbytedevice.cpp",
        "qlocale_unix.cpp",
        "/clang/",
        "qmetatype.h", // TODO: fix in Qt
        "qbytearray.h" // TODO: fix in Qt
    };
}

static std::string warningMsgForSmallType(int sizeOf, const std::string &typeName)
{
    std::string sizeStr = std::to_string(sizeOf);
    return "Missing reference on large type sizeof " + typeName + " is " + sizeStr + " bytes)";
}

void FunctionArgsByRef::processFunction(FunctionDecl *functionDecl)
{
    if (!functionDecl || shouldIgnoreFunction(functionDecl)
            || !functionDecl->isThisDeclarationADefinition()) return;

    Stmt *body = functionDecl->getBody();

    int i = -1;
    for (auto it = functionDecl->param_begin(), end = functionDecl->param_end(); it != end; ++it) {
        i++;
        const ParmVarDecl *param = *it;
        QualType paramQt = Utils::unrefQualType(param->getType());
        const Type *paramType = paramQt.getTypePtrOrNull();
        if (!paramType || paramType->isIncompleteType() || paramType->isDependentType())
            continue;

        if (shouldIgnoreClass(paramType->getAsCXXRecordDecl()))
            continue;

        Utils::QualTypeClassification classif;
        bool success = Utils::classifyQualType(param, classif, body);
        if (!success)
            continue;

        if (classif.passBigTypeByConstRef || classif.passNonTriviallyCopyableByConstRef || classif.passSmallTrivialByValue) {
            string error;
            std::vector<FixItHint> fixits;
            const string paramStr = param->getType().getAsString();
            if (classif.passBigTypeByConstRef) {
                error = warningMsgForSmallType(classif.size_of_T, paramStr);
            } else if (classif.passNonTriviallyCopyableByConstRef) {
                error = "Missing reference on non-trivial type (" + paramStr + ")";
            } else if (classif.passSmallTrivialByValue) {
                error = "Pass small and trivially-copyable type by value (" + paramStr + ")";
                if (isFixitEnabled(FixitAll)) {
                    for (auto it = functionDecl->redecls_begin(), end = functionDecl->redecls_end(); it != end; ++it) { // Fix in both header and .cpp
                        FunctionDecl *fdecl = dyn_cast<FunctionDecl>(*it);
                        const ParmVarDecl *param = fdecl->getParamDecl(i);
                        fixits.push_back(fixitByValue(fdecl, param, classif));
                    }
                }
            }

            emitWarning(param->getLocStart(), error.c_str(), fixits);
        }
    }
}

void FunctionArgsByRef::VisitDecl(Decl *decl)
{
    processFunction(dyn_cast<FunctionDecl>(decl));
}

void FunctionArgsByRef::VisitStmt(Stmt *stmt)
{
    if (LambdaExpr *lambda = dyn_cast<LambdaExpr>(stmt)) {
        processFunction(lambda->getCallOperator());
    }
}

FixItHint FunctionArgsByRef::fixitByValue(FunctionDecl *func, const ParmVarDecl *param, const Utils::QualTypeClassification &)
{
    QualType qt = Utils::unrefQualType(param->getType());
    qt.removeLocalConst();
    const string typeName = qt.getAsString(PrintingPolicy(m_ci.getLangOpts()));
    string replacement = typeName + " " + string(param->getName());
    SourceLocation startLoc = param->getLocStart();
    SourceLocation endLoc = param->getLocEnd();

    const int numRedeclarations = std::distance(func->redecls_begin(), func->redecls_end());
    const bool definitionIsAlsoDeclaration = numRedeclarations == 1;
    const bool isDeclarationButNotDefinition = !func->doesThisDeclarationHaveABody();

    if (param->hasDefaultArg() && (isDeclarationButNotDefinition || definitionIsAlsoDeclaration)) {
        endLoc = param->getDefaultArg()->getLocStart().getLocWithOffset(-1);
        replacement += " =";
    }

    if (!startLoc.isValid() || !endLoc.isValid()) {
        llvm::errs() << "Internal error could not apply fixit " << startLoc.printToString(m_ci.getSourceManager())
                     << ";" << endLoc.printToString(m_ci.getSourceManager()) << "\n";
        return {};
    }

    return FixItUtils::createReplacement({ startLoc, endLoc }, replacement);
}

clang::FixItHint FunctionArgsByRef::fixitByConstRef(const ParmVarDecl *, const Utils::QualTypeClassification &)
{
    FixItHint fixit;
    return fixit;
}

const char *const s_checkName = "function-args-by-ref";
REGISTER_CHECK_WITH_FLAGS(s_checkName, FunctionArgsByRef, CheckLevel2)
// REGISTER_FIXIT(FixitAll, "fix-func-args", s_checkName)
<commit_msg>function-args-by-ref: Blacklist even more stuff already fixed in Qt 6<commit_after>/*
   This file is part of the clang-lazy static checker.

  Copyright (C) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
  Author: Sérgio Martins <sergio.martins@kdab.com>

  Copyright (C) 2015 Sergio Martins <smartins@kde.org>

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

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

  You should have received a copy of the GNU General Public License along
  with this program; if not, write to the Free Software Foundation, Inc.,
  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

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

#include "functionargsbyref.h"
#include "Utils.h"
#include "FixItUtils.h"
#include "checkmanager.h"

#include <clang/AST/AST.h>
#include <clang/Lex/Lexer.h>

using namespace clang;
using namespace std;

enum Fixit {
    FixitNone = 0,
    FixitAll = 0x1 // More granularity isn't needed I guess
};

static bool shouldIgnoreClass(CXXRecordDecl *record)
{
    if (!record)
        return false;

    if (Utils::isSharedPointer(record))
        return true;

    static const vector<string> ignoreList = {"QDebug", // Too many warnings
                                              "QGenericReturnArgument",
                                              "QColor", // TODO: Remove in Qt6
                                              "QStringRef", // TODO: Remove in Qt6
                                              "QList::const_iterator", // TODO: Remove in Qt6
                                              "QJsonArray::const_iterator", // TODO: Remove in Qt6
                                              "QList<QString>::const_iterator",  // TODO: Remove in Qt6
                                              "QtMetaTypePrivate::QSequentialIterableImpl",
                                              "QtMetaTypePrivate::QAssociativeIterableImpl",
                                              "QVariantComparisonHelper",
                                              "QHashDummyValue", "QCharRef", "QString::Null"
                                             };
    return std::find(ignoreList.cbegin(), ignoreList.cend(), record->getQualifiedNameAsString()) != ignoreList.cend();
}

static bool shouldIgnoreFunction(clang::FunctionDecl *function)
{
    // Too many warnings in operator<<
    static const vector<string> ignoreList = {"operator<<"};
    static const vector<string> qualifiedIgnoreList = {"QDBusMessage::createErrorReply", // Fixed in Qt6
                                                       "QMenu::exec", // Fixed in Qt6
                                                       "QTextFrame::iterator", // Fixed in Qt6
                                                       "QGraphicsWidget::addActions", // Fixed in Qt6
                                                       "QListWidget::mimeData", // Fixed in Qt6
                                                       "QTableWidget::mimeData", // Fixed in Qt6
                                                       "QTreeWidget::mimeData", // Fixed in Qt6
                                                       "QWidget::addActions", // Fixed in Qt6
                                                       "QSslCertificate::verify", // Fixed in Qt6
                                                       "QSslConfiguration::setAllowedNextProtocols" // Fixed in Qt6
                                                      };
    if (std::find(ignoreList.cbegin(), ignoreList.cend(), function->getNameAsString()) != ignoreList.cend())
        return true;

    return std::find(qualifiedIgnoreList.cbegin(), qualifiedIgnoreList.cend(), function->getQualifiedNameAsString()) != qualifiedIgnoreList.cend();
}

FunctionArgsByRef::FunctionArgsByRef(const std::string &name)
    : CheckBase(name)
{
}

std::vector<string> FunctionArgsByRef::filesToIgnore() const
{
    return {"/c++/",
        "qimage.cpp", // TODO: Uncomment in Qt6
        "qimage.h",    // TODO: Uncomment in Qt6
        "qevent.h", // TODO: Uncomment in Qt6
        "avxintrin.h",
        "avx2intrin.h",
        "qnoncontiguousbytedevice.cpp",
        "qlocale_unix.cpp",
        "/clang/",
        "qmetatype.h", // TODO: fix in Qt
        "qbytearray.h" // TODO: fix in Qt
    };
}

static std::string warningMsgForSmallType(int sizeOf, const std::string &typeName)
{
    std::string sizeStr = std::to_string(sizeOf);
    return "Missing reference on large type sizeof " + typeName + " is " + sizeStr + " bytes)";
}

void FunctionArgsByRef::processFunction(FunctionDecl *functionDecl)
{
    if (!functionDecl || shouldIgnoreFunction(functionDecl)
            || !functionDecl->isThisDeclarationADefinition()) return;

    Stmt *body = functionDecl->getBody();

    int i = -1;
    for (auto it = functionDecl->param_begin(), end = functionDecl->param_end(); it != end; ++it) {
        i++;
        const ParmVarDecl *param = *it;
        QualType paramQt = Utils::unrefQualType(param->getType());
        const Type *paramType = paramQt.getTypePtrOrNull();
        if (!paramType || paramType->isIncompleteType() || paramType->isDependentType())
            continue;

        if (shouldIgnoreClass(paramType->getAsCXXRecordDecl()))
            continue;

        Utils::QualTypeClassification classif;
        bool success = Utils::classifyQualType(param, classif, body);
        if (!success)
            continue;

        if (classif.passBigTypeByConstRef || classif.passNonTriviallyCopyableByConstRef || classif.passSmallTrivialByValue) {
            string error;
            std::vector<FixItHint> fixits;
            const string paramStr = param->getType().getAsString();
            if (classif.passBigTypeByConstRef) {
                error = warningMsgForSmallType(classif.size_of_T, paramStr);
            } else if (classif.passNonTriviallyCopyableByConstRef) {
                error = "Missing reference on non-trivial type (" + paramStr + ")";
            } else if (classif.passSmallTrivialByValue) {
                error = "Pass small and trivially-copyable type by value (" + paramStr + ")";
                if (isFixitEnabled(FixitAll)) {
                    for (auto it = functionDecl->redecls_begin(), end = functionDecl->redecls_end(); it != end; ++it) { // Fix in both header and .cpp
                        FunctionDecl *fdecl = dyn_cast<FunctionDecl>(*it);
                        const ParmVarDecl *param = fdecl->getParamDecl(i);
                        fixits.push_back(fixitByValue(fdecl, param, classif));
                    }
                }
            }

            emitWarning(param->getLocStart(), error.c_str(), fixits);
        }
    }
}

void FunctionArgsByRef::VisitDecl(Decl *decl)
{
    processFunction(dyn_cast<FunctionDecl>(decl));
}

void FunctionArgsByRef::VisitStmt(Stmt *stmt)
{
    if (LambdaExpr *lambda = dyn_cast<LambdaExpr>(stmt)) {
        processFunction(lambda->getCallOperator());
    }
}

FixItHint FunctionArgsByRef::fixitByValue(FunctionDecl *func, const ParmVarDecl *param, const Utils::QualTypeClassification &)
{
    QualType qt = Utils::unrefQualType(param->getType());
    qt.removeLocalConst();
    const string typeName = qt.getAsString(PrintingPolicy(m_ci.getLangOpts()));
    string replacement = typeName + " " + string(param->getName());
    SourceLocation startLoc = param->getLocStart();
    SourceLocation endLoc = param->getLocEnd();

    const int numRedeclarations = std::distance(func->redecls_begin(), func->redecls_end());
    const bool definitionIsAlsoDeclaration = numRedeclarations == 1;
    const bool isDeclarationButNotDefinition = !func->doesThisDeclarationHaveABody();

    if (param->hasDefaultArg() && (isDeclarationButNotDefinition || definitionIsAlsoDeclaration)) {
        endLoc = param->getDefaultArg()->getLocStart().getLocWithOffset(-1);
        replacement += " =";
    }

    if (!startLoc.isValid() || !endLoc.isValid()) {
        llvm::errs() << "Internal error could not apply fixit " << startLoc.printToString(m_ci.getSourceManager())
                     << ";" << endLoc.printToString(m_ci.getSourceManager()) << "\n";
        return {};
    }

    return FixItUtils::createReplacement({ startLoc, endLoc }, replacement);
}

clang::FixItHint FunctionArgsByRef::fixitByConstRef(const ParmVarDecl *, const Utils::QualTypeClassification &)
{
    FixItHint fixit;
    return fixit;
}

const char *const s_checkName = "function-args-by-ref";
REGISTER_CHECK_WITH_FLAGS(s_checkName, FunctionArgsByRef, CheckLevel2)
// REGISTER_FIXIT(FixitAll, "fix-func-args", s_checkName)
<|endoftext|>