<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.

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

#include <mitkTestingMacros.h>
#include <mitkTractAnalyzer.h>
#include <itkImageFileReader.h>
#include <mitkPointSetReader.h>
#include <mitkNrrdTbssRoiImageReader.h>

/**Documentation
 *  test for the class "mitkTractAnalyzer".
 */
int mitkTractAnalyzerTest(int argc , char* argv[])
{

  MITK_TEST_BEGIN("TractAnalyzer");

  // Load image
  typedef itk::Image<float, 3> FloatImageType;
  typedef itk::ImageFileReader<FloatImageType> ImageReaderType;

  ImageReaderType::Pointer reader = ImageReaderType::New();

  reader->SetFileName(argv[1]);
  reader->Update();
  FloatImageType::Pointer itkImage = reader->GetOutput();
  mitk::Image::Pointer mitkImage = mitk::Image::New();

  mitk::CastToMitkImage(itkImage, mitkImage);

  // load point set

  mitk::PointSetReader::Pointer pointSetReader = mitk::PointSetReader::New();
  pointSetReader->SetFileName(argv[2]);
  pointSetReader->Update();

  mitk::PointSet::Pointer pointSet = pointSetReader->GetOutput();

  mitk::TractAnalyzer analyzer;

  analyzer.SetInputImage(mitkImage);
  analyzer.SetThreshold(0.2);
  analyzer.SetPointSet(pointSet);
  analyzer.MakeRoi();

  mitk::TbssRoiImage::Pointer tbssRoi = analyzer.GetRoiImage();

  // load reference roi
  mitk::NrrdTbssRoiImageReader::Pointer roiReader = mitk::NrrdTbssRoiImageReader::New();
  roiReader->SetFileName(argv[3]);
  roiReader->Update();

  mitk::TbssRoiImage* referenceRoi = roiReader->GetOutput(0);

  // compare point sets of tbssRoi and reference roi

  std::vector< itk::Index<3> > roi = tbssRoi->GetRoi();
  std::vector< itk::Index<3> > refRoi = referenceRoi->GetRoi();

  bool equalSize(roi.size() == refRoi.size());
  MITK_TEST_CONDITION(equalSize, "Size of skeleton and control skeleton are the same.");

  if(equalSize)
  {
    bool samePath = true;
    for(int t=0; t<roi.size(); t++)
    {
      itk::Index<3> ix = roi.at(t);
      itk::Index<3> refIx = refRoi.at(t);

      if(ix != refIx)
      {
        samePath = false;
      }
    }

    MITK_TEST_CONDITION(samePath, "Calculated ROI matches reference ROI.");
  }

  MITK_TEST_END();
}
<commit_msg>COMP: new macro<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.

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

#include <mitkTestingMacros.h>
#include <mitkTractAnalyzer.h>
#include <itkImageFileReader.h>
#include <mitkPointSetReader.h>
#include <mitkNrrdTbssRoiImageReader.h>

/**Documentation
 *  test for the class "mitkTractAnalyzer".
 */
