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

  Copyright (c) Kapteyn Astronomical Institute
  University of Groningen, Groningen, Netherlands. All Rights Reserved.

  See COPYRIGHT.txt
  or http://www.slicer.org/copyright/copyright.txt for details.

  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.

  This file was originally developed by Davide Punzo, Kapteyn Astronomical Institute,
  and was supported through the European Research Consil grant nr. 291531.

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

// MRML includes
#include <vtkMRMLAstroLabelMapVolumeDisplayNode.h>
#include <vtkMRMLAstroLabelMapVolumeNode.h>
#include <vtkMRMLAstroVolumeDisplayNode.h>
#include <vtkMRMLAstroVolumeNode.h>
#include <vtkMRMLAstroVolumeStorageNode.h>
#include <vtkMRMLScene.h>
#include <vtkMRMLVolumeNode.h>

//vtkFits includes
#include <vtkFITSReader.h>
#include <vtkFITSWriter.h>

// VTK includes
#include <vtkDataSetAttributes.h>
#include <vtkImageChangeInformation.h>
#include <vtkImageData.h>
#include <vtkNew.h>
#include <vtkObjectFactory.h>
#include <vtkType.h>

//----------------------------------------------------------------------------
vtkMRMLNodeNewMacro(vtkMRMLAstroVolumeStorageNode);

//----------------------------------------------------------------------------
vtkMRMLAstroVolumeStorageNode::vtkMRMLAstroVolumeStorageNode()
{
  this->CenterImage = 2;
  this->DefaultWriteFileExtension = "fits";
}

//----------------------------------------------------------------------------
vtkMRMLAstroVolumeStorageNode::~vtkMRMLAstroVolumeStorageNode()
{
}

namespace
{
//----------------------------------------------------------------------------
template <typename T> std::string NumberToString(T V)
{
  std::string stringValue;
  std::stringstream strstream;
  strstream << V;
  strstream >> stringValue;
  return stringValue;
}

//----------------------------------------------------------------------------
std::string DoubleToString(double Value)
{
  return NumberToString<double>(Value);
}
}//end namespace

//----------------------------------------------------------------------------
void vtkMRMLAstroVolumeStorageNode::WriteXML(ostream& of, int nIndent)
{
  Superclass::WriteXML(of, nIndent);
  vtkIndent indent(nIndent);

  std::stringstream ss;
  ss << this->CenterImage;
  of << indent << " centerImage=\"" << ss.str() << "\"";
}

//----------------------------------------------------------------------------
void vtkMRMLAstroVolumeStorageNode::ReadXMLAttributes(const char** atts)
{
  int disabledModify = this->StartModify();

  Superclass::ReadXMLAttributes(atts);

  const char* attName;
  const char* attValue;
  while (*atts != NULL)
    {
    attName = *(atts++);
    attValue = *(atts++);
    if (!strcmp(attName, "centerImage"))
      {
      std::stringstream ss;
      ss << attValue;
      ss >> this->CenterImage;
      }
    }

  this->EndModify(disabledModify);
}

//----------------------------------------------------------------------------
// Copy the node's attributes to this object.
// Does NOT copy: ID, FilePrefix, Name, StorageID
void vtkMRMLAstroVolumeStorageNode::Copy(vtkMRMLNode *anode)
{
  if (!anode)
    {
    return;
    }

  int disabledModify = this->StartModify();

  Superclass::Copy(anode);
  vtkMRMLAstroVolumeStorageNode *node = (vtkMRMLAstroVolumeStorageNode *) anode;

  this->SetCenterImage(node->CenterImage);

  this->EndModify(disabledModify);
}

//----------------------------------------------------------------------------
void vtkMRMLAstroVolumeStorageNode::PrintSelf(ostream& os, vtkIndent indent)
{
  vtkMRMLStorageNode::PrintSelf(os,indent);
  os << indent << "CenterImage:   " << this->CenterImage << "\n";
}

//----------------------------------------------------------------------------
bool vtkMRMLAstroVolumeStorageNode::CanReadInReferenceNode(vtkMRMLNode *refNode)
{
  return refNode->IsA("vtkMRMLAstroVolumeNode") ||
         refNode->IsA("vtkMRMLAstroLabelMapVolumeNode");
}

//----------------------------------------------------------------------------
int vtkMRMLAstroVolumeStorageNode::ReadDataInternal(vtkMRMLNode *refNode)
{
  vtkMRMLAstroVolumeNode *volNode = NULL;
  vtkMRMLAstroLabelMapVolumeNode *labvolNode = NULL;
  vtkMRMLAstroVolumeDisplayNode *disNode = NULL;
  vtkMRMLAstroLabelMapVolumeDisplayNode *labdisNode = NULL;

  if ( refNode->IsA("vtkMRMLAstroVolumeNode") )
    {
    volNode = vtkMRMLAstroVolumeNode::SafeDownCast(refNode);
    disNode = volNode->GetAstroVolumeDisplayNode();
    }
  else if ( refNode->IsA("vtkMRMLAstroLabelMapVolumeNode") )
    {
    labvolNode = vtkMRMLAstroLabelMapVolumeNode::SafeDownCast(refNode);
    labdisNode = labvolNode->GetAstroLabelMapVolumeDisplayNode();
    }
  else
    {
    vtkErrorMacro(<< "vtkMRMLAstroVolumeStorageNode::ReadDataInternal : "
                     "Do not recognize node type " << refNode->GetClassName());
    return 0;
    }

  vtkNew<vtkFITSReader> reader;

  // Set Reader member variables
  if (this->CenterImage)
    {
    reader->SetUseNativeOriginOff();
    }
  else
    {
    reader->SetUseNativeOriginOn();
    }

  if ( refNode->IsA("vtkMRMLAstroVolumeNode") )
    {
    if (volNode->GetImageData())
      {
      volNode->SetAndObserveImageData (NULL);
      }
    }
  else if ( refNode->IsA("vtkMRMLAstroLabelMapVolumeNode") )
    {
    if (labvolNode->GetImageData())
      {
      labvolNode->SetAndObserveImageData (NULL);
      }
    }

  std::string fullName = this->GetFullNameFromFileName();

  if (fullName.empty())
    {
    vtkErrorMacro("vtkMRMLAstroVolumeStorageNode::ReadDataInternal : File name not specified");
    return 0;
    }

  reader->SetFileName(fullName.c_str());

  // Check if this is a FITS file that we can read
  if (!reader->CanReadFile(fullName.c_str()))
    {
    vtkErrorMacro("vtkMRMLAstroVolumeStorageNode::ReadDataInternal : This is not a fits file");
    return 0;
    }

  // Read the header to see if the file corresponds to the MRML Node
  reader->UpdateInformation();

  if( refNode->IsA("vtkMRMLAstroVolumeNode") || refNode->IsA("vtkMRMLAstroLabelMapVolumeNode") )
    {
    if (reader->GetPointDataType() != vtkDataSetAttributes::SCALARS &&
         reader->GetNumberOfComponents() > 1 )
      {
      vtkErrorMacro("vtkMRMLAstroVolumeStorageNode::ReadDataInternal : MRMLVolumeNode does not match file kind");
      return 0;
      }
    }

  reader->Update();

  if ( refNode->IsA("vtkMRMLAstroVolumeNode") )
    {
    // set volume attributes
    vtkMatrix4x4* mat = reader->GetRasToIjkMatrix();
    volNode->SetRASToIJKMatrix(mat);

    //set WCSstruct
    disNode->SetWCSStruct(reader->GetWCSStruct());

    // parse WCS Status
    disNode->SetWCSStatus(reader->GetWCSStatus());

    // parse non-specific key-value pairs
    std::vector<std::string> keys = reader->GetHeaderKeysVector();
    for ( std::vector<std::string>::iterator kit = keys.begin();
          kit != keys.end(); ++kit)
      {
      volNode->SetAttribute((*kit).c_str(), reader->GetHeaderValue((*kit).c_str()));
      }
    disNode->SetAttribute("SlicerAstro.NAXIS", reader->GetHeaderValue("SlicerAstro.NAXIS"));

    if (disNode->GetWCSStatus() != 0)
      {
      disNode->SetSpace("IJK");
      }

    if(!strcmp(disNode->GetWCSStruct()->ctype[2] , "FREQ"))
      {
      disNode->SetSpaceQuantity(2,"frequency");
      }

    if (!strcmp(reader->GetHeaderValue("SlicerAstro.BUNIT"), "W.U."))
      {
      volNode->SetAttribute("SlicerAstro.BUNIT", "JY/BEAM");
      vtkWarningMacro("vtkMRMLAstroVolumeStorageNode::ReadDataInternal : the flux unit of Volume "<<volNode->GetName()<<
                      " is in Westerbork Unit. It will be automatically converted in JY/BEAM"<<endl);
      }

    // rescaling flux
    if (!strcmp(reader->GetHeaderValue("SlicerAstro.BUNIT"), "W.U."))
      {
      vtkImageData *imageData = reader->GetOutput();
      int vtkType = reader->GetDataType();
      int *dims = imageData->GetDimensions();
      const int numComponents = imageData->GetNumberOfScalarComponents();
      const int numElements = dims[0] * dims[1] * dims[2] * numComponents;
      switch (vtkType)
        {
        case VTK_DOUBLE:
          double *dPixel;
          dPixel = static_cast<double*>(imageData->GetScalarPointer(0,0,0));

          if (!strcmp(reader->GetHeaderValue("SlicerAstro.BUNIT"), "W.U."))
            {
            for( int elemCnt = 0; elemCnt < numElements; elemCnt++)
              {
              *(dPixel+elemCnt) *= 0.005;
              }
            }
          break;
        case VTK_FLOAT:
          float *fPixel;
          fPixel = static_cast<float*>(imageData->GetScalarPointer(0,0,0));
          if (!strcmp(reader->GetHeaderValue("SlicerAstro.BUNIT"), "W.U."))
            {
            for( int elemCnt = 0; elemCnt < numElements; elemCnt++)
              {
              *(fPixel+elemCnt) *= 0.005;
              }
            }
          break;
        default:
          vtkErrorMacro("vtkMRMLAstroVolumeStorageNode::ReadDataInternal :"
                        "Could not get the data pointer. DataType not allowed.");
          return 0;
        }
      }
    }
  else if ( refNode->IsA("vtkMRMLAstroLabelMapVolumeNode") )
    {
    // set volume attributes
    vtkMatrix4x4* mat = reader->GetRasToIjkMatrix();
    labvolNode->SetRASToIJKMatrix(mat);
    //set WCSstruct
    labdisNode->SetWCSStruct(reader->GetWCSStruct());
    // parse WCS Status
    labdisNode->SetWCSStatus(reader->GetWCSStatus());
    // parse non-specific key-value pairs
    std::vector<std::string> keys = reader->GetHeaderKeysVector();
    for ( std::vector<std::string>::iterator kit = keys.begin();
          kit != keys.end(); ++kit)
      {
      labvolNode->SetAttribute((*kit).c_str(), reader->GetHeaderValue((*kit).c_str()));
      }
    labdisNode->SetAttribute("SlicerAstro.NAXIS", reader->GetHeaderValue("SlicerAstro.NAXIS"));

      // parse Space (WCS or IJK) to the display node
    if (labdisNode->GetWCSStatus() != 0)
      {
      labdisNode->SetSpace("IJK");
      }

    if(!strcmp(disNode->GetWCSStruct()->ctype[2] , "FREQ"))
      {
      disNode->SetSpaceQuantity(2,"frequency");
      }

    if (!strcmp(reader->GetHeaderValue("SlicerAstro.BUNIT"), ""))
      {
      labvolNode->SetAttribute("SlicerAstro.BUNIT", "");
      }
    }

  vtkNew<vtkImageChangeInformation> ici;
  ici->SetInputConnection(reader->GetOutputPort());
  ici->SetOutputSpacing( 1, 1, 1 );
  ici->SetOutputOrigin( 0, 0, 0 );
  ici->Update();

  if ( refNode->IsA("vtkMRMLAstroVolumeNode") )
    {
    volNode->SetImageDataConnection(ici->GetOutputPort());
    if(!strcmp(reader->GetHeaderValue("SlicerAstro.DATAMAX"), "0.") ||
           !strcmp(reader->GetHeaderValue("SlicerAstro.DATAMIN"), "0."))
      {
      volNode->UpdateRangeAttributes();
      }
    if (!strcmp(reader->GetHeaderValue("SlicerAstro.RMS"), "0."))
      {
      volNode->UpdateNoiseAttributes();
      }
    volNode->SetAttribute("SlicerAstro.RenderingInitialized","0");
    }
  else if ( refNode->IsA("vtkMRMLAstroLabelMapVolumeNode") )
    {
    labvolNode->SetImageDataConnection(ici->GetOutputPort());
    if(!strcmp(reader->GetHeaderValue("SlicerAstro.DATAMAX"), "0.") ||
           !strcmp(reader->GetHeaderValue("SlicerAstro.DATAMIN"), "0."))
      {
      labvolNode->UpdateRangeAttributes();
      }

    if (!strcmp(reader->GetHeaderValue("SlicerAstro.RMS"), "0."))
      {
      double noise = 1.;
      labvolNode->SetAttribute("SlicerAstro.RMS", DoubleToString(noise).c_str());
      }
    }

  return 1;
}

