<commit_before>/*

The MIT License (MIT)

Copyright (c) 2015 Martin Richter

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

*/

#ifndef TWPP_DETAIL_FILE_ENV_HPP
#define TWPP_DETAIL_FILE_ENV_HPP

// =============
// Twpp specific

namespace Twpp {

namespace Detail {

enum {
    ProtoMajor = 2,
    ProtoMinor = 3,
    Dsm2 = 0x10000000L,
    App2 = 0x20000000L,
    Ds2  = 0x40000000L
};

}

}

#if defined(TWPP_IS_DS)
#   define TWPP_DETAIL_IS_DS 1
#else
#   define TWPP_DETAIL_IS_DS 0
#endif

// ===========
// OS specific

// Windows
#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
#   define TWPP_DETAIL_OS_WIN 1
#   if defined(WIN64) || defined(_WIN64)
#       define TWPP_DETAIL_OS_WIN64 1
#   else
#       define TWPP_DETAIL_OS_WIN32 1
#   endif
#   if !defined(WIN32_LEAN_AND_MEAN)
#       define WIN32_LEAN_AND_MEAN
#   endif
#   if !defined(NOMINMAX)
#       define NOMINMAX
#   endif
    extern "C" {
#   include <windows.h>
    }
#   define TWPP_DETAIL_CALLSTYLE PASCAL
#   define TWPP_DETAIL_EXPORT __declspec(dllexport)
    namespace Twpp {

    namespace Detail {

    typedef HANDLE RawHandle;

    namespace DsmLibOs {

    typedef HMODULE Handle;
    static constexpr const Handle nullHandle = nullptr;

    template<typename T>
    static inline T resolve(Handle h) noexcept{
        return reinterpret_cast<T>(::GetProcAddress(h, "DSM_Entry"));
    }

    static inline Handle load(bool old) noexcept{
#   if defined(TWPP_DETAIL_OS_WIN32)
        if (old){
            auto h = ::LoadLibraryA("TWAIN_32.dll");
            if (!h){
                h = ::LoadLibraryA("TWAINDSM.dll");
            }

            return h;
        }
#   endif

        auto h = ::LoadLibraryA("TWAINDSM.dll");

#   if defined(TWPP_DETAIL_OS_WIN32)
        if (!h){
            h = ::LoadLibraryA("TWAIN_32.dll");
        }
#   else
        unused(old);
#   endif

        return h;
    }

    static inline void unload(Handle h) noexcept{
        ::FreeLibrary(h);
    }

    } // namespace DsmLibOs

    } // namespace Detail

    } // namespace Twpp

// Mac OS
#elif defined(__APPLE__)
#   pragma warning "No testing has been done on this platform, this framework might not work correctly."
#   define TWPP_DETAIL_OS_MAC 1
    extern "C" {
#   if defined(__MWERKS__)
#       include <Carbon.h>
#   else
#       include <Carbon/Carbon.h>
#   endif
#   include <MacMemory.h>
#   include <dlfcn.h>
    }
#   define TWPP_DETAIL_CALLSTYLE pascal
    namespace Twpp {

    namespace Detail {

    typedef Handle RawHandle;

    namespace DsmLibOs {

    typedef void* Handle;
    static constexpr const Handle nullHandle = nullptr;

    static inline DsmEntry resolve(Handle h) noexcept{
        return reinterpret_cast<DsmEntry>(::dlsym(h, "DSM_Entry"));
    }

    static inline Handle load(bool) noexcept{
        return ::dlopen("/System/Library/Frameworks/TWAIN.framework/TWAIN", RTLD_LAZY);
    }

    static inline void unload(Handle h) noexcept{
        ::dlclose(h);
    }

    } // namespace DsmLibOs

    } // namespace Detail

    } // namespace Twpp

// Linux
#elif defined(__linux__)
#   warning "No testing has been done on this platform, this framework might not work correctly."
#   define TWPP_DETAIL_OS_LINUX 1
    extern "C" {
#   include <dlfcn.h>
    }
#   define TWPP_DETAIL_CALLSTYLE
    namespace Twpp {

    namespace Detail {

    typedef void* RawHandle;

    namespace DsmLibOs {

    typedef void* Handle;
    static constexpr const Handle nullHandle = nullptr;

    static inline DsmEntry resolve(Handle h) noexcept{
        return reinterpret_cast<DsmEntry>(::dlsym(h, "DSM_Entry"));
    }

    static inline Handle load(bool) noexcept{
        return ::dlopen("libtwaindsm.so", RTLD_LAZY);
    }

    static inline void unload(Handle h) noexcept{
        ::dlclose(h);
    }

    } // namespace DsmLibOs

    } // namespace Detail

    } // namespace Twpp

// fail everything else
#else
#   error "unsupported platform, supports only Windows, Mac OS and Linux"
#endif

// =================
// compiler specific

// MSVC
#if defined(_MSC_VER)
#   define TWPP_DETAIL_PACK_BEGIN \
        __pragma(pack (push, beforeTwpp)) \
        __pragma(pack (2))
#   define TWPP_DETAIL_PACK_END  __pragma(pack (pop, beforeTwpp));

// GNU or CLang
#elif defined(__GNUC__) || defined(__clang__)
#   if defined(TWPP_DETAIL_OS_MAC)
#       define TWPP_DETAIL_PACK_BEGIN _Pragma("options align = power")
#       define TWPP_DETAIL_PACK_END _Pragma("options align = reset")
#   else
#       define TWPP_DETAIL_PACK_BEGIN \
            _Pragma("pack (push, beforeTwpp)") \
            _Pragma("pack (2)")
#       define TWPP_DETAIL_PACK_END  _Pragma("pack (pop, beforeTwpp)")
#   endif
#   if !defined(TWPP_DETAIL_EXPORT)
#       define TWPP_DETAIL_EXPORT __attribute__((__visibility__("default")))
#   endif

// Borland
#elif defined(__BORLAND__) || defined(__BORLANDC__) || defined(__CODEGEARC__)
#   define TWPP_DETAIL_PACK_BEGIN _Pragma("option -a2")
#   define TWPP_DETAIL_PACK_END _Pragma("option -a")

// fail everything else
#else
#   error unsupported compiler, please define your own TWPP_DETAIL_PACK_BEGIN \
          and TWPP_DETAIL_PACK_END and possibly TWPP_DETAIL_EXPORT in twpp/env.hpp and send me your patch
#endif

#if (!defined(_MSC_VER) && __cplusplus < 201103L) || (defined(_MSC_VER) && _MSC_VER < 1900) // msvc2015
#   error "C++11 or later is required"
#endif

#endif // TWPP_DETAIL_FILE_ENV_HPP

<commit_msg>Fixed compilation for Mac (and most probably for Linux as well)<commit_after>/*

The MIT License (MIT)

Copyright (c) 2015 Martin Richter

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

*/

#ifndef TWPP_DETAIL_FILE_ENV_HPP
#define TWPP_DETAIL_FILE_ENV_HPP

// =============
// Twpp specific

namespace Twpp {

namespace Detail {

enum {
    ProtoMajor = 2,
    ProtoMinor = 3,
    Dsm2 = 0x10000000L,
    App2 = 0x20000000L,
    Ds2  = 0x40000000L
};

}

}

#if defined(TWPP_IS_DS)
#   define TWPP_DETAIL_IS_DS 1
#else
#   define TWPP_DETAIL_IS_DS 0
#endif

// ===========
// OS specific

// Windows
#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
#   define TWPP_DETAIL_OS_WIN 1
#   if defined(WIN64) || defined(_WIN64)
#       define TWPP_DETAIL_OS_WIN64 1
#   else
#       define TWPP_DETAIL_OS_WIN32 1
#   endif
#   if !defined(WIN32_LEAN_AND_MEAN)
#       define WIN32_LEAN_AND_MEAN
#   endif
#   if !defined(NOMINMAX)
#       define NOMINMAX
#   endif
    extern "C" {
#   include <windows.h>
    }
#   define TWPP_DETAIL_CALLSTYLE PASCAL
#   define TWPP_DETAIL_EXPORT __declspec(dllexport)
    namespace Twpp {

    namespace Detail {

    typedef HANDLE RawHandle;

    namespace DsmLibOs {

    typedef HMODULE Handle;
    static constexpr const Handle nullHandle = nullptr;

    template<typename T>
    static inline T resolve(Handle h) noexcept{
        return reinterpret_cast<T>(::GetProcAddress(h, "DSM_Entry"));
    }

    static inline Handle load(bool old) noexcept{
#   if defined(TWPP_DETAIL_OS_WIN32)
        if (old){
            auto h = ::LoadLibraryA("TWAIN_32.dll");
            if (!h){
                h = ::LoadLibraryA("TWAINDSM.dll");
            }

            return h;
        }
#   endif

        auto h = ::LoadLibraryA("TWAINDSM.dll");

#   if defined(TWPP_DETAIL_OS_WIN32)
        if (!h){
            h = ::LoadLibraryA("TWAIN_32.dll");
        }
#   else
        unused(old);
#   endif

        return h;
    }

    static inline void unload(Handle h) noexcept{
        ::FreeLibrary(h);
    }

    } // namespace DsmLibOs

    } // namespace Detail

    } // namespace Twpp

// Mac OS
#elif defined(__APPLE__)
#   pragma warning "No testing has been done on this platform, this framework might not work correctly."
#   define TWPP_DETAIL_OS_MAC 1
    extern "C" {
#   if defined(__MWERKS__)
#       include <Carbon.h>
#   else
#       include <Carbon/Carbon.h>
#   endif
#   include <MacMemory.h>
#   include <dlfcn.h>
    }
#   define TWPP_DETAIL_CALLSTYLE pascal
    namespace Twpp {

    namespace Detail {

    typedef Handle RawHandle;

    namespace DsmLibOs {

    typedef void* Handle;
    static constexpr const Handle nullHandle = nullptr;

    template<typename T>
    static inline T resolve(Handle h) noexcept{
        return reinterpret_cast<T>(::dlsym(h, "DSM_Entry"));
    }

    static inline Handle load(bool) noexcept{
        return ::dlopen("/System/Library/Frameworks/TWAIN.framework/TWAIN", RTLD_LAZY);
    }

    static inline void unload(Handle h) noexcept{
        ::dlclose(h);
    }

    } // namespace DsmLibOs

    } // namespace Detail

    } // namespace Twpp

// Linux
#elif defined(__linux__)
#   warning "No testing has been done on this platform, this framework might not work correctly."
#   define TWPP_DETAIL_OS_LINUX 1
    extern "C" {
#   include <dlfcn.h>
    }
#   define TWPP_DETAIL_CALLSTYLE
    namespace Twpp {

    namespace Detail {

    typedef void* RawHandle;

    namespace DsmLibOs {

    typedef void* Handle;
    static constexpr const Handle nullHandle = nullptr;

    template<typename T>
    static inline T resolve(Handle h) noexcept{
        return reinterpret_cast<T>(::dlsym(h, "DSM_Entry"));
    }

    static inline Handle load(bool) noexcept{
        return ::dlopen("libtwaindsm.so", RTLD_LAZY);
    }

    static inline void unload(Handle h) noexcept{
        ::dlclose(h);
    }

    } // namespace DsmLibOs

    } // namespace Detail

    } // namespace Twpp

// fail everything else
#else
#   error "unsupported platform, supports only Windows, Mac OS and Linux"
#endif

