<commit_before>/*=========================================================================
 *
 *  Copyright Insight Software Consortium
 *
 *  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.txt
 *
 *  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 "itkVoronoiDiagram2DGenerator.h"
#include "itkMeshFileWriter.h"

int itkVoronoiDiagram2DTest(int argc, char* argv[] ){

  if( argc != 2 )
    {
    std::cerr << "Usage: itkVoronoiDiagram2DTest outputFileName" << std::endl;
    return EXIT_FAILURE;
    }

  const double HEI=400;
  const double WID=400;
  const int NUMSEEDS=20;

  typedef itk::VoronoiDiagram2D<double>          Vor;
  typedef itk::VoronoiDiagram2DGenerator<double> VorGenerator;

  typedef Vor::PointType            PointType;
  typedef Vor::CellType             CellType;
  typedef Vor::CellAutoPointer      CellAutoPointer;
  typedef CellType::PointIdIterator PointIdIterator;
  typedef Vor::NeighborIdIterator   NeighborIdIterator;

  Vor::Pointer testVor(Vor::New());
  VorGenerator::Pointer testVorGen(VorGenerator::New());

  PointType insize;
  insize[0]=WID;
  insize[1]=HEI;
  testVorGen->SetBoundary(insize);

  testVorGen->SetRandomSeeds(NUMSEEDS);
  testVorGen->Update();
  testVor=testVorGen->GetOutput();

  for( int i = 0; i < NUMSEEDS; i++ ){
    PointType currP=testVor->GetSeed(i);
    std::cout<<"Seed No."<<i<<": At ("<<currP[0]<<"," <<currP[1]<<")"<<std::endl;
    std::cout<<"  Boundary Vertices List (in order):";
    CellAutoPointer currCell;
    testVor->GetCellId(i, currCell);
    PointIdIterator currCellP;
    for( currCellP = currCell->PointIdsBegin(); currCellP != currCell->PointIdsEnd(); ++currCellP )
    {
      std::cout<<(*currCellP)<<",";
    }
    std::cout<<std::endl;
    std::cout<<"  Neighbors (Seed No.):";
    NeighborIdIterator currNeibor;
    for( currNeibor = testVor->NeighborIdsBegin(i); currNeibor != testVor->NeighborIdsEnd(i); ++currNeibor )
    {
      std::cout<<(*currNeibor)<<",";
    }
    std::cout<<std::endl<<std::endl;
  }

  std::cout<<"Vertices Informations:"<<std::endl;
  Vor::VertexIterator allVerts;
  int j = 0;
  for( allVerts = testVor->VertexBegin(); allVerts != testVor->VertexEnd(); ++allVerts )
  {
    std::cout<<"Vertices No."<<j;
    j++;
    std::cout<<": At ("<<(allVerts.Value())[0]<<","<<(allVerts.Value())[1]<<")"<<std::endl;
  }

  typedef itk::MeshFileWriter<Vor> WriterType;
  WriterType::Pointer writer = WriterType::New();
  writer->SetInput(testVor);
  writer->SetFileName(argv[1]);
  writer->Update();

  return EXIT_SUCCESS;
}
<commit_msg>ENH: Improve VoronoiDiagram2DGenerator coverage.<commit_after>/*=========================================================================
 *
 *  Copyright Insight Software Consortium
 *
 *  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.txt
 *
 *  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 "itkVoronoiDiagram2DGenerator.h"
#include "itkMeshSource.h"
#include "itkMeshFileWriter.h"
#include "itkTestingMacros.h"

int itkVoronoiDiagram2DTest( int argc, char* argv[] )
{

  if( argc != 2 )
    {
    std::cerr << "Usage: itkVoronoiDiagram2DTest outputFileName" << std::endl;
    return EXIT_FAILURE;
    }

  const double height = 400;
  const double width = 400;
  const int numberOfSeeds = 20;

  typedef itk::VoronoiDiagram2D<double>          VoronoiDiagram;
  typedef itk::VoronoiDiagram2DGenerator<double> VoronoiDiagramGenerator;

  typedef VoronoiDiagram::PointType            PointType;
  typedef VoronoiDiagram::CellType             CellType;
  typedef VoronoiDiagram::CellAutoPointer      CellAutoPointer;
  typedef CellType::PointIdIterator            PointIdIterator;
  typedef VoronoiDiagram::NeighborIdIterator   NeighborIdIterator;

  VoronoiDiagram::Pointer voronoiDiagram = VoronoiDiagram::New();

  VoronoiDiagramGenerator::Pointer voronoiDiagramGenerator =
    VoronoiDiagramGenerator::New();
  EXERCISE_BASIC_OBJECT_METHODS ( voronoiDiagramGenerator, VoronoiDiagram2DGenerator,
    MeshSource );

  PointType insize;
  insize[0] = width;
  insize[1] = height;
  voronoiDiagramGenerator->SetBoundary(insize);

  voronoiDiagramGenerator->SetRandomSeeds(numberOfSeeds);
  TEST_SET_GET_VALUE( numberOfSeeds, voronoiDiagramGenerator->GetNumberOfSeeds() );

  voronoiDiagramGenerator->Update();
  voronoiDiagram = voronoiDiagramGenerator->GetOutput();

  for( unsigned int i = 0; i < voronoiDiagramGenerator->GetNumberOfSeeds(); ++i )
    {
    PointType currP = voronoiDiagram->GetSeed(i);
    std::cout << "Seed No." << i << ": At (" << currP[0] << "," << currP[1] << ")" << std::endl;
    std::cout << "Boundary Vertices List (in order): ";
    CellAutoPointer currCell;
    voronoiDiagram->GetCellId(i, currCell);
    PointIdIterator currCellP;
    for( currCellP = currCell->PointIdsBegin(); currCellP != currCell->PointIdsEnd(); ++currCellP )
      {
      std::cout << *currCellP << ",";
      }
    std::cout << std::endl;
    std::cout << " Neighbors (Seed No.): ";
    NeighborIdIterator currNeibor;
    for( currNeibor = voronoiDiagram->NeighborIdsBegin(i);
      currNeibor != voronoiDiagram->NeighborIdsEnd(i); ++currNeibor )
      {
      std::cout << *currNeibor << ",";
      }
    std::cout << std::endl << std::endl;
    }

  std::cout << "Vertices Informations:" << std::endl;
  VoronoiDiagram::VertexIterator allVerts;
  int j = 0;
  for( allVerts = voronoiDiagram->VertexBegin();
    allVerts != voronoiDiagram->VertexEnd(); ++allVerts )
    {
    std::cout << "Vertices No. " << j;
    j++;
    std::cout << ": At (" << allVerts.Value()[0] << ","
      << allVerts.Value()[1] << ")" << std::endl;
    }

  typedef itk::MeshFileWriter< VoronoiDiagram > WriterType;
  WriterType::Pointer writer = WriterType::New();
  writer->SetInput( voronoiDiagram );
  writer->SetFileName( argv[1] );

  try
    {
    writer->Update();
    }
  catch( itk::ExceptionObject & excp )
    {
    std::cout << excp << std::endl;
    return EXIT_FAILURE;
    }

  return EXIT_SUCCESS;
}
<|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 "mitkUSZonesInteractor.h"
#include "mitkDataStorage.h"
#include "mitkDataNode.h"
#include "mitkSurface.h"
#include "mitkInteractionPositionEvent.h"

#include "vtkSphereSource.h"

const char* mitk::USZonesInteractor::DATANODE_PROPERTY_SIZE = "zone.size";
const char* mitk::USZonesInteractor::DATANODE_PROPERTY_CREATED = "zone.created";

void mitk::USZonesInteractor::UpdateSurface(mitk::DataNode::Pointer dataNode)
{
  if ( ! dataNode->GetData())
  {
    MITK_WARN("USZonesInteractor")("DataInteractor")
        << "Cannot update surface for node as no data is set to the node.";
    return;
  }

  mitk::Point3D origin = dataNode->GetData()->GetGeometry()->GetOrigin();

  float radius;
  if ( ! dataNode->GetFloatProperty(DATANODE_PROPERTY_SIZE, radius) )
  {
    MITK_WARN("USZonesInteractor")("DataInteractor")
        << "Cannut update surface for node as no radius is specified in the node properties.";
    return;
  }

  mitk::Surface::Pointer zone = mitk::Surface::New();

  // create a vtk sphere with given radius
  vtkSphereSource *vtkData = vtkSphereSource::New();
  vtkData->SetRadius( radius );
  vtkData->SetCenter(0,0,0);
  vtkData->Update();
  zone->SetVtkPolyData(vtkData->GetOutput());
  vtkData->Delete();

  // set vtk sphere and origin to data node (origin must be set
  // again, because of the new sphere set as data)
  dataNode->SetData(zone);
  dataNode->GetData()->GetGeometry()->SetOrigin(origin);

  // update the RenderWindow to show the changed surface
  mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}

mitk::USZonesInteractor::USZonesInteractor()
{
}

mitk::USZonesInteractor::~USZonesInteractor()
{
}

void mitk::USZonesInteractor::ConnectActionsAndFunctions()
{
  CONNECT_FUNCTION("addCenter", AddCenter);
  CONNECT_FUNCTION("changeRadius", ChangeRadius);
  CONNECT_FUNCTION("endCreation", EndCreation);
  CONNECT_FUNCTION("abortCreation", AbortCreation);
}

void mitk::USZonesInteractor::DataNodeChanged()
{
  mitk::DataNode::Pointer dataNode = this->GetDataNode();
  if ( dataNode.IsNotNull() && dataNode->GetData() == 0 )
  {
    dataNode->SetData(mitk::Surface::New());
  }
}

bool mitk::USZonesInteractor::AddCenter(mitk::StateMachineAction* , mitk::InteractionEvent* interactionEvent)
{
  // cast InteractionEvent to a position event in order to read out the mouse position
  mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>(interactionEvent);
  if (positionEvent == NULL) { return false; }

  this->GetDataNode()->SetBoolProperty(DATANODE_PROPERTY_CREATED, false);

  // set origin of the data node to the mouse click position
  this->GetDataNode()->GetData()->GetGeometry()->SetOrigin(positionEvent->GetPositionInWorld());

  this->GetDataNode()->SetFloatProperty("opacity", 0.60f );

  return true;
}

bool mitk::USZonesInteractor::ChangeRadius(mitk::StateMachineAction* , mitk::InteractionEvent* interactionEvent)
{
  // cast InteractionEvent to a position event in order to read out the mouse position
  mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>(interactionEvent);
  if (positionEvent == NULL) { return false; }

  mitk::DataNode::Pointer curNode = this->GetDataNode();
  mitk::Point3D mousePosition = positionEvent->GetPositionInWorld();

  mitk::ScalarType radius = mousePosition.EuclideanDistanceTo(curNode->GetData()->GetGeometry()->GetOrigin());
  curNode->SetFloatProperty(DATANODE_PROPERTY_SIZE, radius);

  mitk::USZonesInteractor::UpdateSurface(curNode);

  return true;
}

bool mitk::USZonesInteractor::EndCreation(mitk::StateMachineAction* , mitk::InteractionEvent* /*interactionEvent*/)
{
  this->GetDataNode()->SetBoolProperty(DATANODE_PROPERTY_CREATED, true);
  return true;
}

bool mitk::USZonesInteractor::AbortCreation(mitk::StateMachineAction* , mitk::InteractionEvent*)
{
  this->GetDataNode()->SetData(mitk::Surface::New());

  // update the RenderWindow to remove the surface
  mitk::RenderingManager::GetInstance()->RequestUpdateAll();

  return true;
}
<commit_msg>Higher sphere resolution and additional test for data in USZonesInteractor.<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 "mitkUSZonesInteractor.h"
#include "mitkDataStorage.h"
#include "mitkDataNode.h"
#include "mitkSurface.h"
#include "mitkInteractionPositionEvent.h"

#include "vtkSphereSource.h"