//----------------------------------------------------------------------------
int vtkMRMLAstroVolumeStorageNode::WriteDataInternal(vtkMRMLNode *refNode)
{
  vtkMRMLVolumeNode *volNode = NULL;

  if ( refNode->IsA("vtkMRMLAstroVolumeNode") )
    {
    volNode = vtkMRMLAstroVolumeNode::SafeDownCast(refNode);
    }
  else if ( refNode->IsA("vtkMRMLAstroLabelMapVolumeNode") )
    {
    volNode = vtkMRMLAstroLabelMapVolumeNode::SafeDownCast(refNode);
    }
  else if ( refNode->IsA("vtkMRMLVolumeNode") )
    {
    // Generic case used for any VolumeNode. Used when Extensions add
    // node types that are subclasses of VolumeNode.
    volNode = vtkMRMLVolumeNode::SafeDownCast(refNode);
    }
  else
    {
    vtkErrorMacro(<< "vtkMRMLAstroVolumeStorageNode::WriteDataInternal :"
                     " Do not recognize node type " << refNode->GetClassName());
    return 0;
    }

  if (volNode->GetImageData() == NULL)
    {
    vtkErrorMacro("vtkMRMLAstroVolumeStorageNode::WriteDataInternal :"
                  " Cannot write NULL ImageData");
    }

  std::string fullName = this->GetFullNameFromFileName();
  if (fullName == std::string(""))
    {
    vtkErrorMacro("vtkMRMLAstroVolumeStorageNode::WriteDataInternal :"
                  " File name not specified");
    return 0;
    }

  // Use here the FITS Writer
  vtkNew<vtkFITSWriter> writer;
  writer->SetFileName(fullName.c_str());
  writer->SetInputConnection(volNode->GetImageDataConnection());
  writer->SetUseCompression(0);

  // pass down all MRML attributes
  std::vector<std::string> attributeNames = volNode->GetAttributeNames();
  std::vector<std::string>::iterator ait = attributeNames.begin();
  for (; ait != attributeNames.end(); ++ait)
    {
    writer->SetAttribute((*ait), volNode->GetAttribute((*ait).c_str()));
    }

  writer->Write();
  int writeFlag = 1;
  if (writer->GetWriteError())
    {
    vtkErrorMacro("vtkMRMLAstroVolumeStorageNode::WriteDataInternal : "
                  "ERROR writing FITS file " << (writer->GetFileName() == NULL ? "null" : writer->GetFileName()));
    writeFlag = 0;
    }

  this->StageWriteData(refNode);

  return writeFlag;
}

//----------------------------------------------------------------------------
void vtkMRMLAstroVolumeStorageNode::InitializeSupportedReadFileTypes()
{
  this->SupportedReadFileTypes->InsertNextValue("FITS (.fits)");
}

//----------------------------------------------------------------------------
void vtkMRMLAstroVolumeStorageNode::InitializeSupportedWriteFileTypes()
{
  this->SupportedWriteFileTypes->InsertNextValue("FITS (.fits)");
}