// =================
// compiler specific

// MSVC
#if defined(_MSC_VER)
#   define TWPP_DETAIL_PACK_BEGIN \
        __pragma(pack (push, beforeTwpp)) \
        __pragma(pack (2))
#   define TWPP_DETAIL_PACK_END  __pragma(pack (pop, beforeTwpp));

// GNU or CLang
#elif defined(__GNUC__) || defined(__clang__)
#   if defined(TWPP_DETAIL_OS_MAC)
#       define TWPP_DETAIL_PACK_BEGIN _Pragma("options align = power")
#       define TWPP_DETAIL_PACK_END _Pragma("options align = reset")
#   else
#       define TWPP_DETAIL_PACK_BEGIN \
            _Pragma("pack (push, beforeTwpp)") \
            _Pragma("pack (2)")
#       define TWPP_DETAIL_PACK_END  _Pragma("pack (pop, beforeTwpp)")
#   endif
#   if !defined(TWPP_DETAIL_EXPORT)
#       define TWPP_DETAIL_EXPORT __attribute__((__visibility__("default")))
#   endif

// Borland
#elif defined(__BORLAND__) || defined(__BORLANDC__) || defined(__CODEGEARC__)
#   define TWPP_DETAIL_PACK_BEGIN _Pragma("option -a2")
#   define TWPP_DETAIL_PACK_END _Pragma("option -a")

// fail everything else
#else
#   error unsupported compiler, please define your own TWPP_DETAIL_PACK_BEGIN \
          and TWPP_DETAIL_PACK_END and possibly TWPP_DETAIL_EXPORT in twpp/env.hpp and send me your patch
#endif

#if (!defined(_MSC_VER) && __cplusplus < 201103L) || (defined(_MSC_VER) && _MSC_VER < 1900) // msvc2015
#   error "C++11 or later is required"
#endif

#endif // TWPP_DETAIL_FILE_ENV_HPP

<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    vtkBYUReader.cc
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-1995 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/
#include "vtkBYUReader.hh"
#include "vtkFloatPoints.hh"
#include "vtkFloatVectors.hh"
#include "vtkFloatScalars.hh"
#include "vtkFloatTCoords.hh"

vtkBYUReader::vtkBYUReader()
{
  this->GeometryFilename = NULL;
  this->DisplacementFilename = NULL;
  this->ScalarFilename = NULL;
  this->TextureFilename = NULL;

  this->ReadDisplacement = 1;
  this->ReadScalar = 1;
  this->ReadTexture = 1;

  this->PartNumber = 0;
}

vtkBYUReader::~vtkBYUReader()
{
  if ( this->GeometryFilename ) delete [] this->GeometryFilename;
  if ( this->DisplacementFilename ) delete [] this->DisplacementFilename;
  if ( this->ScalarFilename ) delete [] this->ScalarFilename;
  if ( this->TextureFilename ) delete [] this->TextureFilename;
}

void vtkBYUReader::Execute()
{
  FILE *geomFp;
  int numPts;

  if ((geomFp = fopen(this->GeometryFilename, "r")) == NULL)
    {
    vtkErrorMacro(<< "Geometry file: " << this->GeometryFilename << " not found");
    return;
    }
  else
    {
    this->ReadGeometryFile(geomFp,numPts);
    }

  this->ReadDisplacementFile(numPts);
  this->ReadScalarFile(numPts);
  this->ReadTextureFile(numPts);
}

void vtkBYUReader::ReadGeometryFile(FILE *geomFile, int &numPts)
{
  int numParts, numPolys, numEdges;
  int partStart, partEnd;
  int i;
  vtkFloatPoints *newPts;
  vtkCellArray *newPolys;
  float x[3];
  vtkIdList pts(VTK_CELL_SIZE);
  int id, polyId, pt;
  vtkPolyData *output = this->GetOutput();

  //
  // Read header (not using fixed format! - potential problem in some files.)
  //
  fscanf (geomFile, "%d %d %d %d", &numParts, &numPts, &numPolys, &numEdges);

  if ( this->PartNumber > numParts )
    {
    vtkWarningMacro(<<"Specified part number > number of parts");
    this->PartNumber = 0;
    }

  if ( this->PartNumber > 0 ) // read just part specified
    {
    vtkDebugMacro(<<"Reading part number: " << this->PartNumber);
    for (i=0; i < (this->PartNumber-1); i++) fscanf (geomFile, "%*d %*d");
    fscanf (geomFile, "%d %d", &partStart, &partEnd);
    for (i=this->PartNumber; i < numParts; i++) fscanf (geomFile, "%*d %*d");
    }
  else // read all parts
    {
    vtkDebugMacro(<<"Reading all parts.");
    for (i=0; i < numParts; i++) fscanf (geomFile, "%*d %*d");
    partStart = 1;
    partEnd = VTK_LARGE_INTEGER;
    }

  if ( numParts < 1 || numPts < 1 || numPolys < 1 )
    {
    vtkErrorMacro(<<"Bad MOVIE.BYU file");
    return;
    }
//
// Allocate data objects
//
  newPts = new vtkFloatPoints(numPts);
  newPolys = new vtkCellArray(numPolys+numEdges);
//
// Read data
//
  // read point coordinates
  for (i=0; i<numPts; i++)
    {
    fscanf(geomFile, "%e %e %e", x, x+1, x+2);
    newPts->InsertPoint(i,x);
    }

  // read poly data. Have to fix 1-offset. Only reading part number specified.
  for ( polyId=1; polyId <= numPolys; polyId++ )
    {
    // read this polygon
    for ( pts.Reset(); fscanf(geomFile, "%d", &pt) && pt > 0; )
      {
      pts.InsertNextId(pt-1);//convert to vtk 0-offset
      }
    pts.InsertNextId(-(pt+1));

    // Insert polygon (if in selected part)
    if ( partStart <= polyId && polyId <= partEnd )
      {
      newPolys->InsertNextCell(pts);
      }
    }

  vtkDebugMacro(<<"Reading:" << numPts << " points, "
                 << numPolys << " polygons.");

  output->SetPoints(newPts);
  newPts->Delete();

  output->SetPolys(newPolys);
  newPolys->Delete();
}

void vtkBYUReader::ReadDisplacementFile(int numPts)
{
  FILE *dispFp;
  int i;
  float v[3];
  vtkFloatVectors *newVectors;
  vtkPolyData *output = this->GetOutput();

  if ( this->ReadDisplacement && this->DisplacementFilename )
    {
    if ( !(dispFp = fopen(this->DisplacementFilename, "r")) )
      {
      vtkErrorMacro (<<"Couldn't open displacement file");
      return;
      }
    }
  else return;
//
// Allocate and read data
//
  newVectors = new vtkFloatVectors(numPts);

  for (i=0; i<numPts; i++)
    {
    fscanf(dispFp, "%e %e %e", v, v+1, v+2);
    newVectors->SetVector(i,v);
    }

  vtkDebugMacro(<<"Read " << numPts << " displacements");

  output->GetPointData()->SetVectors(newVectors);
  newVectors->Delete();
}

void vtkBYUReader::ReadScalarFile(int numPts)
{
  FILE *scalarFp;
  int i;
  float s;
  vtkFloatScalars *newScalars;
  vtkPolyData *output = this->GetOutput();

  if ( this->ReadScalar && this->ScalarFilename )
    {
    if ( !(scalarFp = fopen(this->ScalarFilename, "r")) )
      {
      vtkErrorMacro (<<"Couldn't open scalar file");
      return;
      }
    }
  else return;
//
// Allocate and read data
//
  newScalars = new vtkFloatScalars(numPts);

  for (i=0; i<numPts; i++)
    {
    fscanf(scalarFp, "%e", &s);
    newScalars->SetScalar(i,s);
    }

  vtkDebugMacro(<<"Read " << numPts << " scalars");

  output->GetPointData()->SetScalars(newScalars);
  newScalars->Delete();
}

void vtkBYUReader::ReadTextureFile(int numPts)
{
  FILE *textureFp;
  int i;
  float t[2];
  vtkFloatTCoords *newTCoords;
  vtkPolyData *output = this->GetOutput();

  if ( this->ReadTexture && this->TextureFilename )
    {
    if ( !(textureFp = fopen(this->TextureFilename, "r")) )
      {
      vtkErrorMacro (<<"Couldn't open texture file");
      return;
      }
    }
  else return;
//
// Allocate and read data
//
  newTCoords = new vtkFloatTCoords(numPts,2);

  for (i=0; i<numPts; i++)
    {
    fscanf(textureFp, "%e %e", t, t+1);
    newTCoords->SetTCoord(i,t);
    }

  vtkDebugMacro(<<"Read " << numPts << " texture coordinates");

  output->GetPointData()->SetTCoords(newTCoords);
  newTCoords->Delete();
}

void vtkBYUReader::PrintSelf(ostream& os, vtkIndent indent)
{
  vtkPolySource::PrintSelf(os,indent);

  os << indent << "Geometry Filename: " << this->GeometryFilename << "\n";
  os << indent << "Read Displacement: " << (this->ReadDisplacement ? "On\n" : "Off\n");
  os << indent << "Displacement Filename: " << this->DisplacementFilename << "\n";
  os << indent << "Read Scalar: " << (this->ReadScalar ? "On\n" : "Off\n");
  os << indent << "Scalar Filename: " << this->ScalarFilename << "\n";
  os << indent << "Read Texture: " << (this->ReadTexture ? "On\n" : "Off\n");
  os << indent << "Texture Filename: " << this->TextureFilename << "\n";
}

<commit_msg>removed unused variable<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkBYUReader.cc
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-1995 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/
#include "vtkBYUReader.hh"
#include "vtkFloatPoints.hh"
#include "vtkFloatVectors.hh"
#include "vtkFloatScalars.hh"
#include "vtkFloatTCoords.hh"

vtkBYUReader::vtkBYUReader()
{
  this->GeometryFilename = NULL;
  this->DisplacementFilename = NULL;
  this->ScalarFilename = NULL;
  this->TextureFilename = NULL;

  this->ReadDisplacement = 1;
  this->ReadScalar = 1;
  this->ReadTexture = 1;

  this->PartNumber = 0;
}

vtkBYUReader::~vtkBYUReader()
{
  if ( this->GeometryFilename ) delete [] this->GeometryFilename;
  if ( this->DisplacementFilename ) delete [] this->DisplacementFilename;
  if ( this->ScalarFilename ) delete [] this->ScalarFilename;
  if ( this->TextureFilename ) delete [] this->TextureFilename;
}

void vtkBYUReader::Execute()
{
  FILE *geomFp;
  int numPts;

  if ((geomFp = fopen(this->GeometryFilename, "r")) == NULL)
    {
    vtkErrorMacro(<< "Geometry file: " << this->GeometryFilename << " not found");
    return;
    }
  else
    {
    this->ReadGeometryFile(geomFp,numPts);
    }

  this->ReadDisplacementFile(numPts);
  this->ReadScalarFile(numPts);
  this->ReadTextureFile(numPts);
}