const char* mitk::USZonesInteractor::DATANODE_PROPERTY_SIZE = "zone.size";
const char* mitk::USZonesInteractor::DATANODE_PROPERTY_CREATED = "zone.created";

void mitk::USZonesInteractor::UpdateSurface(mitk::DataNode::Pointer dataNode)
{
  if ( ! dataNode->GetData())
  {
    MITK_WARN("USZonesInteractor")("DataInteractor")
        << "Cannot update surface for node as no data is set to the node.";
    return;
  }

  mitk::Point3D origin = dataNode->GetData()->GetGeometry()->GetOrigin();

  float radius;
  if ( ! dataNode->GetFloatProperty(DATANODE_PROPERTY_SIZE, radius) )
  {
    MITK_WARN("USZonesInteractor")("DataInteractor")
        << "Cannut update surface for node as no radius is specified in the node properties.";
    return;
  }

  mitk::Surface::Pointer zone = mitk::Surface::New();

  // create a vtk sphere with given radius
  vtkSphereSource *vtkData = vtkSphereSource::New();
  vtkData->SetRadius( radius );
  vtkData->SetCenter(0,0,0);
  vtkData->SetPhiResolution(20);
  vtkData->SetThetaResolution(20);
  vtkData->Update();
  zone->SetVtkPolyData(vtkData->GetOutput());
  vtkData->Delete();

  // set vtk sphere and origin to data node (origin must be set
  // again, because of the new sphere set as data)
  dataNode->SetData(zone);
  dataNode->GetData()->GetGeometry()->SetOrigin(origin);

  // update the RenderWindow to show the changed surface
  mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}

mitk::USZonesInteractor::USZonesInteractor()
{
}

mitk::USZonesInteractor::~USZonesInteractor()
{
}

void mitk::USZonesInteractor::ConnectActionsAndFunctions()
{
  CONNECT_FUNCTION("addCenter", AddCenter);
  CONNECT_FUNCTION("changeRadius", ChangeRadius);
  CONNECT_FUNCTION("endCreation", EndCreation);
  CONNECT_FUNCTION("abortCreation", AbortCreation);
}

void mitk::USZonesInteractor::DataNodeChanged()
{
  mitk::DataNode::Pointer dataNode = this->GetDataNode();
  if ( dataNode.IsNotNull() && dataNode->GetData() == 0 )
  {
    dataNode->SetData(mitk::Surface::New());
  }
}

bool mitk::USZonesInteractor::AddCenter(mitk::StateMachineAction* , mitk::InteractionEvent* interactionEvent)
{
  // cast InteractionEvent to a position event in order to read out the mouse position
  mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>(interactionEvent);
  if (positionEvent == NULL) { return false; }

  mitk::DataNode::Pointer dataNode = this->GetDataNode();
  dataNode->SetBoolProperty(DATANODE_PROPERTY_CREATED, false);

  // make sure that data node contains data
  mitk::BaseData::Pointer dataNodeData = this->GetDataNode()->GetData();
  if ( dataNodeData.IsNull() )
  {
    dataNodeData = mitk::Surface::New();
    this->GetDataNode()->SetData(dataNodeData);
  }

  // set origin of the data node to the mouse click position
  dataNodeData->GetGeometry()->SetOrigin(positionEvent->GetPositionInWorld());

  dataNode->SetFloatProperty("opacity", 0.60f );

  return true;
}

bool mitk::USZonesInteractor::ChangeRadius(mitk::StateMachineAction* , mitk::InteractionEvent* interactionEvent)
{
  // cast InteractionEvent to a position event in order to read out the mouse position
  mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>(interactionEvent);
  if (positionEvent == NULL) { return false; }

  mitk::DataNode::Pointer curNode = this->GetDataNode();
  mitk::Point3D mousePosition = positionEvent->GetPositionInWorld();

  mitk::ScalarType radius = mousePosition.EuclideanDistanceTo(curNode->GetData()->GetGeometry()->GetOrigin());
  curNode->SetFloatProperty(DATANODE_PROPERTY_SIZE, radius);

  mitk::USZonesInteractor::UpdateSurface(curNode);

  return true;
}

bool mitk::USZonesInteractor::EndCreation(mitk::StateMachineAction* , mitk::InteractionEvent* /*interactionEvent*/)
{
  this->GetDataNode()->SetBoolProperty(DATANODE_PROPERTY_CREATED, true);
  return true;
}

bool mitk::USZonesInteractor::AbortCreation(mitk::StateMachineAction* , mitk::InteractionEvent*)
{
  this->GetDataNode()->SetData(mitk::Surface::New());

  // update the RenderWindow to remove the surface
  mitk::RenderingManager::GetInstance()->RequestUpdateAll();

  return true;
}
<|endoftext|>


<commit_before>//$Id$

//#include "HopsanCore.h"
#include "GUIPort.h"
#include "plotwidget.h"
#include "mainwindow.h"

#include <QtGui>

//! Constructor.
//! @param corePort a pointer to the corresponing port in Core.
//! @param x the x-coord. of where the port should be placed.
//! @param y the y-coord. of where the port should be placed.
//! @param rot how the port should be rotated.
//! @param iconPath a string with the path to the svg-figure representing the port.
//! @param parent the port's parent, the component it is a part of.
GUIPort::GUIPort(Port *pCorePort, qreal xpos, qreal ypos, PortAppearance* pPortAppearance, GUIObject *pParent)
    : QGraphicsSvgItem(pPortAppearance->iconPath, pParent)
{
    //*****Core Interaction*****
    mpCorePort = pCorePort;
    //**************************

    mpParentGraphicsView = pParent->mpParentGraphicsView;
    mpParentGuiObject = pParent;
    mpPortAppearance = pPortAppearance;

    //setTransformOriginPoint(boundingRect().width()/2,boundingRect().height()/2);
    setTransformOriginPoint(boundingRect().center());

    mXpos = xpos;
    mYpos = ypos;

    updatePosition();

//    pRectParent = parent;
    this->setAcceptHoverEvents(true);

    //QBrush brush(Qt::green);
    //this->setBrush(brush);

    mpPortLabel = new QGraphicsTextItem(this);
    QString label("
");
    label.append(this->getName()).append("
");
    mpPortLabel->setHtml(label);
    mpPortLabel->setTextInteractionFlags(Qt::NoTextInteraction);
    mpPortLabel->setPos(7.0,7.0);
    mpPortLabel->hide();

    //*****Core Interaction*****
    if(this->getPortType() == Port::POWERPORT)
    //**************************
    {
        this->setRotation(0.0);
        mpPortLabel->setRotation(0.0);
    }
    else
    {
        this->setRotation(mpPortAppearance->rot);
        mpPortLabel->setRotation(-mpPortAppearance->rot);
    }

    mMag = 1.6180339887;
    mIsMag = false;
    isConnected = false;

    MainWindow *pMainWindow = mpParentGuiObject->mpParentGraphicsScene->mpParentProjectTab->mpParentProjectTabWidget->mpParentMainWindow;
    connect(this,SIGNAL(portClicked(GUIPort*)),this->getParentView(),SLOT(addConnector(GUIPort*)));
    connect(pMainWindow->hidePortsAction,SIGNAL(triggered(bool)),this, SLOT(hideIfNotConnected(bool)));
    //connect(pMainWindow->showPortsAction,SIGNAL(triggered()),this, SLOT(showIfNotConnected()));
}

GUIPort::~GUIPort()
{
}

//! Magnify the port with a class mebmer factor 'mMag'. Is used i.e. at hovering over disconnected port.
//! @param blowup says if the port should be magnified or not.
void GUIPort::magnify(bool blowup)
{
    if ((!blowup) && (mIsMag))
    {
        this->moveBy((mMag-1)*boundingRect().width()/2, (mMag-1)*boundingRect().height()/2);
        this->scale(1/mMag,1/mMag);
        this->mpPortLabel->scale(mMag,mMag);
        mIsMag = false;
    }
    else if ((blowup) && (!mIsMag))
    {
        this->scale(mMag, mMag);
        this->moveBy(-(mMag-1)*boundingRect().width()/2, -(mMag-1)*boundingRect().height()/2);
        this->mpPortLabel->scale(1/mMag,1/mMag);
        mIsMag = true;
    }
}

//! Defines what happens when mouse cursor begins to hover a port.
//! @param *event defines the mouse event.
void GUIPort::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
    QGraphicsSvgItem::hoverEnterEvent(event);

    this->setCursor(Qt::CrossCursor);
    QBrush brush(Qt::blue);
    std::cout << "GUIPort.cpp: " << "hovering over port" << std::endl;
    magnify(true);

    mpPortLabel->setRotation(-this->mpParentGuiObject->rotation()-this->rotation());
    //qDebug() << "label: " << mpPortLabel->rotation() << " this: " << this->rotation();
    this->setZValue(1.0);
    mpPortLabel->show();
}

void GUIPort::updatePosition()
{
    if(mpParentGuiObject->rotation() == 0)
        setPos(mXpos-this->boundingRect().width()/2.0, mYpos-this->boundingRect().height()/2.0);
    else if(mpParentGuiObject->rotation() == 90)
        setPos(mXpos-this->boundingRect().width()/2.0, mYpos+this->boundingRect().height()/2.0);
    else if(mpParentGuiObject->rotation() == 180)
        setPos(mXpos+this->boundingRect().width()/2.0, mYpos+this->boundingRect().height()/2.0);
    else
        setPos(mXpos+this->boundingRect().width()/2.0, mYpos-this->boundingRect().height()/2.0);
}

//! Defines what happens when mouse cursor stops hovering a port.
//! @param *event defines the mouse event.
void GUIPort::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{
    QGraphicsSvgItem::hoverLeaveEvent(event);

    QBrush brush(Qt::green);
    //this->setBrush(brush);
    this->setCursor(Qt::ArrowCursor);
    magnify(false);

    mpPortLabel->hide();
    this->setZValue(0.0);
}

//! Defines what happens when clicking on a port.
//! @param *event defines the mouse event.
void GUIPort::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    //QGraphicsItem::mousePressEvent(event); //Don't work if this is called
    if (event->button() == Qt::LeftButton)
    {
        std::cout << "GUIPort.cpp: " << "portClick emitted\n";
        emit portClicked(this);
    }
    else if (event->button() == Qt::RightButton)
    {
        std::cout << "GUIPort.cpp: " << "RightClick" << std::endl;
    }
    magnify(false);
}

void GUIPort::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
{
    std::cout << "GUIPort.cpp: " << "contextMenuEvent" << std::endl;

    //*****Core Interaction*****
    if ((!(this->mpCorePort->isConnected())) || (this->mpCorePort->getTimeVectorPtr()->empty()))
    //**************************
    {
        event->ignore();
    }
    else
    {
        QMenu menu;

        //*****Core Interaction*****
        if (mpCorePort->getNodeType() =="NodeHydraulic")
        //**************************
        {
            QAction *plotPressureAction = menu.addAction("Plot pressure");
            QAction *plotFlowAction = menu.addAction("Plot flow");
            QAction *selectedAction = menu.exec(event->screenPos());

            if (selectedAction == plotFlowAction)
            {
                plot(0);
            }
            if (selectedAction == plotPressureAction)
            {
                plot(1);
            }
        }
        //*****Core Interaction*****
        if (mpCorePort->getNodeType() =="NodeMechanic")
        //**************************
        {
            QAction *plotVelocityAction = menu.addAction("Plot velocity");
            QAction *plotForceAction = menu.addAction("Plot force");
            QAction *plotPositionAction = menu.addAction("Plot position");
            QAction *selectedAction = menu.exec(event->screenPos());

            if (selectedAction == plotVelocityAction)
            {
                plot(0);
            }
            if (selectedAction == plotForceAction)
            {
                plot(1);
            }
            if (selectedAction == plotPositionAction)
            {
                plot(2);
            }
        }
        //*****Core Interaction*****
        if (mpCorePort->getNodeType() =="NodeSignal")
        //**************************
        {
            QAction *plotSignalAction = menu.addAction("Plot signal value");
            QAction *selectedAction = menu.exec(event->screenPos());

            if (selectedAction == plotSignalAction)
            {
                plot(0);
            }
        }
    }
}