int mitkTractAnalyzerTest(int argc , char* argv[])
{

  MITK_TEST_BEGIN("TractAnalyzer");

  // Load image
  typedef itk::Image<float, 3> FloatImageType;
  typedef itk::ImageFileReader<FloatImageType> ImageReaderType;

  ImageReaderType::Pointer reader = ImageReaderType::New();

  reader->SetFileName(argv[1]);
  reader->Update();
  FloatImageType::Pointer itkImage = reader->GetOutput();
  mitk::Image::Pointer mitkImage = mitk::Image::New();

  mitk::CastToMitkImage(itkImage, mitkImage);

  // load point set

  mitk::PointSetReader::Pointer pointSetReader = mitk::PointSetReader::New();
  pointSetReader->SetFileName(argv[2]);
  pointSetReader->Update();

  mitk::PointSet::Pointer pointSet = pointSetReader->GetOutput();

  mitk::TractAnalyzer analyzer;

  analyzer.SetInputImage(mitkImage);
  analyzer.SetThreshold(0.2);
  analyzer.SetPointSet(pointSet);
  analyzer.MakeRoi();

  mitk::TbssRoiImage::Pointer tbssRoi = analyzer.GetRoiImage();

  // load reference roi
  mitk::NrrdTbssRoiImageReader::Pointer roiReader = mitk::NrrdTbssRoiImageReader::New();
  roiReader->SetFileName(argv[3]);
  roiReader->Update();

  mitk::TbssRoiImage* referenceRoi = roiReader->GetOutput(0);

  // compare point sets of tbssRoi and reference roi

  std::vector< itk::Index<3> > roi = tbssRoi->GetRoi();
  std::vector< itk::Index<3> > refRoi = referenceRoi->GetRoi();

  bool equalSize(roi.size() == refRoi.size());

  MITK_TEST_EQUAL(roi.size(), refRoi.size(), "Size of roi and control roi are the same.");

  if(equalSize)
  {
    bool samePath = true;
    for(int t=0; t<roi.size(); t++)
    {
      itk::Index<3> ix = roi.at(t);
      itk::Index<3> refIx = refRoi.at(t);

      if(ix != refIx)
      {
        samePath = false;
      }
    }

    MITK_TEST_CONDITION(samePath, "Calculated ROI matches reference ROI.");
  }

  MITK_TEST_END();
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: unocontrolbase.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: hr $ $Date: 2003-03-27 17:03:21 $
 *
 *  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 _COM_SUN_STAR_AWT_XLAYOUTCONSTRAINS_HPP_
#include <com/sun/star/awt/XLayoutConstrains.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XTEXTLAYOUTCONSTRAINS_HPP_
#include <com/sun/star/awt/XTextLayoutConstrains.hpp>
#endif

#include <toolkit/controls/unocontrolbase.hxx>
#include <toolkit/helper/property.hxx>

#include <tools/debug.hxx>

//  ----------------------------------------------------
//  class UnoControlBase
//  ----------------------------------------------------

sal_Bool UnoControlBase::ImplHasProperty( sal_uInt16 nPropId )
{
    ::rtl::OUString aPropName( GetPropertyName( nPropId ) );
    return ImplHasProperty( aPropName );
}

sal_Bool UnoControlBase::ImplHasProperty( const ::rtl::OUString& aPropertyName )
{
    ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >  xPSet( mxModel, ::com::sun::star::uno::UNO_QUERY );
    ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo >  xInfo = xPSet->getPropertySetInfo();
    return xInfo->hasPropertyByName( aPropertyName );
}

void UnoControlBase::ImplSetPropertyValue( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Any& aValue, sal_Bool bUpdateThis )
{
    // Model ggf. schon abgemeldet, aber ein Event schlaegt noch zu...
    if ( mxModel.is() )
    {
        ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >  xPSet( mxModel, ::com::sun::star::uno::UNO_QUERY );
        if ( !bUpdateThis )
            StartUpdatingModel();
        xPSet->setPropertyValue( aPropertyName, aValue );
        if ( !bUpdateThis )
            EndUpdatingModel();
    }
}

::com::sun::star::uno::Any UnoControlBase::ImplGetPropertyValue( const ::rtl::OUString& aPropertyName )
{
    ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >  xPSet( mxModel, ::com::sun::star::uno::UNO_QUERY );
    return xPSet->getPropertyValue( aPropertyName );
}

sal_Bool UnoControlBase::ImplGetPropertyValue_BOOL( sal_uInt16 nProp )
{
    sal_Bool b = sal_False;
    if ( mxModel.is() )
    {
        ::com::sun::star::uno::Any aVal = ImplGetPropertyValue( GetPropertyName( nProp ) );
        aVal >>= b;
    }
    return b;
}

sal_Int16 UnoControlBase::ImplGetPropertyValue_INT16( sal_uInt16 nProp )
{
    sal_Int16 n = 0;
    if ( mxModel.is() )
    {
        ::com::sun::star::uno::Any aVal = ImplGetPropertyValue( GetPropertyName( nProp ) );
        aVal >>= n;
    }
    return n;
}

sal_uInt16 UnoControlBase::ImplGetPropertyValue_UINT16( sal_uInt16 nProp )
{
    sal_uInt16 n = 0;
    if ( mxModel.is() )
    {
        ::com::sun::star::uno::Any aVal = ImplGetPropertyValue( GetPropertyName( nProp ) );
        aVal >>= n;
    }
    return n;
}

sal_Int32 UnoControlBase::ImplGetPropertyValue_INT32( sal_uInt16 nProp )
{
    sal_Int32 n = 0;
    if ( mxModel.is() )
    {
        ::com::sun::star::uno::Any aVal = ImplGetPropertyValue( GetPropertyName( nProp ) );
        aVal >>= n;
    }
    return n;
}

sal_uInt32 UnoControlBase::ImplGetPropertyValue_UINT32( sal_uInt16 nProp )
{
    sal_uInt32 n = 0;
    if ( mxModel.is() )
    {
        ::com::sun::star::uno::Any aVal = ImplGetPropertyValue( GetPropertyName( nProp ) );
        aVal >>= n;
    }
    return n;
}

double UnoControlBase::ImplGetPropertyValue_DOUBLE( sal_uInt16 nProp )
{
    double n = 0;
    if ( mxModel.is() )
    {
        ::com::sun::star::uno::Any aVal = ImplGetPropertyValue( GetPropertyName( nProp ) );
        aVal >>= n;
    }
    return n;
}

::rtl::OUString UnoControlBase::ImplGetPropertyValue_UString( sal_uInt16 nProp )
{
    ::rtl::OUString aStr;
    if ( mxModel.is() )
    {
        ::com::sun::star::uno::Any aVal = ImplGetPropertyValue( GetPropertyName( nProp ) );
        aVal >>= aStr;
    }
    return aStr;
}

::com::sun::star::awt::Size UnoControlBase::Impl_getMinimumSize()
{
    ::com::sun::star::awt::Size aSz;
    ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >  xP = ImplGetCompatiblePeer( sal_True );
    DBG_ASSERT( xP.is(), "Layout: No Peer!" );
    if ( xP.is() )
    {
        ::com::sun::star::uno::Reference< ::com::sun::star::awt::XLayoutConstrains >  xL( xP, ::com::sun::star::uno::UNO_QUERY );
        if ( xL.is() )
            aSz = xL->getMinimumSize();

        if ( !getPeer().is() || ( getPeer() != xP ) )
            xP->dispose();
    }
    return aSz;
}

::com::sun::star::awt::Size UnoControlBase::Impl_getPreferredSize()
{
    ::com::sun::star::awt::Size aSz;
    ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >  xP = ImplGetCompatiblePeer( sal_True );
    DBG_ASSERT( xP.is(), "Layout: No Peer!" );
    if ( xP.is() )
    {
        ::com::sun::star::uno::Reference< ::com::sun::star::awt::XLayoutConstrains >  xL( xP, ::com::sun::star::uno::UNO_QUERY );
        if ( xL.is() )
            aSz = xL->getPreferredSize();

        if ( !getPeer().is() || ( getPeer() != xP ) )
            xP->dispose();
    }
    return aSz;
}

::com::sun::star::awt::Size UnoControlBase::Impl_calcAdjustedSize( const ::com::sun::star::awt::Size& rNewSize )
{
    ::com::sun::star::awt::Size aSz;
    ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >  xP = ImplGetCompatiblePeer( sal_True );
    DBG_ASSERT( xP.is(), "Layout: No Peer!" );
    if ( xP.is() )
    {
        ::com::sun::star::uno::Reference< ::com::sun::star::awt::XLayoutConstrains > xL( xP, ::com::sun::star::uno::UNO_QUERY );
        if ( xL.is() )
            aSz = xL->calcAdjustedSize( rNewSize );

        if ( !getPeer().is() || ( getPeer() != xP ) )
            xP->dispose();
    }
    return aSz;
}

::com::sun::star::awt::Size UnoControlBase::Impl_getMinimumSize( sal_Int16 nCols, sal_Int16 nLines )
{
    ::com::sun::star::awt::Size aSz;
    ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >  xP = ImplGetCompatiblePeer( sal_True );
    DBG_ASSERT( xP.is(), "Layout: No Peer!" );
    if ( xP.is() )
    {
        ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTextLayoutConstrains >  xL( xP, ::com::sun::star::uno::UNO_QUERY );
        if ( xL.is() )
            aSz = xL->getMinimumSize( nCols, nLines );

        if ( !getPeer().is() || ( getPeer() != xP ) )
            xP->dispose();
    }
    return aSz;
}

void UnoControlBase::Impl_getColumnsAndLines( sal_Int16& nCols, sal_Int16& nLines )
{
    ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >  xP = ImplGetCompatiblePeer( sal_True );
    DBG_ASSERT( xP.is(), "Layout: No Peer!" );
    if ( xP.is() )
    {
        ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTextLayoutConstrains >  xL( xP, ::com::sun::star::uno::UNO_QUERY );
        if ( xL.is() )
            xL->getColumnsAndLines( nCols, nLines );

        if ( !getPeer().is() || ( getPeer() != xP ) )
            xP->dispose();
    }
}

<commit_msg>INTEGRATION: CWS frmcontrols03 (1.3.128); FILE MERGED 2004/03/02 08:05:34 fs 1.3.128.1: #i24387# ImplHasProperty: allow to be called when the model is still NULL<commit_after>/*************************************************************************
 *
 *  $RCSfile: unocontrolbase.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2004-05-07 16:17:33 $
 *
 *  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 _COM_SUN_STAR_AWT_XLAYOUTCONSTRAINS_HPP_
#include <com/sun/star/awt/XLayoutConstrains.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XTEXTLAYOUTCONSTRAINS_HPP_
#include <com/sun/star/awt/XTextLayoutConstrains.hpp>
#endif

#include <toolkit/controls/unocontrolbase.hxx>
#include <toolkit/helper/property.hxx>

#include <tools/debug.hxx>

//  ----------------------------------------------------
//  class UnoControlBase
//  ----------------------------------------------------

sal_Bool UnoControlBase::ImplHasProperty( sal_uInt16 nPropId )
{
    ::rtl::OUString aPropName( GetPropertyName( nPropId ) );
    return ImplHasProperty( aPropName );
}

sal_Bool UnoControlBase::ImplHasProperty( const ::rtl::OUString& aPropertyName )
{
    ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >  xPSet( mxModel, ::com::sun::star::uno::UNO_QUERY );
    if ( !xPSet.is() )
        return sal_False;
    ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo >  xInfo = xPSet->getPropertySetInfo();
    if ( !xInfo.is() )
        return sal_False;

    return xInfo->hasPropertyByName( aPropertyName );
}

void UnoControlBase::ImplSetPropertyValue( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Any& aValue, sal_Bool bUpdateThis )
{
    // Model ggf. schon abgemeldet, aber ein Event schlaegt noch zu...
    if ( mxModel.is() )
    {
        ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >  xPSet( mxModel, ::com::sun::star::uno::UNO_QUERY );
        if ( !bUpdateThis )
            StartUpdatingModel();
        xPSet->setPropertyValue( aPropertyName, aValue );
        if ( !bUpdateThis )
            EndUpdatingModel();
    }
}

::com::sun::star::uno::Any UnoControlBase::ImplGetPropertyValue( const ::rtl::OUString& aPropertyName )
{
    ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >  xPSet( mxModel, ::com::sun::star::uno::UNO_QUERY );
    return xPSet->getPropertyValue( aPropertyName );
}

sal_Bool UnoControlBase::ImplGetPropertyValue_BOOL( sal_uInt16 nProp )
{
    sal_Bool b = sal_False;
    if ( mxModel.is() )
    {
        ::com::sun::star::uno::Any aVal = ImplGetPropertyValue( GetPropertyName( nProp ) );
        aVal >>= b;
    }
    return b;
}

sal_Int16 UnoControlBase::ImplGetPropertyValue_INT16( sal_uInt16 nProp )
{
    sal_Int16 n = 0;
    if ( mxModel.is() )
    {
        ::com::sun::star::uno::Any aVal = ImplGetPropertyValue( GetPropertyName( nProp ) );
        aVal >>= n;
    }
    return n;
}

sal_uInt16 UnoControlBase::ImplGetPropertyValue_UINT16( sal_uInt16 nProp )
{
    sal_uInt16 n = 0;
    if ( mxModel.is() )
    {
        ::com::sun::star::uno::Any aVal = ImplGetPropertyValue( GetPropertyName( nProp ) );
        aVal >>= n;
    }
    return n;
}

sal_Int32 UnoControlBase::ImplGetPropertyValue_INT32( sal_uInt16 nProp )
{
    sal_Int32 n = 0;
    if ( mxModel.is() )
    {
        ::com::sun::star::uno::Any aVal = ImplGetPropertyValue( GetPropertyName( nProp ) );
        aVal >>= n;
    }
    return n;
}

sal_uInt32 UnoControlBase::ImplGetPropertyValue_UINT32( sal_uInt16 nProp )
{
    sal_uInt32 n = 0;
    if ( mxModel.is() )
    {
        ::com::sun::star::uno::Any aVal = ImplGetPropertyValue( GetPropertyName( nProp ) );
        aVal >>= n;
    }
    return n;
}

double UnoControlBase::ImplGetPropertyValue_DOUBLE( sal_uInt16 nProp )
{
    double n = 0;
    if ( mxModel.is() )
    {
        ::com::sun::star::uno::Any aVal = ImplGetPropertyValue( GetPropertyName( nProp ) );
        aVal >>= n;
    }
    return n;
}

::rtl::OUString UnoControlBase::ImplGetPropertyValue_UString( sal_uInt16 nProp )
{
    ::rtl::OUString aStr;
    if ( mxModel.is() )
    {
        ::com::sun::star::uno::Any aVal = ImplGetPropertyValue( GetPropertyName( nProp ) );
        aVal >>= aStr;
    }
    return aStr;
}

::com::sun::star::awt::Size UnoControlBase::Impl_getMinimumSize()
{
    ::com::sun::star::awt::Size aSz;
    ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >  xP = ImplGetCompatiblePeer( sal_True );
    DBG_ASSERT( xP.is(), "Layout: No Peer!" );
    if ( xP.is() )
    {
        ::com::sun::star::uno::Reference< ::com::sun::star::awt::XLayoutConstrains >  xL( xP, ::com::sun::star::uno::UNO_QUERY );
        if ( xL.is() )
            aSz = xL->getMinimumSize();

        if ( !getPeer().is() || ( getPeer() != xP ) )
            xP->dispose();
    }
    return aSz;
}

::com::sun::star::awt::Size UnoControlBase::Impl_getPreferredSize()
{
    ::com::sun::star::awt::Size aSz;
    ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >  xP = ImplGetCompatiblePeer( sal_True );
    DBG_ASSERT( xP.is(), "Layout: No Peer!" );
    if ( xP.is() )
    {
        ::com::sun::star::uno::Reference< ::com::sun::star::awt::XLayoutConstrains >  xL( xP, ::com::sun::star::uno::UNO_QUERY );
        if ( xL.is() )
            aSz = xL->getPreferredSize();

        if ( !getPeer().is() || ( getPeer() != xP ) )
            xP->dispose();
    }
    return aSz;
}

::com::sun::star::awt::Size UnoControlBase::Impl_calcAdjustedSize( const ::com::sun::star::awt::Size& rNewSize )
{
    ::com::sun::star::awt::Size aSz;
    ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >  xP = ImplGetCompatiblePeer( sal_True );
    DBG_ASSERT( xP.is(), "Layout: No Peer!" );
    if ( xP.is() )
    {
        ::com::sun::star::uno::Reference< ::com::sun::star::awt::XLayoutConstrains > xL( xP, ::com::sun::star::uno::UNO_QUERY );
        if ( xL.is() )
            aSz = xL->calcAdjustedSize( rNewSize );

        if ( !getPeer().is() || ( getPeer() != xP ) )
            xP->dispose();
    }
    return aSz;
}

::com::sun::star::awt::Size UnoControlBase::Impl_getMinimumSize( sal_Int16 nCols, sal_Int16 nLines )
{
    ::com::sun::star::awt::Size aSz;
    ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >  xP = ImplGetCompatiblePeer( sal_True );
    DBG_ASSERT( xP.is(), "Layout: No Peer!" );
    if ( xP.is() )
    {
        ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTextLayoutConstrains >  xL( xP, ::com::sun::star::uno::UNO_QUERY );
        if ( xL.is() )
            aSz = xL->getMinimumSize( nCols, nLines );

        if ( !getPeer().is() || ( getPeer() != xP ) )
            xP->dispose();
    }
    return aSz;
}

void UnoControlBase::Impl_getColumnsAndLines( sal_Int16& nCols, sal_Int16& nLines )
{
    ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >  xP = ImplGetCompatiblePeer( sal_True );
    DBG_ASSERT( xP.is(), "Layout: No Peer!" );
    if ( xP.is() )
    {
        ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTextLayoutConstrains >  xL( xP, ::com::sun::star::uno::UNO_QUERY );
        if ( xL.is() )
            xL->getColumnsAndLines( nCols, nLines );

        if ( !getPeer().is() || ( getPeer() != xP ) )
            xP->dispose();
    }
}

<|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.

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

#include "mitkGetPropertyService.h"
#include "QmitkAddNewPropertyDialog.h"
#include "QmitkPropertiesPreferencePage.h"
#include "QmitkPropertyItemDelegate.h"
#include "QmitkPropertyItemModel.h"
#include "QmitkPropertyItemSortFilterProxyModel.h"
#include "QmitkPropertyTreeView.h"
#include <berryIBerryPreferences.h>
#include <mitkIPropertyAliases.h>
#include <mitkIPropertyDescriptions.h>
#include <QmitkRenderWindow.h>
#include <QPainter>

const std::string QmitkPropertyTreeView::VIEW_ID = "org.mitk.views.properties";

QmitkPropertyTreeView::QmitkPropertyTreeView()
  : m_Parent(NULL),
    m_PropertyNameChangedTag(0),
    m_PropertyAliases(NULL),
    m_PropertyDescriptions(NULL),
    m_ShowAliasesInDescription(true),
    m_DeveloperMode(false),
    m_ProxyModel(NULL),
    m_Model(NULL),
    m_Delegate(NULL),
    m_Renderer(NULL)
{
}

QmitkPropertyTreeView::~QmitkPropertyTreeView()
{
}

void QmitkPropertyTreeView::CreateQtPartControl(QWidget* parent)
{
  m_Parent = parent;

  m_Controls.setupUi(parent);

  m_Controls.propertyListComboBox->addItem("independent");

  mitk::IRenderWindowPart* renderWindowPart = this->GetRenderWindowPart();

  if (renderWindowPart != NULL)
  {
    QHash<QString, QmitkRenderWindow*> renderWindows = renderWindowPart->GetQmitkRenderWindows();

    Q_FOREACH(QString renderWindow, renderWindows.keys())
    {
      m_Controls.propertyListComboBox->addItem(renderWindow);
    }
  }

  m_Controls.newButton->setEnabled(false);

  m_Controls.description->hide();
  m_Controls.propertyListLabel->hide();
  m_Controls.propertyListComboBox->hide();
  m_Controls.newButton->hide();

  m_ProxyModel = new QmitkPropertyItemSortFilterProxyModel(m_Controls.treeView);
  m_Model = new QmitkPropertyItemModel(m_ProxyModel);

  m_ProxyModel->setSourceModel(m_Model);
  m_ProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
  m_ProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
  m_ProxyModel->setDynamicSortFilter(true);

  m_Delegate = new QmitkPropertyItemDelegate(m_Controls.treeView);

  m_Controls.treeView->setItemDelegateForColumn(1, m_Delegate);
  m_Controls.treeView->setModel(m_ProxyModel);
  m_Controls.treeView->setColumnWidth(0, 160);
  m_Controls.treeView->sortByColumn(0, Qt::AscendingOrder);
  m_Controls.treeView->setSelectionBehavior(QAbstractItemView::SelectRows);
  m_Controls.treeView->setSelectionMode(QAbstractItemView::SingleSelection);
  m_Controls.treeView->setEditTriggers(QAbstractItemView::SelectedClicked | QAbstractItemView::DoubleClicked);

  connect(m_Controls.filterLineEdit, SIGNAL(textChanged(const QString&)), this, SLOT(OnFilterTextChanged(const QString&)));
  connect(m_Controls.propertyListComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(OnPropertyListChanged(int)));
  connect(m_Controls.newButton, SIGNAL(clicked()), this, SLOT(OnAddNewProperty()));
  connect(m_Controls.treeView->selectionModel(), SIGNAL(currentRowChanged(const QModelIndex&, const QModelIndex&)), this, SLOT(OnCurrentRowChanged(const QModelIndex&, const QModelIndex&)));
  connect(m_Model, SIGNAL(modelReset()), this, SLOT(OnModelReset()));
}

QString QmitkPropertyTreeView::GetPropertyNameOrAlias(const QModelIndex& index)
{
  QString propertyName;

  if (index.isValid())
  {
    QModelIndex current = index;

    while (current.isValid())
    {
      QString name = m_ProxyModel->data(m_ProxyModel->index(current.row(), 0, current.parent())).toString();

      propertyName.prepend(propertyName.isEmpty()
        ? name
        : name.append('.'));

      current = current.parent();
    }
  }

  return propertyName;
}

void QmitkPropertyTreeView::OnCurrentRowChanged(const QModelIndex& current, const QModelIndex&)
{
  if (m_PropertyDescriptions != NULL && current.isValid())
  {
    QString name = this->GetPropertyNameOrAlias(current);

    if (!name.isEmpty())
    {
      QString alias;
      bool isTrueName = true;

      if (m_PropertyAliases != NULL)
      {
        std::string trueName = m_PropertyAliases->GetPropertyName(name.toStdString());

        if (trueName.empty() && !m_SelectionClassName.empty())
          trueName = m_PropertyAliases->GetPropertyName(name.toStdString(), m_SelectionClassName);

        if (!trueName.empty())
        {
          alias = name;
          name = QString::fromStdString(trueName);
          isTrueName = false;
        }
      }

      QString description = QString::fromStdString(m_PropertyDescriptions->GetDescription(name.toStdString()));
      std::vector<std::string> aliases;

      if (!isTrueName && m_PropertyAliases != NULL)
      {
        aliases = m_PropertyAliases->GetAliases(name.toStdString(), m_SelectionClassName);

        if (aliases.empty() && !m_SelectionClassName.empty())
          aliases = m_PropertyAliases->GetAliases(name.toStdString());
      }

      if (!description.isEmpty() || !aliases.empty())
      {
        QString customizedDescription;

        if (m_ShowAliasesInDescription && !aliases.empty())
        {
          customizedDescription = "
" + name + "
";

          std::size_t numAliases = aliases.size();
          std::size_t lastAlias = numAliases - 1;

          for (std::size_t i = 0; i < numAliases; ++i)
          {
            customizedDescription += i != lastAlias
              ? "
"
              : "
";

            customizedDescription += QString::fromStdString(aliases[i]) + "
";
          }
        }
        else
        {
          customizedDescription = "
" + name + "
";
        }

        if (!description.isEmpty())
          customizedDescription += description;

        m_Controls.description->setText(customizedDescription);
        m_Controls.description->show();

        return;
      }
    }
  }

  m_Controls.description->hide();
}

void QmitkPropertyTreeView::OnFilterTextChanged(const QString& filter)
{
  m_ProxyModel->setFilterWildcard(filter);

  if (filter.isEmpty())
    m_Controls.treeView->collapseAll();
  else
    m_Controls.treeView->expandAll();
}

void QmitkPropertyTreeView::OnModelReset()
{
  m_Controls.description->hide();
}

void QmitkPropertyTreeView::OnPreferencesChanged(const berry::IBerryPreferences* preferences)
{
  bool showAliases = preferences->GetBool(QmitkPropertiesPreferencePage::SHOW_ALIASES, true);
  bool showDescriptions = preferences->GetBool(QmitkPropertiesPreferencePage::SHOW_DESCRIPTIONS, true);
  bool showAliasesInDescription = preferences->GetBool(QmitkPropertiesPreferencePage::SHOW_ALIASES_IN_DESCRIPTION, true);
  bool developerMode = preferences->GetBool(QmitkPropertiesPreferencePage::DEVELOPER_MODE, false);

  bool updateAliases = showAliases != (m_PropertyAliases != NULL);
  bool updateDescriptions = showDescriptions != (m_PropertyDescriptions != NULL);
  bool updateAliasesInDescription = showAliasesInDescription != m_ShowAliasesInDescription;
  bool updateDeveloperMode = developerMode != m_DeveloperMode;

  if (updateAliases)
    m_PropertyAliases = showAliases
      ? mitk::GetPropertyService<mitk::IPropertyAliases>()
      : NULL;

  if (updateDescriptions)
    m_PropertyDescriptions = showDescriptions
      ? mitk::GetPropertyService<mitk::IPropertyDescriptions>()
      : NULL;

  if (updateAliasesInDescription)
    m_ShowAliasesInDescription = showAliasesInDescription;

  if (updateDescriptions || updateAliasesInDescription)
  {
    QModelIndexList selection = m_Controls.treeView->selectionModel()->selectedRows();

    if (!selection.isEmpty())
      this->OnCurrentRowChanged(selection[0], selection[0]);
  }

  if (updateDeveloperMode)
  {
    m_DeveloperMode = developerMode;

    if (!developerMode)
      m_Controls.propertyListComboBox->setCurrentIndex(0);

    m_Controls.propertyListLabel->setVisible(developerMode);
    m_Controls.propertyListComboBox->setVisible(developerMode);
    m_Controls.newButton->setVisible(developerMode);
  }

  m_Model->OnPreferencesChanged(preferences);
}

void QmitkPropertyTreeView::OnPropertyNameChanged(const itk::EventObject&)
{
  mitk::PropertyList* propertyList = m_Model->GetPropertyList();

  if (propertyList != NULL)
  {
    mitk::BaseProperty* nameProperty = propertyList->GetProperty("name");

    if (nameProperty != NULL)
    {
      std::ostringstream partName;
      partName << "Properties (" << nameProperty->GetValueAsString() << ')';
      this->SetPartName(partName.str());
    }
  }
}

void QmitkPropertyTreeView::OnSelectionChanged(berry::IWorkbenchPart::Pointer, const QList<mitk::DataNode::Pointer>& nodes)
{
  mitk::PropertyList* propertyList = m_Model->GetPropertyList();

  if (propertyList != NULL)
  {
    mitk::BaseProperty* nameProperty = propertyList->GetProperty("name");

    if (nameProperty != NULL)
      nameProperty->RemoveObserver(m_PropertyNameChangedTag);

    m_PropertyNameChangedTag = 0;
  }

  if (nodes.empty() || nodes.front().IsNull())
  {
    m_SelectedNode = NULL;

    this->SetPartName("Properties");
    m_Model->SetPropertyList(NULL);
    m_Delegate->SetPropertyList(NULL);

    m_Controls.newButton->setEnabled(false);
  }
  else
  {
    m_SelectedNode = nodes.front();

    QString selectionClassName = m_SelectedNode->GetData() != NULL
      ? m_SelectedNode->GetData()->GetNameOfClass()
      : "";

    m_SelectionClassName = selectionClassName.toStdString();
    m_Model->SetPropertyList(m_SelectedNode->GetPropertyList(m_Renderer), selectionClassName);
    m_Delegate->SetPropertyList(m_SelectedNode->GetPropertyList(m_Renderer));
    OnPropertyNameChanged(itk::ModifiedEvent());

    mitk::BaseProperty* nameProperty = m_SelectedNode->GetProperty("name");

    if (nameProperty != NULL)
    {
      itk::ReceptorMemberCommand<QmitkPropertyTreeView>::Pointer command = itk::ReceptorMemberCommand<QmitkPropertyTreeView>::New();
      command->SetCallbackFunction(this, &QmitkPropertyTreeView::OnPropertyNameChanged);
      m_PropertyNameChangedTag = nameProperty->AddObserver(itk::ModifiedEvent(), command);
    }

    m_Controls.newButton->setEnabled(true);
  }

  if (!m_ProxyModel->filterRegExp().isEmpty())
    m_Controls.treeView->expandAll();
}

void QmitkPropertyTreeView::SetFocus()
{
  m_Controls.filterLineEdit->setFocus();
}

void QmitkPropertyTreeView::RenderWindowPartActivated(mitk::IRenderWindowPart* renderWindowPart)
{
  if (m_Controls.propertyListComboBox->count() == 1)
  {
    QHash<QString, QmitkRenderWindow*> renderWindows = this->GetRenderWindowPart()->GetQmitkRenderWindows();

    Q_FOREACH(QString renderWindow, renderWindows.keys())
    {
      m_Controls.propertyListComboBox->addItem(renderWindow);
    }
  }
}

void QmitkPropertyTreeView::RenderWindowPartDeactivated(mitk::IRenderWindowPart*)
{
  if (m_Controls.propertyListComboBox->count() > 1)
  {
    m_Controls.propertyListComboBox->clear();
    m_Controls.propertyListComboBox->addItem("independent");
  }
}

void QmitkPropertyTreeView::OnPropertyListChanged(int index)
{
  if (index == -1)
    return;

  QString renderer = m_Controls.propertyListComboBox->itemText(index);

  m_Renderer = renderer != "independent"
    ? this->GetRenderWindowPart()->GetQmitkRenderWindow(renderer)->GetRenderer()
    : NULL;

  QList<mitk::DataNode::Pointer> nodes;

  if (m_SelectedNode.IsNotNull())
    nodes << m_SelectedNode;

  berry::IWorkbenchPart::Pointer workbenchPart;

  this->OnSelectionChanged(workbenchPart, nodes);
}

void QmitkPropertyTreeView::OnAddNewProperty()
{
  QmitkAddNewPropertyDialog dialog(m_SelectedNode, m_Renderer, m_Parent);

  if (dialog.exec() == QDialog::Accepted)
    this->m_Model->Update();
}
<commit_msg>Made base data properties available in developer mode of Properties view.<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.

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

#include "mitkGetPropertyService.h"
#include "QmitkAddNewPropertyDialog.h"
#include "QmitkPropertiesPreferencePage.h"
#include "QmitkPropertyItemDelegate.h"
#include "QmitkPropertyItemModel.h"
#include "QmitkPropertyItemSortFilterProxyModel.h"
#include "QmitkPropertyTreeView.h"
#include <berryIBerryPreferences.h>
#include <mitkIPropertyAliases.h>
#include <mitkIPropertyDescriptions.h>
#include <QmitkRenderWindow.h>
#include <QPainter>

const std::string QmitkPropertyTreeView::VIEW_ID = "org.mitk.views.properties";

QmitkPropertyTreeView::QmitkPropertyTreeView()
  : m_Parent(NULL),
    m_PropertyNameChangedTag(0),
    m_PropertyAliases(NULL),
    m_PropertyDescriptions(NULL),
    m_ShowAliasesInDescription(true),
    m_DeveloperMode(false),
    m_ProxyModel(NULL),
    m_Model(NULL),
    m_Delegate(NULL),
    m_Renderer(NULL)
{
}

QmitkPropertyTreeView::~QmitkPropertyTreeView()
{
}

void QmitkPropertyTreeView::CreateQtPartControl(QWidget* parent)
{
  m_Parent = parent;

  m_Controls.setupUi(parent);

  m_Controls.propertyListComboBox->addItem("Data node: common");

  mitk::IRenderWindowPart* renderWindowPart = this->GetRenderWindowPart();

  if (renderWindowPart != NULL)
  {
    QHash<QString, QmitkRenderWindow*> renderWindows = renderWindowPart->GetQmitkRenderWindows();

    Q_FOREACH(QString renderWindow, renderWindows.keys())
    {
      m_Controls.propertyListComboBox->addItem(QString("Data node: ") + renderWindow);
    }
  }

  m_Controls.propertyListComboBox->addItem("Base data");

  m_Controls.newButton->setEnabled(false);

  m_Controls.description->hide();
  m_Controls.propertyListLabel->hide();
  m_Controls.propertyListComboBox->hide();
  m_Controls.newButton->hide();

  m_ProxyModel = new QmitkPropertyItemSortFilterProxyModel(m_Controls.treeView);
  m_Model = new QmitkPropertyItemModel(m_ProxyModel);

  m_ProxyModel->setSourceModel(m_Model);
  m_ProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
  m_ProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
  m_ProxyModel->setDynamicSortFilter(true);

  m_Delegate = new QmitkPropertyItemDelegate(m_Controls.treeView);

  m_Controls.treeView->setItemDelegateForColumn(1, m_Delegate);
  m_Controls.treeView->setModel(m_ProxyModel);
  m_Controls.treeView->setColumnWidth(0, 160);
  m_Controls.treeView->sortByColumn(0, Qt::AscendingOrder);
  m_Controls.treeView->setSelectionBehavior(QAbstractItemView::SelectRows);
  m_Controls.treeView->setSelectionMode(QAbstractItemView::SingleSelection);
  m_Controls.treeView->setEditTriggers(QAbstractItemView::SelectedClicked | QAbstractItemView::DoubleClicked);

  connect(m_Controls.filterLineEdit, SIGNAL(textChanged(const QString&)), this, SLOT(OnFilterTextChanged(const QString&)));
  connect(m_Controls.propertyListComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(OnPropertyListChanged(int)));
  connect(m_Controls.newButton, SIGNAL(clicked()), this, SLOT(OnAddNewProperty()));
  connect(m_Controls.treeView->selectionModel(), SIGNAL(currentRowChanged(const QModelIndex&, const QModelIndex&)), this, SLOT(OnCurrentRowChanged(const QModelIndex&, const QModelIndex&)));
  connect(m_Model, SIGNAL(modelReset()), this, SLOT(OnModelReset()));
}

QString QmitkPropertyTreeView::GetPropertyNameOrAlias(const QModelIndex& index)
{
  QString propertyName;

  if (index.isValid())
  {
    QModelIndex current = index;

    while (current.isValid())
    {
      QString name = m_ProxyModel->data(m_ProxyModel->index(current.row(), 0, current.parent())).toString();

      propertyName.prepend(propertyName.isEmpty()
        ? name
        : name.append('.'));

      current = current.parent();
    }
  }

  return propertyName;
}

void QmitkPropertyTreeView::OnCurrentRowChanged(const QModelIndex& current, const QModelIndex&)
{
  if (m_PropertyDescriptions != NULL && current.isValid())
  {
    QString name = this->GetPropertyNameOrAlias(current);

    if (!name.isEmpty())
    {
      QString alias;
      bool isTrueName = true;

      if (m_PropertyAliases != NULL)
      {
        std::string trueName = m_PropertyAliases->GetPropertyName(name.toStdString());

        if (trueName.empty() && !m_SelectionClassName.empty())
          trueName = m_PropertyAliases->GetPropertyName(name.toStdString(), m_SelectionClassName);

        if (!trueName.empty())
        {
          alias = name;
          name = QString::fromStdString(trueName);
          isTrueName = false;
        }
      }

      QString description = QString::fromStdString(m_PropertyDescriptions->GetDescription(name.toStdString()));
      std::vector<std::string> aliases;

      if (!isTrueName && m_PropertyAliases != NULL)
      {
        aliases = m_PropertyAliases->GetAliases(name.toStdString(), m_SelectionClassName);

        if (aliases.empty() && !m_SelectionClassName.empty())
          aliases = m_PropertyAliases->GetAliases(name.toStdString());
      }

      if (!description.isEmpty() || !aliases.empty())
      {
        QString customizedDescription;

        if (m_ShowAliasesInDescription && !aliases.empty())
        {
          customizedDescription = "
" + name + "
";

          std::size_t numAliases = aliases.size();
          std::size_t lastAlias = numAliases - 1;

          for (std::size_t i = 0; i < numAliases; ++i)
          {
            customizedDescription += i != lastAlias
              ? "
"
              : "
";

            customizedDescription += QString::fromStdString(aliases[i]) + "
";
          }
        }
        else
        {
          customizedDescription = "
" + name + "
";
        }

        if (!description.isEmpty())
          customizedDescription += description;

        m_Controls.description->setText(customizedDescription);
        m_Controls.description->show();

        return;
      }
    }
  }

  m_Controls.description->hide();
}

void QmitkPropertyTreeView::OnFilterTextChanged(const QString& filter)
{
  m_ProxyModel->setFilterWildcard(filter);

  if (filter.isEmpty())
    m_Controls.treeView->collapseAll();
  else
    m_Controls.treeView->expandAll();
}

void QmitkPropertyTreeView::OnModelReset()
{
  m_Controls.description->hide();
}

void QmitkPropertyTreeView::OnPreferencesChanged(const berry::IBerryPreferences* preferences)
{
  bool showAliases = preferences->GetBool(QmitkPropertiesPreferencePage::SHOW_ALIASES, true);
  bool showDescriptions = preferences->GetBool(QmitkPropertiesPreferencePage::SHOW_DESCRIPTIONS, true);
  bool showAliasesInDescription = preferences->GetBool(QmitkPropertiesPreferencePage::SHOW_ALIASES_IN_DESCRIPTION, true);
  bool developerMode = preferences->GetBool(QmitkPropertiesPreferencePage::DEVELOPER_MODE, false);

  bool updateAliases = showAliases != (m_PropertyAliases != NULL);
  bool updateDescriptions = showDescriptions != (m_PropertyDescriptions != NULL);
  bool updateAliasesInDescription = showAliasesInDescription != m_ShowAliasesInDescription;
  bool updateDeveloperMode = developerMode != m_DeveloperMode;

  if (updateAliases)
    m_PropertyAliases = showAliases
      ? mitk::GetPropertyService<mitk::IPropertyAliases>()
      : NULL;

  if (updateDescriptions)
    m_PropertyDescriptions = showDescriptions
      ? mitk::GetPropertyService<mitk::IPropertyDescriptions>()
      : NULL;

  if (updateAliasesInDescription)
    m_ShowAliasesInDescription = showAliasesInDescription;

  if (updateDescriptions || updateAliasesInDescription)
  {
    QModelIndexList selection = m_Controls.treeView->selectionModel()->selectedRows();

    if (!selection.isEmpty())
      this->OnCurrentRowChanged(selection[0], selection[0]);
  }

  if (updateDeveloperMode)
  {
    m_DeveloperMode = developerMode;

    if (!developerMode)
      m_Controls.propertyListComboBox->setCurrentIndex(0);

    m_Controls.propertyListLabel->setVisible(developerMode);
    m_Controls.propertyListComboBox->setVisible(developerMode);
    m_Controls.newButton->setVisible(developerMode);
  }

  m_Model->OnPreferencesChanged(preferences);
}

void QmitkPropertyTreeView::OnPropertyNameChanged(const itk::EventObject&)
{
  mitk::PropertyList* propertyList = m_Model->GetPropertyList();

  if (propertyList != NULL)
  {
    mitk::BaseProperty* nameProperty = propertyList->GetProperty("name");

    if (nameProperty != NULL)
    {
      std::ostringstream partName;
      partName << "Properties (" << nameProperty->GetValueAsString() << ')';
      this->SetPartName(partName.str());
    }
  }
}

void QmitkPropertyTreeView::OnSelectionChanged(berry::IWorkbenchPart::Pointer, const QList<mitk::DataNode::Pointer>& nodes)
{
  mitk::PropertyList* propertyList = m_Model->GetPropertyList();

  if (propertyList != NULL)
  {
    mitk::BaseProperty* nameProperty = propertyList->GetProperty("name");

    if (nameProperty != NULL)
      nameProperty->RemoveObserver(m_PropertyNameChangedTag);

    m_PropertyNameChangedTag = 0;
  }

  if (nodes.empty() || nodes.front().IsNull())
  {
    m_SelectedNode = NULL;

    this->SetPartName("Properties");
    m_Model->SetPropertyList(NULL);
    m_Delegate->SetPropertyList(NULL);

    m_Controls.newButton->setEnabled(false);
  }
  else
  {
    m_SelectedNode = nodes.front();

    QString selectionClassName = m_SelectedNode->GetData() != NULL
      ? m_SelectedNode->GetData()->GetNameOfClass()
      : "";

    m_SelectionClassName = selectionClassName.toStdString();

    mitk::PropertyList::Pointer propertyList;

    if (m_Renderer == NULL && m_Controls.propertyListComboBox->currentText() == "Base data")
    {
      propertyList = m_SelectedNode->GetData() != NULL
        ? m_SelectedNode->GetData()->GetPropertyList()
        : NULL;
    }
    else
    {
      propertyList = m_SelectedNode->GetPropertyList(m_Renderer);
    }

    m_Model->SetPropertyList(propertyList, selectionClassName);
    m_Delegate->SetPropertyList(propertyList);

    OnPropertyNameChanged(itk::ModifiedEvent());

    mitk::BaseProperty* nameProperty = m_SelectedNode->GetProperty("name");

    if (nameProperty != NULL)
    {
      itk::ReceptorMemberCommand<QmitkPropertyTreeView>::Pointer command = itk::ReceptorMemberCommand<QmitkPropertyTreeView>::New();
      command->SetCallbackFunction(this, &QmitkPropertyTreeView::OnPropertyNameChanged);
      m_PropertyNameChangedTag = nameProperty->AddObserver(itk::ModifiedEvent(), command);
    }

    m_Controls.newButton->setEnabled(true);
  }

  if (!m_ProxyModel->filterRegExp().isEmpty())
    m_Controls.treeView->expandAll();
}

void QmitkPropertyTreeView::SetFocus()
{
  m_Controls.filterLineEdit->setFocus();
}

void QmitkPropertyTreeView::RenderWindowPartActivated(mitk::IRenderWindowPart* renderWindowPart)
{
  if (m_Controls.propertyListComboBox->count() == 2)
  {
    QHash<QString, QmitkRenderWindow*> renderWindows = this->GetRenderWindowPart()->GetQmitkRenderWindows();

    Q_FOREACH(QString renderWindow, renderWindows.keys())
    {
      m_Controls.propertyListComboBox->insertItem(m_Controls.propertyListComboBox->count() - 1, QString("Data node: ") + renderWindow);
    }
  }
}

void QmitkPropertyTreeView::RenderWindowPartDeactivated(mitk::IRenderWindowPart*)
{
  if (m_Controls.propertyListComboBox->count() > 2)
  {
    m_Controls.propertyListComboBox->clear();
    m_Controls.propertyListComboBox->addItem("Data node: common");
    m_Controls.propertyListComboBox->addItem("Base data");
  }
}

void QmitkPropertyTreeView::OnPropertyListChanged(int index)
{
  if (index == -1)
    return;

  QString renderer = m_Controls.propertyListComboBox->itemText(index);

  if (renderer.startsWith("Data node: "))
    renderer = QString::fromStdString(renderer.toStdString().substr(11));

  m_Renderer = renderer != "common" && renderer != "Base data"
    ? this->GetRenderWindowPart()->GetQmitkRenderWindow(renderer)->GetRenderer()
    : NULL;

  QList<mitk::DataNode::Pointer> nodes;

  if (m_SelectedNode.IsNotNull())
    nodes << m_SelectedNode;

  berry::IWorkbenchPart::Pointer workbenchPart;

  this->OnSelectionChanged(workbenchPart, nodes);
}

void QmitkPropertyTreeView::OnAddNewProperty()
{
  QmitkAddNewPropertyDialog dialog(m_SelectedNode, m_Renderer, m_Parent);

  if (dialog.exec() == QDialog::Accepted)
    this->m_Model->Update();
}
<|endoftext|>


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

#include "rosrecord/Recorder.h"

#include "rosrecord/constants.h"

#include <iomanip>
#include <signal.h>
#include <sys/statvfs.h>

#include <boost/filesystem.hpp>
#include <boost/iostreams/filter/gzip.hpp>
#include <boost/iostreams/filter/bzip2.hpp>

using namespace ros::record;

ros::record::Recorder::Recorder()
  : file_header_pos_(0), index_data_pos_(0), header_buf_(NULL), header_buf_len_(0), header_buf_size_(0),
    message_buf_(NULL), message_buf_len_(0), message_buf_size_(0), logging_enabled_(true)
{
}

ros::record::Recorder::~Recorder()
{
  close();
}

const void* ros::record::Recorder::getHeaderBuffer()
{
  return header_buf_;
}

unsigned int ros::record::Recorder::getHeaderBufferLength()
{
  return header_buf_len_;
}

void ros::record::Recorder::resetHeaderBuffer()
{
  header_buf_len_ = 0;
}

void ros::record::Recorder::writeFieldToHeaderBuffer(const std::string& name, const void* value, unsigned int value_len)
{
  // Do a little buffer-size management.
  unsigned int new_len = header_buf_len_ + name.size() + 1 + 4 + value_len;
  if (header_buf_size_ < new_len)
  {
    if (header_buf_size_ == 0)
      header_buf_size_ = new_len;
    else
    {
      while (header_buf_size_ < new_len)
        header_buf_size_ *= 2;
    }
    header_buf_ = (unsigned char*) realloc(header_buf_, header_buf_size_);
    ROS_ASSERT(header_buf_);
  }

  // Copy in the data as
  //   <name>=<value_len><value>
  // where <value_len> is a 4-byte little-endian integer.
  //
  // (see http://pr.willowgarage.com/wiki/ROS/LogFormat)
  memcpy(header_buf_ + header_buf_len_, name.c_str(), name.size());
  header_buf_len_ += name.size();
  header_buf_[header_buf_len_] = FIELD_DELIM;
  header_buf_len_ += 1;
  memcpy(header_buf_ + header_buf_len_, &value_len, 4);
  header_buf_len_ += 4;
  memcpy(header_buf_ + header_buf_len_, value, value_len);
  header_buf_len_ += value_len;
}

bool ros::record::Recorder::open(const std::string& file_name, bool random_access)
{
  if (!openFile(file_name, random_access))
    return false;

  writeVersion();
  writeFileHeader();

  return true;
}

bool ros::record::Recorder::openFile(const std::string& file_name, bool random_access)
{
  file_name_ = file_name;

  std::string ext = boost::filesystem::extension(file_name);

  store_index_ = !(ext == ".gz" || ext == ".bz2");
  if (store_index_ && random_access)
    record_file_.open(file_name.c_str(), std::ios::in | std::ios::out | std::ios::binary);
  else
    record_file_.open(file_name.c_str(), std::ios::out | std::ios::binary | std::ios::app);

  if (record_file_.fail())
  {
    ROS_FATAL("rosrecord::Record: Failed to open file: %s", file_name.c_str());
    return false;
  }

  // Removing compression until we work out how to play nicely with index: JML
  /*
  if (ext == ".gz")
    record_stream_.push(boost::iostreams::gzip_compressor());
  else if (ext == ".bz2")
    record_stream_.push(boost::iostreams::bzip2_compressor());
  */
  record_stream_.push(record_file_);

  check_disk_next_ = ros::WallTime::now() + ros::WallDuration().fromSec(20.0);
  warn_next_ = ros::WallTime();

  record_pos_ = 0;

  checkDisk();

  return true;
}

pos_t ros::record::Recorder::getOffset()
{
  return record_pos_;
}

void ros::record::Recorder::close()
{
  if (!record_file_.is_open())
    return;

  if (store_index_)
    writeIndex();

  topics_recorded_.clear();
  topic_indexes_.clear();

  closeFile();
}

void ros::record::Recorder::closeFile()
{
  // Unfortunately closing this possibly enormous file takes a while
  // (especially over NFS) and handling of a SIGINT while a file is
  // closing leads to a double free.  So, we disable signals while
  // we close the file.

  // Darwin doesn't have sighandler_t; I hope that sig_t on Linux does
  // the right thing.
  //sighandler_t old = signal(SIGINT, SIG_IGN);
  sig_t old = signal(SIGINT, SIG_IGN);
  if (record_file_.is_open())
  {
    while (!record_stream_.empty())
      record_stream_.pop();
    record_file_.close();
  }
  signal(SIGINT, old);
}

void ros::record::Recorder::writeVersion()
{
  std::string version = std::string("#ROSRECORD V") + VERSION + std::string("\n");
  write(version);
}

bool ros::record::Recorder::checkDisk()
{
  struct statvfs fiData;

  if ((statvfs(file_name_.c_str(), &fiData)) < 0)
  {
    ROS_WARN("rosrecord::Record: Failed to check filesystem stats.");
  }
  else
  {
    unsigned long long free_space = 0;

    free_space = (unsigned long long)(fiData.f_bsize) * (unsigned long long)(fiData.f_bavail);

    if (free_space < 1073741824ull)
    {
      ROS_ERROR("rosrecord::Record: Less than 1GB of space free on disk with %s.  Disabling logging.", file_name_.c_str());
      logging_enabled_ = false;
      return false;
    }
    else if (free_space < 5368709120ull)
    {
      ROS_WARN("rosrecord::Record: Less than 5GB of space free on disk with %s.", file_name_.c_str());
    }
    else
    {
      logging_enabled_ = true;
    }
  }
  return true;
}

bool ros::record::Recorder::record(std::string topic_name, ros::Message::ConstPtr msg, ros::Time time)
{
  if (!logging_enabled_)
  {
    ros::WallTime nowtime = ros::WallTime::now();
    if (nowtime > warn_next_)
    {
      warn_next_ = nowtime + ros::WallDuration().fromSec(5.0);
      ROS_WARN("Not logging message because logging disabled.  Most likely cause is a full disk.");
    }
    return false;
  }

  bool needs_def_written = false;
  std::map<std::string, MsgInfo>::iterator key;
  {
    boost::mutex::scoped_lock lock(topics_recorded_mutex_);

    key = topics_recorded_.find(topic_name);

    if (key == topics_recorded_.end())
    {
      MsgInfo& info = topics_recorded_[topic_name];
      info.msg_def  = msg->__getMessageDefinition();
      info.datatype = msg->__getDataType();
      info.md5sum   = msg->__getMD5Sum();

      key = topics_recorded_.find(topic_name);

      topic_indexes_[topic_name] = std::vector<IndexEntry>();

      needs_def_written = true;
    }
  }
  const MsgInfo& msg_info = key->second;

  {
    boost::mutex::scoped_lock lock(check_disk_mutex_);

    if (ros::WallTime::now() > check_disk_next_)
    {
      check_disk_next_ = check_disk_next_ + ros::WallDuration().fromSec(20.0);

      if (!checkDisk())
        return false;
    }
  }

  {
    boost::mutex::scoped_lock lock(record_mutex_);

    // Assemble the header in memory first, because we need to write its length first.

    // Add to topic index
    IndexEntry index_entry;
    index_entry.sec  = time.sec;
    index_entry.nsec = time.nsec;
    index_entry.pos  = record_pos_;
    topic_indexes_[topic_name].push_back(index_entry);

    // Write a message definition record, if necessary
    if (needs_def_written)
    {
      M_string header;
      header[OP_FIELD_NAME]    = std::string((char*)&OP_MSG_DEF, 1);
      header[TOPIC_FIELD_NAME] = topic_name;
      header[MD5_FIELD_NAME]   = msg_info.md5sum;
      header[TYPE_FIELD_NAME]  = msg_info.datatype;
      header[DEF_FIELD_NAME]   = msg_info.msg_def;
      writeHeader(header, 0);
    }

    // Serialize the message into the message buffer
    if (message_buf_size_ < msg->__serialized_length)
    {
      if (message_buf_size_ == 0)
        message_buf_size_ = msg->__serialized_length;
      else
      {
        while (message_buf_size_ < msg->__serialized_length)
          message_buf_size_ *= 2;
      }
      message_buf_ = (unsigned char*)realloc(message_buf_, message_buf_size_);
      ROS_ASSERT(message_buf_);
    }
    msg->serialize(message_buf_, 0);

    // Write a message instance record
    M_string header;
    header[OP_FIELD_NAME]    = std::string((char*)&OP_MSG_DATA, 1);
    header[TOPIC_FIELD_NAME] = topic_name;
    header[MD5_FIELD_NAME]   = msg_info.md5sum;
    header[TYPE_FIELD_NAME]  = msg_info.datatype;
    header[SEC_FIELD_NAME]   = std::string((char*)&time.sec, 4);
    header[NSEC_FIELD_NAME]  = std::string((char*)&time.nsec, 4);
    writeRecord(header, (char*)message_buf_, msg->__serialized_length);
    if (record_file_.fail())
    {
      ROS_FATAL("rosrecord::Record: could not write to file.  Check permissions and diskspace\n");
      return false;
    }
  }

  return true;
}

void ros::record::Recorder::writeFileHeader()
{
  boost::mutex::scoped_lock lock(record_mutex_);

  // Remember position of file header record
  file_header_pos_ = record_pos_;

  // Write file header record
  M_string header;
  header[OP_FIELD_NAME]        = std::string((char*)&OP_FILE_HEADER, 1);
  header[INDEX_POS_FIELD_NAME] = std::string((char*)&index_data_pos_, 8);

  boost::shared_array<uint8_t> header_buffer;
  uint32_t header_len;
  Header::write(header, header_buffer, header_len);
  uint32_t data_len = 0;
  if (header_len < FILE_HEADER_LENGTH)
    data_len = FILE_HEADER_LENGTH - header_len;
  write((char*)&header_len, 4);
  write((char*)header_buffer.get(), header_len);
  write((char*)&data_len, 4);

  // Pad the file header record out
  if (data_len > 0)
  {
    std::string padding;
    padding.resize(data_len, ' ');
    write(padding);
  }
}

void ros::record::Recorder::writeIndex()
{
	{
		boost::mutex::scoped_lock lock(record_mutex_);

		// Remember position of first index record
		index_data_pos_ = record_pos_;

		for (std::map<std::string, std::vector<IndexEntry> >::const_iterator i = topic_indexes_.begin(); i != topic_indexes_.end(); i++)
		{
			const std::string&             topic_name  = i->first;
			const std::vector<IndexEntry>& topic_index = i->second;

			uint32_t topic_index_size = topic_index.size();

	    const MsgInfo& msg_info = topics_recorded_[topic_name];

	    // Write the index record header
			M_string header;
			header[OP_FIELD_NAME]    = std::string((char*)&OP_INDEX_DATA, 1);
			header[TOPIC_FIELD_NAME] = topic_name;
	    header[TYPE_FIELD_NAME]  = msg_info.datatype;
			header[VER_FIELD_NAME]   = std::string((char*)&INDEX_VERSION, 4);
			header[COUNT_FIELD_NAME] = std::string((char*)&topic_index_size, 4);

			uint32_t data_len = topic_index_size * sizeof(IndexEntry);
			writeHeader(header, data_len);

			// Write the index record data (pairs of timestamp and position in file)
			for (std::vector<IndexEntry>::const_iterator j = topic_index.begin(); j != topic_index.end(); j++)
			{
				const IndexEntry& index_entry = *j;
				write((char*)&index_entry.sec,  4);
				write((char*)&index_entry.nsec, 4);
				write((char*)&index_entry.pos,  8);
			}
		}
	}

	// Re-open the file for random access, and rewrite the file header to point to the first index data message
  closeFile();
  openFile(file_name_, true);
  seek(file_header_pos_);
  writeFileHeader();
}

//

void ros::record::Recorder::writeRecord(const M_string& fields, const char* data, uint32_t data_len)
{
  writeHeader(fields, data_len);
  write(data, data_len);
}

void ros::record::Recorder::writeHeader(const M_string& fields, uint32_t data_len)
{
  boost::shared_array<uint8_t> header_buffer;
  uint32_t header_len;
  Header::write(fields, header_buffer, header_len);

  write((char*)&header_len, 4);
  write((char*)header_buffer.get(), header_len);
  write((char*)&data_len, 4);
}

void ros::record::Recorder::write(const char* s, std::streamsize n)
{
  record_stream_.write(s, n);
  record_pos_ += n;
}

void ros::record::Recorder::write(const std::string& s)
{
  write(s.c_str(), s.length());
}

void ros::record::Recorder::seek(pos_t pos)
{
  record_file_.seekp(pos, std::ios_base::beg);
  record_pos_ = pos;
}
<commit_msg>Fixing rosrecord so it no longer depends on __serialized_length.<commit_after>/*********************************************************************
* Software License Agreement (BSD License)
*
*  Copyright (c) 2008, Willow Garage, Inc.
*  All rights reserved.
*
*  Redistribution and use in source and binary forms, with or without
*  modification, are permitted provided that the following conditions
*  are met:
*
*   * Redistributions of source code must retain the above copyright
*     notice, this list of conditions and the following disclaimer.
*   * Redistributions in binary form must reproduce the above
*     copyright notice, this list of conditions and the following
*     disclaimer in the documentation and/or other materials provided
*     with the distribution.
*   * Neither the name of Willow Garage, Inc. nor the names of its
*     contributors may be used to endorse or promote products derived
*     from this software without specific prior written permission.
*
*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
*  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
*  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
*  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
*  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
*  POSSIBILITY OF SUCH DAMAGE.
********************************************************************/

#include "rosrecord/Recorder.h"

#include "rosrecord/constants.h"

#include <iomanip>
#include <signal.h>
#include <sys/statvfs.h>

#include <boost/filesystem.hpp>
#include <boost/iostreams/filter/gzip.hpp>
#include <boost/iostreams/filter/bzip2.hpp>

using namespace ros::record;

ros::record::Recorder::Recorder()
  : file_header_pos_(0), index_data_pos_(0), header_buf_(NULL), header_buf_len_(0), header_buf_size_(0),
    message_buf_(NULL), message_buf_len_(0), message_buf_size_(0), logging_enabled_(true)
{
}

ros::record::Recorder::~Recorder()
{
  close();
}

const void* ros::record::Recorder::getHeaderBuffer()
{
  return header_buf_;
}

unsigned int ros::record::Recorder::getHeaderBufferLength()
{
  return header_buf_len_;
}

void ros::record::Recorder::resetHeaderBuffer()
{
  header_buf_len_ = 0;
}

void ros::record::Recorder::writeFieldToHeaderBuffer(const std::string& name, const void* value, unsigned int value_len)
{
  // Do a little buffer-size management.
  unsigned int new_len = header_buf_len_ + name.size() + 1 + 4 + value_len;
  if (header_buf_size_ < new_len)
  {
    if (header_buf_size_ == 0)
      header_buf_size_ = new_len;
    else
    {
      while (header_buf_size_ < new_len)
        header_buf_size_ *= 2;
    }
    header_buf_ = (unsigned char*) realloc(header_buf_, header_buf_size_);
    ROS_ASSERT(header_buf_);
  }

  // Copy in the data as
  //   <name>=<value_len><value>
  // where <value_len> is a 4-byte little-endian integer.
  //
  // (see http://pr.willowgarage.com/wiki/ROS/LogFormat)
  memcpy(header_buf_ + header_buf_len_, name.c_str(), name.size());
  header_buf_len_ += name.size();
  header_buf_[header_buf_len_] = FIELD_DELIM;
  header_buf_len_ += 1;
  memcpy(header_buf_ + header_buf_len_, &value_len, 4);
  header_buf_len_ += 4;
  memcpy(header_buf_ + header_buf_len_, value, value_len);
  header_buf_len_ += value_len;
}

bool ros::record::Recorder::open(const std::string& file_name, bool random_access)
{
  if (!openFile(file_name, random_access))
    return false;

  writeVersion();
  writeFileHeader();

  return true;
}

bool ros::record::Recorder::openFile(const std::string& file_name, bool random_access)
{
  file_name_ = file_name;

  std::string ext = boost::filesystem::extension(file_name);

  store_index_ = !(ext == ".gz" || ext == ".bz2");
  if (store_index_ && random_access)
    record_file_.open(file_name.c_str(), std::ios::in | std::ios::out | std::ios::binary);
  else
    record_file_.open(file_name.c_str(), std::ios::out | std::ios::binary | std::ios::app);

  if (record_file_.fail())
  {
    ROS_FATAL("rosrecord::Record: Failed to open file: %s", file_name.c_str());
    return false;
  }

  // Removing compression until we work out how to play nicely with index: JML
  /*
  if (ext == ".gz")
    record_stream_.push(boost::iostreams::gzip_compressor());
  else if (ext == ".bz2")
    record_stream_.push(boost::iostreams::bzip2_compressor());
  */
  record_stream_.push(record_file_);

  check_disk_next_ = ros::WallTime::now() + ros::WallDuration().fromSec(20.0);
  warn_next_ = ros::WallTime();

  record_pos_ = 0;

  checkDisk();

  return true;
}

pos_t ros::record::Recorder::getOffset()
{
  return record_pos_;
}

void ros::record::Recorder::close()
{
  if (!record_file_.is_open())
    return;

  if (store_index_)
    writeIndex();

  topics_recorded_.clear();
  topic_indexes_.clear();

  closeFile();
}

void ros::record::Recorder::closeFile()
{
  // Unfortunately closing this possibly enormous file takes a while
  // (especially over NFS) and handling of a SIGINT while a file is
  // closing leads to a double free.  So, we disable signals while
  // we close the file.

  // Darwin doesn't have sighandler_t; I hope that sig_t on Linux does
  // the right thing.
  //sighandler_t old = signal(SIGINT, SIG_IGN);
  sig_t old = signal(SIGINT, SIG_IGN);
  if (record_file_.is_open())
  {
    while (!record_stream_.empty())
      record_stream_.pop();
    record_file_.close();
  }
  signal(SIGINT, old);
}

void ros::record::Recorder::writeVersion()
{
  std::string version = std::string("#ROSRECORD V") + VERSION + std::string("\n");
  write(version);
}

bool ros::record::Recorder::checkDisk()
{
  struct statvfs fiData;

  if ((statvfs(file_name_.c_str(), &fiData)) < 0)
  {
    ROS_WARN("rosrecord::Record: Failed to check filesystem stats.");
  }
  else
  {
    unsigned long long free_space = 0;

    free_space = (unsigned long long)(fiData.f_bsize) * (unsigned long long)(fiData.f_bavail);

    if (free_space < 1073741824ull)
    {
      ROS_ERROR("rosrecord::Record: Less than 1GB of space free on disk with %s.  Disabling logging.", file_name_.c_str());
      logging_enabled_ = false;
      return false;
    }
    else if (free_space < 5368709120ull)
    {
      ROS_WARN("rosrecord::Record: Less than 5GB of space free on disk with %s.", file_name_.c_str());
    }
    else
    {
      logging_enabled_ = true;
    }
  }
  return true;
}

bool ros::record::Recorder::record(std::string topic_name, ros::Message::ConstPtr msg, ros::Time time)
{
  if (!logging_enabled_)
  {
    ros::WallTime nowtime = ros::WallTime::now();
    if (nowtime > warn_next_)
    {
      warn_next_ = nowtime + ros::WallDuration().fromSec(5.0);
      ROS_WARN("Not logging message because logging disabled.  Most likely cause is a full disk.");
    }
    return false;
  }

  bool needs_def_written = false;
  std::map<std::string, MsgInfo>::iterator key;
  {
    boost::mutex::scoped_lock lock(topics_recorded_mutex_);

    key = topics_recorded_.find(topic_name);

    if (key == topics_recorded_.end())
    {
      MsgInfo& info = topics_recorded_[topic_name];
      info.msg_def  = msg->__getMessageDefinition();
      info.datatype = msg->__getDataType();
      info.md5sum   = msg->__getMD5Sum();

      key = topics_recorded_.find(topic_name);

      topic_indexes_[topic_name] = std::vector<IndexEntry>();

      needs_def_written = true;
    }
  }
  const MsgInfo& msg_info = key->second;

  {
    boost::mutex::scoped_lock lock(check_disk_mutex_);

    if (ros::WallTime::now() > check_disk_next_)
    {
      check_disk_next_ = check_disk_next_ + ros::WallDuration().fromSec(20.0);

      if (!checkDisk())
        return false;
    }
  }

  {
    boost::mutex::scoped_lock lock(record_mutex_);

    // Assemble the header in memory first, because we need to write its length first.

    // Add to topic index
    IndexEntry index_entry;
    index_entry.sec  = time.sec;
    index_entry.nsec = time.nsec;
    index_entry.pos  = record_pos_;
    topic_indexes_[topic_name].push_back(index_entry);

    // Write a message definition record, if necessary
    if (needs_def_written)
    {
      M_string header;
      header[OP_FIELD_NAME]    = std::string((char*)&OP_MSG_DEF, 1);
      header[TOPIC_FIELD_NAME] = topic_name;
      header[MD5_FIELD_NAME]   = msg_info.md5sum;
      header[TYPE_FIELD_NAME]  = msg_info.datatype;
      header[DEF_FIELD_NAME]   = msg_info.msg_def;
      writeHeader(header, 0);
    }

    // Serialize the message into the message buffer
    if (message_buf_size_ < msg->serializationLength())
    {
      if (message_buf_size_ == 0)
        message_buf_size_ = msg->serializationLength();
      else
      {
        while (message_buf_size_ < msg->serializationLength())
          message_buf_size_ *= 2;
      }
      message_buf_ = (unsigned char*)realloc(message_buf_, message_buf_size_);
      ROS_ASSERT(message_buf_);
    }
    msg->serialize(message_buf_, 0);

    // Write a message instance record
    M_string header;
    header[OP_FIELD_NAME]    = std::string((char*)&OP_MSG_DATA, 1);
    header[TOPIC_FIELD_NAME] = topic_name;
    header[MD5_FIELD_NAME]   = msg_info.md5sum;
    header[TYPE_FIELD_NAME]  = msg_info.datatype;
    header[SEC_FIELD_NAME]   = std::string((char*)&time.sec, 4);
    header[NSEC_FIELD_NAME]  = std::string((char*)&time.nsec, 4);
    writeRecord(header, (char*)message_buf_, msg->serializationLength());
    if (record_file_.fail())
    {
      ROS_FATAL("rosrecord::Record: could not write to file.  Check permissions and diskspace\n");
      return false;
    }
  }

  return true;
}

void ros::record::Recorder::writeFileHeader()
{
  boost::mutex::scoped_lock lock(record_mutex_);

  // Remember position of file header record
  file_header_pos_ = record_pos_;

  // Write file header record
  M_string header;
  header[OP_FIELD_NAME]        = std::string((char*)&OP_FILE_HEADER, 1);
  header[INDEX_POS_FIELD_NAME] = std::string((char*)&index_data_pos_, 8);

  boost::shared_array<uint8_t> header_buffer;
  uint32_t header_len;
  Header::write(header, header_buffer, header_len);
  uint32_t data_len = 0;
  if (header_len < FILE_HEADER_LENGTH)
    data_len = FILE_HEADER_LENGTH - header_len;
  write((char*)&header_len, 4);
  write((char*)header_buffer.get(), header_len);
  write((char*)&data_len, 4);

  // Pad the file header record out
  if (data_len > 0)
  {
    std::string padding;
    padding.resize(data_len, ' ');
    write(padding);
  }
}

void ros::record::Recorder::writeIndex()
{
	{
		boost::mutex::scoped_lock lock(record_mutex_);

		// Remember position of first index record
		index_data_pos_ = record_pos_;

		for (std::map<std::string, std::vector<IndexEntry> >::const_iterator i = topic_indexes_.begin(); i != topic_indexes_.end(); i++)
		{
			const std::string&             topic_name  = i->first;
			const std::vector<IndexEntry>& topic_index = i->second;

			uint32_t topic_index_size = topic_index.size();

	    const MsgInfo& msg_info = topics_recorded_[topic_name];

	    // Write the index record header
			M_string header;
			header[OP_FIELD_NAME]    = std::string((char*)&OP_INDEX_DATA, 1);
			header[TOPIC_FIELD_NAME] = topic_name;
	    header[TYPE_FIELD_NAME]  = msg_info.datatype;
			header[VER_FIELD_NAME]   = std::string((char*)&INDEX_VERSION, 4);
			header[COUNT_FIELD_NAME] = std::string((char*)&topic_index_size, 4);

			uint32_t data_len = topic_index_size * sizeof(IndexEntry);
			writeHeader(header, data_len);

			// Write the index record data (pairs of timestamp and position in file)
			for (std::vector<IndexEntry>::const_iterator j = topic_index.begin(); j != topic_index.end(); j++)
			{
				const IndexEntry& index_entry = *j;
				write((char*)&index_entry.sec,  4);
				write((char*)&index_entry.nsec, 4);
				write((char*)&index_entry.pos,  8);
			}
		}
	}

	// Re-open the file for random access, and rewrite the file header to point to the first index data message
  closeFile();
  openFile(file_name_, true);
  seek(file_header_pos_);
  writeFileHeader();
}

//

void ros::record::Recorder::writeRecord(const M_string& fields, const char* data, uint32_t data_len)
{
  writeHeader(fields, data_len);
  write(data, data_len);
}

void ros::record::Recorder::writeHeader(const M_string& fields, uint32_t data_len)
{
  boost::shared_array<uint8_t> header_buffer;
  uint32_t header_len;
  Header::write(fields, header_buffer, header_len);

  write((char*)&header_len, 4);
  write((char*)header_buffer.get(), header_len);
  write((char*)&data_len, 4);
}

void ros::record::Recorder::write(const char* s, std::streamsize n)
{
  record_stream_.write(s, n);
  record_pos_ += n;
}

void ros::record::Recorder::write(const std::string& s)
{
  write(s.c_str(), s.length());
}

void ros::record::Recorder::seek(pos_t pos)
{
  record_file_.seekp(pos, std::ios_base::beg);
  record_pos_ = pos;
}
<|endoftext|>


<commit_before>
#include <ctime>
#include <cstdio>
#include <cstring>

#include <fstream>
#include <iostream>

#ifndef HPCG_NOMPI
#include <mpi.h>
#endif

#include "hpcg.hpp"

std::ofstream HPCG_fout;

static int
startswith(const char *s, const char *prefix) {
    size_t n = strlen( prefix );
    if (strncmp( s, prefix, n ))
        return 0;
    return 1;
}

int
HPCG_Init(int *argc_p, char ***argv_p, HPCG_Params & params) {
  int argc = *argc_p;
  char **argv = *argv_p;
  char fname[80];
  int i, j, iparams[3];
  char cparams[3][6] = {"--nx=", "--ny=", "--nz="};
  time_t rawtime;
  tm *ptm;

  /* for sequential and some MPI implementations it's OK to read first three args */
  for (i = 0; i < 3; ++i)
    if (argc <= i+1 || sscanf(argv[i+1], "%d", iparams+i) != 1 || iparams[i] < 10) iparams[i] = 0;

  /* for some MPI environments, command line arguments may get complicated so we need a prefix */
  for (i = 1; i <= argc && argv[i]; ++i)
    for (j = 0; j < 3; ++j)
      if (startswith(argv[i], cparams[j]))
        if (sscanf(argv[i]+strlen(cparams[j]), "%d", iparams+j) != 1 || iparams[j] < 10) iparams[j] = 0;

  if (! iparams[0] && ! iparams[1] && ! iparams[2]) { /* no geometry arguments on the command line */
    FILE *f = fopen("hpcg.dat", "r");
    if (f) {
      for (i = 0; i < 3; ++i)
        if (fscanf(f, "%d", iparams+i) != 1 || iparams[i] < 10) iparams[i] = 0;

      fclose(f);
    }
  }

  for (i = 0; i < 3; ++i) {
    if (iparams[i] < 10)
      for (j = 1; j <= 2; ++j)
        if (iparams[(i+j)%3] > iparams[i])
          iparams[i] = iparams[(i+j)%3];
    if (iparams[i] < 10)
      iparams[i] = 10;
  }

#ifndef HPCG_NOMPI
  MPI_Bcast( iparams, 3, MPI_INT, 0, MPI_COMM_WORLD );
#endif

  params.nx = iparams[0];
  params.ny = iparams[1];
  params.nz = iparams[2];

#ifdef HPCG_NOMPI
  params.comm_rank = 0;
  params.comm_size = 1;
#else
  MPI_Comm_rank( MPI_COMM_WORLD, &params.comm_rank );
  MPI_Comm_size( MPI_COMM_WORLD, &params.comm_size );
#endif

#ifdef HPCG_NOOPENMP
  params.numThreads = 1;
#else
#pragma omp parallel
  params.numThreads = omp_get_num_threads();
#endif

  time ( &rawtime );
  ptm = localtime(&rawtime);
  sprintf( fname, "hpcg_log_%04d%02d%02d_%02d:%02d:%02d.txt",
      1900 + ptm->tm_year, ptm->tm_mon+1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec );

  if (0 == params.comm_rank)
    HPCG_fout.open(fname);
  else {
#if defined(HPCG_DEBUG) || defined(HPCG_DETAILEDDEBUG)
    char local[15];
    sprintf( local, "%d_", params.comm_rank );
    sprintf( fname, "hpcg_log_%s%04d%02d%02d_%02d:%02d:%02d.txt", local,
      1900 + ptm->tm_year, ptm->tm_mon+1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec );
    HPCG_fout.open(fname);
#else
    HPCG_fout.open("/dev/null");
#endif
  }

  return 0;
}
<commit_msg>Adding the omp.h include to this file, since it is needed to set the number of threads in the params struct.<commit_after>
#include <ctime>
#include <cstdio>
#include <cstring>

#include <fstream>
#include <iostream>

#ifndef HPCG_NOMPI
#include <mpi.h>
#endif

#ifndef HPCG_NOOPENMP
#include <omp.h>
#endif

#include "hpcg.hpp"

std::ofstream HPCG_fout;

static int
startswith(const char *s, const char *prefix) {
    size_t n = strlen( prefix );
    if (strncmp( s, prefix, n ))
        return 0;
    return 1;
}

int
HPCG_Init(int *argc_p, char ***argv_p, HPCG_Params & params) {
  int argc = *argc_p;
  char **argv = *argv_p;
  char fname[80];
  int i, j, iparams[3];
  char cparams[3][6] = {"--nx=", "--ny=", "--nz="};
  time_t rawtime;
  tm *ptm;

  /* for sequential and some MPI implementations it's OK to read first three args */
  for (i = 0; i < 3; ++i)
    if (argc <= i+1 || sscanf(argv[i+1], "%d", iparams+i) != 1 || iparams[i] < 10) iparams[i] = 0;

  /* for some MPI environments, command line arguments may get complicated so we need a prefix */
  for (i = 1; i <= argc && argv[i]; ++i)
    for (j = 0; j < 3; ++j)
      if (startswith(argv[i], cparams[j]))
        if (sscanf(argv[i]+strlen(cparams[j]), "%d", iparams+j) != 1 || iparams[j] < 10) iparams[j] = 0;

  if (! iparams[0] && ! iparams[1] && ! iparams[2]) { /* no geometry arguments on the command line */
    FILE *f = fopen("hpcg.dat", "r");
    if (f) {
      for (i = 0; i < 3; ++i)
        if (fscanf(f, "%d", iparams+i) != 1 || iparams[i] < 10) iparams[i] = 0;

      fclose(f);
    }
  }

  for (i = 0; i < 3; ++i) {
    if (iparams[i] < 10)
      for (j = 1; j <= 2; ++j)
        if (iparams[(i+j)%3] > iparams[i])
          iparams[i] = iparams[(i+j)%3];
    if (iparams[i] < 10)
      iparams[i] = 10;
  }

#ifndef HPCG_NOMPI
  MPI_Bcast( iparams, 3, MPI_INT, 0, MPI_COMM_WORLD );
#endif

  params.nx = iparams[0];
  params.ny = iparams[1];
  params.nz = iparams[2];

#ifdef HPCG_NOMPI
  params.comm_rank = 0;
  params.comm_size = 1;
#else
  MPI_Comm_rank( MPI_COMM_WORLD, &params.comm_rank );
  MPI_Comm_size( MPI_COMM_WORLD, &params.comm_size );
#endif

#ifdef HPCG_NOOPENMP
  params.numThreads = 1;
#else
#pragma omp parallel
  params.numThreads = omp_get_num_threads();
#endif

  time ( &rawtime );
  ptm = localtime(&rawtime);
  sprintf( fname, "hpcg_log_%04d%02d%02d_%02d:%02d:%02d.txt",
      1900 + ptm->tm_year, ptm->tm_mon+1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec );

  if (0 == params.comm_rank)
    HPCG_fout.open(fname);
  else {
#if defined(HPCG_DEBUG) || defined(HPCG_DETAILEDDEBUG)
    char local[15];
    sprintf( local, "%d_", params.comm_rank );
    sprintf( fname, "hpcg_log_%s%04d%02d%02d_%02d:%02d:%02d.txt", local,
      1900 + ptm->tm_year, ptm->tm_mon+1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec );
    HPCG_fout.open(fname);
#else
    HPCG_fout.open("/dev/null");
#endif
  }

  return 0;
}
<|endoftext|>


<commit_before>#include <allegro.h>
#ifdef ALLEGRO_WINDOWS
#include <winalleg.h>
#endif

#ifndef ALLEGRO_WINDOWS
#include <signal.h>
#include <string.h>
#endif

#include "globals.h"
#include "init.h"
#include <pthread.h>
#include "network/network.h"

#include <ostream>
#include "dumb/include/dumb.h"
#include "dumb/include/aldumb.h"
#include "loadpng/loadpng.h"
#include "util/bitmap.h"
#include "configuration.h"
#include "script/script.h"

using namespace std;

volatile int Global::speed_counter = 0;
volatile int Global::second_counter = 0;

/* the original engine was running at 90 ticks per second, but we dont
 * need to render that fast, so TICS_PER_SECOND is really fps and
 * LOGIC_MULTIPLIER will be used to adjust the speed counter to its
 * original value.
 */
static const int TICS_PER_SECOND = 40;
const double Global::LOGIC_MULTIPLIER = (double) 90 / (double) TICS_PER_SECOND;

pthread_mutex_t Global::loading_screen_mutex;
bool Global::done_loading = false;

const int Global::WINDOWED = GFX_AUTODETECT_WINDOWED;
const int Global::FULLSCREEN = GFX_AUTODETECT_FULLSCREEN;

void inc_speed_counter() {
	Global::speed_counter += 1;
}
END_OF_FUNCTION( inc_speed_counter );

void inc_second_counter() {
	Global::second_counter += 1;
}
END_OF_FUNCTION( inc_second_counter );

#ifndef ALLEGRO_WINDOWS
static void handleSigSegV(int i, siginfo_t * sig, void * data){
    Bitmap::setGfxModeText();
    allegro_exit();
    /* write to a log file or something because sigsegv shouldn't
     * normally happen.
     */
    exit(0);
}
#else
#endif

/* catch a socket being closed prematurely on unix */
#ifndef ALLEGRO_WINDOWS
static void handleSigPipe( int i, siginfo_t * sig, void * data ){
}

/*
static void handleSigUsr1( int i, siginfo_t * sig, void * data ){
	pthread_exit( NULL );
}
*/
#endif

static void registerSignals(){
#ifndef ALLEGRO_WINDOWS
	struct sigaction action;
	memset( &action, 0, sizeof(struct sigaction) );
	action.sa_sigaction = handleSigPipe;
	sigaction( SIGPIPE, &action, NULL );

	memset( &action, 0, sizeof(struct sigaction) );
	action.sa_sigaction = handleSigSegV;
	sigaction( SIGSEGV, &action, NULL );

	/*
	action.sa_sigaction = handleSigUsr1;
	sigaction( SIGUSR1, &action, NULL );
	*/
#endif
}

static void close_paintown(){
    Bitmap::setGfxModeText();
    allegro_exit();
    exit(0);
}
END_OF_FUNCTION(close_paintown)

bool Global::init( int gfx ){

	ostream & out = Global::debug( 0 );
	out << "-- BEGIN init --" << endl;
        out << "Paintown version " << Global::getVersionString() << endl;
	out << "Allegro version: " << ALLEGRO_VERSION_STR << endl;
	out <<"Allegro init: "<<allegro_init()<<endl;
	out <<"Install timer: "<<install_timer()<<endl;

	set_volume_per_voice( 0 );
	out<<"Install sound: "<<install_sound( DIGI_AUTODETECT, MIDI_NONE, "" )<<endl;

        /* png */
	loadpng_init();

        Bitmap::SCALE_X = GFX_X;
        Bitmap::SCALE_Y = GFX_Y;

        Configuration::loadConfigurations();

        const int sx = Configuration::getScreenWidth();
        const int sy = Configuration::getScreenHeight();

	out<<"Install keyboard: "<<install_keyboard()<<endl;
	out<<"Install mouse: "<<install_mouse()<<endl;
        /* 16 bit color depth */
	set_color_depth( 16 );

        /* set up the screen */
	out<<"Set gfx mode: " << Bitmap::setGraphicsMode( gfx, sx, sy ) <<endl;

	LOCK_VARIABLE( speed_counter );
	LOCK_VARIABLE( second_counter );
	LOCK_FUNCTION( (void *)inc_speed_counter );
	LOCK_FUNCTION( (void *)inc_second_counter );
        /* set up the timers */
	out<<"Install game timer: "<<install_int_ex( inc_speed_counter, BPS_TO_TIMER( TICS_PER_SECOND ) )<<endl;
	out<<"Install second timer: "<<install_int_ex( inc_second_counter, BPS_TO_TIMER( 1 ) )<<endl;
	out << "Initialize random number generator" << endl;
        /* initialize random number generator */
	srand( time( NULL ) );

        /* keep running in the background */
	set_display_switch_mode(SWITCH_BACKGROUND);

        /* close window when the X is pressed */
        LOCK_FUNCTION(close_paintown);
        set_close_button_callback(close_paintown);

        /* music */
	atexit( &dumb_exit );
	atexit( Network::closeAll );
	dumb_register_packfiles();

	registerSignals();

	out << "Initialize network" << endl;
	Network::init();

        /* this mutex is used to show the loading screen while the game loads */
	pthread_mutex_init( &Global::loading_screen_mutex, NULL );

	out<<"-- END init --"<<endl;

	return true;
}
<commit_msg>warn the user that he/she is ugly<commit_after>#include <allegro.h>
#ifdef ALLEGRO_WINDOWS
#include <winalleg.h>
#endif

#ifndef ALLEGRO_WINDOWS
#include <signal.h>
#include <string.h>
#endif

#warning you are ugly

#include "globals.h"
#include "init.h"
#include <pthread.h>
#include "network/network.h"

#include <ostream>
#include "dumb/include/dumb.h"
#include "dumb/include/aldumb.h"
#include "loadpng/loadpng.h"
#include "util/bitmap.h"
#include "configuration.h"
#include "script/script.h"

using namespace std;

volatile int Global::speed_counter = 0;
volatile int Global::second_counter = 0;

/* the original engine was running at 90 ticks per second, but we dont
 * need to render that fast, so TICS_PER_SECOND is really fps and
 * LOGIC_MULTIPLIER will be used to adjust the speed counter to its
 * original value.
 */
static const int TICS_PER_SECOND = 40;
const double Global::LOGIC_MULTIPLIER = (double) 90 / (double) TICS_PER_SECOND;

pthread_mutex_t Global::loading_screen_mutex;
bool Global::done_loading = false;

const int Global::WINDOWED = GFX_AUTODETECT_WINDOWED;
const int Global::FULLSCREEN = GFX_AUTODETECT_FULLSCREEN;

void inc_speed_counter() {
	Global::speed_counter += 1;
}
END_OF_FUNCTION( inc_speed_counter );

void inc_second_counter() {
	Global::second_counter += 1;
}
END_OF_FUNCTION( inc_second_counter );

#ifndef ALLEGRO_WINDOWS
static void handleSigSegV(int i, siginfo_t * sig, void * data){
    Bitmap::setGfxModeText();
    allegro_exit();
    /* write to a log file or something because sigsegv shouldn't
     * normally happen.
     */
    exit(0);
}
#else
#endif

/* catch a socket being closed prematurely on unix */
#ifndef ALLEGRO_WINDOWS
static void handleSigPipe( int i, siginfo_t * sig, void * data ){
}

/*
static void handleSigUsr1( int i, siginfo_t * sig, void * data ){
	pthread_exit( NULL );
}
*/
#endif

static void registerSignals(){
#ifndef ALLEGRO_WINDOWS
	struct sigaction action;
	memset( &action, 0, sizeof(struct sigaction) );
	action.sa_sigaction = handleSigPipe;
	sigaction( SIGPIPE, &action, NULL );

	memset( &action, 0, sizeof(struct sigaction) );
	action.sa_sigaction = handleSigSegV;
	sigaction( SIGSEGV, &action, NULL );

	/*
	action.sa_sigaction = handleSigUsr1;
	sigaction( SIGUSR1, &action, NULL );
	*/
#endif
}

static void close_paintown(){
    Bitmap::setGfxModeText();
    allegro_exit();
    exit(0);
}
END_OF_FUNCTION(close_paintown)

bool Global::init( int gfx ){

	ostream & out = Global::debug( 0 );
	out << "-- BEGIN init --" << endl;
        out << "Paintown version " << Global::getVersionString() << endl;
	out << "Allegro version: " << ALLEGRO_VERSION_STR << endl;
	out <<"Allegro init: "<<allegro_init()<<endl;
	out <<"Install timer: "<<install_timer()<<endl;

	set_volume_per_voice( 0 );
	out<<"Install sound: "<<install_sound( DIGI_AUTODETECT, MIDI_NONE, "" )<<endl;

        /* png */
	loadpng_init();

        Bitmap::SCALE_X = GFX_X;
        Bitmap::SCALE_Y = GFX_Y;

        Configuration::loadConfigurations();

        const int sx = Configuration::getScreenWidth();
        const int sy = Configuration::getScreenHeight();

	out<<"Install keyboard: "<<install_keyboard()<<endl;
	out<<"Install mouse: "<<install_mouse()<<endl;
        /* 16 bit color depth */
	set_color_depth( 16 );

        /* set up the screen */
	out<<"Set gfx mode: " << Bitmap::setGraphicsMode( gfx, sx, sy ) <<endl;

	LOCK_VARIABLE( speed_counter );
	LOCK_VARIABLE( second_counter );
	LOCK_FUNCTION( (void *)inc_speed_counter );
	LOCK_FUNCTION( (void *)inc_second_counter );
        /* set up the timers */
	out<<"Install game timer: "<<install_int_ex( inc_speed_counter, BPS_TO_TIMER( TICS_PER_SECOND ) )<<endl;
	out<<"Install second timer: "<<install_int_ex( inc_second_counter, BPS_TO_TIMER( 1 ) )<<endl;
	out << "Initialize random number generator" << endl;
        /* initialize random number generator */
	srand( time( NULL ) );

        /* keep running in the background */
	set_display_switch_mode(SWITCH_BACKGROUND);

        /* close window when the X is pressed */
        LOCK_FUNCTION(close_paintown);
        set_close_button_callback(close_paintown);

        /* music */
	atexit( &dumb_exit );
	atexit( Network::closeAll );
	dumb_register_packfiles();

	registerSignals();

	out << "Initialize network" << endl;
	Network::init();

        /* this mutex is used to show the loading screen while the game loads */
	pthread_mutex_init( &Global::loading_screen_mutex, NULL );

	out<<"-- END init --"<<endl;

	return true;
}
<|endoftext|>