void vtkBYUReader::ReadGeometryFile(FILE *geomFile, int &numPts)
{
  int numParts, numPolys, numEdges;
  int partStart, partEnd;
  int i;
  vtkFloatPoints *newPts;
  vtkCellArray *newPolys;
  float x[3];
  vtkIdList pts(VTK_CELL_SIZE);
  int polyId, pt;
  vtkPolyData *output = this->GetOutput();

  //
  // Read header (not using fixed format! - potential problem in some files.)
  //
  fscanf (geomFile, "%d %d %d %d", &numParts, &numPts, &numPolys, &numEdges);

  if ( this->PartNumber > numParts )
    {
    vtkWarningMacro(<<"Specified part number > number of parts");
    this->PartNumber = 0;
    }

  if ( this->PartNumber > 0 ) // read just part specified
    {
    vtkDebugMacro(<<"Reading part number: " << this->PartNumber);
    for (i=0; i < (this->PartNumber-1); i++) fscanf (geomFile, "%*d %*d");
    fscanf (geomFile, "%d %d", &partStart, &partEnd);
    for (i=this->PartNumber; i < numParts; i++) fscanf (geomFile, "%*d %*d");
    }
  else // read all parts
    {
    vtkDebugMacro(<<"Reading all parts.");
    for (i=0; i < numParts; i++) fscanf (geomFile, "%*d %*d");
    partStart = 1;
    partEnd = VTK_LARGE_INTEGER;
    }

  if ( numParts < 1 || numPts < 1 || numPolys < 1 )
    {
    vtkErrorMacro(<<"Bad MOVIE.BYU file");
    return;
    }
//
// Allocate data objects
//
  newPts = new vtkFloatPoints(numPts);
  newPolys = new vtkCellArray(numPolys+numEdges);
//
// Read data
//
  // read point coordinates
  for (i=0; i<numPts; i++)
    {
    fscanf(geomFile, "%e %e %e", x, x+1, x+2);
    newPts->InsertPoint(i,x);
    }

  // read poly data. Have to fix 1-offset. Only reading part number specified.
  for ( polyId=1; polyId <= numPolys; polyId++ )
    {
    // read this polygon
    for ( pts.Reset(); fscanf(geomFile, "%d", &pt) && pt > 0; )
      {
      pts.InsertNextId(pt-1);//convert to vtk 0-offset
      }
    pts.InsertNextId(-(pt+1));

    // Insert polygon (if in selected part)
    if ( partStart <= polyId && polyId <= partEnd )
      {
      newPolys->InsertNextCell(pts);
      }
    }

  vtkDebugMacro(<<"Reading:" << numPts << " points, "
                 << numPolys << " polygons.");

  output->SetPoints(newPts);
  newPts->Delete();

  output->SetPolys(newPolys);
  newPolys->Delete();
}

void vtkBYUReader::ReadDisplacementFile(int numPts)
{
  FILE *dispFp;
  int i;
  float v[3];
  vtkFloatVectors *newVectors;
  vtkPolyData *output = this->GetOutput();

  if ( this->ReadDisplacement && this->DisplacementFilename )
    {
    if ( !(dispFp = fopen(this->DisplacementFilename, "r")) )
      {
      vtkErrorMacro (<<"Couldn't open displacement file");
      return;
      }
    }
  else return;
//
// Allocate and read data
//
  newVectors = new vtkFloatVectors(numPts);

  for (i=0; i<numPts; i++)
    {
    fscanf(dispFp, "%e %e %e", v, v+1, v+2);
    newVectors->SetVector(i,v);
    }

  vtkDebugMacro(<<"Read " << numPts << " displacements");

  output->GetPointData()->SetVectors(newVectors);
  newVectors->Delete();
}

void vtkBYUReader::ReadScalarFile(int numPts)
{
  FILE *scalarFp;
  int i;
  float s;
  vtkFloatScalars *newScalars;
  vtkPolyData *output = this->GetOutput();

  if ( this->ReadScalar && this->ScalarFilename )
    {
    if ( !(scalarFp = fopen(this->ScalarFilename, "r")) )
      {
      vtkErrorMacro (<<"Couldn't open scalar file");
      return;
      }
    }
  else return;
//
// Allocate and read data
//
  newScalars = new vtkFloatScalars(numPts);

  for (i=0; i<numPts; i++)
    {
    fscanf(scalarFp, "%e", &s);
    newScalars->SetScalar(i,s);
    }

  vtkDebugMacro(<<"Read " << numPts << " scalars");

  output->GetPointData()->SetScalars(newScalars);
  newScalars->Delete();
}

void vtkBYUReader::ReadTextureFile(int numPts)
{
  FILE *textureFp;
  int i;
  float t[2];
  vtkFloatTCoords *newTCoords;
  vtkPolyData *output = this->GetOutput();

  if ( this->ReadTexture && this->TextureFilename )
    {
    if ( !(textureFp = fopen(this->TextureFilename, "r")) )
      {
      vtkErrorMacro (<<"Couldn't open texture file");
      return;
      }
    }
  else return;
//
// Allocate and read data
//
  newTCoords = new vtkFloatTCoords(numPts,2);

  for (i=0; i<numPts; i++)
    {
    fscanf(textureFp, "%e %e", t, t+1);
    newTCoords->SetTCoord(i,t);
    }

  vtkDebugMacro(<<"Read " << numPts << " texture coordinates");

  output->GetPointData()->SetTCoords(newTCoords);
  newTCoords->Delete();
}

void vtkBYUReader::PrintSelf(ostream& os, vtkIndent indent)
{
  vtkPolySource::PrintSelf(os,indent);

  os << indent << "Geometry Filename: " << this->GeometryFilename << "\n";
  os << indent << "Read Displacement: " << (this->ReadDisplacement ? "On\n" : "Off\n");
  os << indent << "Displacement Filename: " << this->DisplacementFilename << "\n";
  os << indent << "Read Scalar: " << (this->ReadScalar ? "On\n" : "Off\n");
  os << indent << "Scalar Filename: " << this->ScalarFilename << "\n";
  os << indent << "Read Texture: " << (this->ReadTexture ? "On\n" : "Off\n");
  os << indent << "Texture Filename: " << this->TextureFilename << "\n";
}

<|endoftext|>


<commit_before>#include <dbus/dbus-glib.h>
#include <webkit2/webkit-web-extension.h>
#include <JavaScriptCore/JSContextRef.h>
#include <JavaScriptCore/JSStringRef.h>
#include <string.h>
#include "dbus.h"
#include "utils.h"

static GDBusConnection* connection;

static gboolean web_page_send_request(WebKitWebPage* web_page, WebKitURIRequest* request, WebKitURIResponse* redirected_response, gpointer data) {
	GError* error = NULL;
	// ignore redirected requests - it's transparent to the user
	if (redirected_response != NULL) {
		return FALSE;
	}
	const char* uri = webkit_uri_request_get_uri(request);
	SoupMessageHeaders* headers = webkit_uri_request_get_http_headers(request);

	GVariantDict dictIn;
	GVariant* variantIn = soup_headers_to_gvariant_dict(headers);
	g_variant_dict_init(&dictIn, variantIn);
	g_variant_dict_insert(&dictIn, "uri", "s", uri);
	variantIn = g_variant_dict_end(&dictIn);

	GVariant* tuple[1];
	tuple[0] = variantIn;

	GVariant* results = g_dbus_connection_call_sync(connection, NULL, DBUS_OBJECT_WKGTK, DBUS_INTERFACE_WKGTK, "HandleRequest", g_variant_new_tuple(tuple, 1), G_VARIANT_TYPE_TUPLE, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);

	g_variant_dict_clear(&dictIn);

	if (results == NULL) {
		g_printerr("ERR g_dbus_connection_call_sync %s\n", error->message);
		g_error_free(error);
		return FALSE;
	}

	GVariantDict dictOut;
	g_variant_dict_init(&dictOut, g_variant_get_child_value(results, 0));

	bool ret = FALSE;
	const gchar* newuri = NULL;
	const gchar* cancel = NULL;
	if (g_variant_dict_lookup(&dictOut, "cancel", "s", &cancel) && cancel != NULL && !g_strcmp0(cancel, "1")) {
		ret = TRUE;
	} else if (g_variant_dict_lookup(&dictOut, "uri", "s", &newuri) && newuri != NULL) {
		webkit_uri_request_set_uri(request, newuri);
	}
	g_variant_dict_remove(&dictOut, "uri");

	results = g_variant_dict_end(&dictOut);
	update_soup_headers_with_dict(headers, results);
	g_variant_unref(results);

	return ret;
}

static void web_page_created_callback(WebKitWebExtension* extension, WebKitWebPage* web_page, gpointer data) {
	g_signal_connect(web_page, "send-request", G_CALLBACK(web_page_send_request), data);
}

static gboolean event_listener(WebKitDOMDOMWindow* view, WebKitDOMEvent* event, gpointer data) {
	char* message = webkit_dom_keyboard_event_get_key_identifier((WebKitDOMKeyboardEvent*)event);
	GError* error = NULL;
	g_dbus_connection_call_sync(connection, NULL, DBUS_OBJECT_WKGTK, DBUS_INTERFACE_WKGTK,
		"NotifyEvent", g_variant_new("(s)", message), G_VARIANT_TYPE("()"), G_DBUS_CALL_FLAGS_NONE, -1, NULL,
		&error);
	if (error != NULL) {
		g_printerr("Failed to finish dbus call: %s\n", error->message);
		g_error_free(error);
	}
	g_free(message);
	return TRUE;
}

static void window_object_cleared_callback(WebKitScriptWorld* world, WebKitWebPage* page, WebKitFrame* frame, gchar* eventName) {
	WebKitDOMDocument* document = webkit_web_page_get_dom_document(page);
	WebKitDOMDOMWindow* window = webkit_dom_document_get_default_view(document);
	webkit_dom_event_target_add_event_listener(WEBKIT_DOM_EVENT_TARGET(window), eventName, G_CALLBACK(event_listener), false, NULL);
}

extern "C" {
	G_MODULE_EXPORT void webkit_web_extension_initialize_with_user_data(WebKitWebExtension* extension, const GVariant* constData) {
		gchar* address = NULL;
		gchar* eventName = NULL;
		g_variant_get((GVariant*)constData, "(ss)", &address, &eventName);

		g_signal_connect(webkit_script_world_get_default(), "window-object-cleared", G_CALLBACK(window_object_cleared_callback), eventName);

		g_signal_connect(extension, "page-created", G_CALLBACK(web_page_created_callback), NULL);

		GError* error = NULL;
		connection = g_dbus_connection_new_for_address_sync(address, G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, NULL, NULL, &error);
		if (connection == NULL) {
			g_printerr("Failed to open connection to bus: %s\n", error->message);
			g_error_free(error);
		}
	}
}
<commit_msg>Do not return TRUE to block requests or it hangs XHR<commit_after>#include <dbus/dbus-glib.h>
#include <webkit2/webkit-web-extension.h>
#include <JavaScriptCore/JSContextRef.h>
#include <JavaScriptCore/JSStringRef.h>
#include <string.h>
#include "dbus.h"
#include "utils.h"

static GDBusConnection* connection;