//! Returns a pointer to the GraphicsView that the port belongs to.
QGraphicsView *GUIPort::getParentView()
{
    return mpParentGraphicsView;
}

//! Returns a pointer to the GUIComponent the port belongs to.
GUIObject *GUIPort::getGuiObject()
{
    //! @todo Thiss will crash if not GUIComponent should be GUI object may need to change code elsewhere
//    GUIComponent* ptr = qobject_cast<GUIComponent*>(mpParentGuiObject);
//    return ptr;
    return mpParentGuiObject;
}

//! Plots the varable number 'nVar' in the node the port is connected to.
//! @param nVar tells which variable to plot.
void GUIPort::plot(size_t nVar) //En del vansinne i denna metoden...
{
    std::cout << "GUIPort.cpp: " << "Plot()" << std::endl;

    //*****Core Interaction*****
    size_t dataLength = this->mpCorePort->getTimeVectorPtr()->size();

    QVector<double> time = QVector<double>::fromStdVector(*(this->mpCorePort->getTimeVectorPtr())); //Inte lampligt att skyffla data pa detta viset
    QVector<double> y(dataLength);// = QVector<double>::fromStdVector((this->mpCorePort->getDataVectorPtr()->at(1)));
    //**************************

    qDebug() << "Time size: " << time.size() << " last time: " << *time.end() << " datalength: " << dataLength << "y.size(): " << y.size();
    qDebug() << "time[0]: " << time[0] << " time[last-1]: " << time[time.size()-2] << " time[last]: " << time[time.size()-1];

    for (size_t i = 0; i<time.size(); ++i)
    {
        //qDebug() << time[i];
    }

    for (size_t i = 0; i<dataLength; ++i) //Denna loop ar inte klok
    {
        //*****Core Interaction*****
        //timeq[i] = this->mpCorePort->getTimeVectorPtr()->at(i);
        y[i] = (this->mpCorePort->getDataVectorPtr()->at(i)).at(nVar);
        //**************************
    }

    qDebug() << "y[0]: " << y[0] << " y[last-1]: " << y[y.size()-2] << " y[last]: " << y[y.size()-1];

    QString title;
    QString xlabel;
    QString ylabel;

//    if (mpCorePort->getNodeType() == "NodeHydraulic")
//    {
//        if (nVar == 0)
//        {
//            title.append("Flow");
//            ylabel.append("Flow, [m^3/s]");
//        }
//        else if (nVar == 1)
//        {
//            title.append("Pressure");
//            ylabel.append("Pressure, [Pa]");
//        }
//    }
//    if (mpCorePort->getNodeType() == "NodeMechanic")
//    {
//        string name, unit;
//        mpCorePort->getNodeDataNameAndUnit(nVar, name, unit);
//        title.append(QString::fromStdString(name));
//        ylabel.append(QString::fromStdString(name) + ", [" + QString::fromStdString(unit) + "]");
//    }
//    else if (mpCorePort->getNodeType() == "NodeSignal")
//    {
//            title.append("Signal value");
//            ylabel.append("Value, [-]");
//    }
    string name, unit;
    mpCorePort->getNodeDataNameAndUnit(nVar, name, unit);
    title.append(QString::fromStdString(name));
    ylabel.append(QString::fromStdString(name) + ", [" + QString::fromStdString(unit) + "]");

    //! @todo need to comment this out  for now  fix later
    //title.append(" at component: ").append(QString::fromStdString(mpParentComponent->mpCoreComponent->getName())).append(", port: ").append(QString::fromStdString(mpCorePort->getPortName()));
    xlabel.append("Time, [s]");

    PlotWidget *newPlot = new PlotWidget(time,y,mpParentGuiObject->mpParentGraphicsView);

    //newPlot->mpVariablePlot->setTitle(title);
    newPlot->mpCurve->setTitle(title);
    newPlot->mpVariablePlot->setAxisTitle(VariablePlot::yLeft, ylabel);
    newPlot->mpVariablePlot->setAxisTitle(VariablePlot::xBottom, xlabel);
    newPlot->mpVariablePlot->insertLegend(new QwtLegend(), QwtPlot::TopLegend);

    newPlot->show();

}

//! Returns the number of the port by calling the equivalent function in the parent component.
int GUIPort::getPortNumber()
{
    return this->getGuiObject()->getPortNumber(this);
}

//! Wrapper for the Core getPortType() function
Port::PORTTYPE GUIPort::getPortType()
{
    //*****Core Interaction*****
    return mpCorePort->getPortType();
    //**************************
}

PortAppearance::portDirectionType GUIPort::getPortDirection()
{
    return mpPortAppearance->direction;
}

void GUIPort::setPortDirection(PortAppearance::portDirectionType direction)
{
    mpPortAppearance->direction = direction;
}

QString GUIPort::getName()
{
    //*****Core Interaction*****
    return QString::fromStdString(mpCorePort->getPortName());
    //**************************
}

void GUIPort::hideIfNotConnected(bool justDoIt)
{
    if(!isConnected and justDoIt)
    {
        this->hide();
    }
    else if(!isConnected and !justDoIt)
    {
        this->show();
    }
}
<commit_msg>one more core mark<commit_after>//$Id$

//#include "HopsanCore.h"
#include "GUIPort.h"
#include "plotwidget.h"
#include "mainwindow.h"

#include <QtGui>

//! Constructor.
//! @param corePort a pointer to the corresponing port in Core.
//! @param x the x-coord. of where the port should be placed.
//! @param y the y-coord. of where the port should be placed.
//! @param rot how the port should be rotated.
//! @param iconPath a string with the path to the svg-figure representing the port.
//! @param parent the port's parent, the component it is a part of.
GUIPort::GUIPort(Port *pCorePort, qreal xpos, qreal ypos, PortAppearance* pPortAppearance, GUIObject *pParent)
    : QGraphicsSvgItem(pPortAppearance->iconPath, pParent)
{
    //*****Core Interaction*****
    mpCorePort = pCorePort;
    //**************************

    mpParentGraphicsView = pParent->mpParentGraphicsView;
    mpParentGuiObject = pParent;
    mpPortAppearance = pPortAppearance;

    //setTransformOriginPoint(boundingRect().width()/2,boundingRect().height()/2);
    setTransformOriginPoint(boundingRect().center());

    mXpos = xpos;
    mYpos = ypos;

    updatePosition();

//    pRectParent = parent;
    this->setAcceptHoverEvents(true);

    //QBrush brush(Qt::green);
    //this->setBrush(brush);

    mpPortLabel = new QGraphicsTextItem(this);
    QString label("
");
    label.append(this->getName()).append("
");
    mpPortLabel->setHtml(label);
    mpPortLabel->setTextInteractionFlags(Qt::NoTextInteraction);
    mpPortLabel->setPos(7.0,7.0);
    mpPortLabel->hide();

    //*****Core Interaction*****
    if(this->getPortType() == Port::POWERPORT)
    //**************************
    {
        this->setRotation(0.0);
        mpPortLabel->setRotation(0.0);
    }
    else
    {
        this->setRotation(mpPortAppearance->rot);
        mpPortLabel->setRotation(-mpPortAppearance->rot);
    }

    mMag = 1.6180339887;
    mIsMag = false;
    isConnected = false;

    MainWindow *pMainWindow = mpParentGuiObject->mpParentGraphicsScene->mpParentProjectTab->mpParentProjectTabWidget->mpParentMainWindow;
    connect(this,SIGNAL(portClicked(GUIPort*)),this->getParentView(),SLOT(addConnector(GUIPort*)));
    connect(pMainWindow->hidePortsAction,SIGNAL(triggered(bool)),this, SLOT(hideIfNotConnected(bool)));
    //connect(pMainWindow->showPortsAction,SIGNAL(triggered()),this, SLOT(showIfNotConnected()));
}

GUIPort::~GUIPort()
{
}

//! Magnify the port with a class mebmer factor 'mMag'. Is used i.e. at hovering over disconnected port.
//! @param blowup says if the port should be magnified or not.
void GUIPort::magnify(bool blowup)
{
    if ((!blowup) && (mIsMag))
    {
        this->moveBy((mMag-1)*boundingRect().width()/2, (mMag-1)*boundingRect().height()/2);
        this->scale(1/mMag,1/mMag);
        this->mpPortLabel->scale(mMag,mMag);
        mIsMag = false;
    }
    else if ((blowup) && (!mIsMag))
    {
        this->scale(mMag, mMag);
        this->moveBy(-(mMag-1)*boundingRect().width()/2, -(mMag-1)*boundingRect().height()/2);
        this->mpPortLabel->scale(1/mMag,1/mMag);
        mIsMag = true;
    }
}

//! Defines what happens when mouse cursor begins to hover a port.
//! @param *event defines the mouse event.
void GUIPort::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
    QGraphicsSvgItem::hoverEnterEvent(event);

    this->setCursor(Qt::CrossCursor);
    QBrush brush(Qt::blue);
    std::cout << "GUIPort.cpp: " << "hovering over port" << std::endl;
    magnify(true);

    mpPortLabel->setRotation(-this->mpParentGuiObject->rotation()-this->rotation());
    //qDebug() << "label: " << mpPortLabel->rotation() << " this: " << this->rotation();
    this->setZValue(1.0);
    mpPortLabel->show();
}

void GUIPort::updatePosition()
{
    if(mpParentGuiObject->rotation() == 0)
        setPos(mXpos-this->boundingRect().width()/2.0, mYpos-this->boundingRect().height()/2.0);
    else if(mpParentGuiObject->rotation() == 90)
        setPos(mXpos-this->boundingRect().width()/2.0, mYpos+this->boundingRect().height()/2.0);
    else if(mpParentGuiObject->rotation() == 180)
        setPos(mXpos+this->boundingRect().width()/2.0, mYpos+this->boundingRect().height()/2.0);
    else
        setPos(mXpos+this->boundingRect().width()/2.0, mYpos-this->boundingRect().height()/2.0);
}

//! Defines what happens when mouse cursor stops hovering a port.
//! @param *event defines the mouse event.
void GUIPort::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{
    QGraphicsSvgItem::hoverLeaveEvent(event);

    QBrush brush(Qt::green);
    //this->setBrush(brush);
    this->setCursor(Qt::ArrowCursor);
    magnify(false);

    mpPortLabel->hide();
    this->setZValue(0.0);
}

//! Defines what happens when clicking on a port.
//! @param *event defines the mouse event.
void GUIPort::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    //QGraphicsItem::mousePressEvent(event); //Don't work if this is called
    if (event->button() == Qt::LeftButton)
    {
        std::cout << "GUIPort.cpp: " << "portClick emitted\n";
        emit portClicked(this);
    }
    else if (event->button() == Qt::RightButton)
    {
        std::cout << "GUIPort.cpp: " << "RightClick" << std::endl;
    }
    magnify(false);
}

void GUIPort::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
{
    std::cout << "GUIPort.cpp: " << "contextMenuEvent" << std::endl;

    //*****Core Interaction*****
    if ((!(this->mpCorePort->isConnected())) || (this->mpCorePort->getTimeVectorPtr()->empty()))
    //**************************
    {
        event->ignore();
    }
    else
    {
        QMenu menu;

        //*****Core Interaction*****
        if (mpCorePort->getNodeType() =="NodeHydraulic")
        //**************************
        {
            QAction *plotPressureAction = menu.addAction("Plot pressure");
            QAction *plotFlowAction = menu.addAction("Plot flow");
            QAction *selectedAction = menu.exec(event->screenPos());

            if (selectedAction == plotFlowAction)
            {
                plot(0);
            }
            if (selectedAction == plotPressureAction)
            {
                plot(1);
            }
        }
        //*****Core Interaction*****
        if (mpCorePort->getNodeType() =="NodeMechanic")
        //**************************
        {
            QAction *plotVelocityAction = menu.addAction("Plot velocity");
            QAction *plotForceAction = menu.addAction("Plot force");
            QAction *plotPositionAction = menu.addAction("Plot position");
            QAction *selectedAction = menu.exec(event->screenPos());

            if (selectedAction == plotVelocityAction)
            {
                plot(0);
            }
            if (selectedAction == plotForceAction)
            {
                plot(1);
            }
            if (selectedAction == plotPositionAction)
            {
                plot(2);
            }
        }
        //*****Core Interaction*****
        if (mpCorePort->getNodeType() =="NodeSignal")
        //**************************
        {
            QAction *plotSignalAction = menu.addAction("Plot signal value");
            QAction *selectedAction = menu.exec(event->screenPos());

            if (selectedAction == plotSignalAction)
            {
                plot(0);
            }
        }
    }
}