//----------------------------------------------------------------------------
void vtkMRMLAstroVolumeStorageNode::ConfigureForDataExchange()
{
  this->UseCompressionOff();
}
<commit_msg>BUG: fixing Label 3rd axis string display<commit_after>/*==============================================================================

  Copyright (c) Kapteyn Astronomical Institute
  University of Groningen, Groningen, Netherlands. All Rights Reserved.

  See COPYRIGHT.txt
  or http://www.slicer.org/copyright/copyright.txt for details.

  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.

  This file was originally developed by Davide Punzo, Kapteyn Astronomical Institute,
  and was supported through the European Research Consil grant nr. 291531.

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

// MRML includes
#include <vtkMRMLAstroLabelMapVolumeDisplayNode.h>
#include <vtkMRMLAstroLabelMapVolumeNode.h>
#include <vtkMRMLAstroVolumeDisplayNode.h>
#include <vtkMRMLAstroVolumeNode.h>
#include <vtkMRMLAstroVolumeStorageNode.h>
#include <vtkMRMLScene.h>
#include <vtkMRMLVolumeNode.h>

//vtkFits includes
#include <vtkFITSReader.h>
#include <vtkFITSWriter.h>

// VTK includes
#include <vtkDataSetAttributes.h>
#include <vtkImageChangeInformation.h>
#include <vtkImageData.h>
#include <vtkNew.h>
#include <vtkObjectFactory.h>
#include <vtkType.h>

//----------------------------------------------------------------------------
vtkMRMLNodeNewMacro(vtkMRMLAstroVolumeStorageNode);

//----------------------------------------------------------------------------
vtkMRMLAstroVolumeStorageNode::vtkMRMLAstroVolumeStorageNode()
{
  this->CenterImage = 2;
  this->DefaultWriteFileExtension = "fits";
}

//----------------------------------------------------------------------------
vtkMRMLAstroVolumeStorageNode::~vtkMRMLAstroVolumeStorageNode()
{
}

namespace
{
//----------------------------------------------------------------------------
template <typename T> std::string NumberToString(T V)
{
  std::string stringValue;
  std::stringstream strstream;
  strstream << V;
  strstream >> stringValue;
  return stringValue;
}

//----------------------------------------------------------------------------
std::string DoubleToString(double Value)
{
  return NumberToString<double>(Value);
}
}//end namespace

//----------------------------------------------------------------------------
void vtkMRMLAstroVolumeStorageNode::WriteXML(ostream& of, int nIndent)
{
  Superclass::WriteXML(of, nIndent);
  vtkIndent indent(nIndent);

  std::stringstream ss;
  ss << this->CenterImage;
  of << indent << " centerImage=\"" << ss.str() << "\"";
}

//----------------------------------------------------------------------------
void vtkMRMLAstroVolumeStorageNode::ReadXMLAttributes(const char** atts)
{
  int disabledModify = this->StartModify();

  Superclass::ReadXMLAttributes(atts);

  const char* attName;
  const char* attValue;
  while (*atts != NULL)
    {
    attName = *(atts++);
    attValue = *(atts++);
    if (!strcmp(attName, "centerImage"))
      {
      std::stringstream ss;
      ss << attValue;
      ss >> this->CenterImage;
      }
    }

  this->EndModify(disabledModify);
}

//----------------------------------------------------------------------------
// Copy the node's attributes to this object.
// Does NOT copy: ID, FilePrefix, Name, StorageID
void vtkMRMLAstroVolumeStorageNode::Copy(vtkMRMLNode *anode)
{
  if (!anode)
    {
    return;
    }

  int disabledModify = this->StartModify();

  Superclass::Copy(anode);
  vtkMRMLAstroVolumeStorageNode *node = (vtkMRMLAstroVolumeStorageNode *) anode;

  this->SetCenterImage(node->CenterImage);

  this->EndModify(disabledModify);
}

//----------------------------------------------------------------------------
void vtkMRMLAstroVolumeStorageNode::PrintSelf(ostream& os, vtkIndent indent)
{
  vtkMRMLStorageNode::PrintSelf(os,indent);
  os << indent << "CenterImage:   " << this->CenterImage << "\n";
}

//----------------------------------------------------------------------------
bool vtkMRMLAstroVolumeStorageNode::CanReadInReferenceNode(vtkMRMLNode *refNode)
{
  return refNode->IsA("vtkMRMLAstroVolumeNode") ||
         refNode->IsA("vtkMRMLAstroLabelMapVolumeNode");
}

//----------------------------------------------------------------------------
int vtkMRMLAstroVolumeStorageNode::ReadDataInternal(vtkMRMLNode *refNode)
{
  vtkMRMLAstroVolumeNode *volNode = NULL;
  vtkMRMLAstroLabelMapVolumeNode *labvolNode = NULL;
  vtkMRMLAstroVolumeDisplayNode *disNode = NULL;
  vtkMRMLAstroLabelMapVolumeDisplayNode *labdisNode = NULL;

  if ( refNode->IsA("vtkMRMLAstroVolumeNode") )
    {
    volNode = vtkMRMLAstroVolumeNode::SafeDownCast(refNode);
    disNode = volNode->GetAstroVolumeDisplayNode();
    }
  else if ( refNode->IsA("vtkMRMLAstroLabelMapVolumeNode") )
    {
    labvolNode = vtkMRMLAstroLabelMapVolumeNode::SafeDownCast(refNode);
    labdisNode = labvolNode->GetAstroLabelMapVolumeDisplayNode();
    }
  else
    {
    vtkErrorMacro(<< "vtkMRMLAstroVolumeStorageNode::ReadDataInternal : "
                     "Do not recognize node type " << refNode->GetClassName());
    return 0;
    }

  vtkNew<vtkFITSReader> reader;

  // Set Reader member variables
  if (this->CenterImage)
    {
    reader->SetUseNativeOriginOff();
    }
  else
    {
    reader->SetUseNativeOriginOn();
    }

  if ( refNode->IsA("vtkMRMLAstroVolumeNode") )
    {
    if (volNode->GetImageData())
      {
      volNode->SetAndObserveImageData (NULL);
      }
    }
  else if ( refNode->IsA("vtkMRMLAstroLabelMapVolumeNode") )
    {
    if (labvolNode->GetImageData())
      {
      labvolNode->SetAndObserveImageData (NULL);
      }
    }

  std::string fullName = this->GetFullNameFromFileName();

  if (fullName.empty())
    {
    vtkErrorMacro("vtkMRMLAstroVolumeStorageNode::ReadDataInternal : File name not specified");
    return 0;
    }

  reader->SetFileName(fullName.c_str());

  // Check if this is a FITS file that we can read
  if (!reader->CanReadFile(fullName.c_str()))
    {
    vtkErrorMacro("vtkMRMLAstroVolumeStorageNode::ReadDataInternal : This is not a fits file");
    return 0;
    }

  // Read the header to see if the file corresponds to the MRML Node
  reader->UpdateInformation();

  if( refNode->IsA("vtkMRMLAstroVolumeNode") || refNode->IsA("vtkMRMLAstroLabelMapVolumeNode") )
    {
    if (reader->GetPointDataType() != vtkDataSetAttributes::SCALARS &&
         reader->GetNumberOfComponents() > 1 )
      {
      vtkErrorMacro("vtkMRMLAstroVolumeStorageNode::ReadDataInternal : MRMLVolumeNode does not match file kind");
      return 0;
      }
    }

  reader->Update();

  if ( refNode->IsA("vtkMRMLAstroVolumeNode") )
    {
    // set volume attributes
    vtkMatrix4x4* mat = reader->GetRasToIjkMatrix();
    volNode->SetRASToIJKMatrix(mat);

    //set WCSstruct
    disNode->SetWCSStruct(reader->GetWCSStruct());

    // parse WCS Status
    disNode->SetWCSStatus(reader->GetWCSStatus());

    // parse non-specific key-value pairs
    std::vector<std::string> keys = reader->GetHeaderKeysVector();
    for ( std::vector<std::string>::iterator kit = keys.begin();
          kit != keys.end(); ++kit)
      {
      volNode->SetAttribute((*kit).c_str(), reader->GetHeaderValue((*kit).c_str()));
      }
    disNode->SetAttribute("SlicerAstro.NAXIS", reader->GetHeaderValue("SlicerAstro.NAXIS"));

    if (disNode->GetWCSStatus() != 0)
      {
      disNode->SetSpace("IJK");
      }

    if(!strcmp(disNode->GetWCSStruct()->ctype[2] , "FREQ"))
      {
      disNode->SetSpaceQuantity(2,"frequency");
      }

    if (!strcmp(reader->GetHeaderValue("SlicerAstro.BUNIT"), "W.U."))
      {
      volNode->SetAttribute("SlicerAstro.BUNIT", "JY/BEAM");
      vtkWarningMacro("vtkMRMLAstroVolumeStorageNode::ReadDataInternal : the flux unit of Volume "<<volNode->GetName()<<
                      " is in Westerbork Unit. It will be automatically converted in JY/BEAM"<<endl);
      }

    // rescaling flux
    if (!strcmp(reader->GetHeaderValue("SlicerAstro.BUNIT"), "W.U."))
      {
      vtkImageData *imageData = reader->GetOutput();
      int vtkType = reader->GetDataType();
      int *dims = imageData->GetDimensions();
      const int numComponents = imageData->GetNumberOfScalarComponents();
      const int numElements = dims[0] * dims[1] * dims[2] * numComponents;
      switch (vtkType)
        {
        case VTK_DOUBLE:
          double *dPixel;
          dPixel = static_cast<double*>(imageData->GetScalarPointer(0,0,0));

          if (!strcmp(reader->GetHeaderValue("SlicerAstro.BUNIT"), "W.U."))
            {
            for( int elemCnt = 0; elemCnt < numElements; elemCnt++)
              {
              *(dPixel+elemCnt) *= 0.005;
              }
            }
          break;
        case VTK_FLOAT:
          float *fPixel;
          fPixel = static_cast<float*>(imageData->GetScalarPointer(0,0,0));
          if (!strcmp(reader->GetHeaderValue("SlicerAstro.BUNIT"), "W.U."))
            {
            for( int elemCnt = 0; elemCnt < numElements; elemCnt++)
              {
              *(fPixel+elemCnt) *= 0.005;
              }
            }
          break;
        default:
          vtkErrorMacro("vtkMRMLAstroVolumeStorageNode::ReadDataInternal :"
                        "Could not get the data pointer. DataType not allowed.");
          return 0;
        }
      }
    }
  else if ( refNode->IsA("vtkMRMLAstroLabelMapVolumeNode") )
    {
    // set volume attributes
    vtkMatrix4x4* mat = reader->GetRasToIjkMatrix();
    labvolNode->SetRASToIJKMatrix(mat);
    //set WCSstruct
    labdisNode->SetWCSStruct(reader->GetWCSStruct());
    // parse WCS Status
    labdisNode->SetWCSStatus(reader->GetWCSStatus());
    // parse non-specific key-value pairs
    std::vector<std::string> keys = reader->GetHeaderKeysVector();
    for ( std::vector<std::string>::iterator kit = keys.begin();
          kit != keys.end(); ++kit)
      {
      labvolNode->SetAttribute((*kit).c_str(), reader->GetHeaderValue((*kit).c_str()));
      }
    labdisNode->SetAttribute("SlicerAstro.NAXIS", reader->GetHeaderValue("SlicerAstro.NAXIS"));

      // parse Space (WCS or IJK) to the display node
    if (labdisNode->GetWCSStatus() != 0)
      {
      labdisNode->SetSpace("IJK");
      }

    if(!strcmp(labdisNode->GetWCSStruct()->ctype[2] , "FREQ"))
      {
      labdisNode->SetSpaceQuantity(2,"frequency");
      }

    if (!strcmp(reader->GetHeaderValue("SlicerAstro.BUNIT"), ""))
      {
      labvolNode->SetAttribute("SlicerAstro.BUNIT", "");
      }
    }

  vtkNew<vtkImageChangeInformation> ici;
  ici->SetInputConnection(reader->GetOutputPort());
  ici->SetOutputSpacing( 1, 1, 1 );
  ici->SetOutputOrigin( 0, 0, 0 );
  ici->Update();

  if ( refNode->IsA("vtkMRMLAstroVolumeNode") )
    {
    volNode->SetImageDataConnection(ici->GetOutputPort());
    if(!strcmp(reader->GetHeaderValue("SlicerAstro.DATAMAX"), "0.") ||
           !strcmp(reader->GetHeaderValue("SlicerAstro.DATAMIN"), "0."))
      {
      volNode->UpdateRangeAttributes();
      }
    if (!strcmp(reader->GetHeaderValue("SlicerAstro.RMS"), "0."))
      {
      volNode->UpdateNoiseAttributes();
      }
    volNode->SetAttribute("SlicerAstro.RenderingInitialized","0");
    }
  else if ( refNode->IsA("vtkMRMLAstroLabelMapVolumeNode") )
    {
    labvolNode->SetImageDataConnection(ici->GetOutputPort());
    if(!strcmp(reader->GetHeaderValue("SlicerAstro.DATAMAX"), "0.") ||
           !strcmp(reader->GetHeaderValue("SlicerAstro.DATAMIN"), "0."))
      {
      labvolNode->UpdateRangeAttributes();
      }

    if (!strcmp(reader->GetHeaderValue("SlicerAstro.RMS"), "0."))
      {
      double noise = 1.;
      labvolNode->SetAttribute("SlicerAstro.RMS", DoubleToString(noise).c_str());
      }
    }

  return 1;
}

//----------------------------------------------------------------------------
int vtkMRMLAstroVolumeStorageNode::WriteDataInternal(vtkMRMLNode *refNode)
{
  vtkMRMLVolumeNode *volNode = NULL;

  if ( refNode->IsA("vtkMRMLAstroVolumeNode") )
    {
    volNode = vtkMRMLAstroVolumeNode::SafeDownCast(refNode);
    }
  else if ( refNode->IsA("vtkMRMLAstroLabelMapVolumeNode") )
    {
    volNode = vtkMRMLAstroLabelMapVolumeNode::SafeDownCast(refNode);
    }
  else if ( refNode->IsA("vtkMRMLVolumeNode") )
    {
    // Generic case used for any VolumeNode. Used when Extensions add
    // node types that are subclasses of VolumeNode.
    volNode = vtkMRMLVolumeNode::SafeDownCast(refNode);
    }
  else
    {
    vtkErrorMacro(<< "vtkMRMLAstroVolumeStorageNode::WriteDataInternal :"
                     " Do not recognize node type " << refNode->GetClassName());
    return 0;
    }

  if (volNode->GetImageData() == NULL)
    {
    vtkErrorMacro("vtkMRMLAstroVolumeStorageNode::WriteDataInternal :"
                  " Cannot write NULL ImageData");
    }

  std::string fullName = this->GetFullNameFromFileName();
  if (fullName == std::string(""))
    {
    vtkErrorMacro("vtkMRMLAstroVolumeStorageNode::WriteDataInternal :"
                  " File name not specified");
    return 0;
    }

  // Use here the FITS Writer
  vtkNew<vtkFITSWriter> writer;
  writer->SetFileName(fullName.c_str());
  writer->SetInputConnection(volNode->GetImageDataConnection());
  writer->SetUseCompression(0);

  // pass down all MRML attributes
  std::vector<std::string> attributeNames = volNode->GetAttributeNames();
  std::vector<std::string>::iterator ait = attributeNames.begin();
  for (; ait != attributeNames.end(); ++ait)
    {
    writer->SetAttribute((*ait), volNode->GetAttribute((*ait).c_str()));
    }

  writer->Write();
  int writeFlag = 1;
  if (writer->GetWriteError())
    {
    vtkErrorMacro("vtkMRMLAstroVolumeStorageNode::WriteDataInternal : "
                  "ERROR writing FITS file " << (writer->GetFileName() == NULL ? "null" : writer->GetFileName()));
    writeFlag = 0;
    }

  this->StageWriteData(refNode);

  return writeFlag;
}

//----------------------------------------------------------------------------
void vtkMRMLAstroVolumeStorageNode::InitializeSupportedReadFileTypes()
{
  this->SupportedReadFileTypes->InsertNextValue("FITS (.fits)");
}

//----------------------------------------------------------------------------
void vtkMRMLAstroVolumeStorageNode::InitializeSupportedWriteFileTypes()
{
  this->SupportedWriteFileTypes->InsertNextValue("FITS (.fits)");
}

//----------------------------------------------------------------------------
void vtkMRMLAstroVolumeStorageNode::ConfigureForDataExchange()
{
  this->UseCompressionOff();
}
<|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 "chrome/browser/chromeos/volume_bubble.h"

#include <gdk/gdk.h>

#include "base/timer.h"
#include "chrome/browser/chromeos/volume_bubble_view.h"
#include "chrome/browser/views/info_bubble.h"
#include "views/widget/root_view.h"

namespace {

const int kBubbleShowTimeoutSec = 2;
const int kAnimationDurationMs = 200;

// Horizontal relative position: 0 - leftmost, 0.5 - center, 1 - rightmost.
const double kVolumeBubbleXRatio = 0.5;

// Vertical gap from the bottom of the screen in pixels.
const int kVolumeBubbleBottomGap = 30;

}  // namespace

namespace chromeos {

// Temporary helper routine. Returns currently shown Chrome widget or NULL.
// TODO(glotov): remove this in favor of enabling InfoBubble class act
// without |parent| specified. crosbug.com/4025
static views::Widget* GetToplevelWidget() {
  views::Widget* widget = NULL;
  GList *window_list = gtk_window_list_toplevels();
  for (GList* iter = window_list; iter; iter = g_list_next(iter)) {
    GtkWindow* const window = GTK_WINDOW(iter->data);
    if (window && GTK_WIDGET(window)->window ==
        gdk_screen_get_active_window(gdk_screen_get_default())) {
      views::RootView* root = views::Widget::FindRootView(window);
      if (root)
        widget = root->GetWidget();
      break;
    }
  }
  g_list_free(window_list);
  return widget;
}

VolumeBubble::VolumeBubble()
    : previous_percent_(-1),
      current_percent_(-1),
      bubble_(NULL),
      view_(NULL),
      animation_(this) {
  animation_.SetSlideDuration(kAnimationDurationMs);
  animation_.SetTweenType(Tween::LINEAR);
}

void VolumeBubble::ShowVolumeBubble(int percent) {
  if (percent < 0)
    percent = 0;
  if (percent > 100)
    percent = 100;
  if (previous_percent_ == -1)
    previous_percent_ = percent;
  current_percent_ = percent;
  if (!bubble_) {
    views::Widget* widget = GetToplevelWidget();
    if (widget == NULL)
      return;
    DCHECK(view_ == NULL);
    view_ = new VolumeBubbleView;
    view_->Init(previous_percent_);
    // Calculate position of the volume bubble.
    // TODO(glotov): Place volume bubble over the keys initiated the
    // volume change. This metric must be specific to the given
    // architecture. crosbug.com/4028
    gfx::Rect bounds;
    widget->GetBounds(&bounds, false);
    const gfx::Size view_size = view_->GetPreferredSize();
    // Note that (x, y) is the point of the center of the bubble.
    const int x = view_size.width() / 2 +
        kVolumeBubbleXRatio * (bounds.width() - view_size.width());
    const int y = bounds.height() - view_size.height() / 2 -
        kVolumeBubbleBottomGap;
    bubble_ = InfoBubble::ShowFocusless(widget, gfx::Rect(x, y, 0, 20),
                                        BubbleBorder::FLOAT, view_, this);
  } else {
    DCHECK(view_);
    timeout_timer_.Stop();
  }
  if (animation_.is_animating())
    animation_.End();
  animation_.Reset();
  animation_.Show();
  timeout_timer_.Start(base::TimeDelta::FromSeconds(kBubbleShowTimeoutSec),
                       this, &VolumeBubble::OnTimeout);
}

void VolumeBubble::OnTimeout() {
  if (bubble_)
    bubble_->Close();
}

void VolumeBubble::InfoBubbleClosing(InfoBubble* info_bubble, bool) {
  DCHECK(info_bubble == bubble_);
  timeout_timer_.Stop();
  animation_.Stop();
  bubble_ = NULL;
  view_ = NULL;
}

void VolumeBubble::AnimationEnded(const Animation* animation) {
  previous_percent_ = current_percent_;
}

void VolumeBubble::AnimationProgressed(const Animation* animation) {
  if (view_) {
    view_->Update(
        Tween::ValueBetween(animation->GetCurrentValue(),
                            previous_percent_,
                            current_percent_));
  }
}

}  // namespace chromeos
<commit_msg>chromeos: Use only normal browsers as volume bubble parents<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 "chrome/browser/chromeos/volume_bubble.h"

#include <gdk/gdk.h>

#include "base/timer.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/profile_manager.h"
#include "chrome/browser/chromeos/volume_bubble_view.h"
#include "chrome/browser/views/info_bubble.h"
#include "views/widget/root_view.h"

namespace {

const int kBubbleShowTimeoutSec = 2;
const int kAnimationDurationMs = 200;

// Horizontal relative position: 0 - leftmost, 0.5 - center, 1 - rightmost.
const double kVolumeBubbleXRatio = 0.5;

// Vertical gap from the bottom of the screen in pixels.
const int kVolumeBubbleBottomGap = 30;

}  // namespace

namespace chromeos {

// Temporary helper routine. Returns the widget from the most-recently-focused
// normal browser window or NULL.
// TODO(glotov): remove this in favor of enabling InfoBubble class act
// without |parent| specified. crosbug.com/4025
static views::Widget* GetToplevelWidget() {
  // We just use the default profile here -- this gets overridden as needed
  // in Chrome OS depending on whether the user is logged in or not.
  Browser* browser =
      BrowserList::FindBrowserWithType(
          ProfileManager::GetDefaultProfile(),
          Browser::TYPE_NORMAL,
          true);  // match_incognito
  if (!browser)
    return NULL;

  views::RootView* root =
      views::Widget::FindRootView(
          GTK_WINDOW(browser->window()->GetNativeHandle()));
  DCHECK(root);
  if (!root)
    return NULL;

  return root->GetWidget();
}

VolumeBubble::VolumeBubble()
    : previous_percent_(-1),
      current_percent_(-1),
      bubble_(NULL),
      view_(NULL),
      animation_(this) {
  animation_.SetSlideDuration(kAnimationDurationMs);
  animation_.SetTweenType(Tween::LINEAR);
}

void VolumeBubble::ShowVolumeBubble(int percent) {
  if (percent < 0)
    percent = 0;
  if (percent > 100)
    percent = 100;
  if (previous_percent_ == -1)
    previous_percent_ = percent;
  current_percent_ = percent;
  if (!bubble_) {
    views::Widget* widget = GetToplevelWidget();
    if (widget == NULL)
      return;
    DCHECK(view_ == NULL);
    view_ = new VolumeBubbleView;
    view_->Init(previous_percent_);
    // Calculate position of the volume bubble.
    // TODO(glotov): Place volume bubble over the keys initiated the
    // volume change. This metric must be specific to the given
    // architecture. crosbug.com/4028
    gfx::Rect bounds;
    widget->GetBounds(&bounds, false);
    const gfx::Size view_size = view_->GetPreferredSize();
    // Note that (x, y) is the point of the center of the bubble.
    const int x = view_size.width() / 2 +
        kVolumeBubbleXRatio * (bounds.width() - view_size.width());
    const int y = bounds.height() - view_size.height() / 2 -
        kVolumeBubbleBottomGap;
    bubble_ = InfoBubble::ShowFocusless(widget, gfx::Rect(x, y, 0, 20),
                                        BubbleBorder::FLOAT, view_, this);
  } else {
    DCHECK(view_);
    timeout_timer_.Stop();
  }
  if (animation_.is_animating())
    animation_.End();
  animation_.Reset();
  animation_.Show();
  timeout_timer_.Start(base::TimeDelta::FromSeconds(kBubbleShowTimeoutSec),
                       this, &VolumeBubble::OnTimeout);
}

void VolumeBubble::OnTimeout() {
  if (bubble_)
    bubble_->Close();
}

void VolumeBubble::InfoBubbleClosing(InfoBubble* info_bubble, bool) {
  DCHECK(info_bubble == bubble_);
  timeout_timer_.Stop();
  animation_.Stop();
  bubble_ = NULL;
  view_ = NULL;
}

void VolumeBubble::AnimationEnded(const Animation* animation) {
  previous_percent_ = current_percent_;
}

void VolumeBubble::AnimationProgressed(const Animation* animation) {
  if (view_) {
    view_->Update(
        Tween::ValueBetween(animation->GetCurrentValue(),
                            previous_percent_,
                            current_percent_));
  }
}

}  // namespace chromeos
<|endoftext|>


<commit_before>
#include "type_info.hpp"
#include "objectmemory.hpp"
#include "gen/includes.hpp"
#include "builtin/fixnum.hpp"
#include "builtin/symbol.hpp"

namespace rubinius {

  TypeInfo::~TypeInfo() { }

  TypeInfo::TypeInfo(object_type type) : type(type) {
    state = NULL;
  }

  void TypeInfo::cleanup(OBJECT obj) { }

  void TypeInfo::set_field(STATE, OBJECT target, size_t index, OBJECT val) {
    throw std::runtime_error("field access denied");
  }

  OBJECT TypeInfo::get_field(STATE, OBJECT target, size_t index) {
    throw std::runtime_error("unable to access field");
  }

  /* By default, just call auto_mark(). This exists so that
   * other types can overload this to perform work before or
   * after auto_marking is done. */
  void TypeInfo::mark(OBJECT obj, ObjectMark& mark) {
    auto_mark(obj, mark);
  }

  /* For each type, there is an automatically generated version
   * of this function (called via virtual dispatch) that marks
   * all slots. */
  void TypeInfo::auto_mark(OBJECT, ObjectMark& mark) {
    throw std::runtime_error("unable to mark object");
  }

  void TypeInfo::show(STATE, OBJECT self) {
    if(FIXNUM i = try_as<Fixnum>(self)) {
      std::cout << i->to_native() << std::endl;
    } else if(Bignum* b = try_as<Bignum>(self)) {
      std::cout << *b->to_s(state, Fixnum::from(10)) << std::endl;
    } else if(Float* f = try_as<Float>(self)) {
      std::cout << f->val << std::endl;
    } else if(String* str = try_as<String>(self)) {
      std::cout << *str << std::endl;
    } else if(SYMBOL sym = try_as<Symbol>(self)) {
      std::cout << ":" << *sym->to_str(state) << std::endl;
    } else {
      inspect(state, self);
    }
  }