static gboolean web_page_send_request(WebKitWebPage* web_page, WebKitURIRequest* request, WebKitURIResponse* redirected_response, gpointer data) {
	GError* error = NULL;
	// ignore redirected requests - it's transparent to the user
	if (redirected_response != NULL) {
		return FALSE;
	}
	const char* uri = webkit_uri_request_get_uri(request);
	SoupMessageHeaders* headers = webkit_uri_request_get_http_headers(request);

	GVariantDict dictIn;
	GVariant* variantIn = soup_headers_to_gvariant_dict(headers);
	g_variant_dict_init(&dictIn, variantIn);
	g_variant_dict_insert(&dictIn, "uri", "s", uri);
	variantIn = g_variant_dict_end(&dictIn);

	GVariant* tuple[1];
	tuple[0] = variantIn;

	GVariant* results = g_dbus_connection_call_sync(connection, NULL, DBUS_OBJECT_WKGTK, DBUS_INTERFACE_WKGTK, "HandleRequest", g_variant_new_tuple(tuple, 1), G_VARIANT_TYPE_TUPLE, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);

	g_variant_dict_clear(&dictIn);

	if (results == NULL) {
		g_printerr("ERR g_dbus_connection_call_sync %s\n", error->message);
		g_error_free(error);
		return FALSE;
	}

	GVariantDict dictOut;
	g_variant_dict_init(&dictOut, g_variant_get_child_value(results, 0));

	const gchar* newuri = NULL;
	const gchar* cancel = NULL;
	if (g_variant_dict_lookup(&dictOut, "cancel", "s", &cancel) && cancel != NULL && !g_strcmp0(cancel, "1")) {
		// returning TRUE blocks requests - it's better to set an empty uri - it sets status to 0
		webkit_uri_request_set_uri(request, "");
	} else if (g_variant_dict_lookup(&dictOut, "uri", "s", &newuri) && newuri != NULL) {
		webkit_uri_request_set_uri(request, newuri);
	}
	g_variant_dict_remove(&dictOut, "uri");

	results = g_variant_dict_end(&dictOut);
	update_soup_headers_with_dict(headers, results);
	g_variant_unref(results);

	return FALSE;
}

static void web_page_created_callback(WebKitWebExtension* extension, WebKitWebPage* web_page, gpointer data) {
	g_signal_connect(web_page, "send-request", G_CALLBACK(web_page_send_request), data);
}

static gboolean event_listener(WebKitDOMDOMWindow* view, WebKitDOMEvent* event, gpointer data) {
	char* message = webkit_dom_keyboard_event_get_key_identifier((WebKitDOMKeyboardEvent*)event);
	GError* error = NULL;
	g_dbus_connection_call_sync(connection, NULL, DBUS_OBJECT_WKGTK, DBUS_INTERFACE_WKGTK,
		"NotifyEvent", g_variant_new("(s)", message), G_VARIANT_TYPE("()"), G_DBUS_CALL_FLAGS_NONE, -1, NULL,
		&error);
	if (error != NULL) {
		g_printerr("Failed to finish dbus call: %s\n", error->message);
		g_error_free(error);
	}
	g_free(message);
	return TRUE;
}

static void window_object_cleared_callback(WebKitScriptWorld* world, WebKitWebPage* page, WebKitFrame* frame, gchar* eventName) {
	WebKitDOMDocument* document = webkit_web_page_get_dom_document(page);
	WebKitDOMDOMWindow* window = webkit_dom_document_get_default_view(document);
	webkit_dom_event_target_add_event_listener(WEBKIT_DOM_EVENT_TARGET(window), eventName, G_CALLBACK(event_listener), false, NULL);
}

extern "C" {
	G_MODULE_EXPORT void webkit_web_extension_initialize_with_user_data(WebKitWebExtension* extension, const GVariant* constData) {
		gchar* address = NULL;
		gchar* eventName = NULL;
		g_variant_get((GVariant*)constData, "(ss)", &address, &eventName);

		g_signal_connect(webkit_script_world_get_default(), "window-object-cleared", G_CALLBACK(window_object_cleared_callback), eventName);

		g_signal_connect(extension, "page-created", G_CALLBACK(web_page_created_callback), NULL);

		GError* error = NULL;
		connection = g_dbus_connection_new_for_address_sync(address, G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, NULL, NULL, &error);
		if (connection == NULL) {
			g_printerr("Failed to open connection to bus: %s\n", error->message);
			g_error_free(error);
		}
	}
}
<|endoftext|>


<commit_before>/*
**  Copyright (C) 2017 SoftBank Robotics
**  See COPYING for the license
*/

#ifndef QI_PRINT_HPP
#define QI_PRINT_HPP

#include <qi/api.hpp>
#include <qi/iocolor.hpp>
#include <qi/flags.hpp>
#include <boost/variant.hpp>
#include <boost/utility/string_ref.hpp>
#include <ostream>
#include <memory>

/// @file
/// Contains utilities for I/O like pretty-printing to streams.

namespace qi
{
  class MetaObject;
  class MetaMethod;
  class MetaSignal;
  class MetaProperty;
  class StructTypeInterface;
  class ListTypeInterface;
  class MapTypeInterface;
  class TypeInterface;
  class Signature;

namespace detail
{

  enum class DisplayHiddenMembers : bool
  {
    Hide = false,
    Display = true,
  };

  /// Provides facilities to print informations about types into a stream in a user friendly formatting.
  /// It also supports indentation.
  /// This class is movable but not copyable, thus not regular.
  ///
  /// Example:
  /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
  ///
  /// PrettyPrintStream stream(std::cout, DisplayHiddenMembers::Display,
  ///                          PrettyPrintSteam::Options{ PrettyPrintStream::Option::Colorized
  ///                                                    | PrettyPrintStream::Option::Documentation });
  ///
  /// MetaObject object = ...;
  /// stream << object;
  /// stream << PrettyPrintStream::makeSectionHeader(
  ///             PrettyPrintStream::Line{ PrettyPrintStream::Column("here comes a method") });
  /// {
  ///   const auto indent = stream.makeIndentLevel();
  ///   MetaMethod method = ...;
  ///   stream << method;
  /// }
  ///
  /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
  class QI_API PrettyPrintStream
  {
  public:
    enum class Option
    {
      Colorized      = 1 << 0,
      Documentation  = 1 << 1,
      RawSignatures  = 1 << 2
    };
    using Options = qi::Flags<Option>;

    enum class RecurseOption : bool
    {
      DoNotRecurse = false,
      Recurse = true,
    };

    /// Encapsulates in a RAII style a shift or an indentation level of a PrettyPrintStream instance.
    class IndentLevel
    {
      friend PrettyPrintStream;
      IndentLevel(PrettyPrintStream& printer);

    public:
      ~IndentLevel();

      // deleted copy and assignement
      IndentLevel(const IndentLevel&) = delete;
      IndentLevel& operator=(const IndentLevel&) = delete;

    private:
      PrettyPrintStream& _printer;
    };
    friend IndentLevel;
    using IndentLevelPtr = std::unique_ptr<IndentLevel>;

    /// Contains the data and options needed to fill and format one column of a line
    struct Column
    {
      using ValueType = boost::variant<int, std::string>;
      enum class Alignment
      {
        Left     = 0,
        Right    = 1,
        Internal = 2,
      };
      enum class Option
      {
        DelimitWithSpace = 1 << 0,
      };
      using Options = qi::Flags<Option>;

      explicit Column(ValueType value,
                      StreamColor color = StreamColor_None,
                      Alignment alignment = Alignment::Left,
                      Options opts = Options{Option::DelimitWithSpace},
                      int width = 0,
                      char fillChar = ' ');

    // Regular:
      Column()
        : color(StreamColor_None)
        , alignment(Alignment::Left)
        , width(0)
        , fillChar(0)
      {
      }

      QI_GENERATE_FRIEND_REGULAR_OPS_6(Column, value, color, alignment, opts, width, fillChar)

      ValueType value;
      StreamColor color;
      Alignment alignment;
      Options opts;
      int width;
      char fillChar;
    };
    using Columns = std::vector<Column>;

    /// Contains the data and options needed to fill and format one line.
    /// PrettyPrintStream prints lines which are each composed of multiple columns.
    struct Line
    {
      enum class Option
      {
        NewLine = 1 << 0,
        Indent = 1 << 1,
      };
      using Options = qi::Flags<Option>;

      explicit Line(const std::initializer_list<Column>& columns);
      explicit Line(const Columns& columns, Options opts = Options{Option::NewLine, Option::Indent});

    // Regular:
      Line() = default;

      QI_GENERATE_FRIEND_REGULAR_OPS_2(Line, columns, opts)

      Columns columns;
      Options opts;
    };

    using string_ref = boost::string_ref;
    static const string_ref infoLabel;
    static const string_ref methodsLabel;
    static const string_ref signalsLabel;
    static const string_ref propertiesLabel;
    static const string_ref membersLabel;
    static const string_ref returnTypeLabel;
    static const string_ref returnDescrLabel;
    static const string_ref elementTypeLabel;
    static const string_ref keyTypeLabel;
    static const string_ref parametersLabel;
    static const string_ref signalTypesLabel;

    explicit PrettyPrintStream(std::ostream& stream,
                               DisplayHiddenMembers displayHidden = DisplayHiddenMembers::Hide,
                               Options flags = Options{ Option::Colorized },
                               int indentLevel = 0);

    PrettyPrintStream(const PrettyPrintStream&) = delete;
    PrettyPrintStream& operator=(const PrettyPrintStream&) = delete;

    // TODO: Make this constructor = default when we get rid of VS2013
    PrettyPrintStream(PrettyPrintStream&& o) BOOST_NOEXCEPT
      : _stream(std::move(o._stream))
      , _displayHidden(std::move(o._displayHidden))
      , _options(std::move(o._options))
      , _indentLevel(std::move(o._indentLevel))
    {
      o._stream = nullptr;
    }

    // TODO: Make this operator = default when we get rid of VS2013
    PrettyPrintStream& operator=(PrettyPrintStream&& o) BOOST_NOEXCEPT
    {
      _stream = std::move(o._stream);
      _displayHidden = std::move(o._displayHidden);
      _options = std::move(o._options);
      _indentLevel = std::move(o._indentLevel);
      o._stream = nullptr;
      return *this;
    }

  // Custom:
    static Line makeSectionHeader(const Line& line);
    static Line makeSubSectionHeader(const Line& line);

    IndentLevelPtr makeIndentLevel();

    void print(const Line& line);
    void print(const MetaObject& mobj);
    void print(const MetaMethod& method, int offsetLabel = 0, RecurseOption recurse = RecurseOption::Recurse);
    void print(const MetaSignal& signal, int offsetLabel = 0, RecurseOption recurse = RecurseOption::Recurse);
    void print(const MetaProperty& property, int offsetLabel = 0, RecurseOption recurse = RecurseOption::Recurse);
    void print(TypeInterface* type);
    void print(StructTypeInterface& structType);
    void print(ListTypeInterface& listType);
    void print(MapTypeInterface& mapType);

    /// With PrettyPrintStream& s, P printable, the following is valid:
    ///   s.print(printable);
    template <typename P>
    PrettyPrintStream& operator<<(P&& printable)
    {
      print(std::forward<P>(printable));
      return *this;
    }

  private:
    inline int indentWidth() const
    {
      return _indentLevel * indentFactor;
    }

    void increaseIndent();
    void decreaseIndent();

    StreamColor colorIfEnabled(StreamColor color) const;

    /// Returns a string corresponding to the signature, depending if we want it raw or not
    std::string stringify(const qi::Signature& signature) const;

    void print(const Column& column) const;

    void printParameters(const std::vector<qi::Signature>& paramsSignatures,
                         const std::string& label,
                         RecurseOption recurse);