//! Returns a pointer to the GraphicsView that the port belongs to.
QGraphicsView *GUIPort::getParentView()
{
    return mpParentGraphicsView;
}

//! Returns a pointer to the GUIComponent the port belongs to.
GUIObject *GUIPort::getGuiObject()
{
    //! @todo Thiss will crash if not GUIComponent should be GUI object may need to change code elsewhere
//    GUIComponent* ptr = qobject_cast<GUIComponent*>(mpParentGuiObject);
//    return ptr;
    return mpParentGuiObject;
}

//! Plots the varable number 'nVar' in the node the port is connected to.
//! @param nVar tells which variable to plot.
void GUIPort::plot(size_t nVar) //En del vansinne i denna metoden...
{
    std::cout << "GUIPort.cpp: " << "Plot()" << std::endl;

    //*****Core Interaction*****
    size_t dataLength = this->mpCorePort->getTimeVectorPtr()->size();

    QVector<double> time = QVector<double>::fromStdVector(*(this->mpCorePort->getTimeVectorPtr())); //Inte lampligt att skyffla data pa detta viset
    QVector<double> y(dataLength);// = QVector<double>::fromStdVector((this->mpCorePort->getDataVectorPtr()->at(1)));
    //**************************

    qDebug() << "Time size: " << time.size() << " last time: " << *time.end() << " datalength: " << dataLength << "y.size(): " << y.size();
    qDebug() << "time[0]: " << time[0] << " time[last-1]: " << time[time.size()-2] << " time[last]: " << time[time.size()-1];

    for (size_t i = 0; i<time.size(); ++i)
    {
        //qDebug() << time[i];
    }

    for (size_t i = 0; i<dataLength; ++i) //Denna loop ar inte klok
    {
        //*****Core Interaction*****
        //timeq[i] = this->mpCorePort->getTimeVectorPtr()->at(i);
        y[i] = (this->mpCorePort->getDataVectorPtr()->at(i)).at(nVar);
        //**************************
    }

    qDebug() << "y[0]: " << y[0] << " y[last-1]: " << y[y.size()-2] << " y[last]: " << y[y.size()-1];

    QString title;
    QString xlabel;
    QString ylabel;

    string name, unit;
    //*****Core Interaction*****
    mpCorePort->getNodeDataNameAndUnit(nVar, name, unit);
    //**************************
    title.append(QString::fromStdString(name));
    ylabel.append(QString::fromStdString(name) + ", [" + QString::fromStdString(unit) + "]");

    //! @todo need to comment this out  for now  fix later
    //title.append(" at component: ").append(QString::fromStdString(mpParentComponent->mpCoreComponent->getName())).append(", port: ").append(QString::fromStdString(mpCorePort->getPortName()));
    xlabel.append("Time, [s]");

    PlotWidget *newPlot = new PlotWidget(time,y,mpParentGuiObject->mpParentGraphicsView);

    //newPlot->mpVariablePlot->setTitle(title);
    newPlot->mpCurve->setTitle(title);
    newPlot->mpVariablePlot->setAxisTitle(VariablePlot::yLeft, ylabel);
    newPlot->mpVariablePlot->setAxisTitle(VariablePlot::xBottom, xlabel);
    newPlot->mpVariablePlot->insertLegend(new QwtLegend(), QwtPlot::TopLegend);

    newPlot->show();

}

//! Returns the number of the port by calling the equivalent function in the parent component.
int GUIPort::getPortNumber()
{
    return this->getGuiObject()->getPortNumber(this);
}

//! Wrapper for the Core getPortType() function
Port::PORTTYPE GUIPort::getPortType()
{
    //*****Core Interaction*****
    return mpCorePort->getPortType();
    //**************************
}

PortAppearance::portDirectionType GUIPort::getPortDirection()
{
    return mpPortAppearance->direction;
}

void GUIPort::setPortDirection(PortAppearance::portDirectionType direction)
{
    mpPortAppearance->direction = direction;
}

QString GUIPort::getName()
{
    //*****Core Interaction*****
    return QString::fromStdString(mpCorePort->getPortName());
    //**************************
}

void GUIPort::hideIfNotConnected(bool justDoIt)
{
    if(!isConnected and justDoIt)
    {
        this->hide();
    }
    else if(!isConnected and !justDoIt)
    {
        this->show();
    }
}
<|endoftext|>


<commit_before>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/*
$Log$
Revision 1.1  2007/10/01 14:12:45  pchrist
Class creating the aligmnent object fro the surveyor measurements.

*/

//
//  Creates the SSD align object
//
//
#include "Riostream.h"
#include "TFile.h"
#include "TSystem.h"
#include "TClonesArray.h"
#include "TGeoManager.h"
#include "TGeoMatrix.h"
#include "TGeoPhysicalNode.h"

#include "AliITSSurveyToAlignSSD.h"
#include "AliSurveyObj.h"
#include "AliSurveyPoint.h"
#include "AliAlignObjParams.h"

#include "AliLog.h"

#include "AliCDBManager.h"
#include "AliCDBEntry.h"
#include "AliCDBStorage.h"

ClassImp(AliITSSurveyToAlignSSD)

//________________________________________________________________________
AliITSSurveyToAlignSSD::AliITSSurveyToAlignSSD() :
  TObject(),
  fRun(0),
  fFileLoc(0x0),
  fFileGlob(0x0),
  fSurveyPoints(0),
  fSSDAlignObj(new TClonesArray("AliAlignObjParams",100)),
  fSSDAlignObjParam(0),
  fDebug(0) {
  //
  //  default constructor
  //
}

//________________________________________________________________________
AliITSSurveyToAlignSSD::AliITSSurveyToAlignSSD(Int_t run, Int_t reportloc, Int_t reportglob) :
  TObject(),
  fRun(0),
  fFileLoc(0x0),
  fFileGlob(0x0),
  fSurveyPoints(0),
  fSSDAlignObj(new TClonesArray("AliAlignObjParams",100)),
  fSSDAlignObjParam(0),
  fDebug(0) {
  //
  // constructor - defines data files
  //
  fFileLoc = new Char_t[80];
  fFileGlob = new Char_t[80];
  Char_t path[50];
  sprintf(path,gSystem->Getenv("ALICE_ROOT"));
  //
  sprintf(fFileLoc,"%s/ITS/Survey_SSD_%d.txt",path,reportloc);
  sprintf(fFileGlob,"%s/ITS/Survey_SSD_%d.txt",path,reportglob);
  //

}
//_________________________________________________________________________
AliITSSurveyToAlignSSD::AliITSSurveyToAlignSSD(const AliITSSurveyToAlignSSD &align) :
  TObject(),
  fFileLoc(0x0),
  fFileGlob(0x0),
  fSurveyPoints(0),
  fSSDAlignObj(new TClonesArray("AliAlignObjParams",100)),
  fSSDAlignObjParam(0),
  fDebug(0) {
  //
  //  copy constructor - dummy

  fDebug = align.fDebug;
}

//__________________________________________________________________________
AliITSSurveyToAlignSSD & AliITSSurveyToAlignSSD::operator =(const AliITSSurveyToAlignSSD & align) {
  //
  // assignment operator - dummy
  //
  fDebug = align.fDebug;
  return (*this);
}

//__________________________________________________________________________
AliITSSurveyToAlignSSD::~AliITSSurveyToAlignSSD() {
  //
  // destructor
  //
  if(fSurveyPoints) delete fSurveyPoints;
  if(fSSDAlignObj) delete fSSDAlignObj;
  if(fSSDAlignObjParam) delete fSSDAlignObjParam;
}

//______________________________________________________________________
void AliITSSurveyToAlignSSD::Run() {
  //
  // runs the full chain
  //
  SetDebug(0);
  Bool_t flag = LoadSurveyData();
  if(!flag) {
    cout<<"Missing points"<<endl;
    return;
  }
  CreateAlignObj();
  StoreAlignObj();
  //
}

//__________________________________________________________________________
Bool_t AliITSSurveyToAlignSSD::LoadSurveyData() {
  //
  // for a time being it loads from the local file the surveyed point
  // and has the ideal points hardwired. I am waiting until Ricardo
  // completes his job
  //

  //Load survey data from the local file
  AliSurveyObj * s1 = new AliSurveyObj();
  if(s1->FillFromLocalFile(fFileGlob))
    fSurveyPoints = s1->GetData();
  else
    return kFALSE;

  cout<<"Number of SSD survey points: "<<fSurveyPoints->GetEntries()<<endl;

  return kTRUE;
}

//_______________________________________________________________________
void AliITSSurveyToAlignSSD::CreateAlignObj(){
  //
  // This method creates AliAlignObj and fills it with Euler angles
  // and shifts. The units are degrees and cm.
  //
  TClonesArray &alobj = *fSSDAlignObj;

  //load ideal geometry from the OCDB
  AliCDBManager *cdb = AliCDBManager::Instance();
  cdb->SetDefaultStorage("local://$ALICE_ROOT");
  cdb->SetRun(fRun);
  AliCDBEntry* entry = cdb->Get("GRP/Geometry/Data");
  AliGeomManager::SetGeometry(gGeoManager);

  AliSurveyPoint* pt = 0;
  TGeoHMatrix* hm = 0;
  TGeoPNEntry* pne = 0;
  Double_t* tr;
  Int_t uid;
  const char* symname;
  Double_t sx, sy, sz;
  Int_t ilayer, imodule;

  for(Int_t imod = 0; imod < fSurveyPoints->GetEntries(); imod++) {
    pt = (AliSurveyPoint*) fSurveyPoints->At(imod);
    if(!pt) continue;
    sx = pt->GetX()*100.;
    sy = pt->GetY()*100.;
    sz = pt->GetZ()*100.;

    ilayer = (imod < 748) ? AliGeomManager::kSSD1 : AliGeomManager::kSSD2;
    imodule = (imod < 748) ? imod : imod - 748;

    uid = AliGeomManager::LayerToVolUID(ilayer,imodule);
    symname = AliGeomManager::SymName(uid);
    pne = gGeoManager->GetAlignableEntryByUID(uid);
    hm = pne->GetGlobalOrig();
    tr = hm->GetTranslation();

    //Printf("symname %s", symname);
    //Printf("x,y,z from survey: %f %f %f", sx, sy, sz);
    //Printf("x,y,z from ideal : %f %f %f", tr[0], tr[1], tr[2]);

   new(alobj[imod]) AliAlignObjParams(symname, uid, sx-tr[0], sy-tr[1], sz-tr[2], 0., 0., 0., kTRUE);
  }//module loop

  delete entry;
}

//_________________________________________________________________________
void AliITSSurveyToAlignSSD::StoreAlignObj(){
  // Stores the TClonesArray of AliAlignObj in
  // $ALICE_ROOT/ITS/Align/Data/SSDfromSurvey.root
  // In a later version these objects will be merged
  // with the SDD ones and will be put in the OCDB
  const char* filename = "$ALICE_ROOT/ITS/Align/Data/SSDfromSurvey.root";
  TFile *f = TFile::Open(filename,"RECREATE");
  if(!f){
    Error(filename,"cannot open file for output\n");
    return;
  }
  cout<<"Saving alignment objects to the file "<<filename<<endl;
  f->cd();
  f->WriteObject(fSSDAlignObj,"SSDAlignObjs","kSingleKey");
  f->Close();

}
<commit_msg>Modification to match the surveyed points in the updated report which are now given in cm (Panos)<commit_after>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/*
$Log$
Revision 1.1  2007/10/01 14:12:45  pchrist
Class creating the aligmnent object fro the surveyor measurements.

*/