#include "gen/typechecks.gen.cpp"

  /* For use in gdb. */
  extern "C" {
    /* A wrapper because gdb can't do virtual dispatch. */
    void __show__(STATE, OBJECT obj) {
      obj->show(state);
    }
  }
}
<commit_msg>Hook up some garbage collector stuff for Object's TypeInfo<commit_after>
#include "type_info.hpp"
#include "objectmemory.hpp"
#include "gen/includes.hpp"
#include "builtin/fixnum.hpp"
#include "builtin/symbol.hpp"

namespace rubinius {

  TypeInfo::~TypeInfo() { }

  TypeInfo::TypeInfo(object_type type) : type(type) {
    state = NULL;
  }

  void TypeInfo::cleanup(OBJECT obj) { }

  void TypeInfo::set_field(STATE, OBJECT target, size_t index, OBJECT val) {
    throw std::runtime_error("field access denied");
  }

  OBJECT TypeInfo::get_field(STATE, OBJECT target, size_t index) {
    throw std::runtime_error("unable to access field");
  }

  /* By default, just call auto_mark(). This exists so that
   * other types can overload this to perform work before or
   * after auto_marking is done. */
  void TypeInfo::mark(OBJECT obj, ObjectMark& mark) {
    auto_mark(obj, mark);
  }