    /// Procedure<optional<Line> (int)> Proc
    template <typename Proc>
    void printParameters(const std::vector<qi::Signature>& paramsSignatures,
                         const std::string& label,
                         RecurseOption recurse,
                         Proc makeExtraLine);

    /// Procedure<optional<Line> (std::string)> Proc
    template <typename Proc>
    void print(TypeInterface* type, Proc makeHeaderLine);

    void printDetails(TypeInterface& type);

    /// Linearizable<std::pair<_, MetaMethod || MetaSignal || MetaProperty>> L
    template <typename L>
    void printMetaObjectMembers(const L& members, string_ref headerLabel);

    static const int indentFactor;
    static const int maxOffset;
    static const int idColumnWidth;
    std::ostream* _stream;
    DisplayHiddenMembers _displayHidden;
    Options _options;
    int _indentLevel;
  };

  /// Provides facilities to print informations about types into a stream in parseable formatting.
  /// This class is movable but not copyable, thus not regular.
  ///
  /// Example:
  /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
  ///
  /// ParseablePrintStream stream(std::cout, DisplayHiddenMembers::Display);
  ///
  /// MetaObject object = ...;
  /// stream << object;
  /// MetaMethod method = ...;
  /// stream << method.name(); // no overload for MetaMethod, just print its name
  ///
  /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
  class QI_API ParseablePrintStream
  {
  public:
    explicit ParseablePrintStream(std::ostream& stream,
                                  DisplayHiddenMembers displayHidden = DisplayHiddenMembers::Hide);

    ParseablePrintStream(const ParseablePrintStream&) = delete;
    ParseablePrintStream& operator=(const ParseablePrintStream&) = delete;

    // TODO: Make this constructor = default when we get rid of VS2013
    ParseablePrintStream(ParseablePrintStream&& o) BOOST_NOEXCEPT
      : _stream(std::move(o._stream))
      , _displayHidden(std::move(o._displayHidden))
    {
      o._stream = nullptr;
    }

    // TODO: Make this operator = default when we get rid of VS2013
    ParseablePrintStream& operator=(ParseablePrintStream&& o) BOOST_NOEXCEPT
    {
      _stream = std::move(o._stream);
      _displayHidden = std::move(o._displayHidden);
      o._stream = nullptr;
      return *this;
    }

  // Custom:
    /// OutputStreamable S
    template <typename S>
    ParseablePrintStream& operator<<(S&& streamable)
    {
      *_stream << std::forward<S>(streamable);
      return *this;
    }

    ParseablePrintStream& operator<<(const MetaObject& obj)
    {
      print(obj);
      return *this;
    }

    void print(const MetaObject& mobj);

  private:
    /// Linearizable<std::pair<_, MetaMethod || MetaSignal || MetaProperty>> L
    template <typename L>
    void printMetaObjectMembers(const L& members);

    std::ostream* _stream;
    DisplayHiddenMembers _displayHidden;
  };

}
}

#endif // QI_PRINT_HPP
<commit_msg>PrettyPrint: exports enclosed printer classes for VS2013<commit_after>/*
**  Copyright (C) 2017 SoftBank Robotics
**  See COPYING for the license
*/

#ifndef QI_PRINT_HPP
#define QI_PRINT_HPP

#include <qi/api.hpp>
#include <qi/iocolor.hpp>
#include <qi/flags.hpp>
#include <boost/variant.hpp>
#include <boost/utility/string_ref.hpp>
#include <ostream>
#include <memory>

/// @file
/// Contains utilities for I/O like pretty-printing to streams.

namespace qi
{
  class MetaObject;
  class MetaMethod;
  class MetaSignal;
  class MetaProperty;
  class StructTypeInterface;
  class ListTypeInterface;
  class MapTypeInterface;
  class TypeInterface;
  class Signature;

namespace detail
{

  enum class DisplayHiddenMembers : bool
  {
    Hide = false,
    Display = true,
  };

  /// Provides facilities to print informations about types into a stream in a user friendly formatting.
  /// It also supports indentation.
  /// This class is movable but not copyable, thus not regular.
  ///
  /// Example:
  /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
  ///
  /// PrettyPrintStream stream(std::cout, DisplayHiddenMembers::Display,
  ///                          PrettyPrintSteam::Options{ PrettyPrintStream::Option::Colorized
  ///                                                    | PrettyPrintStream::Option::Documentation });
  ///
  /// MetaObject object = ...;
  /// stream << object;
  /// stream << PrettyPrintStream::makeSectionHeader(
  ///             PrettyPrintStream::Line{ PrettyPrintStream::Column("here comes a method") });
  /// {
  ///   const auto indent = stream.makeIndentLevel();
  ///   MetaMethod method = ...;
  ///   stream << method;
  /// }
  ///
  /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
  class QI_API PrettyPrintStream
  {
  public:
    enum class Option
    {
      Colorized      = 1 << 0,
      Documentation  = 1 << 1,
      RawSignatures  = 1 << 2
    };
    using Options = qi::Flags<Option>;

    enum class RecurseOption : bool
    {
      DoNotRecurse = false,
      Recurse = true,
    };

    /// Encapsulates in a RAII style a shift or an indentation level of a PrettyPrintStream instance.
    class QI_API IndentLevel
    {
      friend PrettyPrintStream;
      IndentLevel(PrettyPrintStream& printer);

    public:
      ~IndentLevel();

      // deleted copy and assignement
      IndentLevel(const IndentLevel&) = delete;
      IndentLevel& operator=(const IndentLevel&) = delete;

    private:
      PrettyPrintStream& _printer;
    };
    friend IndentLevel;
    using IndentLevelPtr = std::unique_ptr<IndentLevel>;

    /// Contains the data and options needed to fill and format one column of a line
    struct QI_API Column
    {
      using ValueType = boost::variant<int, std::string>;
      enum class Alignment
      {
        Left     = 0,
        Right    = 1,
        Internal = 2,
      };
      enum class Option
      {
        DelimitWithSpace = 1 << 0,
      };
      using Options = qi::Flags<Option>;

      explicit Column(ValueType value,
                      StreamColor color = StreamColor_None,
                      Alignment alignment = Alignment::Left,
                      Options opts = Options{Option::DelimitWithSpace},
                      int width = 0,
                      char fillChar = ' ');

    // Regular:
      Column()
        : color(StreamColor_None)
        , alignment(Alignment::Left)
        , width(0)
        , fillChar(0)
      {
      }

      QI_GENERATE_FRIEND_REGULAR_OPS_6(Column, value, color, alignment, opts, width, fillChar)

      ValueType value;
      StreamColor color;
      Alignment alignment;
      Options opts;
      int width;
      char fillChar;
    };
    using Columns = std::vector<Column>;

    /// Contains the data and options needed to fill and format one line.
    /// PrettyPrintStream prints lines which are each composed of multiple columns.
    struct QI_API Line
    {
      enum class Option
      {
        NewLine = 1 << 0,
        Indent = 1 << 1,
      };
      using Options = qi::Flags<Option>;

      explicit Line(const std::initializer_list<Column>& columns);
      explicit Line(const Columns& columns, Options opts = Options{Option::NewLine, Option::Indent});

    // Regular:
      Line() = default;

      QI_GENERATE_FRIEND_REGULAR_OPS_2(Line, columns, opts)

      Columns columns;
      Options opts;
    };

    using string_ref = boost::string_ref;
    static const string_ref infoLabel;
    static const string_ref methodsLabel;
    static const string_ref signalsLabel;
    static const string_ref propertiesLabel;
    static const string_ref membersLabel;
    static const string_ref returnTypeLabel;
    static const string_ref returnDescrLabel;
    static const string_ref elementTypeLabel;
    static const string_ref keyTypeLabel;
    static const string_ref parametersLabel;
    static const string_ref signalTypesLabel;

    explicit PrettyPrintStream(std::ostream& stream,
                               DisplayHiddenMembers displayHidden = DisplayHiddenMembers::Hide,
                               Options flags = Options{ Option::Colorized },
                               int indentLevel = 0);

    PrettyPrintStream(const PrettyPrintStream&) = delete;
    PrettyPrintStream& operator=(const PrettyPrintStream&) = delete;

    // TODO: Make this constructor = default when we get rid of VS2013
    PrettyPrintStream(PrettyPrintStream&& o) BOOST_NOEXCEPT
      : _stream(std::move(o._stream))
      , _displayHidden(std::move(o._displayHidden))
      , _options(std::move(o._options))
      , _indentLevel(std::move(o._indentLevel))
    {
      o._stream = nullptr;
    }

    // TODO: Make this operator = default when we get rid of VS2013
    PrettyPrintStream& operator=(PrettyPrintStream&& o) BOOST_NOEXCEPT
    {
      _stream = std::move(o._stream);
      _displayHidden = std::move(o._displayHidden);
      _options = std::move(o._options);
      _indentLevel = std::move(o._indentLevel);
      o._stream = nullptr;
      return *this;
    }

  // Custom:
    static Line makeSectionHeader(const Line& line);
    static Line makeSubSectionHeader(const Line& line);

    IndentLevelPtr makeIndentLevel();

    void print(const Line& line);
    void print(const MetaObject& mobj);
    void print(const MetaMethod& method, int offsetLabel = 0, RecurseOption recurse = RecurseOption::Recurse);
    void print(const MetaSignal& signal, int offsetLabel = 0, RecurseOption recurse = RecurseOption::Recurse);
    void print(const MetaProperty& property, int offsetLabel = 0, RecurseOption recurse = RecurseOption::Recurse);
    void print(TypeInterface* type);
    void print(StructTypeInterface& structType);
    void print(ListTypeInterface& listType);
    void print(MapTypeInterface& mapType);

    /// With PrettyPrintStream& s, P printable, the following is valid:
    ///   s.print(printable);
    template <typename P>
    PrettyPrintStream& operator<<(P&& printable)
    {
      print(std::forward<P>(printable));
      return *this;
    }

  private:
    inline int indentWidth() const
    {
      return _indentLevel * indentFactor;
    }

    void increaseIndent();
    void decreaseIndent();

    StreamColor colorIfEnabled(StreamColor color) const;

    /// Returns a string corresponding to the signature, depending if we want it raw or not
    std::string stringify(const qi::Signature& signature) const;

    void print(const Column& column) const;

    void printParameters(const std::vector<qi::Signature>& paramsSignatures,
                         const std::string& label,
                         RecurseOption recurse);

    /// Procedure<optional<Line> (int)> Proc
    template <typename Proc>
    void printParameters(const std::vector<qi::Signature>& paramsSignatures,
                         const std::string& label,
                         RecurseOption recurse,
                         Proc makeExtraLine);

    /// Procedure<optional<Line> (std::string)> Proc
    template <typename Proc>
    void print(TypeInterface* type, Proc makeHeaderLine);

    void printDetails(TypeInterface& type);

    /// Linearizable<std::pair<_, MetaMethod || MetaSignal || MetaProperty>> L
    template <typename L>
    void printMetaObjectMembers(const L& members, string_ref headerLabel);

    static const int indentFactor;
    static const int maxOffset;
    static const int idColumnWidth;
    std::ostream* _stream;
    DisplayHiddenMembers _displayHidden;
    Options _options;
    int _indentLevel;
  };