//
//  Creates the SSD align object
//
//
#include "Riostream.h"
#include "TFile.h"
#include "TSystem.h"
#include "TClonesArray.h"
#include "TGeoManager.h"
#include "TGeoMatrix.h"
#include "TGeoPhysicalNode.h"

#include "AliITSSurveyToAlignSSD.h"
#include "AliSurveyObj.h"
#include "AliSurveyPoint.h"
#include "AliAlignObjParams.h"

#include "AliLog.h"

#include "AliCDBManager.h"
#include "AliCDBEntry.h"
#include "AliCDBStorage.h"

ClassImp(AliITSSurveyToAlignSSD)

//________________________________________________________________________
AliITSSurveyToAlignSSD::AliITSSurveyToAlignSSD() :
  TObject(),
  fRun(0),
  fFileLoc(0x0),
  fFileGlob(0x0),
  fSurveyPoints(0),
  fSSDAlignObj(new TClonesArray("AliAlignObjParams",100)),
  fSSDAlignObjParam(0),
  fDebug(0) {
  //
  //  default constructor
  //
}

//________________________________________________________________________
AliITSSurveyToAlignSSD::AliITSSurveyToAlignSSD(Int_t run, Int_t reportloc, Int_t reportglob) :
  TObject(),
  fRun(0),
  fFileLoc(0x0),
  fFileGlob(0x0),
  fSurveyPoints(0),
  fSSDAlignObj(new TClonesArray("AliAlignObjParams",100)),
  fSSDAlignObjParam(0),
  fDebug(0) {
  //
  // constructor - defines data files
  //
  fFileLoc = new Char_t[80];
  fFileGlob = new Char_t[80];
  Char_t path[50];
  sprintf(path,gSystem->Getenv("ALICE_ROOT"));
  //
  sprintf(fFileLoc,"%s/ITS/Survey_SSD_%d.txt",path,reportloc);
  sprintf(fFileGlob,"%s/ITS/Survey_SSD_%d.txt",path,reportglob);
  //

}
//_________________________________________________________________________
AliITSSurveyToAlignSSD::AliITSSurveyToAlignSSD(const AliITSSurveyToAlignSSD &align) :
  TObject(),
  fFileLoc(0x0),
  fFileGlob(0x0),
  fSurveyPoints(0),
  fSSDAlignObj(new TClonesArray("AliAlignObjParams",100)),
  fSSDAlignObjParam(0),
  fDebug(0) {
  //
  //  copy constructor - dummy

  fDebug = align.fDebug;
}

//__________________________________________________________________________
AliITSSurveyToAlignSSD & AliITSSurveyToAlignSSD::operator =(const AliITSSurveyToAlignSSD & align) {
  //
  // assignment operator - dummy
  //
  fDebug = align.fDebug;
  return (*this);
}

//__________________________________________________________________________
AliITSSurveyToAlignSSD::~AliITSSurveyToAlignSSD() {
  //
  // destructor
  //
  if(fSurveyPoints) delete fSurveyPoints;
  if(fSSDAlignObj) delete fSSDAlignObj;
  if(fSSDAlignObjParam) delete fSSDAlignObjParam;
}

//______________________________________________________________________
void AliITSSurveyToAlignSSD::Run() {
  //
  // runs the full chain
  //
  SetDebug(0);
  Bool_t flag = LoadSurveyData();
  if(!flag) {
    cout<<"Missing points"<<endl;
    return;
  }
  CreateAlignObj();
  StoreAlignObj();
  //
}

//__________________________________________________________________________
Bool_t AliITSSurveyToAlignSSD::LoadSurveyData() {
  //
  // for a time being it loads from the local file the surveyed point
  // and has the ideal points hardwired. I am waiting until Ricardo
  // completes his job
  //

  //Load survey data from the local file
  AliSurveyObj * s1 = new AliSurveyObj();
  if(s1->FillFromLocalFile(fFileGlob))
    fSurveyPoints = s1->GetData();
  else
    return kFALSE;

  cout<<"Number of SSD survey points: "<<fSurveyPoints->GetEntries()<<endl;

  return kTRUE;
}

//_______________________________________________________________________
void AliITSSurveyToAlignSSD::CreateAlignObj(){
  //
  // This method creates AliAlignObj and fills it with Euler angles
  // and shifts. The units are degrees and cm.
  //
  TClonesArray &alobj = *fSSDAlignObj;

  //load ideal geometry from the OCDB
  AliCDBManager *cdb = AliCDBManager::Instance();
  cdb->SetDefaultStorage("local://$ALICE_ROOT");
  cdb->SetRun(fRun);
  AliCDBEntry* entry = cdb->Get("GRP/Geometry/Data");
  AliGeomManager::SetGeometry(gGeoManager);

  AliSurveyPoint* pt = 0;
  TGeoHMatrix* hm = 0;
  TGeoPNEntry* pne = 0;
  Double_t* tr;
  Int_t uid;
  const char* symname;
  Double_t sx, sy, sz;
  Int_t ilayer, imodule;

  for(Int_t imod = 0; imod < fSurveyPoints->GetEntries(); imod++) {
    pt = (AliSurveyPoint*) fSurveyPoints->At(imod);
    if(!pt) continue;
    sx = pt->GetX();
    sy = pt->GetY();
    sz = pt->GetZ();

    ilayer = (imod < 748) ? AliGeomManager::kSSD1 : AliGeomManager::kSSD2;
    imodule = (imod < 748) ? imod : imod - 748;

    uid = AliGeomManager::LayerToVolUID(ilayer,imodule);
    symname = AliGeomManager::SymName(uid);
    pne = gGeoManager->GetAlignableEntryByUID(uid);
    hm = pne->GetGlobalOrig();
    tr = hm->GetTranslation();

    //Printf("symname %s", symname);
    //Printf("x,y,z from survey: %f %f %f", sx, sy, sz);
    //Printf("x,y,z from ideal : %f %f %f", tr[0], tr[1], tr[2]);

   new(alobj[imod]) AliAlignObjParams(symname, uid, sx-tr[0], sy-tr[1], sz-tr[2], 0., 0., 0., kTRUE);
  }//module loop

  delete entry;
}

//_________________________________________________________________________
void AliITSSurveyToAlignSSD::StoreAlignObj(){
  // Stores the TClonesArray of AliAlignObj in
  // $ALICE_ROOT/ITS/Align/Data/SSDfromSurvey.root
  // In a later version these objects will be merged
  // with the SDD ones and will be put in the OCDB
  const char* filename = "$ALICE_ROOT/ITS/Align/Data/SSDfromSurvey.root";
  TFile *f = TFile::Open(filename,"RECREATE");
  if(!f){
    Error(filename,"cannot open file for output\n");
    return;
  }
  cout<<"Saving alignment objects to the file "<<filename<<endl;
  f->cd();
  f->WriteObject(fSSDAlignObj,"SSDAlignObjs","kSingleKey");
  f->Close();

}
<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    vtkGeoEdgeStrategy.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
/*-------------------------------------------------------------------------
  Copyright 2008 Sandia Corporation.
  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
  the U.S. Government retains certain rights in this software.
-------------------------------------------------------------------------*/
#include "vtkGeoEdgeStrategy.h"

#include "vtkCellArray.h"
#include "vtkCellData.h"
#include "vtkCommand.h"
#include "vtkEdgeListIterator.h"
#include "vtkFloatArray.h"
#include "vtkGeoMath.h"
#include "vtkGlobeSource.h"
#include "vtkGraph.h"
#include "vtkMath.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkSmartPointer.h"

#include <vtksys/stl/utility>
#include <vtksys/stl/vector>
#include <vtksys/stl/map>

vtkCxxRevisionMacro(vtkGeoEdgeStrategy, "1.1");
vtkStandardNewMacro(vtkGeoEdgeStrategy);

vtkGeoEdgeStrategy::vtkGeoEdgeStrategy()
{
  this->GlobeRadius = vtkGeoMath::EarthRadiusMeters();
  this->ExplodeFactor = 0.2;
  this->NumberOfSubdivisions = 20;
}

void vtkGeoEdgeStrategy::Layout()
{
  vtksys_stl::map<vtksys_stl::pair<vtkIdType, vtkIdType>, int> edgeCount;
  vtksys_stl::map<vtksys_stl::pair<vtkIdType, vtkIdType>, int> edgeNumber;
  vtksys_stl::vector<vtkEdgeType> edgeVector(this->Graph->GetNumberOfEdges());
  vtkSmartPointer<vtkEdgeListIterator> it =
    vtkSmartPointer<vtkEdgeListIterator>::New();
  this->Graph->GetEdges(it);
  while (it->HasNext())
    {
    vtkEdgeType e = it->Next();
    vtkIdType src, tgt;
    if (e.Source < e.Target)
      {
      src = e.Source;
      tgt = e.Target;
      }
    else
      {
      src = e.Target;
      tgt = e.Source;
      }
    edgeCount[vtksys_stl::pair<vtkIdType, vtkIdType>(src, tgt)]++;
    edgeVector[e.Id] = e;
    }
  vtkIdType numEdges = this->Graph->GetNumberOfEdges();
  double* pts = new double[this->NumberOfSubdivisions*3];
  for (vtkIdType eid = 0; eid < numEdges; ++eid)
    {
    vtkEdgeType e = edgeVector[eid];
    vtkIdType src, tgt;
    if (e.Source < e.Target)
      {
      src = e.Source;
      tgt = e.Target;
      }
    else
      {
      src = e.Target;
      tgt = e.Source;
      }
    // Lookup the total number of edges with this source
    // and target, as well as how many times this pair
    // has been found so far.
    vtksys_stl::pair<vtkIdType,vtkIdType> p(src, tgt);
    edgeNumber[p]++;
    int cur = edgeNumber[p];
    int total = edgeCount[p];

    double sourcePt[3];
    double targetPt[3];
    this->Graph->GetPoint(e.Source, sourcePt);
    this->Graph->GetPoint(e.Target, targetPt);

    // Find w, a unit vector pointing from the center of the
    // earth directly inbetween the two endpoints.
    double w[3];
    for (int c = 0; c < 3; ++c)
      {
      w[c] = (sourcePt[c] + targetPt[c])/2.0;
      }
    vtkMath::Normalize(w);

    // The center of the circle used to draw the arc is a
    // point along the vector w scaled by the explode factor.
    // Use cur and total to separate parallel arcs.
    double center[3];
    for (int c = 0; c < 3; ++c)
      {
      center[c] = this->ExplodeFactor * this->GlobeRadius * w[c]
                  * (cur + 1) / total;
      }

    // The vectors u and x are unit vectors pointing from the
    // center of the circle to the two endpoints of the arc,
    // lastPoint and curPoint, respectively.
    double u[3], x[3];
    for (int c = 0; c < 3; ++c)
      {
      u[c] = sourcePt[c] - center[c];
      x[c] = targetPt[c] - center[c];
      }
    double radius = vtkMath::Norm(u);
    vtkMath::Normalize(u);
    vtkMath::Normalize(x);

    // Find the angle that the arc spans.
    double theta = acos(vtkMath::Dot(u, x));

    // If the vectors u, x point toward the center of the earth, take
    // the larger angle between the vectors.
    // We determine whether u points toward the center of the earth
    // by checking whether the dot product of u and w is negative.
    if (vtkMath::Dot(w, u) < 0)
      {
      theta = 2.0*vtkMath::Pi() - theta;
      }

    // We need two perpendicular vectors on the plane of the circle
    // in order to draw the circle.  First we calculate n, a vector
    // normal to the circle, by crossing u and w.  Next, we cross
    // n and u in order to get a vector v in the plane of the circle
    // that is perpendicular to u.
    double n[3];
    vtkMath::Cross(u, w, n);
    vtkMath::Normalize(n);
    double v[3];
    vtkMath::Cross(n, u, v);
    vtkMath::Normalize(v);

    // Use the general equation for a circle in three dimensions
    // to draw an arc from the last point to the current point.
    for (int s = 0; s < this->NumberOfSubdivisions; ++s)
      {
      double angle = (this->NumberOfSubdivisions - 1.0 - s)
        * theta / (this->NumberOfSubdivisions - 1.0);
      for (int c = 0; c < 3; ++c)
        {
        pts[3*s + c] = center[c]
          + radius*cos(angle)*u[c]
          + radius*sin(angle)*v[c];
        }
      }
    this->Graph->SetEdgePoints(e.Id, this->NumberOfSubdivisions, pts);

    if (eid % 1000 == 0)
      {
      double progress = eid / static_cast<double>(numEdges);
      this->InvokeEvent(vtkCommand::ProgressEvent, static_cast<void*>(&progress));
      }
    }
  double progress = 1.0;
  this->InvokeEvent(vtkCommand::ProgressEvent, static_cast<void*>(&progress));
  delete [] pts;
}