  /* For each type, there is an automatically generated version
   * of this function (called via virtual dispatch) that marks
   * all slots. */
  void TypeInfo::auto_mark(OBJECT obj, ObjectMark& mark) {
    for(size_t i = 0; i < obj->field_count; i++) {
      Object* slot = obj->field[i];
      if(slot->reference_p()) {
        OBJECT res = mark.call(slot);
        if(res) {
          obj->field[i] = as<Object>(res);
          mark.just_set(obj, res);
        }
      }
    }
  }

  void TypeInfo::show(STATE, OBJECT self) {
    if(FIXNUM i = try_as<Fixnum>(self)) {
      std::cout << i->to_native() << std::endl;
    } else if(Bignum* b = try_as<Bignum>(self)) {
      std::cout << *b->to_s(state, Fixnum::from(10)) << std::endl;
    } else if(Float* f = try_as<Float>(self)) {
      std::cout << f->val << std::endl;
    } else if(String* str = try_as<String>(self)) {
      std::cout << *str << std::endl;
    } else if(SYMBOL sym = try_as<Symbol>(self)) {
      std::cout << ":" << *sym->to_str(state) << std::endl;
    } else {
      inspect(state, self);
    }
  }
#include "gen/typechecks.gen.cpp"

  /* For use in gdb. */
  extern "C" {
    /* A wrapper because gdb can't do virtual dispatch. */
    void __show__(STATE, OBJECT obj) {
      obj->show(state);
    }
  }
}
<|endoftext|>


<commit_before>#if defined(__GNUG__) && __GNUG__ < 3
#define _XOPEN_SOURCE
#endif

#include "datetime.h"
#include "error.h"

#include <ctime>
#include <cctype>

namespace ledger {

std::time_t         now	      = std::time(NULL);
int                 now_year  = std::localtime(&now)->tm_year;

static std::time_t  base      = -1;
static int	    base_year = -1;

static const int    month_days[12] = {
  31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};

char input_format[128];

const char * formats[] = {
  "%Y/%m/%d",
  "%m/%d",
  "%Y.%m.%d",
  "%m.%d",
  "%Y-%m-%d",
  "%m-%d",
  "%a",
  "%A",
  "%b",
  "%B",
  "%Y",
  NULL
};

std::time_t interval_t::first(const std::time_t moment) const
{
  std::time_t quant = begin;

  if (moment && std::difftime(moment, quant) > 0) {
    // Find an efficient starting point for the upcoming while loop.
    // We want a date early enough that the range will be correct, but
    // late enough that we don't spend hundreds of thousands of loops
    // skipping through time.

    struct std::tm * desc = std::localtime(&moment);
    if (years)
      desc->tm_mon = 0;
    desc->tm_mday = 1;
    desc->tm_hour = 0;
    desc->tm_min  = 0;
    desc->tm_sec  = 0;
    quant = std::mktime(desc);

    std::time_t temp;
    while (std::difftime(moment, temp = increment(quant)) >= 0) {
      if (quant == temp)
	break;
      quant = temp;
    }
  }

  return quant;
}

std::time_t interval_t::increment(const std::time_t moment) const
{
  std::time_t then = moment;

  if (years || months) {
    struct std::tm * desc = std::localtime(&then);

    if (years)
      desc->tm_year += years;

    if (months) {
      desc->tm_mon += months;

      if (desc->tm_mon > 11) {
	desc->tm_year++;
	desc->tm_mon -= 12;
      }
      else if (desc->tm_mon < 0) {
	desc->tm_year--;
	desc->tm_mon += 12;
      }
    }

    desc->tm_hour = 0;
    desc->tm_min  = 0;
    desc->tm_sec  = 0;

    then = std::mktime(desc);
  }

  return then + seconds;
}

static void parse_inclusion_specifier(const std::string& word,
				      std::time_t *	 begin,
				      std::time_t *	 end)
{
  struct std::tm when;

  if (! parse_date_mask(word.c_str(), &when))
    throw interval_expr_error(std::string("Could not parse date mask: ") +
			      word);

  when.tm_hour = 0;
  when.tm_min  = 0;
  when.tm_sec  = 0;

  bool saw_year = true;
  bool saw_mon  = true;

  if (when.tm_year == -1) {
    when.tm_year = now_year;
    saw_year = false;
  }
  if (when.tm_mon == -1) {
    when.tm_mon = 0;
    saw_mon = false;
  } else {
    saw_year = false;		// don't increment by year if month used
  }
  if (when.tm_mday == -1)
    when.tm_mday = 1;

  if (begin) {
    *begin = std::mktime(&when);
    if (end)
      *end = interval_t(0, saw_mon ? 1 : 0, saw_year ? 1 : 0).increment(*begin);
  }
  else if (end) {
    *end = std::mktime(&when);
  }
}

static inline void read_lower_word(std::istream& in, std::string& word) {
  in >> word;
  for (int i = 0, l = word.length(); i < l; i++)
    word[i] = std::tolower(word[i]);
}

static void parse_date_words(std::istream& in, std::string& word,
			     std::time_t * begin, std::time_t * end)
{
  std::string type;
  bool	      mon_spec = false;
  char	      buf[32];

  if (word == "this" || word == "last" || word == "next") {
    type = word;
    if (! in.eof())
      read_lower_word(in, word);
    else
      word = "month";
  } else {
    type = "this";
  }

  if (word == "month") {
    std::strftime(buf, 31, "%B", std::localtime(&now));
    word = buf;
    mon_spec = true;
  }
  else if (word == "year") {
    std::strftime(buf, 31, "%Y", std::localtime(&now));
    word = buf;
  }

  parse_inclusion_specifier(word, begin, end);

  if (type == "last") {
    if (mon_spec) {
      if (begin)
	*begin = interval_t(0, -1, 0).increment(*begin);
      if (end)
	*end   = interval_t(0, -1, 0).increment(*end);
    } else {
      if (begin)
	*begin = interval_t(0, 0, -1).increment(*begin);
      if (end)
	*end   = interval_t(0, 0, -1).increment(*end);
    }
  }
  else if (type == "next") {
    if (mon_spec) {
      if (begin)
	*begin = interval_t(0, 1, 0).increment(*begin);
      if (end)
	*end   = interval_t(0, 1, 0).increment(*end);
    } else {
      if (begin)
	*begin = interval_t(0, 0, 1).increment(*begin);
      if (end)
	*end   = interval_t(0, 0, 1).increment(*end);
    }
  }
}

void interval_t::parse(std::istream& in)
{
  std::string word;

  while (! in.eof()) {
    read_lower_word(in, word);
    if (word == "every") {
      read_lower_word(in, word);
      if (std::isdigit(word[0])) {
	int quantity = std::atol(word.c_str());
	read_lower_word(in, word);
	if (word == "days")
	  seconds = 86400 * quantity;
	else if (word == "weeks")
	  seconds = 7 * 86400 * quantity;
	else if (word == "months")
	  months = quantity;
	else if (word == "quarters")
	  months = 3 * quantity;
	else if (word == "years")
	  years = quantity;
      }
      else if (word == "day")
	seconds = 86400;
      else if (word == "week")
	seconds = 7 * 86400;
      else if (word == "monthly")
	months = 1;
      else if (word == "quarter")
	months = 3;
      else if (word == "year")
	years = 1;
    }
    else if (word == "daily")
      seconds = 86400;
    else if (word == "weekly")
      seconds = 7 * 86400;
    else if (word == "biweekly")
      seconds = 14 * 86400;
    else if (word == "monthly")
      months = 1;
    else if (word == "bimonthly")
      months = 2;
    else if (word == "quarterly")
      months = 3;
    else if (word == "yearly")
      years = 1;
    else if (word == "this" || word == "last" || word == "next") {
      parse_date_words(in, word, &begin, &end);
    }
    else if (word == "in") {
      read_lower_word(in, word);
      parse_date_words(in, word, &begin, &end);
    }
    else if (word == "from" || word == "since") {
      read_lower_word(in, word);
      parse_date_words(in, word, &begin, NULL);
    }
    else if (word == "to" || word == "until") {
      read_lower_word(in, word);
      parse_date_words(in, word, NULL, &end);
    }
    else {
      parse_inclusion_specifier(word, &begin, &end);
    }
  }
}

bool parse_date_mask(const char * date_str, struct std::tm * result)
{
  for (const char ** f = formats; *f; f++) {
    memset(result, INT_MAX, sizeof(struct std::tm));
    if (strptime(date_str, *f, result))
      return true;
  }
  return false;
}

bool parse_date(const char * date_str, std::time_t * result, const int year)
{
  struct std::tm when;

  if (! parse_date_mask(date_str, &when))
    return false;

  when.tm_hour = 0;
  when.tm_min  = 0;
  when.tm_sec  = 0;

  if (when.tm_year == -1)
    when.tm_year = ((year == -1) ? now_year : (year - 1900));

  if (when.tm_mon == -1)
    when.tm_mon = 0;

  if (when.tm_mday == -1)
    when.tm_mday = 1;

  *result = std::mktime(&when);

  return true;
}

bool quick_parse_date(const char * date_str, std::time_t * result)
{
#if 1
  return parse_date(date_str, result, now_year + 1900);
#else
  int year = -1, month = -1, day, num = 0;

  for (const char * p = date_str; *p; p++) {
    if (*p == '/' || *p == '-' || *p == '.') {
      if (year == -1)
	year = num;
      else
	month = num;
      num = 0;
    }
    else if (*p < '0' || *p > '9') {
      return false;
    }
    else {
      num *= 10;
      num += *p - '0';
    }
  }

  day = num;

  if (month == -1) {
    month = year;
    year  = now_year + 1900;
  }

  if (base == -1 || year != base_year) {
    struct std::tm when;
    std::memset(&when, 0, sizeof(when));

    base_year    = year == -1 ? now_year + 1900 : year;
    when.tm_year = year == -1 ? now_year : year - 1900;
    when.tm_mday = 1;

    base = std::mktime(&when);
    year = base_year;
  }

  *result = base;

  --month;
  while (--month >= 0) {
    *result += month_days[month] * 24 * 60 * 60;
    if (month == 1 && year % 4 == 0 && year != 2000) // february in leap years
      *result += 24 * 60 * 60;
  }

  if (--day)
    *result += day * 24 * 60 * 60;

  return true;
#endif
}

} // namespace ledger