  /// Provides facilities to print informations about types into a stream in parseable formatting.
  /// This class is movable but not copyable, thus not regular.
  ///
  /// Example:
  /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
  ///
  /// ParseablePrintStream stream(std::cout, DisplayHiddenMembers::Display);
  ///
  /// MetaObject object = ...;
  /// stream << object;
  /// MetaMethod method = ...;
  /// stream << method.name(); // no overload for MetaMethod, just print its name
  ///
  /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
  class QI_API ParseablePrintStream
  {
  public:
    explicit ParseablePrintStream(std::ostream& stream,
                                  DisplayHiddenMembers displayHidden = DisplayHiddenMembers::Hide);

    ParseablePrintStream(const ParseablePrintStream&) = delete;
    ParseablePrintStream& operator=(const ParseablePrintStream&) = delete;

    // TODO: Make this constructor = default when we get rid of VS2013
    ParseablePrintStream(ParseablePrintStream&& o) BOOST_NOEXCEPT
      : _stream(std::move(o._stream))
      , _displayHidden(std::move(o._displayHidden))
    {
      o._stream = nullptr;
    }

    // TODO: Make this operator = default when we get rid of VS2013
    ParseablePrintStream& operator=(ParseablePrintStream&& o) BOOST_NOEXCEPT
    {
      _stream = std::move(o._stream);
      _displayHidden = std::move(o._displayHidden);
      o._stream = nullptr;
      return *this;
    }

  // Custom:
    /// OutputStreamable S
    template <typename S>
    ParseablePrintStream& operator<<(S&& streamable)
    {
      *_stream << std::forward<S>(streamable);
      return *this;
    }

    ParseablePrintStream& operator<<(const MetaObject& obj)
    {
      print(obj);
      return *this;
    }

    void print(const MetaObject& mobj);

  private:
    /// Linearizable<std::pair<_, MetaMethod || MetaSignal || MetaProperty>> L
    template <typename L>
    void printMetaObjectMembers(const L& members);

    std::ostream* _stream;
    DisplayHiddenMembers _displayHidden;
  };

}
}

#endif // QI_PRINT_HPP
<|endoftext|>


<commit_before>#include "QOsgViewer.h"

#include <osgGA/TrackballManipulator>
#include <osgViewer/ViewerEventHandlers>
#include "xo/system/log.h"
#include "qevent.h"
#include "osg/MatrixTransform"
#include "xo/geometry/quat.h"
#include "osg/Material"
#include "osg/PositionAttitudeTransform"

// class for routing GUI events to QOsgViewer
// This is needed because QOsgViewer can't derive from GUIEventHandler directly
// because both are derived from osg::Object (basically, because of bad design)
class QOsgEventHandler : public osgGA::GUIEventHandler
{
public:
	QOsgEventHandler( QOsgViewer& viewer ) : viewer_( viewer ) {}
	virtual bool handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa ) { return viewer_.handle( ea, aa ); }
private:
	QOsgViewer& viewer_;
};

QOsgViewer::QOsgViewer( QWidget* parent /*= 0*/, Qt::WindowFlags f /*= 0*/, osgViewer::ViewerBase::ThreadingModel threadingModel/*=osgViewer::CompositeViewer::SingleThreaded*/ ) :
QWidget( parent, f ),
frame_count_( 0 ),
capture_handler_( nullptr ),
scene_light_offset_( -2, 8, 3 )
{
	setThreadingModel( threadingModel );

	// disable the default setting of viewer.done() by pressing Escape.
	setKeyEventSetsDone( 0 );

	// setup viewer grid
	view_widget_ = addViewWidget( createGraphicsWindow( 0, 0, 100, 100, "", true ) );
	auto* grid = new QGridLayout;
	grid->addWidget( view_widget_ );
	setLayout( grid );
	grid->setMargin( 1 );

	// start timer that checks for updates in the camera manager
	connect( &timer_, SIGNAL( timeout() ), this, SLOT( timerUpdate() ) );
	startTimer();

	// this allows us to detect events, and update the viewer accordingly
	// overriding mouseMoveEvent, etc. does not work, because they are send directly to GLWidget
	//QCoreApplication::instance()->installEventFilter( this );
}

osgQt::GLWidget* QOsgViewer::addViewWidget( osgQt::GraphicsWindowQt* gw )
{
	view_ = new osgViewer::View;
	addView( view_ );

	osg::Camera* cam = view_->getCamera();
	cam->setGraphicsContext( gw );

	const osg::GraphicsContext::Traits* traits = gw->getTraits();

	cam->setClearColor( osg::Vec4( 0.55, 0.55, 0.55, 1.0 ) );
	cam->setViewport( new osg::Viewport( 0, 0, traits->width, traits->height ) );
	cam->setProjectionMatrixAsPerspective( 30.0f, static_cast<double>( traits->width ) / static_cast<double>( traits->height ), 1.0f, 10000.0f );

	// add event handlers
	view_->addEventHandler( new osgViewer::StatsHandler );
	view_->addEventHandler( new QOsgEventHandler( *this ) );

	// disable lighting by default
	view_->setLightingMode( osg::View::NO_LIGHT );

	// setup camera manipulator
	gw->setTouchEventsEnabled( true );

	camera_man_ = new vis::osg_camera_man();
	camera_man_->setVerticalAxisFixed( false );
	view_->setCameraManipulator( camera_man_ );

	return gw->getGLWidget();
}

osgQt::GraphicsWindowQt* QOsgViewer::createGraphicsWindow( int x, int y, int w, int h, const std::string& name/*=""*/, bool windowDecoration/*=false */ )
{
	osg::DisplaySettings* ds = osg::DisplaySettings::instance().get();
	ds->setNumMultiSamples( 2 );

	osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
	traits->windowName = name;
	traits->windowDecoration = windowDecoration;
	traits->x = x;
	traits->y = y;
	traits->width = w;
	traits->height = h;
	traits->doubleBuffer = true;
	traits->alpha = ds->getMinimumNumAlphaBits();
	traits->stencil = ds->getMinimumNumStencilBits();
	traits->sampleBuffers = ds->getMultiSamples();
	traits->samples = ds->getNumMultiSamples();

	width_ = w;
	height_ = h;

	return new osgQt::GraphicsWindowQt( traits.get() );
}

void QOsgViewer::paintEvent( QPaintEvent* event )
{
	// prevent capturing duplicate frames
	if ( isCapturing() && current_frame_time_ == last_drawn_frame_time_ )
		return; // this frame was already captured, skip

	++frame_count_;

	// advance and handle camera events
	advance();
	eventTraversal();

	// update camera light position
	updateLightPos();

	// update and render
	updateTraversal();
	renderingTraversals();

	last_drawn_frame_time_ = current_frame_time_;
}

void QOsgViewer::setScene( osg::Group* s )
{
	scene_ = s;
	for ( size_t i = 0; i < getNumViews(); ++i )
		getView( i )->setSceneData( s );

	// init light
	scene_light_ = new osg::Light;
	scene_light_->setLightNum( 0 );
	scene_light_->setPosition( osg::Vec4f( scene_light_offset_.x, scene_light_offset_.y, scene_light_offset_.z, 1 ) );
	scene_light_->setDiffuse( osg::Vec4( 1, 1, 1, 1 ) );
	scene_light_->setSpecular( osg::Vec4( 1, 1, 1, 1 ) );
	scene_light_->setAmbient( osg::Vec4( 1, 1, 1, 1 ) );

	auto light_source = new osg::LightSource;
	light_source->setLight( scene_light_ );
	light_source->setLocalStateSetModes( osg::StateAttribute::ON );
	light_source->setReferenceFrame( osg::LightSource::RELATIVE_RF );

	// directly add the light to the parent node
	s->addChild( light_source );
	s->getOrCreateStateSet()->setMode( GL_LIGHT0, osg::StateAttribute::ON );
	scene_light_->setConstantAttenuation( 1.0f );
}

void QOsgViewer::createHud( const xo::path& file )
{
	hud_node_ = new osg::PositionAttitudeTransform;

	osg::ref_ptr<osg::Image> img = osgDB::readImageFile( file.str() );
	xo_assert( img.valid() );
	auto width = osg::Vec3f( hud_size, 0, 0 );
	auto height = osg::Vec3f( 0, hud_size, 0 );

	osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D;
	texture->setImage( img );
	texture->setWrap( osg::Texture::WRAP_S, osg::Texture::REPEAT );
	texture->setWrap( osg::Texture::WRAP_T, osg::Texture::REPEAT );

	osg::ref_ptr<osg::Geometry> geom = osg::createTexturedQuadGeometry(
		width * -0.5f - height * 0.5f,
		width, height, 0, 0, 1.0f, 1.0f );

	geom->getOrCreateStateSet()->setTextureAttributeAndModes( 0, texture.get() );
	geom->getOrCreateStateSet()->setMode( GL_DEPTH_TEST, osg::StateAttribute::OFF );
	geom->getOrCreateStateSet()->setMode( GL_BLEND, osg::StateAttribute::ON );

	osg::ref_ptr<osg::Geode> geode = new osg::Geode();
	geode->addDrawable( geom );

	hud_node_->addChild( geode );

	hud_node_->setReferenceFrame( osg::Transform::ABSOLUTE_RF );
	view_->getCamera()->addChild( hud_node_ );
	updateHudPos();
}

void QOsgViewer::updateHudPos()
{
	if ( hud_node_ )
	{
		double fovy, aspect, nearplane, farplane;
		view_->getCamera()->getProjectionMatrixAsPerspective( fovy, aspect, nearplane, farplane );
		auto hh = tan( xo::degreed( fovy / 2 ) );
		auto hw = tan( atan( hh * aspect ) );
		//xo::log::info( "Updating HUD position to ", hw - 0.55f * hud_size, ", ", -hh + 0.55f * hud_size, "; aspect ratio = ", aspect );
		hud_node_->setPosition( osg::Vec3( hw - 0.55f * hud_size, -hh + 0.55f * hud_size, -1 ) );
	}
}

void QOsgViewer::updateLightPos()
{
	auto center = camera_man_->getCenter();
	auto ori = xo::quat_from_axis_angle( xo::vec3f::unit_y(), camera_man_->getYaw() );
	auto v = ori * scene_light_offset_;
	auto p = center + osg::Vec3d( v.x, v.y, v.z );
	scene_light_->setPosition( osg::Vec4( p, 1 ) );
}

void QOsgViewer::viewerInit()
{
	updateHudPos();
}

void QOsgViewer::setClearColor( const osg::Vec4& col )
{
	view_->getCamera()->setClearColor( col );
}

void QOsgViewer::moveCamera( const osg::Vec3d& delta_pos )
{
	camera_man_->setCenter( camera_man_->getCenter() + delta_pos );
}

bool QOsgViewer::handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa )
{
	if ( ea.getEventType() == osgGA::GUIEventAdapter::RESIZE )
	{
		width_ = ea.getWindowWidth();
		height_ = ea.getWindowHeight();
		xo::log::info( "Viewer resized to ", width_, "x", height_ );
		updateHudPos();
		return true;
	}
	return false;
}

void QOsgViewer::startCapture( const std::string& filename )
{
	// create capture handler
	xo::log::info( "Started capturing video to ", filename );
	capture_handler_ = new osgViewer::ScreenCaptureHandler(
		new osgViewer::ScreenCaptureHandler::WriteToFile( filename, "png", osgViewer::ScreenCaptureHandler::WriteToFile::SEQUENTIAL_NUMBER ), -1 );
	view_->addEventHandler( capture_handler_ );
	capture_handler_->startCapture();
}