void vtkGeoEdgeStrategy::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
  os << indent << "GlobeRadius: " << this->GlobeRadius << endl;
  os << indent << "ExplodeFactor: " << this->ExplodeFactor << endl;
  os << indent << "NumberOfSubdivisions: " << this->NumberOfSubdivisions << endl;
}

<commit_msg>COMP: Remove unneeded include fron non-dependent library.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkGeoEdgeStrategy.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
/*-------------------------------------------------------------------------
  Copyright 2008 Sandia Corporation.
  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
  the U.S. Government retains certain rights in this software.
-------------------------------------------------------------------------*/
#include "vtkGeoEdgeStrategy.h"

#include "vtkCellArray.h"
#include "vtkCellData.h"
#include "vtkCommand.h"
#include "vtkEdgeListIterator.h"
#include "vtkFloatArray.h"
#include "vtkGeoMath.h"
#include "vtkGraph.h"
#include "vtkMath.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkSmartPointer.h"

#include <vtksys/stl/utility>
#include <vtksys/stl/vector>
#include <vtksys/stl/map>

vtkCxxRevisionMacro(vtkGeoEdgeStrategy, "1.2");
vtkStandardNewMacro(vtkGeoEdgeStrategy);

vtkGeoEdgeStrategy::vtkGeoEdgeStrategy()
{
  this->GlobeRadius = vtkGeoMath::EarthRadiusMeters();
  this->ExplodeFactor = 0.2;
  this->NumberOfSubdivisions = 20;
}

void vtkGeoEdgeStrategy::Layout()
{
  vtksys_stl::map<vtksys_stl::pair<vtkIdType, vtkIdType>, int> edgeCount;
  vtksys_stl::map<vtksys_stl::pair<vtkIdType, vtkIdType>, int> edgeNumber;
  vtksys_stl::vector<vtkEdgeType> edgeVector(this->Graph->GetNumberOfEdges());
  vtkSmartPointer<vtkEdgeListIterator> it =
    vtkSmartPointer<vtkEdgeListIterator>::New();
  this->Graph->GetEdges(it);
  while (it->HasNext())
    {
    vtkEdgeType e = it->Next();
    vtkIdType src, tgt;
    if (e.Source < e.Target)
      {
      src = e.Source;
      tgt = e.Target;
      }
    else
      {
      src = e.Target;
      tgt = e.Source;
      }
    edgeCount[vtksys_stl::pair<vtkIdType, vtkIdType>(src, tgt)]++;
    edgeVector[e.Id] = e;
    }
  vtkIdType numEdges = this->Graph->GetNumberOfEdges();
  double* pts = new double[this->NumberOfSubdivisions*3];
  for (vtkIdType eid = 0; eid < numEdges; ++eid)
    {
    vtkEdgeType e = edgeVector[eid];
    vtkIdType src, tgt;
    if (e.Source < e.Target)
      {
      src = e.Source;
      tgt = e.Target;
      }
    else
      {
      src = e.Target;
      tgt = e.Source;
      }
    // Lookup the total number of edges with this source
    // and target, as well as how many times this pair
    // has been found so far.
    vtksys_stl::pair<vtkIdType,vtkIdType> p(src, tgt);
    edgeNumber[p]++;
    int cur = edgeNumber[p];
    int total = edgeCount[p];

    double sourcePt[3];
    double targetPt[3];
    this->Graph->GetPoint(e.Source, sourcePt);
    this->Graph->GetPoint(e.Target, targetPt);

    // Find w, a unit vector pointing from the center of the
    // earth directly inbetween the two endpoints.
    double w[3];
    for (int c = 0; c < 3; ++c)
      {
      w[c] = (sourcePt[c] + targetPt[c])/2.0;
      }
    vtkMath::Normalize(w);

    // The center of the circle used to draw the arc is a
    // point along the vector w scaled by the explode factor.
    // Use cur and total to separate parallel arcs.
    double center[3];
    for (int c = 0; c < 3; ++c)
      {
      center[c] = this->ExplodeFactor * this->GlobeRadius * w[c]
                  * (cur + 1) / total;
      }

    // The vectors u and x are unit vectors pointing from the
    // center of the circle to the two endpoints of the arc,
    // lastPoint and curPoint, respectively.
    double u[3], x[3];
    for (int c = 0; c < 3; ++c)
      {
      u[c] = sourcePt[c] - center[c];
      x[c] = targetPt[c] - center[c];
      }
    double radius = vtkMath::Norm(u);
    vtkMath::Normalize(u);
    vtkMath::Normalize(x);

    // Find the angle that the arc spans.
    double theta = acos(vtkMath::Dot(u, x));

    // If the vectors u, x point toward the center of the earth, take
    // the larger angle between the vectors.
    // We determine whether u points toward the center of the earth
    // by checking whether the dot product of u and w is negative.
    if (vtkMath::Dot(w, u) < 0)
      {
      theta = 2.0*vtkMath::Pi() - theta;
      }

    // We need two perpendicular vectors on the plane of the circle
    // in order to draw the circle.  First we calculate n, a vector
    // normal to the circle, by crossing u and w.  Next, we cross
    // n and u in order to get a vector v in the plane of the circle
    // that is perpendicular to u.
    double n[3];
    vtkMath::Cross(u, w, n);
    vtkMath::Normalize(n);
    double v[3];
    vtkMath::Cross(n, u, v);
    vtkMath::Normalize(v);

    // Use the general equation for a circle in three dimensions
    // to draw an arc from the last point to the current point.
    for (int s = 0; s < this->NumberOfSubdivisions; ++s)
      {
      double angle = (this->NumberOfSubdivisions - 1.0 - s)
        * theta / (this->NumberOfSubdivisions - 1.0);
      for (int c = 0; c < 3; ++c)
        {
        pts[3*s + c] = center[c]
          + radius*cos(angle)*u[c]
          + radius*sin(angle)*v[c];
        }
      }
    this->Graph->SetEdgePoints(e.Id, this->NumberOfSubdivisions, pts);

    if (eid % 1000 == 0)
      {
      double progress = eid / static_cast<double>(numEdges);
      this->InvokeEvent(vtkCommand::ProgressEvent, static_cast<void*>(&progress));
      }
    }
  double progress = 1.0;
  this->InvokeEvent(vtkCommand::ProgressEvent, static_cast<void*>(&progress));
  delete [] pts;
}

void vtkGeoEdgeStrategy::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
  os << indent << "GlobeRadius: " << this->GlobeRadius << endl;
  os << indent << "ExplodeFactor: " << this->ExplodeFactor << endl;
  os << indent << "NumberOfSubdivisions: " << this->NumberOfSubdivisions << endl;
}

<|endoftext|>


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

#include <atlbase.h>
#include <vector>

#include "base/file_path.h"
#include "base/scoped_comptr_win.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/renderer_host/render_widget_host_view_win.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/notification_type.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"

namespace {

class AccessibilityWinBrowserTest : public InProcessBrowserTest {
 public:
  void SetUpCommandLine(CommandLine* command_line) {
    // Turns on the accessibility in the renderer. Off by default until
    // http://crbug.com/25564 is fixed.
    command_line->AppendSwitch(switches::kEnableRendererAccessibility);
  }

 protected:
  IAccessible* GetRenderWidgetHostViewClientAccessible();
};

class AccessibleChecker {
 public:
  AccessibleChecker(std::wstring expected_name, int32 expected_role);

  // Append an AccessibleChecker that verifies accessibility information for
  // a child IAccessible. Order is important.
  void AppendExpectedChild(AccessibleChecker* expected_child);

  // Check that the name and role of the given IAccessible instance and its
  // descendants match the expected names and roles that this object was
  // initialized with.
  void CheckAccessible(IAccessible* accessible);

  typedef std::vector<AccessibleChecker*> AccessibleCheckerVector;

 private:
  void CheckAccessibleName(IAccessible* accessible);
  void CheckAccessibleRole(IAccessible* accessible);
  void CheckAccessibleChildren(IAccessible* accessible);

 private:
  // Expected accessible name. Checked against IAccessible::get_accName.
  std::wstring name_;

  // Expected accessible role. Checked against IAccessible::get_accRole.
  int32 role_;