#ifdef USE_BOOST_PYTHON

#include <boost/python.hpp>

using namespace boost::python;
using namespace ledger;

unsigned int interval_len(interval_t& interval)
{
  int periods = 1;
  std::time_t when = interval.first();
  while (interval.end && when < interval.end) {
    when = interval.increment(when);
    if (when < interval.end)
      periods++;
  }
  return periods;
}

std::time_t interval_getitem(interval_t& interval, int i)
{
  static std::time_t last_index = 0;
  static std::time_t last_moment = 0;

  if (i == 0) {
    last_index = 0;
    last_moment = interval.first();
  }
  else {
    last_moment = interval.increment(last_moment);
    if (interval.end && last_moment >= interval.end) {
      PyErr_SetString(PyExc_IndexError, "Index out of range");
      throw_error_already_set();
    }
  }
  return last_moment;
}

std::time_t py_parse_date(const char * date_str)
{
  std::time_t temp;
  if (parse_date(date_str, &temp))
    return temp;
  return 0;
}

std::time_t py_parse_date_yr(const char * date_str, const int year)
{
  std::time_t temp;
  if (parse_date(date_str, &temp, year))
    return temp;
  return 0;
}

void export_datetime()
{
  class_< interval_t >
    ("Interval", init<optional<int, int, int, std::time_t, std::time_t> >())
    .def(init<std::string>())
    .def(! self)

    .def_readwrite("years", &interval_t::years)
    .def_readwrite("months", &interval_t::months)
    .def_readwrite("seconds", &interval_t::seconds)
    .def_readwrite("begin", &interval_t::begin)
    .def_readwrite("end", &interval_t::end)

    .def("__len__", interval_len)
    .def("__getitem__", interval_getitem)

    .def("increment", &interval_t::increment)
    ;

  def("parse_date", py_parse_date);
  def("parse_date", py_parse_date_yr);
}

#endif // USE_BOOST_PYTHON
<commit_msg>(parse_inclusion_specifier): When a specific day is given as a date specifier, set the end of the "range" to be the beginning of the next day, rather than the beginning of the next month.<commit_after>#if defined(__GNUG__) && __GNUG__ < 3
#define _XOPEN_SOURCE
#endif

#include "datetime.h"
#include "error.h"

#include <ctime>
#include <cctype>

namespace ledger {

std::time_t         now	      = std::time(NULL);
int                 now_year  = std::localtime(&now)->tm_year;

static std::time_t  base      = -1;
static int	    base_year = -1;

static const int    month_days[12] = {
  31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};

char input_format[128];

const char * formats[] = {
  "%Y/%m/%d",
  "%m/%d",
  "%Y.%m.%d",
  "%m.%d",
  "%Y-%m-%d",
  "%m-%d",
  "%a",
  "%A",
  "%b",
  "%B",
  "%Y",
  NULL
};

std::time_t interval_t::first(const std::time_t moment) const
{
  std::time_t quant = begin;

  if (moment && std::difftime(moment, quant) > 0) {
    // Find an efficient starting point for the upcoming while loop.
    // We want a date early enough that the range will be correct, but
    // late enough that we don't spend hundreds of thousands of loops
    // skipping through time.

    struct std::tm * desc = std::localtime(&moment);
    if (years)
      desc->tm_mon = 0;
    desc->tm_mday = 1;
    desc->tm_hour = 0;
    desc->tm_min  = 0;
    desc->tm_sec  = 0;
    quant = std::mktime(desc);

    std::time_t temp;
    while (std::difftime(moment, temp = increment(quant)) >= 0) {
      if (quant == temp)
	break;
      quant = temp;
    }
  }

  return quant;
}

std::time_t interval_t::increment(const std::time_t moment) const
{
  std::time_t then = moment;

  if (years || months) {
    struct std::tm * desc = std::localtime(&then);

    if (years)
      desc->tm_year += years;

    if (months) {
      desc->tm_mon += months;

      if (desc->tm_mon > 11) {
	desc->tm_year++;
	desc->tm_mon -= 12;
      }
      else if (desc->tm_mon < 0) {
	desc->tm_year--;
	desc->tm_mon += 12;
      }
    }

    desc->tm_hour = 0;
    desc->tm_min  = 0;
    desc->tm_sec  = 0;

    then = std::mktime(desc);
  }

  return then + seconds;
}

static void parse_inclusion_specifier(const std::string& word,
				      std::time_t *	 begin,
				      std::time_t *	 end)
{
  struct std::tm when;

  if (! parse_date_mask(word.c_str(), &when))
    throw interval_expr_error(std::string("Could not parse date mask: ") +
			      word);

  when.tm_hour = 0;
  when.tm_min  = 0;
  when.tm_sec  = 0;

  bool saw_year = true;
  bool saw_mon  = true;
  bool saw_day  = true;

  if (when.tm_year == -1) {
    when.tm_year = now_year;
    saw_year = false;
  }
  if (when.tm_mon == -1) {
    when.tm_mon = 0;
    saw_mon = false;
  } else {
    saw_year = false;		// don't increment by year if month used
  }
  if (when.tm_mday == -1) {
    when.tm_mday = 1;
    saw_day = false;
  } else {
    saw_mon = false;		// don't increment by month if day used
    saw_year = false;		// don't increment by year if day used
  }

  if (begin) {
    *begin = std::mktime(&when);
    if (end)
      *end = interval_t(saw_day ? 86400 : 0, saw_mon ? 1 : 0,
			saw_year ? 1 : 0).increment(*begin);
  }
  else if (end) {
    *end = std::mktime(&when);
  }
}

static inline void read_lower_word(std::istream& in, std::string& word) {
  in >> word;
  for (int i = 0, l = word.length(); i < l; i++)
    word[i] = std::tolower(word[i]);
}

static void parse_date_words(std::istream& in, std::string& word,
			     std::time_t * begin, std::time_t * end)
{
  std::string type;
  bool	      mon_spec = false;
  char	      buf[32];

  if (word == "this" || word == "last" || word == "next") {
    type = word;
    if (! in.eof())
      read_lower_word(in, word);
    else
      word = "month";
  } else {
    type = "this";
  }

  if (word == "month") {
    std::strftime(buf, 31, "%B", std::localtime(&now));
    word = buf;
    mon_spec = true;
  }
  else if (word == "year") {
    std::strftime(buf, 31, "%Y", std::localtime(&now));
    word = buf;
  }

  parse_inclusion_specifier(word, begin, end);

  if (type == "last") {
    if (mon_spec) {
      if (begin)
	*begin = interval_t(0, -1, 0).increment(*begin);
      if (end)
	*end   = interval_t(0, -1, 0).increment(*end);
    } else {
      if (begin)
	*begin = interval_t(0, 0, -1).increment(*begin);
      if (end)
	*end   = interval_t(0, 0, -1).increment(*end);
    }
  }
  else if (type == "next") {
    if (mon_spec) {
      if (begin)
	*begin = interval_t(0, 1, 0).increment(*begin);
      if (end)
	*end   = interval_t(0, 1, 0).increment(*end);
    } else {
      if (begin)
	*begin = interval_t(0, 0, 1).increment(*begin);
      if (end)
	*end   = interval_t(0, 0, 1).increment(*end);
    }
  }
}

void interval_t::parse(std::istream& in)
{
  std::string word;

  while (! in.eof()) {
    read_lower_word(in, word);
    if (word == "every") {
      read_lower_word(in, word);
      if (std::isdigit(word[0])) {
	int quantity = std::atol(word.c_str());
	read_lower_word(in, word);
	if (word == "days")
	  seconds = 86400 * quantity;
	else if (word == "weeks")
	  seconds = 7 * 86400 * quantity;
	else if (word == "months")
	  months = quantity;
	else if (word == "quarters")
	  months = 3 * quantity;
	else if (word == "years")
	  years = quantity;
      }
      else if (word == "day")
	seconds = 86400;
      else if (word == "week")
	seconds = 7 * 86400;
      else if (word == "monthly")
	months = 1;
      else if (word == "quarter")
	months = 3;
      else if (word == "year")
	years = 1;
    }
    else if (word == "daily")
      seconds = 86400;
    else if (word == "weekly")
      seconds = 7 * 86400;
    else if (word == "biweekly")
      seconds = 14 * 86400;
    else if (word == "monthly")
      months = 1;
    else if (word == "bimonthly")
      months = 2;
    else if (word == "quarterly")
      months = 3;
    else if (word == "yearly")
      years = 1;
    else if (word == "this" || word == "last" || word == "next") {
      parse_date_words(in, word, &begin, &end);
    }
    else if (word == "in") {
      read_lower_word(in, word);
      parse_date_words(in, word, &begin, &end);
    }
    else if (word == "from" || word == "since") {
      read_lower_word(in, word);
      parse_date_words(in, word, &begin, NULL);
    }
    else if (word == "to" || word == "until") {
      read_lower_word(in, word);
      parse_date_words(in, word, NULL, &end);
    }
    else {
      parse_inclusion_specifier(word, &begin, &end);
    }
  }
}

bool parse_date_mask(const char * date_str, struct std::tm * result)
{
  for (const char ** f = formats; *f; f++) {
    memset(result, INT_MAX, sizeof(struct std::tm));
    if (strptime(date_str, *f, result))
      return true;
  }
  return false;
}

bool parse_date(const char * date_str, std::time_t * result, const int year)
{
  struct std::tm when;

  if (! parse_date_mask(date_str, &when))
    return false;

  when.tm_hour = 0;
  when.tm_min  = 0;
  when.tm_sec  = 0;

  if (when.tm_year == -1)
    when.tm_year = ((year == -1) ? now_year : (year - 1900));

  if (when.tm_mon == -1)
    when.tm_mon = 0;

  if (when.tm_mday == -1)
    when.tm_mday = 1;

  *result = std::mktime(&when);

  return true;
}

bool quick_parse_date(const char * date_str, std::time_t * result)
{
#if 1
  return parse_date(date_str, result, now_year + 1900);
#else
  int year = -1, month = -1, day, num = 0;

  for (const char * p = date_str; *p; p++) {
    if (*p == '/' || *p == '-' || *p == '.') {
      if (year == -1)
	year = num;
      else
	month = num;
      num = 0;
    }
    else if (*p < '0' || *p > '9') {
      return false;
    }
    else {
      num *= 10;
      num += *p - '0';
    }
  }

  day = num;

  if (month == -1) {
    month = year;
    year  = now_year + 1900;
  }

  if (base == -1 || year != base_year) {
    struct std::tm when;
    std::memset(&when, 0, sizeof(when));

    base_year    = year == -1 ? now_year + 1900 : year;
    when.tm_year = year == -1 ? now_year : year - 1900;
    when.tm_mday = 1;

    base = std::mktime(&when);
    year = base_year;
  }

  *result = base;

  --month;
  while (--month >= 0) {
    *result += month_days[month] * 24 * 60 * 60;
    if (month == 1 && year % 4 == 0 && year != 2000) // february in leap years
      *result += 24 * 60 * 60;
  }

  if (--day)
    *result += day * 24 * 60 * 60;

  return true;
#endif
}

} // namespace ledger