void QOsgViewer::stopCapture()
{
	last_drawn_frame_time_ = ~size_t ( 0 );
	if ( capture_handler_ )
	{
		xo::log::info( "Video capture stopped" );
		capture_handler_->stopCapture();
		capture_handler_ = nullptr;
	}
}

void QOsgViewer::captureCurrentFrame( const std::string& filename )
{
	stopCapture();

	capture_handler_ = new osgViewer::ScreenCaptureHandler(
		new osgViewer::ScreenCaptureHandler::WriteToFile( filename, "png", osgViewer::ScreenCaptureHandler::WriteToFile::OVERWRITE ), -1 );
	view_->addEventHandler( capture_handler_ );
	capture_handler_->startCapture();
	frame();
	capture_handler_->stopCapture();
	capture_handler_ = nullptr;
	xo::log::info( "Written image to ", filename );
}

void QOsgViewer::setFrameTime( double t )
{
	if ( current_frame_time_ != t )
	{
		current_frame_time_ = t;
		repaint();
	}
}

void QOsgViewer::timerUpdate()
{
	// check if update is needed
	eventTraversal();
	camera_man_->handleKeyboardAnimation();
	if ( camera_man_->hasCameraStateChanged() )
		update();
}

bool QOsgViewer::eventFilter( QObject* obj, QEvent* event )
{
	if ( obj == view_widget_ )
	{
		// detect event inside view_widget_
		if ( event->type() == QEvent::MouseMove )
			update();
	}
	return QObject::eventFilter( obj, event );
}
<commit_msg>F: init current_frame_time_<commit_after>#include "QOsgViewer.h"

#include <osgGA/TrackballManipulator>
#include <osgViewer/ViewerEventHandlers>
#include "xo/system/log.h"
#include "qevent.h"
#include "osg/MatrixTransform"
#include "xo/geometry/quat.h"
#include "osg/Material"
#include "osg/PositionAttitudeTransform"

// class for routing GUI events to QOsgViewer
// This is needed because QOsgViewer can't derive from GUIEventHandler directly
// because both are derived from osg::Object (basically, because of bad design)
class QOsgEventHandler : public osgGA::GUIEventHandler
{
public:
	QOsgEventHandler( QOsgViewer& viewer ) : viewer_( viewer ) {}
	virtual bool handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa ) { return viewer_.handle( ea, aa ); }
private:
	QOsgViewer& viewer_;
};

QOsgViewer::QOsgViewer( QWidget* parent /*= 0*/, Qt::WindowFlags f /*= 0*/, osgViewer::ViewerBase::ThreadingModel threadingModel/*=osgViewer::CompositeViewer::SingleThreaded*/ ) :
QWidget( parent, f ),
frame_count_( 0 ),
capture_handler_( nullptr ),
scene_light_offset_( -2, 8, 3 ),
current_frame_time_( -1 )
{
	setThreadingModel( threadingModel );

	// disable the default setting of viewer.done() by pressing Escape.
	setKeyEventSetsDone( 0 );

	// setup viewer grid
	view_widget_ = addViewWidget( createGraphicsWindow( 0, 0, 100, 100, "", true ) );
	auto* grid = new QGridLayout;
	grid->addWidget( view_widget_ );
	setLayout( grid );
	grid->setMargin( 1 );

	// start timer that checks for updates in the camera manager
	connect( &timer_, SIGNAL( timeout() ), this, SLOT( timerUpdate() ) );
	startTimer();

	// this allows us to detect events, and update the viewer accordingly
	// overriding mouseMoveEvent, etc. does not work, because they are send directly to GLWidget
	//QCoreApplication::instance()->installEventFilter( this );
}

osgQt::GLWidget* QOsgViewer::addViewWidget( osgQt::GraphicsWindowQt* gw )
{
	view_ = new osgViewer::View;
	addView( view_ );

	osg::Camera* cam = view_->getCamera();
	cam->setGraphicsContext( gw );

	const osg::GraphicsContext::Traits* traits = gw->getTraits();

	cam->setClearColor( osg::Vec4( 0.55, 0.55, 0.55, 1.0 ) );
	cam->setViewport( new osg::Viewport( 0, 0, traits->width, traits->height ) );
	cam->setProjectionMatrixAsPerspective( 30.0f, static_cast<double>( traits->width ) / static_cast<double>( traits->height ), 1.0f, 10000.0f );

	// add event handlers
	view_->addEventHandler( new osgViewer::StatsHandler );
	view_->addEventHandler( new QOsgEventHandler( *this ) );

	// disable lighting by default
	view_->setLightingMode( osg::View::NO_LIGHT );

	// setup camera manipulator
	gw->setTouchEventsEnabled( true );

	camera_man_ = new vis::osg_camera_man();
	camera_man_->setVerticalAxisFixed( false );
	view_->setCameraManipulator( camera_man_ );

	return gw->getGLWidget();
}

osgQt::GraphicsWindowQt* QOsgViewer::createGraphicsWindow( int x, int y, int w, int h, const std::string& name/*=""*/, bool windowDecoration/*=false */ )
{
	osg::DisplaySettings* ds = osg::DisplaySettings::instance().get();
	ds->setNumMultiSamples( 2 );

	osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
	traits->windowName = name;
	traits->windowDecoration = windowDecoration;
	traits->x = x;
	traits->y = y;
	traits->width = w;
	traits->height = h;
	traits->doubleBuffer = true;
	traits->alpha = ds->getMinimumNumAlphaBits();
	traits->stencil = ds->getMinimumNumStencilBits();
	traits->sampleBuffers = ds->getMultiSamples();
	traits->samples = ds->getNumMultiSamples();

	width_ = w;
	height_ = h;

	return new osgQt::GraphicsWindowQt( traits.get() );
}

void QOsgViewer::paintEvent( QPaintEvent* event )
{
	// prevent capturing duplicate frames
	if ( isCapturing() && current_frame_time_ == last_drawn_frame_time_ )
		return; // this frame was already captured, skip

	++frame_count_;

	// advance and handle camera events
	advance();
	eventTraversal();

	// update camera light position
	updateLightPos();

	// update and render
	updateTraversal();
	renderingTraversals();

	last_drawn_frame_time_ = current_frame_time_;
}

void QOsgViewer::setScene( osg::Group* s )
{
	scene_ = s;
	for ( size_t i = 0; i < getNumViews(); ++i )
		getView( i )->setSceneData( s );

	// init light
	scene_light_ = new osg::Light;
	scene_light_->setLightNum( 0 );
	scene_light_->setPosition( osg::Vec4f( scene_light_offset_.x, scene_light_offset_.y, scene_light_offset_.z, 1 ) );
	scene_light_->setDiffuse( osg::Vec4( 1, 1, 1, 1 ) );
	scene_light_->setSpecular( osg::Vec4( 1, 1, 1, 1 ) );
	scene_light_->setAmbient( osg::Vec4( 1, 1, 1, 1 ) );

	auto light_source = new osg::LightSource;
	light_source->setLight( scene_light_ );
	light_source->setLocalStateSetModes( osg::StateAttribute::ON );
	light_source->setReferenceFrame( osg::LightSource::RELATIVE_RF );

	// directly add the light to the parent node
	s->addChild( light_source );
	s->getOrCreateStateSet()->setMode( GL_LIGHT0, osg::StateAttribute::ON );
	scene_light_->setConstantAttenuation( 1.0f );
}

void QOsgViewer::createHud( const xo::path& file )
{
	hud_node_ = new osg::PositionAttitudeTransform;

	osg::ref_ptr<osg::Image> img = osgDB::readImageFile( file.str() );
	xo_assert( img.valid() );
	auto width = osg::Vec3f( hud_size, 0, 0 );
	auto height = osg::Vec3f( 0, hud_size, 0 );

	osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D;
	texture->setImage( img );
	texture->setWrap( osg::Texture::WRAP_S, osg::Texture::REPEAT );
	texture->setWrap( osg::Texture::WRAP_T, osg::Texture::REPEAT );

	osg::ref_ptr<osg::Geometry> geom = osg::createTexturedQuadGeometry(
		width * -0.5f - height * 0.5f,
		width, height, 0, 0, 1.0f, 1.0f );

	geom->getOrCreateStateSet()->setTextureAttributeAndModes( 0, texture.get() );
	geom->getOrCreateStateSet()->setMode( GL_DEPTH_TEST, osg::StateAttribute::OFF );
	geom->getOrCreateStateSet()->setMode( GL_BLEND, osg::StateAttribute::ON );

	osg::ref_ptr<osg::Geode> geode = new osg::Geode();
	geode->addDrawable( geom );

	hud_node_->addChild( geode );

	hud_node_->setReferenceFrame( osg::Transform::ABSOLUTE_RF );
	view_->getCamera()->addChild( hud_node_ );
	updateHudPos();
}

void QOsgViewer::updateHudPos()
{
	if ( hud_node_ )
	{
		double fovy, aspect, nearplane, farplane;
		view_->getCamera()->getProjectionMatrixAsPerspective( fovy, aspect, nearplane, farplane );
		auto hh = tan( xo::degreed( fovy / 2 ) );
		auto hw = tan( atan( hh * aspect ) );
		//xo::log::info( "Updating HUD position to ", hw - 0.55f * hud_size, ", ", -hh + 0.55f * hud_size, "; aspect ratio = ", aspect );
		hud_node_->setPosition( osg::Vec3( hw - 0.55f * hud_size, -hh + 0.55f * hud_size, -1 ) );
	}
}

void QOsgViewer::updateLightPos()
{
	auto center = camera_man_->getCenter();
	auto ori = xo::quat_from_axis_angle( xo::vec3f::unit_y(), camera_man_->getYaw() );
	auto v = ori * scene_light_offset_;
	auto p = center + osg::Vec3d( v.x, v.y, v.z );
	scene_light_->setPosition( osg::Vec4( p, 1 ) );
}

void QOsgViewer::viewerInit()
{
	updateHudPos();
}

void QOsgViewer::setClearColor( const osg::Vec4& col )
{
	view_->getCamera()->setClearColor( col );
}

void QOsgViewer::moveCamera( const osg::Vec3d& delta_pos )
{
	camera_man_->setCenter( camera_man_->getCenter() + delta_pos );
}

bool QOsgViewer::handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa )
{
	if ( ea.getEventType() == osgGA::GUIEventAdapter::RESIZE )
	{
		width_ = ea.getWindowWidth();
		height_ = ea.getWindowHeight();
		xo::log::info( "Viewer resized to ", width_, "x", height_ );
		updateHudPos();
		return true;
	}
	return false;
}

void QOsgViewer::startCapture( const std::string& filename )
{
	// create capture handler
	xo::log::info( "Started capturing video to ", filename );
	capture_handler_ = new osgViewer::ScreenCaptureHandler(
		new osgViewer::ScreenCaptureHandler::WriteToFile( filename, "png", osgViewer::ScreenCaptureHandler::WriteToFile::SEQUENTIAL_NUMBER ), -1 );
	view_->addEventHandler( capture_handler_ );
	capture_handler_->startCapture();
}

void QOsgViewer::stopCapture()
{
	last_drawn_frame_time_ = ~size_t ( 0 );
	if ( capture_handler_ )
	{
		xo::log::info( "Video capture stopped" );
		capture_handler_->stopCapture();
		capture_handler_ = nullptr;
	}
}