  // Expected accessible children. Checked using IAccessible::get_accChildCount
  // and ::AccessibleChildren.
  AccessibleCheckerVector children_;
};

VARIANT CreateI4Variant(LONG value) {
  VARIANT variant = {0};

  V_VT(&variant) = VT_I4;
  V_I4(&variant) = value;

  return variant;
}

IAccessible* GetAccessibleFromResultVariant(IAccessible* parent, VARIANT *var) {
  switch (V_VT(var)) {
    case VT_DISPATCH:
      return CComQIPtr<IAccessible>(V_DISPATCH(var)).Detach();
      break;

    case VT_I4: {
      CComPtr<IDispatch> dispatch;
      HRESULT hr = parent->get_accChild(CreateI4Variant(V_I4(var)), &dispatch);
      EXPECT_EQ(hr, S_OK);
      return CComQIPtr<IAccessible>(dispatch).Detach();
      break;
    }
  }

  return NULL;
}

// Retrieve the MSAA client accessibility object for the Render Widget Host View
// of the selected tab.
IAccessible*
AccessibilityWinBrowserTest::GetRenderWidgetHostViewClientAccessible() {
  HWND hwnd_render_widget_host_view =
      browser()->GetSelectedTabContents()->GetRenderWidgetHostView()->
          GetNativeView();

  IAccessible* accessible;
  HRESULT hr = AccessibleObjectFromWindow(
      hwnd_render_widget_host_view, OBJID_CLIENT,
      IID_IAccessible, reinterpret_cast<void**>(&accessible));
  EXPECT_EQ(S_OK, hr);
  EXPECT_NE(accessible, reinterpret_cast<IAccessible*>(NULL));

  return accessible;
}

AccessibleChecker::AccessibleChecker(
    std::wstring expected_name, int32 expected_role) :
    name_(expected_name),
    role_(expected_role) {
}

void AccessibleChecker::AppendExpectedChild(
    AccessibleChecker* expected_child) {
  children_.push_back(expected_child);
}

void AccessibleChecker::CheckAccessible(IAccessible* accessible) {
  CheckAccessibleName(accessible);
  CheckAccessibleRole(accessible);
  CheckAccessibleChildren(accessible);
}

void AccessibleChecker::CheckAccessibleName(IAccessible* accessible) {
  CComBSTR name;
  HRESULT hr =
      accessible->get_accName(CreateI4Variant(CHILDID_SELF), &name);

  if (name_.empty()) {
    // If the object doesn't have name S_FALSE should be returned.
    EXPECT_EQ(hr, S_FALSE);
  } else {
    // Test that the correct string was returned.
    EXPECT_EQ(hr, S_OK);
    EXPECT_EQ(CompareString(LOCALE_NEUTRAL, 0, name, SysStringLen(name),
                  name_.c_str(), name_.length()),
              CSTR_EQUAL);
  }
}

void AccessibleChecker::CheckAccessibleRole(IAccessible* accessible) {
  VARIANT var_role = {0};
  HRESULT hr =
      accessible->get_accRole(CreateI4Variant(CHILDID_SELF), &var_role);
  EXPECT_EQ(hr, S_OK);
  EXPECT_EQ(V_VT(&var_role), VT_I4);
  EXPECT_EQ(V_I4(&var_role), role_);
}

void AccessibleChecker::CheckAccessibleChildren(IAccessible* parent) {
  LONG child_count = 0;
  HRESULT hr = parent->get_accChildCount(&child_count);
  EXPECT_EQ(hr, S_OK);

  // TODO(dmazzoni): remove as soon as test passes on build bot
  printf("CheckAccessibleChildren: actual=%d expected=%d\n",
         static_cast<int>(child_count),
         static_cast<int>(children_.size()));

  ASSERT_EQ(child_count, children_.size());

  std::auto_ptr<VARIANT> child_array(new VARIANT[child_count]);
  LONG obtained_count = 0;
  hr = AccessibleChildren(parent, 0, child_count,
                          child_array.get(), &obtained_count);
  ASSERT_EQ(hr, S_OK);
  ASSERT_EQ(child_count, obtained_count);

  VARIANT* child = child_array.get();
  for (AccessibleCheckerVector::iterator child_checker = children_.begin();
       child_checker != children_.end();
       ++child_checker, ++child) {
    ScopedComPtr<IAccessible> child_accessible;
    child_accessible.Attach(GetAccessibleFromResultVariant(parent, child));
    (*child_checker)->CheckAccessible(child_accessible);
  }
}

// Flaky http://crbug.com/44546.
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
                       FAILS_TestRendererAccessibilityTree) {
  GURL tree_url(
      "data:text/html,<title>Accessibility Win Test</title>"
      "<input type='button' value='push' /><input type='checkbox' />"
      "");
  browser()->OpenURL(tree_url, GURL(), CURRENT_TAB, PageTransition::TYPED);
  ui_test_utils::WaitForNotification(
      NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);

  ScopedComPtr<IAccessible> document_accessible(
      GetRenderWidgetHostViewClientAccessible());
  ASSERT_NE(document_accessible.get(), reinterpret_cast<IAccessible*>(NULL));

  AccessibleChecker button_checker(L"push", ROLE_SYSTEM_PUSHBUTTON);
  AccessibleChecker checkbox_checker(L"", ROLE_SYSTEM_CHECKBUTTON);

  AccessibleChecker grouping_checker(L"", ROLE_SYSTEM_GROUPING);
  grouping_checker.AppendExpectedChild(&button_checker);
  grouping_checker.AppendExpectedChild(&checkbox_checker);

  AccessibleChecker document_checker(L"", ROLE_SYSTEM_DOCUMENT);
  document_checker.AppendExpectedChild(&grouping_checker);

  // Check the accessible tree of the renderer.
  document_checker.CheckAccessible(document_accessible);

  // Check that document accessible has a parent accessible.
  ScopedComPtr<IDispatch> parent_dispatch;
  HRESULT hr = document_accessible->get_accParent(parent_dispatch.Receive());
  EXPECT_EQ(hr, S_OK);
  EXPECT_NE(parent_dispatch, reinterpret_cast<IDispatch*>(NULL));

  // Navigate to another page.
  GURL about_url("about:");
  ui_test_utils::NavigateToURL(browser(), about_url);

  // Verify that the IAccessible reference still points to a valid object and
  // that it calls to its methods fail since the tree is no longer valid after
  // the page navagation.
  // Todo(ctguil): Currently this is giving a false positive because E_FAIL is
  // returned when BrowserAccessibilityManager::RequestAccessibilityInfo fails
  // since the previous render view host connection is lost. Verify that
  // instances are actually marked as invalid once the browse side cache is
  // checked in.
  CComBSTR name;
  hr = document_accessible->get_accName(CreateI4Variant(CHILDID_SELF), &name);
  ASSERT_EQ(E_FAIL, hr);
}
}  // namespace.
<commit_msg>Fix TestRendererAccessibilityTree test.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <atlbase.h>
#include <vector>

#include "base/file_path.h"
#include "base/scoped_comptr_win.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/renderer_host/render_widget_host_view_win.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/notification_type.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"

namespace {

class AccessibilityWinBrowserTest : public InProcessBrowserTest {
 public:
  void SetUpCommandLine(CommandLine* command_line) {
    // Turns on the accessibility in the renderer. Off by default until
    // http://crbug.com/25564 is fixed.
    command_line->AppendSwitch(switches::kEnableRendererAccessibility);
  }

 protected:
  IAccessible* GetRenderWidgetHostViewClientAccessible();
};

class AccessibleChecker {
 public:
  AccessibleChecker(std::wstring expected_name, int32 expected_role);
  AccessibleChecker(std::wstring expected_name, std::wstring expected_role);

  // Append an AccessibleChecker that verifies accessibility information for
  // a child IAccessible. Order is important.
  void AppendExpectedChild(AccessibleChecker* expected_child);

  // Check that the name and role of the given IAccessible instance and its
  // descendants match the expected names and roles that this object was
  // initialized with.
  void CheckAccessible(IAccessible* accessible);

  typedef std::vector<AccessibleChecker*> AccessibleCheckerVector;

 private:
  void CheckAccessibleName(IAccessible* accessible);
  void CheckAccessibleRole(IAccessible* accessible);
  void CheckAccessibleChildren(IAccessible* accessible);

 private:
  // Expected accessible name. Checked against IAccessible::get_accName.
  std::wstring name_;

  // Expected accessible role. Checked against IAccessible::get_accRole.
  CComVariant role_;

  // Expected accessible children. Checked using IAccessible::get_accChildCount
  // and ::AccessibleChildren.
  AccessibleCheckerVector children_;
};

VARIANT CreateI4Variant(LONG value) {
  VARIANT variant = {0};

  V_VT(&variant) = VT_I4;
  V_I4(&variant) = value;

  return variant;
}

IAccessible* GetAccessibleFromResultVariant(IAccessible* parent, VARIANT *var) {
  switch (V_VT(var)) {
    case VT_DISPATCH:
      return CComQIPtr<IAccessible>(V_DISPATCH(var)).Detach();
      break;

    case VT_I4: {
      CComPtr<IDispatch> dispatch;
      HRESULT hr = parent->get_accChild(CreateI4Variant(V_I4(var)), &dispatch);
      EXPECT_EQ(hr, S_OK);
      return CComQIPtr<IAccessible>(dispatch).Detach();
      break;
    }
  }

  return NULL;
}

// Retrieve the MSAA client accessibility object for the Render Widget Host View
// of the selected tab.
IAccessible*
AccessibilityWinBrowserTest::GetRenderWidgetHostViewClientAccessible() {
  HWND hwnd_render_widget_host_view =
      browser()->GetSelectedTabContents()->GetRenderWidgetHostView()->
          GetNativeView();

  IAccessible* accessible;
  HRESULT hr = AccessibleObjectFromWindow(
      hwnd_render_widget_host_view, OBJID_CLIENT,
      IID_IAccessible, reinterpret_cast<void**>(&accessible));
  EXPECT_EQ(S_OK, hr);
  EXPECT_NE(accessible, reinterpret_cast<IAccessible*>(NULL));

  return accessible;
}

AccessibleChecker::AccessibleChecker(
    std::wstring expected_name, int32 expected_role) :
    name_(expected_name),
    role_(expected_role) {
}

AccessibleChecker::AccessibleChecker(
    std::wstring expected_name, std::wstring expected_role) :
    name_(expected_name),
    role_(expected_role.c_str()) {
}

void AccessibleChecker::AppendExpectedChild(
    AccessibleChecker* expected_child) {
  children_.push_back(expected_child);
}

void AccessibleChecker::CheckAccessible(IAccessible* accessible) {
  CheckAccessibleName(accessible);
  CheckAccessibleRole(accessible);
  CheckAccessibleChildren(accessible);
}

void AccessibleChecker::CheckAccessibleName(IAccessible* accessible) {
  CComBSTR name;
  HRESULT hr =
      accessible->get_accName(CreateI4Variant(CHILDID_SELF), &name);

  if (name_.empty()) {
    // If the object doesn't have name S_FALSE should be returned.
    EXPECT_EQ(hr, S_FALSE);
  } else {
    // Test that the correct string was returned.
    EXPECT_EQ(hr, S_OK);
    EXPECT_EQ(CompareString(LOCALE_NEUTRAL, 0, name, SysStringLen(name),
                  name_.c_str(), name_.length()),
              CSTR_EQUAL);
  }
}

void AccessibleChecker::CheckAccessibleRole(IAccessible* accessible) {
  VARIANT var_role = {0};
  HRESULT hr =
      accessible->get_accRole(CreateI4Variant(CHILDID_SELF), &var_role);
  EXPECT_EQ(hr, S_OK);
  ASSERT_TRUE(role_ == var_role);
}

void AccessibleChecker::CheckAccessibleChildren(IAccessible* parent) {
  LONG child_count = 0;
  HRESULT hr = parent->get_accChildCount(&child_count);
  EXPECT_EQ(hr, S_OK);
  ASSERT_EQ(child_count, children_.size());

  std::auto_ptr<VARIANT> child_array(new VARIANT[child_count]);
  LONG obtained_count = 0;
  hr = AccessibleChildren(parent, 0, child_count,
                          child_array.get(), &obtained_count);
  ASSERT_EQ(hr, S_OK);
  ASSERT_EQ(child_count, obtained_count);

  VARIANT* child = child_array.get();
  for (AccessibleCheckerVector::iterator child_checker = children_.begin();
       child_checker != children_.end();
       ++child_checker, ++child) {
    ScopedComPtr<IAccessible> child_accessible;
    child_accessible.Attach(GetAccessibleFromResultVariant(parent, child));
    (*child_checker)->CheckAccessible(child_accessible);
  }
}

IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
                       TestRendererAccessibilityTree) {
  GURL tree_url(
      "data:text/html,<title>Accessibility Win Test</title>"
      "<input type='button' value='push' /><input type='checkbox' />"
      "");
  browser()->OpenURL(tree_url, GURL(), CURRENT_TAB, PageTransition::TYPED);
  ui_test_utils::WaitForNotification(
      NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);

  ScopedComPtr<IAccessible> document_accessible(
      GetRenderWidgetHostViewClientAccessible());
  ASSERT_NE(document_accessible.get(), reinterpret_cast<IAccessible*>(NULL));

  AccessibleChecker button_checker(L"push", ROLE_SYSTEM_PUSHBUTTON);
  AccessibleChecker checkbox_checker(L"", ROLE_SYSTEM_CHECKBUTTON);

  AccessibleChecker grouping_checker(L"", L"div");
  grouping_checker.AppendExpectedChild(&button_checker);
  grouping_checker.AppendExpectedChild(&checkbox_checker);

  AccessibleChecker document_checker(L"", ROLE_SYSTEM_DOCUMENT);
  document_checker.AppendExpectedChild(&grouping_checker);

  // Check the accessible tree of the renderer.
  document_checker.CheckAccessible(document_accessible);

  // Check that document accessible has a parent accessible.
  ScopedComPtr<IDispatch> parent_dispatch;
  HRESULT hr = document_accessible->get_accParent(parent_dispatch.Receive());
  EXPECT_EQ(hr, S_OK);
  EXPECT_NE(parent_dispatch, reinterpret_cast<IDispatch*>(NULL));

  // Navigate to another page.
  GURL about_url("about:");
  ui_test_utils::NavigateToURL(browser(), about_url);

  // Verify that the IAccessible reference still points to a valid object and
  // that it calls to its methods fail since the tree is no longer valid after
  // the page navagation.
  // Todo(ctguil): Currently this is giving a false positive because E_FAIL is
  // returned when BrowserAccessibilityManager::RequestAccessibilityInfo fails
  // since the previous render view host connection is lost. Verify that
  // instances are actually marked as invalid once the browse side cache is
  // checked in.
  CComBSTR name;
  hr = document_accessible->get_accName(CreateI4Variant(CHILDID_SELF), &name);
  ASSERT_EQ(E_FAIL, hr);
}
}  // namespace.
<|endoftext|>


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