#ifdef USE_BOOST_PYTHON

#include <boost/python.hpp>

using namespace boost::python;
using namespace ledger;

unsigned int interval_len(interval_t& interval)
{
  int periods = 1;
  std::time_t when = interval.first();
  while (interval.end && when < interval.end) {
    when = interval.increment(when);
    if (when < interval.end)
      periods++;
  }
  return periods;
}

std::time_t interval_getitem(interval_t& interval, int i)
{
  static std::time_t last_index = 0;
  static std::time_t last_moment = 0;

  if (i == 0) {
    last_index = 0;
    last_moment = interval.first();
  }
  else {
    last_moment = interval.increment(last_moment);
    if (interval.end && last_moment >= interval.end) {
      PyErr_SetString(PyExc_IndexError, "Index out of range");
      throw_error_already_set();
    }
  }
  return last_moment;
}

std::time_t py_parse_date(const char * date_str)
{
  std::time_t temp;
  if (parse_date(date_str, &temp))
    return temp;
  return 0;
}

std::time_t py_parse_date_yr(const char * date_str, const int year)
{
  std::time_t temp;
  if (parse_date(date_str, &temp, year))
    return temp;
  return 0;
}

void export_datetime()
{
  class_< interval_t >
    ("Interval", init<optional<int, int, int, std::time_t, std::time_t> >())
    .def(init<std::string>())
    .def(! self)

    .def_readwrite("years", &interval_t::years)
    .def_readwrite("months", &interval_t::months)
    .def_readwrite("seconds", &interval_t::seconds)
    .def_readwrite("begin", &interval_t::begin)
    .def_readwrite("end", &interval_t::end)

    .def("__len__", interval_len)
    .def("__getitem__", interval_getitem)

    .def("increment", &interval_t::increment)
    ;

  def("parse_date", py_parse_date);
  def("parse_date", py_parse_date_yr);
}

#endif // USE_BOOST_PYTHON
<|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 "chrome/browser/chromeos/volume_bubble.h"

#include <gdk/gdk.h>

#include "base/timer.h"
#include "chrome/browser/chromeos/volume_bubble_view.h"
#include "chrome/browser/views/info_bubble.h"
#include "views/widget/root_view.h"

namespace {

const int kBubbleShowTimeoutSec = 2;
const int kAnimationDurationMs = 200;

// Horizontal relative position: 0 - leftmost, 0.5 - center, 1 - rightmost.
const double kVolumeBubbleXRatio = 0.18;

// Vertical gap from the bottom of the screen in pixels.
const int kVolumeBubbleBottomGap = 30;

}  // namespace

namespace chromeos {

// Temporary helper routine. Returns currently shown Chrome widget or NULL.
// TODO(glotov): remove this in favor of enabling InfoBubble class act
// without |parent| specified. crosbug.com/4025
static views::Widget* GetToplevelWidget() {
  views::Widget* widget = NULL;
  GList *window_list = gtk_window_list_toplevels();
  for (GList* iter = window_list; iter; iter = g_list_next(iter)) {
    GtkWindow* const window = GTK_WINDOW(iter->data);
    if (window && GTK_WIDGET(window)->window ==
        gdk_screen_get_active_window(gdk_screen_get_default())) {
      views::RootView* root = views::Widget::FindRootView(window);
      if (root)
        widget = root->GetWidget();
      break;
    }
  }
  g_list_free(window_list);
  return widget;
}

VolumeBubble::VolumeBubble()
    : previous_percent_(-1),
      current_percent_(-1),
      bubble_(NULL),
      view_(NULL),
      animation_(this) {
  animation_.SetSlideDuration(kAnimationDurationMs);
  animation_.SetTweenType(Tween::LINEAR);
}

void VolumeBubble::ShowVolumeBubble(int percent) {
  if (percent < 0)
    percent = 0;
  if (percent > 100)
    percent = 100;
  if (previous_percent_ == -1)
    previous_percent_ = percent;
  current_percent_ = percent;
  if (!bubble_) {
    views::Widget* widget = GetToplevelWidget();
    if (widget == NULL)
      return;
    DCHECK(view_ == NULL);
    view_ = new VolumeBubbleView;
    view_->Init(previous_percent_);
    // Calculate position of the volume bubble.
    // TODO(glotov): Place volume bubble over the keys initiated the
    // volume change. This metric must be specific to the given
    // architecture. crosbug.com/4028
    gfx::Rect bounds;
    widget->GetBounds(&bounds, false);
    const gfx::Size view_size = view_->GetPreferredSize();
    // Note that (x, y) is the point of the center of the bubble.
    const int x = view_size.width() / 2 +
        kVolumeBubbleXRatio * (bounds.width() - view_size.width());
    const int y = bounds.height() - view_size.height() / 2 -
        kVolumeBubbleBottomGap;
    bubble_ = InfoBubble::ShowFocusless(widget, gfx::Rect(x, y, 0, 20),
                                        BubbleBorder::FLOAT, view_, this);
  } else {
    DCHECK(view_);
    timeout_timer_.Stop();
  }
  if (animation_.is_animating())
    animation_.End();
  animation_.Reset();
  animation_.Show();
  timeout_timer_.Start(base::TimeDelta::FromSeconds(kBubbleShowTimeoutSec),
                       this, &VolumeBubble::OnTimeout);
}

void VolumeBubble::OnTimeout() {
  if (bubble_)
    bubble_->Close();
}

void VolumeBubble::InfoBubbleClosing(InfoBubble* info_bubble, bool) {
  DCHECK(info_bubble == bubble_);
  timeout_timer_.Stop();
  animation_.Stop();
  bubble_ = NULL;
  view_ = NULL;
}

void VolumeBubble::AnimationEnded(const Animation* animation) {
  previous_percent_ = current_percent_;
}

void VolumeBubble::AnimationProgressed(const Animation* animation) {
  if (view_) {
    view_->Update(
        Tween::ValueBetween(animation->GetCurrentValue(),
                            previous_percent_,
                            current_percent_));
  }
}

}  // namespace chromeos
<commit_msg>Volume bubble horizontally centered. BUG=chromium-os:5176 TEST=Volume bubble should appear horizontally centered.<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 "chrome/browser/chromeos/volume_bubble.h"

#include <gdk/gdk.h>

#include "base/timer.h"
#include "chrome/browser/chromeos/volume_bubble_view.h"
#include "chrome/browser/views/info_bubble.h"
#include "views/widget/root_view.h"

namespace {

const int kBubbleShowTimeoutSec = 2;
const int kAnimationDurationMs = 200;

// Horizontal relative position: 0 - leftmost, 0.5 - center, 1 - rightmost.
const double kVolumeBubbleXRatio = 0.5;

// Vertical gap from the bottom of the screen in pixels.
const int kVolumeBubbleBottomGap = 30;

}  // namespace

namespace chromeos {

// Temporary helper routine. Returns currently shown Chrome widget or NULL.
// TODO(glotov): remove this in favor of enabling InfoBubble class act
// without |parent| specified. crosbug.com/4025
static views::Widget* GetToplevelWidget() {
  views::Widget* widget = NULL;
  GList *window_list = gtk_window_list_toplevels();
  for (GList* iter = window_list; iter; iter = g_list_next(iter)) {
    GtkWindow* const window = GTK_WINDOW(iter->data);
    if (window && GTK_WIDGET(window)->window ==
        gdk_screen_get_active_window(gdk_screen_get_default())) {
      views::RootView* root = views::Widget::FindRootView(window);
      if (root)
        widget = root->GetWidget();
      break;
    }
  }
  g_list_free(window_list);
  return widget;
}

VolumeBubble::VolumeBubble()
    : previous_percent_(-1),
      current_percent_(-1),
      bubble_(NULL),
      view_(NULL),
      animation_(this) {
  animation_.SetSlideDuration(kAnimationDurationMs);
  animation_.SetTweenType(Tween::LINEAR);
}

void VolumeBubble::ShowVolumeBubble(int percent) {
  if (percent < 0)
    percent = 0;
  if (percent > 100)
    percent = 100;
  if (previous_percent_ == -1)
    previous_percent_ = percent;
  current_percent_ = percent;
  if (!bubble_) {
    views::Widget* widget = GetToplevelWidget();
    if (widget == NULL)
      return;
    DCHECK(view_ == NULL);
    view_ = new VolumeBubbleView;
    view_->Init(previous_percent_);
    // Calculate position of the volume bubble.
    // TODO(glotov): Place volume bubble over the keys initiated the
    // volume change. This metric must be specific to the given
    // architecture. crosbug.com/4028
    gfx::Rect bounds;
    widget->GetBounds(&bounds, false);
    const gfx::Size view_size = view_->GetPreferredSize();
    // Note that (x, y) is the point of the center of the bubble.
    const int x = view_size.width() / 2 +
        kVolumeBubbleXRatio * (bounds.width() - view_size.width());
    const int y = bounds.height() - view_size.height() / 2 -
        kVolumeBubbleBottomGap;
    bubble_ = InfoBubble::ShowFocusless(widget, gfx::Rect(x, y, 0, 20),
                                        BubbleBorder::FLOAT, view_, this);
  } else {
    DCHECK(view_);
    timeout_timer_.Stop();
  }
  if (animation_.is_animating())
    animation_.End();
  animation_.Reset();
  animation_.Show();
  timeout_timer_.Start(base::TimeDelta::FromSeconds(kBubbleShowTimeoutSec),
                       this, &VolumeBubble::OnTimeout);
}

void VolumeBubble::OnTimeout() {
  if (bubble_)
    bubble_->Close();
}

void VolumeBubble::InfoBubbleClosing(InfoBubble* info_bubble, bool) {
  DCHECK(info_bubble == bubble_);
  timeout_timer_.Stop();
  animation_.Stop();
  bubble_ = NULL;
  view_ = NULL;
}

void VolumeBubble::AnimationEnded(const Animation* animation) {
  previous_percent_ = current_percent_;
}

void VolumeBubble::AnimationProgressed(const Animation* animation) {
  if (view_) {
    view_->Update(
        Tween::ValueBetween(animation->GetCurrentValue(),
                            previous_percent_,
                            current_percent_));
  }
}

}  // namespace chromeos
<|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/debugger/debugger_window.h"