void QOsgViewer::captureCurrentFrame( const std::string& filename )
{
	stopCapture();

	capture_handler_ = new osgViewer::ScreenCaptureHandler(
		new osgViewer::ScreenCaptureHandler::WriteToFile( filename, "png", osgViewer::ScreenCaptureHandler::WriteToFile::OVERWRITE ), -1 );
	view_->addEventHandler( capture_handler_ );
	capture_handler_->startCapture();
	frame();
	capture_handler_->stopCapture();
	capture_handler_ = nullptr;
	xo::log::info( "Written image to ", filename );
}

void QOsgViewer::setFrameTime( double t )
{
	if ( current_frame_time_ != t )
	{
		current_frame_time_ = t;
		repaint();
	}
}

void QOsgViewer::timerUpdate()
{
	// check if update is needed
	eventTraversal();
	camera_man_->handleKeyboardAnimation();
	if ( camera_man_->hasCameraStateChanged() )
		update();
}

bool QOsgViewer::eventFilter( QObject* obj, QEvent* event )
{
	if ( obj == view_widget_ )
	{
		// detect event inside view_widget_
		if ( event->type() == QEvent::MouseMove )
			update();
	}
	return QObject::eventFilter( obj, event );
}
<|endoftext|>


<commit_before>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 RC 1        *
*                (c) 2006-2011 INRIA, USTL, UJF, CNRS, MGH                    *
*                                                                             *
* This program is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU General Public License as published by the Free  *
* Software Foundation; either version 2 of the License, or (at your option)   *
* any later version.                                                          *
*                                                                             *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for    *
* more details.                                                               *
*                                                                             *
* You should have received a copy of the GNU General Public License along     *
* with this program; if not, write to the Free Software Foundation, Inc., 51  *
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.                   *
*******************************************************************************
*                            SOFA :: Applications                             *
*                                                                             *
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/

#include "stdafx.h"
#include <sofa/component/engine/TestEngine.h>
#include "Sofa_test.h"

namespace sofa {

/**  Test suite for engine using TestEngine class.
This class has a counter which shows how many times the update method is called.
Add inputs to engine.
Check that the output is updated only if necessary.
Check that update method is called only 1 time
  */
struct Engine_test : public Sofa_test<>
{
    typedef sofa::component::engine::TestEngine TestEngine;
    TestEngine::SPtr engine1;
    TestEngine::SPtr engine2;

    /// Create the engines
    void SetUp()
    {
       // Engine 1
       engine1 = sofa::core::objectmodel::New<TestEngine>();
       engine1->f_numberToMultiply.setValue(1);
       engine1->f_factor.setValue(2);
       std::cout << "init 1 " << std::endl;
       std::cout << "identifier engine 1 :" << engine1->identifier << std::endl;
       engine1->init();

       // Engine 2 linked to the ouput of engine 1
       engine2 = sofa::core::objectmodel::New<TestEngine>();
       sofa::modeling::setDataLink(&engine1->f_result,&engine2->f_numberToMultiply);
       engine2->f_factor.setValue(3);
       std::cout << "init 2 " << std::endl;
        std::cout << "identifier engine 2 :" << engine2->identifier << std::endl;
       engine2->init();

    }

    // Test if the output is updated only if necessary
    void testUpdate()
    {
       //std::cout << "************Get Value Ouput E1*******************"<< std::endl;
       SReal result1 = engine1->f_result.getValue();
       int numberUpdate1Call = engine1->getCounterUpdate();
       ASSERT_EQ(numberUpdate1Called,1);
       ASSERT_EQ(result1,2);

       //std::cout << "************Get Value Ouput E2*******************"<< std::endl;
       SReal result2 = engine2->f_result.getValue();
       numberUpdate1Call = engine1->getCounterUpdate();
       int numberUpdate2Call = engine2->getCounterUpdate();
       ASSERT_EQ(numberUpdate1Called,1);
       ASSERT_EQ(numberUpdate2Called,1);
       ASSERT_EQ(result2,6);

    }

};

// first test case
TEST_F(Engine_test , check_engine_update )
{
    this->testUpdate();
}

}// namespace sofa<commit_msg>ADD: Engine test it fails because update method is called more than 1 time.<commit_after>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 RC 1        *
*                (c) 2006-2011 INRIA, USTL, UJF, CNRS, MGH                    *
*                                                                             *
* This program is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU General Public License as published by the Free  *
* Software Foundation; either version 2 of the License, or (at your option)   *
* any later version.                                                          *
*                                                                             *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for    *
* more details.                                                               *
*                                                                             *
* You should have received a copy of the GNU General Public License along     *
* with this program; if not, write to the Free Software Foundation, Inc., 51  *
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.                   *
*******************************************************************************
*                            SOFA :: Applications                             *
*                                                                             *
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/

#include "stdafx.h"
#include <sofa/component/engine/TestEngine.h>
#include "Sofa_test.h"

namespace sofa {

/**  Test suite for engine using TestEngine class.
This class has a counter which shows how many times the update method is called.
Add inputs to engine.
Check that the output is updated only if necessary.
Check that update method is called only 1 time
  */
struct Engine_test : public Sofa_test<>
{
    typedef sofa::component::engine::TestEngine TestEngine;
    TestEngine::SPtr engine1;
    TestEngine::SPtr engine2;

    /// Create the engines
    void SetUp()
    {
       // Engine 1
       engine1 = sofa::core::objectmodel::New<TestEngine>();
       engine1->f_numberToMultiply.setValue(1);
       engine1->f_factor.setValue(2);
       engine1->init();

       // Engine 2 linked to the ouput of engine 1
       engine2 = sofa::core::objectmodel::New<TestEngine>();
       sofa::modeling::setDataLink(&engine1->f_result,&engine2->f_numberToMultiply);
       engine2->f_factor.setValue(3);
       engine2->init();

    }

    // Test if the output is updated only if necessary
    void testUpdate()
    {
       //std::cout << "************Get Value Ouput E2*******************"<< std::endl;
       SReal result2 = engine2->f_result.getValue();

       // Test if update method of engine1 is called 1 time
       if(engine1->getCounterUpdate()!=1)
       {
           ADD_FAILURE() << "Update method of engine1 was called " << engine1->getCounterUpdate() << " times instead of 1 time " << std::endl;
       }

       // Test if update method of engine2 is called 1 time
       if(engine2->getCounterUpdate()!=1)
       {
           ADD_FAILURE() << "Update method of engine2 was called " << engine2->getCounterUpdate() << " times instead of 1 time " << std::endl;
       }

       // Test if result is correct
       ASSERT_EQ(result2,6);

    }

};

// first test case
TEST_F(Engine_test , check_engine_update )
{
    this->testUpdate();
}

}// namespace sofa<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
** This file is part of the Ovi services plugin for the Maps and
** Navigation API.  The use of these services, whether by use of the
** plugin or by other means, is governed by the terms and conditions
** described by the file OVI_SERVICES_TERMS_AND_CONDITIONS.txt in
** this package, located in the directory containing the Ovi services
** plugin source code.
**
****************************************************************************/

#include "qgeomapreply_nokia.h"

QGeoMapReplyNokia::QGeoMapReplyNokia(QNetworkReply *reply, const QGeoTiledMapRequest &request, QObject *parent)
        : QGeoTiledMapReply(request, parent),
        m_reply(reply)
{
    m_reply->setParent(this);
    QVariant fromCache = m_reply->attribute(QNetworkRequest::SourceIsFromCacheAttribute);
    setCached(fromCache.toBool());

    connect(m_reply,
            SIGNAL(finished()),
            this,
            SLOT(networkFinished()));

    connect(m_reply,
            SIGNAL(error(QNetworkReply::NetworkError)),
            this,
            SLOT(networkError(QNetworkReply::NetworkError)));

    connect(m_reply,
            SIGNAL(destroyed()),
            this,
            SLOT(replyDestroyed()));
}

QGeoMapReplyNokia::~QGeoMapReplyNokia()
{
}

QNetworkReply* QGeoMapReplyNokia::networkReply() const
{
    return m_reply;
}

void QGeoMapReplyNokia::abort()
{
    if (!m_reply)
        return;

    m_reply->abort();
}

void QGeoMapReplyNokia::replyDestroyed()
{
    m_reply = 0;
}

void QGeoMapReplyNokia::networkFinished()
{
    if (!m_reply)
        return;

    if (m_reply->error() != QNetworkReply::NoError) {
        return;
    }

    setMapImageData(m_reply->readAll());
    setMapImageFormat("PNG");
    setFinished(true);

    m_reply->deleteLater();
    m_reply = 0;
}

void QGeoMapReplyNokia::networkError(QNetworkReply::NetworkError error)
{
    if (!m_reply)
        return;

    if (error != QNetworkReply::OperationCanceledError)
        setError(QGeoTiledMapReply::CommunicationError, m_reply->errorString());
    m_reply->deleteLater();
    m_reply = 0;
}
<commit_msg>Nokia maps plugin: forcing finished() signal to be emitted on error<commit_after>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
** This file is part of the Ovi services plugin for the Maps and
** Navigation API.  The use of these services, whether by use of the
** plugin or by other means, is governed by the terms and conditions
** described by the file OVI_SERVICES_TERMS_AND_CONDITIONS.txt in
** this package, located in the directory containing the Ovi services
** plugin source code.
**
****************************************************************************/

#include "qgeomapreply_nokia.h"

QGeoMapReplyNokia::QGeoMapReplyNokia(QNetworkReply *reply, const QGeoTiledMapRequest &request, QObject *parent)
        : QGeoTiledMapReply(request, parent),
        m_reply(reply)
{
    m_reply->setParent(this);
    QVariant fromCache = m_reply->attribute(QNetworkRequest::SourceIsFromCacheAttribute);
    setCached(fromCache.toBool());

    connect(m_reply,
            SIGNAL(finished()),
            this,
            SLOT(networkFinished()));

    connect(m_reply,
            SIGNAL(error(QNetworkReply::NetworkError)),
            this,
            SLOT(networkError(QNetworkReply::NetworkError)));

    connect(m_reply,
            SIGNAL(destroyed()),
            this,
            SLOT(replyDestroyed()));
}

QGeoMapReplyNokia::~QGeoMapReplyNokia()
{
}

QNetworkReply* QGeoMapReplyNokia::networkReply() const
{
    return m_reply;
}

void QGeoMapReplyNokia::abort()
{
    if (!m_reply)
        return;

    m_reply->abort();
}

void QGeoMapReplyNokia::replyDestroyed()
{
    m_reply = 0;
}

void QGeoMapReplyNokia::networkFinished()
{
    if (!m_reply)
        return;

    if (m_reply->error() != QNetworkReply::NoError)
        return;

    setMapImageData(m_reply->readAll());
    setMapImageFormat("PNG");
    setFinished(true);

    m_reply->deleteLater();
    m_reply = 0;
}

void QGeoMapReplyNokia::networkError(QNetworkReply::NetworkError error)
{
    if (!m_reply)
        return;

    if (error != QNetworkReply::OperationCanceledError)
        setError(QGeoTiledMapReply::CommunicationError, m_reply->errorString());
    setFinished(true);
    m_reply->deleteLater();
    m_reply = 0;
}
<|endoftext|>