#include "chrome/browser/browser_accessibility_manager.h"

#include "chrome/browser/browser_accessibility.h"
#include "chrome/browser/render_process_host.h"
#include "chrome/browser/render_widget_host.h"

// The time in ms after which we give up and return an error when processing an
// accessibility message and no response has been received from the renderer.
static const int kAccessibilityMessageTimeOut = 500;

// static
BrowserAccessibilityManager* BrowserAccessibilityManager::GetInstance() {
  return Singleton<BrowserAccessibilityManager>::get();
}

BrowserAccessibilityManager::BrowserAccessibilityManager()
    : instance_id_(0) {
  NotificationService::current()->AddObserver(this,
      NOTIFY_RENDERER_PROCESS_TERMINATED, NotificationService::AllSources());
}

BrowserAccessibilityManager::~BrowserAccessibilityManager() {
  // Clear hashmaps.
  instance_map_.clear();
  render_process_host_map_.clear();

  // We don't remove ourselves as an observer because we are a Singleton object,
  // and NotifcationService is likely gone by this point.
}

STDMETHODIMP BrowserAccessibilityManager::CreateAccessibilityInstance(
    REFIID iid, int iaccessible_id, int instance_id, void** interface_ptr) {
  if (IID_IUnknown == iid || IID_IDispatch == iid || IID_IAccessible == iid) {
    CComObject<BrowserAccessibility>* instance = NULL;

    HRESULT hr = CComObject<BrowserAccessibility>::CreateInstance(&instance);
    DCHECK(SUCCEEDED(hr));

    if (!instance)
      return E_FAIL;

    CComPtr<IAccessible> accessibility_instance(instance);

    // Set unique ids.
    instance->set_iaccessible_id(iaccessible_id);
    instance->set_instance_id(instance_id);

    // Retrieve the RenderWidgetHost connected to this request.
    InstanceMap::iterator it = instance_map_.find(instance_id);

    if (it != instance_map_.end()) {
      UniqueMembers* members = it->second;

      if (!members || !members->render_widget_host_)
        return E_FAIL;

      render_process_host_map_[members->render_widget_host_->process()] =
          instance;
    } else {
      // No RenderProcess active for this instance.
      return E_FAIL;
    }

    // All is well, assign the temp instance to the output pointer.
    *interface_ptr = accessibility_instance.Detach();
    return S_OK;
  }
  // No supported interface found, return error.
  *interface_ptr = NULL;
  return E_NOINTERFACE;
}

bool BrowserAccessibilityManager::RequestAccessibilityInfo(
    int iaccessible_id, int instance_id, int iaccessible_func_id,
    VARIANT var_id, LONG input1, LONG input2) {
  // Create and populate input message structure.
  ViewMsg_Accessibility_In_Params in_params;

  in_params.iaccessible_id = iaccessible_id;
  in_params.iaccessible_function_id = iaccessible_func_id;
  in_params.input_variant_lval = var_id.lVal;
  in_params.input_long1 = input1;
  in_params.input_long2 = input2;

  // Retrieve the RenderWidgetHost connected to this request.
  InstanceMap::iterator it = instance_map_.find(instance_id);

  if (it == instance_map_.end()) {
    // Id not found.
    return false;
  }

  UniqueMembers* members = it->second;

  if (!members || !members->render_widget_host_)
    return false;

  IPC::SyncMessage* msg =
      new ViewMsg_GetAccessibilityInfo(
          members->render_widget_host_->routing_id(), in_params, &out_params_);

  // Necessary for the send to keep the UI responsive.
  msg->EnableMessagePumping();
  bool success = members->render_widget_host_->process()->channel()->
      SendWithTimeout(msg, kAccessibilityMessageTimeOut);

  return success;
}

ViewHostMsg_Accessibility_Out_Params BrowserAccessibilityManager::response() {
  return out_params_;
}

HWND BrowserAccessibilityManager::parent_hwnd(int id) {
  // Retrieve the parent HWND connected to the requester's id.
  InstanceMap::iterator it = instance_map_.find(id);

  if (it == instance_map_.end()) {
    // Id not found.
    return NULL;
  }

  UniqueMembers* members = it->second;

  if (!members || !members->parent_hwnd_)
    return NULL;

  return members->parent_hwnd_;
}

int BrowserAccessibilityManager::SetMembers(BrowserAccessibility* browser_acc,
    HWND parent_hwnd, RenderWidgetHost* render_widget_host) {
  // Set HWND and RenderWidgetHost connected to |browser_acc|.
  instance_map_[instance_id_] =
      new UniqueMembers(parent_hwnd, render_widget_host);

  render_process_host_map_[render_widget_host->process()] = browser_acc;
  return instance_id_++;
}

void BrowserAccessibilityManager::Observe(NotificationType type,
                                          const NotificationSource& source,
                                          const NotificationDetails& details) {
  DCHECK(type == NOTIFY_RENDERER_PROCESS_TERMINATED);
  RenderProcessHost* rph = Source<RenderProcessHost>(source).ptr();
  DCHECK(rph);
  RenderProcessHostMap::iterator it = render_process_host_map_.find(rph);

  if (it == render_process_host_map_.end() || !it->second) {
    // RenderProcessHost not associated with any BrowserAccessibility instance.
    return;
  }

  // Set BrowserAccessibility instance to inactive state.
  it->second->set_instance_active(false);
  render_process_host_map_.erase(it);

  // Delete entry also from InstanceMap.
  InstanceMap::iterator it2 = instance_map_.find(it->second->instance_id());

  if (it2 != instance_map_.end())
    instance_map_.erase(it2);
}
<commit_msg>Fixes a null pointer bug, and adds null checks around potentially dying process and channel.<commit_after>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/browser_accessibility_manager.h"

#include "chrome/browser/browser_accessibility.h"
#include "chrome/browser/render_process_host.h"
#include "chrome/browser/render_widget_host.h"

// The time in ms after which we give up and return an error when processing an
// accessibility message and no response has been received from the renderer.
static const int kAccessibilityMessageTimeOut = 500;

// static
BrowserAccessibilityManager* BrowserAccessibilityManager::GetInstance() {
  return Singleton<BrowserAccessibilityManager>::get();
}

BrowserAccessibilityManager::BrowserAccessibilityManager()
    : instance_id_(0) {
  NotificationService::current()->AddObserver(this,
      NOTIFY_RENDERER_PROCESS_TERMINATED, NotificationService::AllSources());
}

BrowserAccessibilityManager::~BrowserAccessibilityManager() {
  // Clear hashmaps.
  instance_map_.clear();
  render_process_host_map_.clear();

  // We don't remove ourselves as an observer because we are a Singleton object,
  // and NotifcationService is likely gone by this point.
}

STDMETHODIMP BrowserAccessibilityManager::CreateAccessibilityInstance(
    REFIID iid, int iaccessible_id, int instance_id, void** interface_ptr) {
  if (IID_IUnknown == iid || IID_IDispatch == iid || IID_IAccessible == iid) {
    CComObject<BrowserAccessibility>* instance = NULL;

    HRESULT hr = CComObject<BrowserAccessibility>::CreateInstance(&instance);
    DCHECK(SUCCEEDED(hr));

    if (!instance)
      return E_FAIL;

    CComPtr<IAccessible> accessibility_instance(instance);

    // Set unique ids.
    instance->set_iaccessible_id(iaccessible_id);
    instance->set_instance_id(instance_id);

    // Retrieve the RenderWidgetHost connected to this request.
    InstanceMap::iterator it = instance_map_.find(instance_id);

    if (it != instance_map_.end()) {
      UniqueMembers* members = it->second;

      if (!members || !members->render_widget_host_)
        return E_FAIL;

      render_process_host_map_[members->render_widget_host_->process()] =
          instance;
    } else {
      // No RenderProcess active for this instance.
      return E_FAIL;
    }

    // All is well, assign the temp instance to the output pointer.
    *interface_ptr = accessibility_instance.Detach();
    return S_OK;
  }
  // No supported interface found, return error.
  *interface_ptr = NULL;
  return E_NOINTERFACE;
}

bool BrowserAccessibilityManager::RequestAccessibilityInfo(
    int iaccessible_id, int instance_id, int iaccessible_func_id,
    VARIANT var_id, LONG input1, LONG input2) {
  // Create and populate input message structure.
  ViewMsg_Accessibility_In_Params in_params;

  in_params.iaccessible_id = iaccessible_id;
  in_params.iaccessible_function_id = iaccessible_func_id;
  in_params.input_variant_lval = var_id.lVal;
  in_params.input_long1 = input1;
  in_params.input_long2 = input2;

  // Retrieve the RenderWidgetHost connected to this request.
  InstanceMap::iterator it = instance_map_.find(instance_id);

  if (it == instance_map_.end()) {
    // Id not found.
    return false;
  }

  UniqueMembers* members = it->second;

  if (!members || !members->render_widget_host_)
    return false;

  IPC::SyncMessage* msg =
      new ViewMsg_GetAccessibilityInfo(
          members->render_widget_host_->routing_id(), in_params, &out_params_);

  bool success = false;
  if (members->render_widget_host_->process() &&
      members->render_widget_host_->process()->channel()) {
    // Necessary for the send to keep the UI responsive.
    msg->EnableMessagePumping();
    success = members->render_widget_host_->process()->channel()->
        SendWithTimeout(msg, kAccessibilityMessageTimeOut);
  }

  return success;
}

ViewHostMsg_Accessibility_Out_Params BrowserAccessibilityManager::response() {
  return out_params_;
}

HWND BrowserAccessibilityManager::parent_hwnd(int id) {
  // Retrieve the parent HWND connected to the requester's id.
  InstanceMap::iterator it = instance_map_.find(id);

  if (it == instance_map_.end()) {
    // Id not found.
    return NULL;
  }

  UniqueMembers* members = it->second;

  if (!members || !members->parent_hwnd_)
    return NULL;

  return members->parent_hwnd_;
}

int BrowserAccessibilityManager::SetMembers(BrowserAccessibility* browser_acc,
    HWND parent_hwnd, RenderWidgetHost* render_widget_host) {
  // Set HWND and RenderWidgetHost connected to |browser_acc|.
  instance_map_[instance_id_] =
      new UniqueMembers(parent_hwnd, render_widget_host);

  render_process_host_map_[render_widget_host->process()] = browser_acc;
  return instance_id_++;
}

void BrowserAccessibilityManager::Observe(NotificationType type,
                                          const NotificationSource& source,
                                          const NotificationDetails& details) {
  DCHECK(type == NOTIFY_RENDERER_PROCESS_TERMINATED);
  RenderProcessHost* rph = Source<RenderProcessHost>(source).ptr();
  DCHECK(rph);
  RenderProcessHostMap::iterator it = render_process_host_map_.find(rph);

  if (it == render_process_host_map_.end() || !it->second) {
    // RenderProcessHost not associated with any BrowserAccessibility instance.
    return;
  }

  // Set BrowserAccessibility instance to inactive state.
  it->second->set_instance_active(false);

  // Delete entry also from InstanceMap.
  InstanceMap::iterator it2 = instance_map_.find(it->second->instance_id());

  if (it2 != instance_map_.end())
    instance_map_.erase(it2);

  // Only delete the first entry once it is no longer in use.
  render_process_host_map_.erase(it);
}
<|endoftext|>