#include "base/logging.h"
#include "base/string_util.h"
#include "base/json_writer.h"
#include "base/values.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/debugger/resources/debugger_resources.h"
#include "chrome/browser/debugger/debugger_shell.h"
#include "chrome/browser/debugger/debugger_view.h"
#include "chrome/browser/debugger/debugger_wrapper.h"
#include "chrome/browser/dom_ui/chrome_url_data_manager.h"
#include "chrome/browser/render_view_host.h"
#include "chrome/browser/tab_contents.h"
#include "chrome/browser/tab_contents_container_view.h"
#include "chrome/browser/view_ids.h"
#include "chrome/browser/views/standard_layout.h"
#include "chrome/browser/web_contents.h"
#include "chrome/common/gfx/chrome_canvas.h"
#include "chrome/common/resource_bundle.h"
#include "chrome/views/grid_layout.h"
#include "chrome/views/native_scroll_bar.h"
#include "chrome/views/scroll_view.h"
#include "chrome/views/text_field.h"
#include "chrome/views/view.h"

DebuggerView::DebuggerView() : output_ready_(false) {
  web_container_ = new TabContentsContainerView();
  AddChildView(web_container_);
}

DebuggerView::~DebuggerView() {
}

void DebuggerView::GetPreferredSize(CSize* out) {
  out->cx = 700;
  out->cy = 400;
}

void DebuggerView::Layout() {
  web_container_->SetBounds(0, 0, GetWidth(), GetHeight());
}

void DebuggerView::DidChangeBounds(const CRect& previous,
                                   const CRect& current) {
  Layout();
}

void DebuggerView::ViewHierarchyChanged(bool is_add,
                                        ChromeViews::View* parent,
                                        ChromeViews::View* child) {
  if (is_add && child == this) {
    DCHECK(GetViewContainer());
    OnInit();
  }
}

void DebuggerView::Paint(ChromeCanvas* canvas) {
#ifndef NDEBUG
  SkPaint paint;
  canvas->FillRectInt(SK_ColorCYAN, bounds_.left, bounds_.top,
                      bounds_.Width(), bounds_.Height());
#endif
}

void DebuggerView::SetOutputViewReady() {
  output_ready_ = true;
  for (std::vector<std::wstring>::iterator i = pending_output_.begin();
       i != pending_output_.end(); ++i) {
    Output(*i);
  }
  pending_output_.clear();
}

void DebuggerView::Output(const std::string& out) {
  Output(UTF8ToWide(out));
}

void DebuggerView::Output(const std::wstring& out) {
  if (!output_ready_) {
    pending_output_.push_back(out);
    return;
  }
  Value* str_value = Value::CreateStringValue(out);
  std::string json;
  JSONWriter::Write(str_value, false, &json);
  const std::string js = StringPrintf("appendText(%s)", json.c_str());
  ExecuteJavascript(js);
}

void DebuggerView::OnInit() {
  // We can't create the WebContents until we've actually been put into a real
  // view hierarchy somewhere.
  Profile* profile = BrowserList::GetLastActive()->profile();
  TabContents* tc = TabContents::CreateWithType(TAB_CONTENTS_DEBUGGER,
      ::GetDesktopWindow(), profile, NULL);
  web_contents_ = tc->AsWebContents();
  web_contents_->SetupController(profile);
  web_contents_->set_delegate(this);
  web_container_->SetTabContents(web_contents_);
  web_contents_->render_view_host()->AllowDOMUIBindings();

  GURL contents("chrome-resource://debugger/");
  web_contents_->controller()->LoadURL(contents, PageTransition::START_PAGE);
}

void DebuggerView::OnShow() {
  web_contents_->Focus();
  if (output_ready_)
    ExecuteJavascript("focusOnCommandLine()");
}

void DebuggerView::OnClose() {
  web_container_->SetTabContents(NULL);
  web_contents_->CloseContents();
}

void DebuggerView::SetDebuggerBreak(bool is_broken) {
  const std::string js =
      StringPrintf("setDebuggerBreak(%s)", is_broken ? "true" : "false");
  ExecuteJavascript(js);
}

void DebuggerView::OpenURLFromTab(TabContents* source,
                               const GURL& url,
                               WindowOpenDisposition disposition,
                               PageTransition::Type transition) {
  BrowserList::GetLastActive()->OpenURL(url, disposition, transition);
}

void DebuggerView::ExecuteJavascript(const std::string& js) {
  const std::string url = StringPrintf("javascript:void(%s)", js.c_str());
  web_contents_->render_view_host()->ExecuteJavascriptInWebFrame(L"",
      UTF8ToWide(url));
}

void DebuggerView::LoadingStateChanged(TabContents* source) {
  if (!source->is_loading())
    SetOutputViewReady();
}

<commit_msg>fix build bustage<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/debugger/debugger_window.h"

#include "base/logging.h"
#include "base/string_util.h"
#include "base/json_writer.h"
#include "base/values.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/debugger/resources/debugger_resources.h"
#include "chrome/browser/debugger/debugger_shell.h"
#include "chrome/browser/debugger/debugger_view.h"
#include "chrome/browser/debugger/debugger_wrapper.h"
#include "chrome/browser/dom_ui/chrome_url_data_manager.h"
#include "chrome/browser/render_view_host.h"
#include "chrome/browser/tab_contents.h"
#include "chrome/browser/view_ids.h"
#include "chrome/browser/views/standard_layout.h"
#include "chrome/browser/views/tab_contents_container_view.h"
#include "chrome/browser/web_contents.h"
#include "chrome/common/gfx/chrome_canvas.h"
#include "chrome/common/resource_bundle.h"
#include "chrome/views/grid_layout.h"
#include "chrome/views/native_scroll_bar.h"
#include "chrome/views/scroll_view.h"
#include "chrome/views/text_field.h"
#include "chrome/views/view.h"

DebuggerView::DebuggerView() : output_ready_(false) {
  web_container_ = new TabContentsContainerView();
  AddChildView(web_container_);
}

DebuggerView::~DebuggerView() {
}

void DebuggerView::GetPreferredSize(CSize* out) {
  out->cx = 700;
  out->cy = 400;
}

void DebuggerView::Layout() {
  web_container_->SetBounds(0, 0, GetWidth(), GetHeight());
}

void DebuggerView::DidChangeBounds(const CRect& previous,
                                   const CRect& current) {
  Layout();
}

void DebuggerView::ViewHierarchyChanged(bool is_add,
                                        ChromeViews::View* parent,
                                        ChromeViews::View* child) {
  if (is_add && child == this) {
    DCHECK(GetViewContainer());
    OnInit();
  }
}

void DebuggerView::Paint(ChromeCanvas* canvas) {
#ifndef NDEBUG
  SkPaint paint;
  canvas->FillRectInt(SK_ColorCYAN, bounds_.left, bounds_.top,
                      bounds_.Width(), bounds_.Height());
#endif
}

void DebuggerView::SetOutputViewReady() {
  output_ready_ = true;
  for (std::vector<std::wstring>::iterator i = pending_output_.begin();
       i != pending_output_.end(); ++i) {
    Output(*i);
  }
  pending_output_.clear();
}

void DebuggerView::Output(const std::string& out) {
  Output(UTF8ToWide(out));
}

void DebuggerView::Output(const std::wstring& out) {
  if (!output_ready_) {
    pending_output_.push_back(out);
    return;
  }
  Value* str_value = Value::CreateStringValue(out);
  std::string json;
  JSONWriter::Write(str_value, false, &json);
  const std::string js = StringPrintf("appendText(%s)", json.c_str());
  ExecuteJavascript(js);
}

void DebuggerView::OnInit() {
  // We can't create the WebContents until we've actually been put into a real
  // view hierarchy somewhere.
  Profile* profile = BrowserList::GetLastActive()->profile();
  TabContents* tc = TabContents::CreateWithType(TAB_CONTENTS_DEBUGGER,
      ::GetDesktopWindow(), profile, NULL);
  web_contents_ = tc->AsWebContents();
  web_contents_->SetupController(profile);
  web_contents_->set_delegate(this);
  web_container_->SetTabContents(web_contents_);
  web_contents_->render_view_host()->AllowDOMUIBindings();

  GURL contents("chrome-resource://debugger/");
  web_contents_->controller()->LoadURL(contents, PageTransition::START_PAGE);
}

void DebuggerView::OnShow() {
  web_contents_->Focus();
  if (output_ready_)
    ExecuteJavascript("focusOnCommandLine()");
}

void DebuggerView::OnClose() {
  web_container_->SetTabContents(NULL);
  web_contents_->CloseContents();
}

void DebuggerView::SetDebuggerBreak(bool is_broken) {
  const std::string js =
      StringPrintf("setDebuggerBreak(%s)", is_broken ? "true" : "false");
  ExecuteJavascript(js);
}

void DebuggerView::OpenURLFromTab(TabContents* source,
                               const GURL& url,
                               WindowOpenDisposition disposition,
                               PageTransition::Type transition) {
  BrowserList::GetLastActive()->OpenURL(url, disposition, transition);
}

void DebuggerView::ExecuteJavascript(const std::string& js) {
  const std::string url = StringPrintf("javascript:void(%s)", js.c_str());
  web_contents_->render_view_host()->ExecuteJavascriptInWebFrame(L"",
      UTF8ToWide(url));
}

void DebuggerView::LoadingStateChanged(TabContents* source) {
  if (!source->is_loading())
    SetOutputViewReady();
}

<|endoftext|>