<commit_before>/*
 * Copyright (C) 2012-2015 Max Kellermann <max@duempel.org>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the
 * distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
 * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef FILE_DESCRIPTOR_HXX
#define FILE_DESCRIPTOR_HXX

#include <inline/compiler.h>

#include <assert.h>
#include <unistd.h>
#include <sys/types.h>

#ifdef __linux__
#define HAVE_POSIX
#define HAVE_EVENTFD
#define HAVE_SIGNALFD
#define HAVE_INOTIFY
#include <signal.h>
#endif

/**
 * An OO wrapper for a UNIX file descriptor.
 *
 * This class is unmanaged and trivial; for a managed version, see
 * #UniqueFileDescriptor.
 */
class FileDescriptor {
protected:
	int fd;

public:
	FileDescriptor() = default;
	explicit constexpr FileDescriptor(int _fd):fd(_fd) {}

	constexpr bool operator==(FileDescriptor other) const {
		return fd == other.fd;
	}

	constexpr bool IsDefined() const {
		return fd >= 0;
	}

	/**
	 * Returns the file descriptor.  This may only be called if
	 * IsDefined() returns true.
	 */
	constexpr int Get() const {
		return fd;
	}

	void Set(int _fd) {
		fd = _fd;
	}

	int Steal() {
		assert(IsDefined());

		int _fd = fd;
		fd = -1;
		return _fd;
	}

	void SetUndefined() {
		fd = -1;
	}

	static constexpr FileDescriptor Undefined() {
		return FileDescriptor(-1);
	}

	bool Open(const char *pathname, int flags, mode_t mode=0666);
	bool OpenReadOnly(const char *pathname);

#ifdef HAVE_POSIX
	bool OpenNonBlocking(const char *pathname);

	static bool CreatePipe(FileDescriptor &r, FileDescriptor &w);

	/**
	 * Enable non-blocking mode on this file descriptor.
	 */
	void SetNonBlocking();

	/**
	 * Enable blocking mode on this file descriptor.
	 */
	void SetBlocking();

	/**
	 * Duplicate the file descriptor onto the given file descriptor.
	 */
	bool Duplicate(int new_fd) const {
		return ::dup2(Get(), new_fd) == 0;
	}
#endif

#ifdef HAVE_EVENTFD
	bool CreateEventFD(unsigned initval=0);
#endif

#ifdef HAVE_SIGNALFD
	bool CreateSignalFD(const sigset_t *mask);
#endif

#ifdef HAVE_INOTIFY
	bool CreateInotify();
#endif

	/**
	 * Close the file descriptor.  It is legal to call it on an
	 * "undefined" object.  After this call, IsDefined() is guaranteed
	 * to return false, and this object may be reused.
	 */
	bool Close() {
		return ::close(Steal()) == 0;
	}

	/**
	 * Rewind the pointer to the beginning of the file.
	 */
	bool Rewind();

	off_t Seek(off_t offset) {
		return lseek(Get(), offset, SEEK_SET);
	}

	off_t Skip(off_t offset) {
		return lseek(Get(), offset, SEEK_CUR);
	}

	gcc_pure
	off_t Tell() const {
		return lseek(Get(), 0, SEEK_CUR);
	}

	/**
	 * Returns the size of the file in bytes, or -1 on error.
	 */
	gcc_pure
	off_t GetSize() const;

	ssize_t Read(void *buffer, size_t length) {
		return ::read(fd, buffer, length);
	}

	ssize_t Write(const void *buffer, size_t length) {
		return ::write(fd, buffer, length);
	}

#ifdef HAVE_POSIX
	int Poll(short events, int timeout) const;

	int WaitReadable(int timeout) const;
	int WaitWritable(int timeout) const;
#endif
};

#endif
<commit_msg>system/FileDescriptor: Close() should not be called on undefined object<commit_after>/*
 * Copyright (C) 2012-2015 Max Kellermann <max@duempel.org>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the
 * distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
 * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef FILE_DESCRIPTOR_HXX
#define FILE_DESCRIPTOR_HXX

#include <inline/compiler.h>

#include <assert.h>
#include <unistd.h>
#include <sys/types.h>

#ifdef __linux__
#define HAVE_POSIX
#define HAVE_EVENTFD
#define HAVE_SIGNALFD
#define HAVE_INOTIFY
#include <signal.h>
#endif

/**
 * An OO wrapper for a UNIX file descriptor.
 *
 * This class is unmanaged and trivial; for a managed version, see
 * #UniqueFileDescriptor.
 */
class FileDescriptor {
protected:
	int fd;

public:
	FileDescriptor() = default;
	explicit constexpr FileDescriptor(int _fd):fd(_fd) {}

	constexpr bool operator==(FileDescriptor other) const {
		return fd == other.fd;
	}

	constexpr bool IsDefined() const {
		return fd >= 0;
	}

	/**
	 * Returns the file descriptor.  This may only be called if
	 * IsDefined() returns true.
	 */
	constexpr int Get() const {
		return fd;
	}

	void Set(int _fd) {
		fd = _fd;
	}

	int Steal() {
		assert(IsDefined());

		int _fd = fd;
		fd = -1;
		return _fd;
	}

	void SetUndefined() {
		fd = -1;
	}

	static constexpr FileDescriptor Undefined() {
		return FileDescriptor(-1);
	}

	bool Open(const char *pathname, int flags, mode_t mode=0666);
	bool OpenReadOnly(const char *pathname);

#ifdef HAVE_POSIX
	bool OpenNonBlocking(const char *pathname);

	static bool CreatePipe(FileDescriptor &r, FileDescriptor &w);

	/**
	 * Enable non-blocking mode on this file descriptor.
	 */
	void SetNonBlocking();

	/**
	 * Enable blocking mode on this file descriptor.
	 */
	void SetBlocking();

	/**
	 * Duplicate the file descriptor onto the given file descriptor.
	 */
	bool Duplicate(int new_fd) const {
		return ::dup2(Get(), new_fd) == 0;
	}
#endif

#ifdef HAVE_EVENTFD
	bool CreateEventFD(unsigned initval=0);
#endif

#ifdef HAVE_SIGNALFD
	bool CreateSignalFD(const sigset_t *mask);
#endif

#ifdef HAVE_INOTIFY
	bool CreateInotify();
#endif

	/**
	 * Close the file descriptor.  It should not be called on an
	 * "undefined" object.  After this call, IsDefined() is guaranteed
	 * to return false, and this object may be reused.
	 */
	bool Close() {
		return ::close(Steal()) == 0;
	}

	/**
	 * Rewind the pointer to the beginning of the file.
	 */
	bool Rewind();

	off_t Seek(off_t offset) {
		return lseek(Get(), offset, SEEK_SET);
	}

	off_t Skip(off_t offset) {
		return lseek(Get(), offset, SEEK_CUR);
	}

	gcc_pure
	off_t Tell() const {
		return lseek(Get(), 0, SEEK_CUR);
	}

	/**
	 * Returns the size of the file in bytes, or -1 on error.
	 */
	gcc_pure
	off_t GetSize() const;

	ssize_t Read(void *buffer, size_t length) {
		return ::read(fd, buffer, length);
	}

	ssize_t Write(const void *buffer, size_t length) {
		return ::write(fd, buffer, length);
	}

#ifdef HAVE_POSIX
	int Poll(short events, int timeout) const;

	int WaitReadable(int timeout) const;
	int WaitWritable(int timeout) const;
#endif
};

#endif
<|endoftext|>


<commit_before>/*

@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)

*/

#ifndef BOOST_CLBL_TRTS_HAS_VARARGS_HPP
#define BOOST_CLBL_TRTS_HAS_VARARGS_HPP

#include <boost/callable_traits/detail/core.hpp>

namespace boost { namespace callable_traits {

//[ has_varargs_hpp
/*`[section:ref_has_varargs has_varargs]
[heading Header]
``#include <boost/callable_traits/has_varargs.hpp>``
[heading Definition]
*/

// inherits from either std::true_type or std::false_type
template<typename T>
struct has_varargs;

//<-
template<typename T>
struct has_varargs : detail::traits<
    detail::shallow_decay<T>>::has_varargs {

    using type = typename detail::traits<
        detail::shallow_decay<T>>::has_varargs;
};

#ifdef BOOST_CLBL_TRTS_DISABLE_VARIABLE_TEMPLATES

template<typename T>
struct has_varargs_v {
    static_assert(std::is_same<T, detail::dummy>::value,
        "Variable templates not supported on this compiler.");
};

#else
//->
// only available when variable templates are supported
template<typename T>
//<-
BOOST_CLBL_TRAITS_INLINE_VAR
//->
constexpr bool has_varargs_v = //see below
//<-
    detail::traits<detail::shallow_decay<T>>::has_varargs::value;

#endif

}} // namespace boost::callable_traits
//->

/*`
[heading Constraints]
* none

[heading Behavior]
* `std::false_type` is inherited by `has_varargs<T>` and is aliased by `typename has_varargs<T>::type`, except when one of the following criteria is met, in which case `std::true_type` would be similarly inherited and aliased:
  * `T` is a function, function pointer, or function reference where the function's parameter list includes C-style variadics.
  * `T` is a pointer to a member function with C-style variadics in the parameter list.
  * `T` is a function object with a non-overloaded `operator()`, which has C-style variadics in the parameter list of its `operator()`.
* On compilers that support variable templates, `has_varargs_v<T>` is equivalent to `has_varargs<T>::value`.

[heading Input/Output Examples]
[table
    [[`T`]                              [`has_varargs_v<T>`]]
    [[`void(...)`]                      [`true`]]
    [[`void(int, ...) const`]           [`true`]]
    [[`void(* volatile)(...)`]          [`true`]]
    [[`void(&)(...)`]                   [`true`]]
    [[`void(foo::*)(...) const`]        [`true`]]
    [[`void(*)()`]                      [`false`]]
    [[`void(*&)()`]                     [`false`]]
    [[`int`]                            [`false`]]
    [[`const int`]                      [`false`]]
    [[`int foo::*`]                     [`false`]]
]

[heading Example Program]
[import ../example/has_varargs.cpp]
[has_varargs]
[endsect]
*/
//]

#endif
<commit_msg>Delete has_varargs.hpp<commit_after><|endoftext|>


<commit_before>AliAnalysisTask *AddTask_miweber_LMEE_PbPb_woCutLib(Int_t cutDefinition = 0, TString outputFileName = "AnalysisResult.root", TString directoryBaseName = "miweber_LMEE_PbPb", Bool_t isNano = kFALSE, Bool_t bCutQA = kTRUE){

  //get the current analysis manager
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    Error("AddTask_miweber_LMEE_PbPb_woCutLib", "No analysis manager found.");
    return 0;
  }

  Bool_t bESDANA=kFALSE; //Autodetect via InputHandler

  TString configBasePath("$ALICE_PHYSICS/PWGDQ/dielectron/macrosLMEE/");
  TString configFile("Config_miweber_LMEE_PbPb_woCutLib.C");
  TString configFilePath(configBasePath+configFile);

  //load dielectron configuration files
  if (!gROOT->GetListOfGlobalFunctions()->FindObject(configFile.Data()))
    gROOT->LoadMacro(configFilePath.Data());

  //Do we have an MC handler?
  Bool_t hasMC=(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler()!=0x0);

  //AOD Usage currently tested with Input handler
  if (mgr->GetInputEventHandler()->IsA()==AliAODInputHandler::Class()){
    ::Info("AddTask_miweber_LMEE_PbPb_woCutLib", "no dedicated AOD configuration");
  }
  else if (mgr->GetInputEventHandler()->IsA()==AliESDInputHandler::Class()){
    ::Info("AddTask_miweber_LMEE_PbPb_woCutLib","switching on ESD specific code");
    bESDANA=kTRUE;
  }

  //create task and add it to the manager
  AliAnalysisTaskMultiDielectron *task=new AliAnalysisTaskMultiDielectron("MultiDiEData_miweber_PbPb_woCutLib");

  // for MC no  need for physics selection and for Nano AODs this has been done already
  if (!hasMC && !isNano) task->UsePhysicsSelection();

  //Add event filter
  Int_t triggerNames = AliVEvent::kINT7;//PbPb Min Bias, can be set also from outside

  // for Nano AODs this has been done already
  if(!isNano){
    task->SelectCollisionCandidates(triggerNames);
    task->SetTriggerMask(triggerNames);
    // task->SetRejectPileup(); // to be done differently (too strong cuts at the moment in dielectron framework)
  }

  // Note: event cuts are identical for all analysis 'cutDefinition's that run together!

  //Add event filter
  task->SetEventFilter( GetEventCuts() );

  // Add the task to the manager
  mgr->AddTask(task);

  //add dielectron analysis with selected cut to the task
  AliDielectron *diel_low = Config_miweber_LMEE_PbPb_woCutLib(cutDefinition,bESDANA,bCutQA);
  if(diel_low){
    task->AddDielectron(diel_low);
    printf("successfully added AliDielectron: %s\n",diel_low->GetName());
  }

  //create output container
  AliAnalysisDataContainer *coutput1 =
    mgr->CreateContainer(Form("%s_tree",directoryBaseName.Data()),
                         TTree::Class(),
                         AliAnalysisManager::kExchangeContainer,
                         outputFileName.Data());

  AliAnalysisDataContainer *cOutputHist1 =
    mgr->CreateContainer(Form("%s_out",directoryBaseName.Data()),
                         TList::Class(),
                         AliAnalysisManager::kOutputContainer,
                         outputFileName.Data());

  AliAnalysisDataContainer *cOutputHist2 =
    mgr->CreateContainer(Form("%s_CF",directoryBaseName.Data()),
                         TList::Class(),
                         AliAnalysisManager::kOutputContainer,
                         outputFileName.Data());
  //                         "miweber_LMEE_PbPb_CF.root");

  AliAnalysisDataContainer *cOutputHist3 =
    mgr->CreateContainer(Form("%s_EventStat",directoryBaseName.Data()),
                         TH1D::Class(),
                         AliAnalysisManager::kOutputContainer,
                         outputFileName.Data());

  mgr->ConnectInput(task,  0, mgr->GetCommonInputContainer());
  mgr->ConnectOutput(task, 0, coutput1 );
  mgr->ConnectOutput(task, 1, cOutputHist1);
  mgr->ConnectOutput(task, 2, cOutputHist2);
  mgr->ConnectOutput(task, 3, cOutputHist3);

  return task;
}
<commit_msg>Added event plane cut in event cuts<commit_after>AliAnalysisTask *AddTask_miweber_LMEE_PbPb_woCutLib(Int_t cutDefinition = 0, TString outputFileName = "AnalysisResult.root", TString directoryBaseName = "miweber_LMEE_PbPb", Bool_t isNano = kFALSE, Bool_t bCutQA = kTRUE){

  //get the current analysis manager
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    Error("AddTask_miweber_LMEE_PbPb_woCutLib", "No analysis manager found.");
    return 0;
  }

  Bool_t bESDANA=kFALSE; //Autodetect via InputHandler

  TString configBasePath("$ALICE_PHYSICS/PWGDQ/dielectron/macrosLMEE/");
  TString configFile("Config_miweber_LMEE_PbPb_woCutLib.C");
  TString configFilePath(configBasePath+configFile);

  //load dielectron configuration files
  if (!gROOT->GetListOfGlobalFunctions()->FindObject(configFile.Data()))
    gROOT->LoadMacro(configFilePath.Data());

  //Do we have an MC handler?
  Bool_t hasMC=(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler()!=0x0);

  //AOD Usage currently tested with Input handler
  if (mgr->GetInputEventHandler()->IsA()==AliAODInputHandler::Class()){
    ::Info("AddTask_miweber_LMEE_PbPb_woCutLib", "no dedicated AOD configuration");
  }
  else if (mgr->GetInputEventHandler()->IsA()==AliESDInputHandler::Class()){
    ::Info("AddTask_miweber_LMEE_PbPb_woCutLib","switching on ESD specific code");
    bESDANA=kTRUE;
  }

  //create task and add it to the manager
  AliAnalysisTaskMultiDielectron *task=new AliAnalysisTaskMultiDielectron("MultiDiEData_miweber_PbPb_woCutLib");

  // for MC no  need for physics selection and for Nano AODs this has been done already
  if (!hasMC && !isNano) task->UsePhysicsSelection();

  //Add event filter
  Int_t triggerNames = AliVEvent::kINT7;//PbPb Min Bias, can be set also from outside

  // for Nano AODs this has been done already
  if(!isNano){
    task->SelectCollisionCandidates(triggerNames);
    task->SetTriggerMask(triggerNames);
    // task->SetRejectPileup(); // to be done differently (too strong cuts at the moment in dielectron framework)
  }

  // Note: event cuts are identical for all analysis 'cutDefinition's that run together!

  //Add event filter
  task->SetEventFilter( GetEventCuts() );

  // Add the task to the manager
  mgr->AddTask(task);

  //add dielectron analysis with selected cut to the task
  AliDielectron *diel_low = Config_miweber_LMEE_PbPb_woCutLib(cutDefinition,bESDANA,bCutQA);
  if(diel_low){
    AliDielectronVarCuts *eventplaneCuts = new AliDielectronVarCuts("eventplaneCuts","eventplaneCuts");
    eventplaneCuts->AddCut(AliDielectronVarManager::kQnTPCrpH2,-999.,kTRUE); // makes sure that the event has an eventplane
    eventplaneCuts->Print();
    diel_low->GetEventFilter().AddCuts(eventplaneCuts);

    task->AddDielectron(diel_low);
    printf("successfully added AliDielectron: %s\n",diel_low->GetName());
  }

  //create output container
  AliAnalysisDataContainer *coutput1 =
    mgr->CreateContainer(Form("%s_tree",directoryBaseName.Data()),
                         TTree::Class(),
                         AliAnalysisManager::kExchangeContainer,
                         outputFileName.Data());

  AliAnalysisDataContainer *cOutputHist1 =
    mgr->CreateContainer(Form("%s_out",directoryBaseName.Data()),
                         TList::Class(),
                         AliAnalysisManager::kOutputContainer,
                         outputFileName.Data());

  AliAnalysisDataContainer *cOutputHist2 =
    mgr->CreateContainer(Form("%s_CF",directoryBaseName.Data()),
                         TList::Class(),
                         AliAnalysisManager::kOutputContainer,
                         outputFileName.Data());
  //                         "miweber_LMEE_PbPb_CF.root");

  AliAnalysisDataContainer *cOutputHist3 =
    mgr->CreateContainer(Form("%s_EventStat",directoryBaseName.Data()),
                         TH1D::Class(),
                         AliAnalysisManager::kOutputContainer,
                         outputFileName.Data());

  mgr->ConnectInput(task,  0, mgr->GetCommonInputContainer());
  mgr->ConnectOutput(task, 0, coutput1 );
  mgr->ConnectOutput(task, 1, cOutputHist1);
  mgr->ConnectOutput(task, 2, cOutputHist2);
  mgr->ConnectOutput(task, 3, cOutputHist3);

  return task;
}
<|endoftext|>


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

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center (DKFZ)
All rights reserved.

Use of this source code is governed by a 3-clause BSD license that can be
found in the LICENSE file.

============================================================================*/
#include "QmitkAutocropAction.h"

#include "mitkAutoCropImageFilter.h"
#include "mitkImageCast.h"
#include "mitkImageWriteAccessor.h"
#include "mitkRenderingManager.h"
#include "mitkProgressBar.h"

#include <itkConstantPadImageFilter.h>

//needed for qApp
#include <qcoreapplication.h>

QmitkAutocropAction::QmitkAutocropAction()
{
}

QmitkAutocropAction::~QmitkAutocropAction()
{
}

void QmitkAutocropAction::Run( const QList<mitk::DataNode::Pointer> &selectedNodes )
{
  foreach ( mitk::DataNode::Pointer node, selectedNodes )
  {
    if (node)
    {
      mitk::Image::Pointer image = dynamic_cast<mitk::Image*>( node->GetData() );
      if (image.IsNull()) return;

      mitk::ProgressBar::GetInstance()->AddStepsToDo(10);
      mitk::ProgressBar::GetInstance()->Progress(2);

      qApp->processEvents();

      mitk::AutoCropImageFilter::Pointer cropFilter = mitk::AutoCropImageFilter::New();
      cropFilter->SetInput( image );
      cropFilter->SetBackgroundValue( 0 );
      try
      {
        cropFilter->Update();

        image = cropFilter->GetOutput();

        if (image.IsNotNull())
        {

          if (image->GetDimension() == 4)
          {
            MITK_INFO << "4D AUTOCROP DOES NOT WORK AT THE MOMENT";
            throw "4D AUTOCROP DOES NOT WORK AT THE MOMENT";

            unsigned int timesteps = image->GetDimension(3);
            for (unsigned int i = 0; i < timesteps; i++)
            {
              mitk::ImageTimeSelector::Pointer imageTimeSelector = mitk::ImageTimeSelector::New();
              imageTimeSelector->SetInput(image);
              imageTimeSelector->SetTimeNr(i);
              imageTimeSelector->UpdateLargestPossibleRegion();

              // We split a long nested code line into separate calls for debugging:
              mitk::ImageSource::OutputImageType *_3dSlice = imageTimeSelector->GetOutput();
              mitk::Image::Pointer _cropped3dSlice = this->IncreaseCroppedImageSize(_3dSlice);

              // +++ BUG +++ BUG +++ BUG +++ BUG +++ BUG +++ BUG +++ BUG +++
              mitk::ImageWriteAccessor imAccess(_cropped3dSlice);
              void *_data = imAccess.GetData();

              // <ToBeRemoved>
              // We write some stripes into the image
              if ((i & 1) == 0)
              {
              int depth = _cropped3dSlice->GetDimension(2);
              int height = _cropped3dSlice->GetDimension(1);
              int width = _cropped3dSlice->GetDimension(0);

              for (int z = 0; z < depth; ++z)
                for (int y = 0; y < height; ++y)
                  for (int x = 0; x < width; ++x)
                    reinterpret_cast<unsigned char *>(_data)[(width * height * z) + (width * y) + x] = x & 1;
              // </ToBeRemoved>
              }

              image->SetVolume(_data, i);
            }
            node->SetData( image ); // bug fix 3145
          }
          else
          {
            node->SetData( this->IncreaseCroppedImageSize(image) ); // bug fix 3145
          }
          // Reinit node
          mitk::RenderingManager::GetInstance()->InitializeViews(
            node->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true );
          mitk::RenderingManager::GetInstance()->RequestUpdateAll();

        }
      }
      catch(...)
      {
        MITK_ERROR << "Cropping image failed...";
      }
      mitk::ProgressBar::GetInstance()->Progress(8);
    }
    else
    {
      MITK_INFO << "   a nullptr node selected";
    }
  }
}

mitk::Image::Pointer QmitkAutocropAction::IncreaseCroppedImageSize( mitk::Image::Pointer image )
{
  typedef itk::Image< short, 3 > ImageType;
  typedef itk::Image< unsigned char, 3 > PADOutputImageType;

  ImageType::Pointer itkTransformImage = ImageType::New();
  mitk::CastToItkImage( image, itkTransformImage );

  typedef itk::ConstantPadImageFilter< ImageType, PADOutputImageType > PadFilterType;
  PadFilterType::Pointer padFilter = PadFilterType::New();

  itk::SizeValueType upperPad[3];
  itk::SizeValueType lowerPad[3];
  int borderLiner = 3;

  mitk::Point3D mitkOriginPoint;
  double origin[3];
  origin[0]=0;
  origin[1]=0;
  origin[2]=0;
  itkTransformImage->SetOrigin(origin);

  lowerPad[0]=borderLiner;
  lowerPad[1]=borderLiner;
  lowerPad[2]=borderLiner;

  upperPad[0]=borderLiner;
  upperPad[1]=borderLiner;
  upperPad[2]=borderLiner;

  padFilter->SetInput(itkTransformImage);
  padFilter->SetConstant(0);
  padFilter->SetPadUpperBound(upperPad);
  padFilter->SetPadLowerBound(lowerPad);
  padFilter->UpdateLargestPossibleRegion();

  mitk::Image::Pointer paddedImage = mitk::Image::New();
  paddedImage->InitializeByItk(padFilter->GetOutput());
  mitk::CastToMitkImage(padFilter->GetOutput(), paddedImage);

  //calculate translation according to padding to get the new origin
  mitk::Point3D paddedOrigin = image->GetGeometry()->GetOrigin();
  mitk::Vector3D spacing = image->GetGeometry()->GetSpacing();
  paddedOrigin[0] -= (borderLiner)*spacing[0];
  paddedOrigin[1] -= (borderLiner)*spacing[1];
  paddedOrigin[2] -= (borderLiner)*spacing[2];

  paddedImage->GetGeometry()->SetOrigin( paddedOrigin );

  return paddedImage;
}

void QmitkAutocropAction::SetSmoothed(bool /*smoothed*/)
{
 //not needed
}

void QmitkAutocropAction::SetDecimated(bool /*decimated*/)
{
  //not needed
}

void QmitkAutocropAction::SetDataStorage(mitk::DataStorage* /*dataStorage*/)
{
  //not needed
}

void QmitkAutocropAction::SetFunctionality(berry::QtViewPart* /*view*/)
{
  //not needed
}
<commit_msg>Do not request a rendering update twice<commit_after>/*============================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center (DKFZ)
All rights reserved.

Use of this source code is governed by a 3-clause BSD license that can be
found in the LICENSE file.

============================================================================*/
#include "QmitkAutocropAction.h"

#include "mitkAutoCropImageFilter.h"
#include "mitkImageCast.h"
#include "mitkImageWriteAccessor.h"
#include "mitkRenderingManager.h"
#include "mitkProgressBar.h"

#include <itkConstantPadImageFilter.h>

//needed for qApp
#include <qcoreapplication.h>

QmitkAutocropAction::QmitkAutocropAction()
{
}

QmitkAutocropAction::~QmitkAutocropAction()
{
}

void QmitkAutocropAction::Run( const QList<mitk::DataNode::Pointer> &selectedNodes )
{
  foreach ( mitk::DataNode::Pointer node, selectedNodes )
  {
    if (node)
    {
      mitk::Image::Pointer image = dynamic_cast<mitk::Image*>( node->GetData() );
      if (image.IsNull()) return;

      mitk::ProgressBar::GetInstance()->AddStepsToDo(10);
      mitk::ProgressBar::GetInstance()->Progress(2);

      qApp->processEvents();

      mitk::AutoCropImageFilter::Pointer cropFilter = mitk::AutoCropImageFilter::New();
      cropFilter->SetInput( image );
      cropFilter->SetBackgroundValue( 0 );
      try
      {
        cropFilter->Update();

        image = cropFilter->GetOutput();

        if (image.IsNotNull())
        {

          if (image->GetDimension() == 4)
          {
            MITK_INFO << "4D AUTOCROP DOES NOT WORK AT THE MOMENT";
            throw "4D AUTOCROP DOES NOT WORK AT THE MOMENT";

            unsigned int timesteps = image->GetDimension(3);
            for (unsigned int i = 0; i < timesteps; i++)
            {
              mitk::ImageTimeSelector::Pointer imageTimeSelector = mitk::ImageTimeSelector::New();
              imageTimeSelector->SetInput(image);
              imageTimeSelector->SetTimeNr(i);
              imageTimeSelector->UpdateLargestPossibleRegion();

              // We split a long nested code line into separate calls for debugging:
              mitk::ImageSource::OutputImageType *_3dSlice = imageTimeSelector->GetOutput();
              mitk::Image::Pointer _cropped3dSlice = this->IncreaseCroppedImageSize(_3dSlice);

              // +++ BUG +++ BUG +++ BUG +++ BUG +++ BUG +++ BUG +++ BUG +++
              mitk::ImageWriteAccessor imAccess(_cropped3dSlice);
              void *_data = imAccess.GetData();

              // <ToBeRemoved>
              // We write some stripes into the image
              if ((i & 1) == 0)
              {
              int depth = _cropped3dSlice->GetDimension(2);
              int height = _cropped3dSlice->GetDimension(1);
              int width = _cropped3dSlice->GetDimension(0);

              for (int z = 0; z < depth; ++z)
                for (int y = 0; y < height; ++y)
                  for (int x = 0; x < width; ++x)
                    reinterpret_cast<unsigned char *>(_data)[(width * height * z) + (width * y) + x] = x & 1;
              // </ToBeRemoved>
              }

              image->SetVolume(_data, i);
            }
            node->SetData( image ); // bug fix 3145
          }
          else
          {
            node->SetData( this->IncreaseCroppedImageSize(image) ); // bug fix 3145
          }
          // Reinit node
          mitk::RenderingManager::GetInstance()->InitializeViews(
            node->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true);
        }
      }
      catch(...)
      {
        MITK_ERROR << "Cropping image failed...";
      }
      mitk::ProgressBar::GetInstance()->Progress(8);
    }
    else
    {
      MITK_INFO << "   a nullptr node selected";
    }
  }
}

mitk::Image::Pointer QmitkAutocropAction::IncreaseCroppedImageSize( mitk::Image::Pointer image )
{
  typedef itk::Image< short, 3 > ImageType;
  typedef itk::Image< unsigned char, 3 > PADOutputImageType;

  ImageType::Pointer itkTransformImage = ImageType::New();
  mitk::CastToItkImage( image, itkTransformImage );

  typedef itk::ConstantPadImageFilter< ImageType, PADOutputImageType > PadFilterType;
  PadFilterType::Pointer padFilter = PadFilterType::New();

  itk::SizeValueType upperPad[3];
  itk::SizeValueType lowerPad[3];
  int borderLiner = 3;

  mitk::Point3D mitkOriginPoint;
  double origin[3];
  origin[0]=0;
  origin[1]=0;
  origin[2]=0;
  itkTransformImage->SetOrigin(origin);

  lowerPad[0]=borderLiner;
  lowerPad[1]=borderLiner;
  lowerPad[2]=borderLiner;

  upperPad[0]=borderLiner;
  upperPad[1]=borderLiner;
  upperPad[2]=borderLiner;

  padFilter->SetInput(itkTransformImage);
  padFilter->SetConstant(0);
  padFilter->SetPadUpperBound(upperPad);
  padFilter->SetPadLowerBound(lowerPad);
  padFilter->UpdateLargestPossibleRegion();

  mitk::Image::Pointer paddedImage = mitk::Image::New();
  paddedImage->InitializeByItk(padFilter->GetOutput());
  mitk::CastToMitkImage(padFilter->GetOutput(), paddedImage);

  //calculate translation according to padding to get the new origin
  mitk::Point3D paddedOrigin = image->GetGeometry()->GetOrigin();
  mitk::Vector3D spacing = image->GetGeometry()->GetSpacing();
  paddedOrigin[0] -= (borderLiner)*spacing[0];
  paddedOrigin[1] -= (borderLiner)*spacing[1];
  paddedOrigin[2] -= (borderLiner)*spacing[2];

  paddedImage->GetGeometry()->SetOrigin( paddedOrigin );

  return paddedImage;
}

void QmitkAutocropAction::SetSmoothed(bool /*smoothed*/)
{
 //not needed
}

void QmitkAutocropAction::SetDecimated(bool /*decimated*/)
{
  //not needed
}

void QmitkAutocropAction::SetDataStorage(mitk::DataStorage* /*dataStorage*/)
{
  //not needed
}

void QmitkAutocropAction::SetFunctionality(berry::QtViewPart* /*view*/)
{
  //not needed
}
<|endoftext|>


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

#include "base/file_util.h"
#include "base/path_service.h"
#include "chrome/browser/extensions/api/file_system/file_system_api.h"
#include "chrome/browser/extensions/platform_app_browsertest_util.h"

using extensions::FileSystemChooseEntryFunction;

class FileSystemApiTest : public extensions::PlatformAppBrowserTest {
 public:
  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
    extensions::PlatformAppBrowserTest::SetUpCommandLine(command_line);
    test_root_folder_ = test_data_dir_.AppendASCII("api_test")
        .AppendASCII("file_system");
  }

  virtual void TearDown() OVERRIDE {
    FileSystemChooseEntryFunction::StopSkippingPickerForTest();
    extensions::PlatformAppBrowserTest::TearDown();
  };

 protected:
  base::FilePath TempFilePath(const std::string& destination_name,
                              bool copy_gold) {
    if (!temp_dir_.CreateUniqueTempDir()) {
      ADD_FAILURE() << "CreateUniqueTempDir failed";
      return base::FilePath();
    }
    base::FilePath destination = temp_dir_.path().AppendASCII(destination_name);
    if (copy_gold) {
      base::FilePath source = test_root_folder_.AppendASCII("gold.txt");
      EXPECT_TRUE(file_util::CopyFile(source, destination));
    }
    return destination;
  }

  base::FilePath test_root_folder_;
  base::ScopedTempDir temp_dir_;
};

IN_PROC_BROWSER_TEST_F(FileSystemApiTest, FileSystemApiGetDisplayPath) {
  base::FilePath test_file = test_root_folder_.AppendASCII("gold.txt");
  FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
      &test_file);
  ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/get_display_path"))
      << message_;
}

#if defined(OS_WIN) || defined(OS_POSIX)
IN_PROC_BROWSER_TEST_F(FileSystemApiTest, FileSystemApiGetDisplayPathPrettify) {
#if defined(OS_WIN)
  int override = base::DIR_PROFILE;
#elif defined(OS_POSIX)
  int override = base::DIR_HOME;
#endif
  ASSERT_TRUE(PathService::OverrideAndCreateIfNeeded(override,
      test_root_folder_, false));

  base::FilePath test_file = test_root_folder_.AppendASCII("gold.txt");
  FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
      &test_file);
  ASSERT_TRUE(RunPlatformAppTest(
      "api_test/file_system/get_display_path_prettify")) << message_;
}
#endif

#if defined(OS_MACOSX)
IN_PROC_BROWSER_TEST_F(FileSystemApiTest,
    FileSystemApiGetDisplayPathPrettifyMac) {
  // On Mac, "test.localized" will be localized into just "test".
  base::FilePath test_path = TempFilePath("test.localized", false);
  ASSERT_TRUE(file_util::CreateDirectory(test_path));

  base::FilePath test_file = test_path.AppendASCII("gold.txt");
  base::FilePath source = test_root_folder_.AppendASCII("gold.txt");
  EXPECT_TRUE(file_util::CopyFile(source, test_file));

  FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
      &test_file);
  ASSERT_TRUE(RunPlatformAppTest(
      "api_test/file_system/get_display_path_prettify_mac")) << message_;
}
#endif

IN_PROC_BROWSER_TEST_F(FileSystemApiTest, FileSystemApiOpenExistingFileTest) {
  base::FilePath test_file = TempFilePath("open_existing.txt", true);
  ASSERT_FALSE(test_file.empty());
  FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
      &test_file);
  ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/open_existing"))
      << message_;
}

IN_PROC_BROWSER_TEST_F(FileSystemApiTest,
    FileSystemApiInvalidChooseEntryTypeTest) {
  base::FilePath test_file = TempFilePath("open_existing.txt", true);
  ASSERT_FALSE(test_file.empty());
  FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
      &test_file);
  ASSERT_TRUE(RunPlatformAppTest(
      "api_test/file_system/invalid_choose_file_type")) << message_;
}

IN_PROC_BROWSER_TEST_F(FileSystemApiTest,
    FileSystemApiOpenExistingFileWithWriteTest) {
  base::FilePath test_file = TempFilePath("open_existing.txt", true);
  ASSERT_FALSE(test_file.empty());
  FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
      &test_file);
  ASSERT_TRUE(RunPlatformAppTest(
      "api_test/file_system/open_existing_with_write")) << message_;
}

IN_PROC_BROWSER_TEST_F(FileSystemApiTest,
    FileSystemApiOpenWritableExistingFileTest) {
  base::FilePath test_file = TempFilePath("open_existing.txt", true);
  ASSERT_FALSE(test_file.empty());
  FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
      &test_file);
  ASSERT_TRUE(RunPlatformAppTest(
      "api_test/file_system/open_writable_existing")) << message_;
}

IN_PROC_BROWSER_TEST_F(FileSystemApiTest,
    FileSystemApiOpenWritableExistingFileWithWriteTest) {
  base::FilePath test_file = TempFilePath("open_existing.txt", true);
  ASSERT_FALSE(test_file.empty());
  FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
      &test_file);
  ASSERT_TRUE(RunPlatformAppTest(
      "api_test/file_system/open_writable_existing_with_write")) << message_;
}

IN_PROC_BROWSER_TEST_F(FileSystemApiTest, FileSystemApiOpenCancelTest) {
  FileSystemChooseEntryFunction::SkipPickerAndAlwaysCancelForTest();
  ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/open_cancel"))
      << message_;
}

IN_PROC_BROWSER_TEST_F(FileSystemApiTest, FileSystemApiOpenBackgroundTest) {
  ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/open_background"))
      << message_;
}

IN_PROC_BROWSER_TEST_F(FileSystemApiTest, FileSystemApiSaveNewFileTest) {
  base::FilePath test_file = TempFilePath("save_new.txt", false);
  ASSERT_FALSE(test_file.empty());
  FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
      &test_file);
  ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/save_new"))
      << message_;
}

IN_PROC_BROWSER_TEST_F(FileSystemApiTest, FileSystemApiSaveExistingFileTest) {
  base::FilePath test_file = TempFilePath("save_existing.txt", true);
  ASSERT_FALSE(test_file.empty());
  FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
      &test_file);
  ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/save_existing"))
      << message_;
}

IN_PROC_BROWSER_TEST_F(FileSystemApiTest,
    FileSystemApiSaveNewFileWithWriteTest) {
  base::FilePath test_file = TempFilePath("save_new.txt", false);
  ASSERT_FALSE(test_file.empty());
  FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
      &test_file);
  ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/save_new_with_write"))
      << message_;
}

IN_PROC_BROWSER_TEST_F(FileSystemApiTest,
    FileSystemApiSaveExistingFileWithWriteTest) {
  base::FilePath test_file = TempFilePath("save_existing.txt", true);
  ASSERT_FALSE(test_file.empty());
  FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
      &test_file);
  ASSERT_TRUE(RunPlatformAppTest(
      "api_test/file_system/save_existing_with_write")) << message_;
}

IN_PROC_BROWSER_TEST_F(FileSystemApiTest, FileSystemApiSaveCancelTest) {
  FileSystemChooseEntryFunction::SkipPickerAndAlwaysCancelForTest();
  ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/save_cancel"))
      << message_;
}

IN_PROC_BROWSER_TEST_F(FileSystemApiTest, FileSystemApiSaveBackgroundTest) {
  ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/save_background"))
      << message_;
}

IN_PROC_BROWSER_TEST_F(FileSystemApiTest, FileSystemApiGetWritableTest) {
  base::FilePath test_file = TempFilePath("writable.txt", true);
  ASSERT_FALSE(test_file.empty());
  FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
      &test_file);
  ASSERT_TRUE(RunPlatformAppTest(
      "api_test/file_system/get_writable_file_entry")) << message_;
}

IN_PROC_BROWSER_TEST_F(FileSystemApiTest,
    FileSystemApiGetWritableWithWriteTest) {
  base::FilePath test_file = TempFilePath("writable.txt", true);
  ASSERT_FALSE(test_file.empty());
  FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
      &test_file);
  ASSERT_TRUE(RunPlatformAppTest(
      "api_test/file_system/get_writable_file_entry_with_write")) << message_;
}

IN_PROC_BROWSER_TEST_F(FileSystemApiTest, FileSystemApiIsWritableTest) {
  base::FilePath test_file = TempFilePath("writable.txt", true);
  ASSERT_FALSE(test_file.empty());
  FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
      &test_file);
  ASSERT_TRUE(RunPlatformAppTest(
      "api_test/file_system/is_writable_file_entry")) << message_;
}

IN_PROC_BROWSER_TEST_F(FileSystemApiTest, FileSystemApiGetEntryId) {
  base::FilePath test_file = TempFilePath("writable.txt", true);
  ASSERT_FALSE(test_file.empty());
  FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
      &test_file);
  ASSERT_TRUE(RunPlatformAppTest(
      "api_test/file_system/get_entry_id")) << message_;
}
<commit_msg>Disable two FileSystemApiTests on Linux: FileSystemApiOpenBackgroundTest FileSystemApiSaveBackgroundTest<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/file_util.h"
#include "base/path_service.h"
#include "build/build_config.h"
#include "chrome/browser/extensions/api/file_system/file_system_api.h"
#include "chrome/browser/extensions/platform_app_browsertest_util.h"

using extensions::FileSystemChooseEntryFunction;

class FileSystemApiTest : public extensions::PlatformAppBrowserTest {
 public:
  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
    extensions::PlatformAppBrowserTest::SetUpCommandLine(command_line);
    test_root_folder_ = test_data_dir_.AppendASCII("api_test")
        .AppendASCII("file_system");
  }

  virtual void TearDown() OVERRIDE {
    FileSystemChooseEntryFunction::StopSkippingPickerForTest();
    extensions::PlatformAppBrowserTest::TearDown();
  };

 protected:
  base::FilePath TempFilePath(const std::string& destination_name,
                              bool copy_gold) {
    if (!temp_dir_.CreateUniqueTempDir()) {
      ADD_FAILURE() << "CreateUniqueTempDir failed";
      return base::FilePath();
    }
    base::FilePath destination = temp_dir_.path().AppendASCII(destination_name);
    if (copy_gold) {
      base::FilePath source = test_root_folder_.AppendASCII("gold.txt");
      EXPECT_TRUE(file_util::CopyFile(source, destination));
    }
    return destination;
  }

  base::FilePath test_root_folder_;
  base::ScopedTempDir temp_dir_;
};

IN_PROC_BROWSER_TEST_F(FileSystemApiTest, FileSystemApiGetDisplayPath) {
  base::FilePath test_file = test_root_folder_.AppendASCII("gold.txt");
  FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
      &test_file);
  ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/get_display_path"))
      << message_;
}

#if defined(OS_WIN) || defined(OS_POSIX)
IN_PROC_BROWSER_TEST_F(FileSystemApiTest, FileSystemApiGetDisplayPathPrettify) {
#if defined(OS_WIN)
  int override = base::DIR_PROFILE;
#elif defined(OS_POSIX)
  int override = base::DIR_HOME;
#endif
  ASSERT_TRUE(PathService::OverrideAndCreateIfNeeded(override,
      test_root_folder_, false));

  base::FilePath test_file = test_root_folder_.AppendASCII("gold.txt");
  FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
      &test_file);
  ASSERT_TRUE(RunPlatformAppTest(
      "api_test/file_system/get_display_path_prettify")) << message_;
}
#endif

#if defined(OS_MACOSX)
IN_PROC_BROWSER_TEST_F(FileSystemApiTest,
    FileSystemApiGetDisplayPathPrettifyMac) {
  // On Mac, "test.localized" will be localized into just "test".
  base::FilePath test_path = TempFilePath("test.localized", false);
  ASSERT_TRUE(file_util::CreateDirectory(test_path));

  base::FilePath test_file = test_path.AppendASCII("gold.txt");
  base::FilePath source = test_root_folder_.AppendASCII("gold.txt");
  EXPECT_TRUE(file_util::CopyFile(source, test_file));

  FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
      &test_file);
  ASSERT_TRUE(RunPlatformAppTest(
      "api_test/file_system/get_display_path_prettify_mac")) << message_;
}
#endif

IN_PROC_BROWSER_TEST_F(FileSystemApiTest, FileSystemApiOpenExistingFileTest) {
  base::FilePath test_file = TempFilePath("open_existing.txt", true);
  ASSERT_FALSE(test_file.empty());
  FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
      &test_file);
  ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/open_existing"))
      << message_;
}

IN_PROC_BROWSER_TEST_F(FileSystemApiTest,
    FileSystemApiInvalidChooseEntryTypeTest) {
  base::FilePath test_file = TempFilePath("open_existing.txt", true);
  ASSERT_FALSE(test_file.empty());
  FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
      &test_file);
  ASSERT_TRUE(RunPlatformAppTest(
      "api_test/file_system/invalid_choose_file_type")) << message_;
}

IN_PROC_BROWSER_TEST_F(FileSystemApiTest,
    FileSystemApiOpenExistingFileWithWriteTest) {
  base::FilePath test_file = TempFilePath("open_existing.txt", true);
  ASSERT_FALSE(test_file.empty());
  FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
      &test_file);
  ASSERT_TRUE(RunPlatformAppTest(
      "api_test/file_system/open_existing_with_write")) << message_;
}

IN_PROC_BROWSER_TEST_F(FileSystemApiTest,
    FileSystemApiOpenWritableExistingFileTest) {
  base::FilePath test_file = TempFilePath("open_existing.txt", true);
  ASSERT_FALSE(test_file.empty());
  FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
      &test_file);
  ASSERT_TRUE(RunPlatformAppTest(
      "api_test/file_system/open_writable_existing")) << message_;
}

IN_PROC_BROWSER_TEST_F(FileSystemApiTest,
    FileSystemApiOpenWritableExistingFileWithWriteTest) {
  base::FilePath test_file = TempFilePath("open_existing.txt", true);
  ASSERT_FALSE(test_file.empty());
  FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
      &test_file);
  ASSERT_TRUE(RunPlatformAppTest(
      "api_test/file_system/open_writable_existing_with_write")) << message_;
}

IN_PROC_BROWSER_TEST_F(FileSystemApiTest, FileSystemApiOpenCancelTest) {
  FileSystemChooseEntryFunction::SkipPickerAndAlwaysCancelForTest();
  ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/open_cancel"))
      << message_;
}

#if defined(OS_LINUX)
// Disabled on linux due to crbug.com/178679.
#define MAYBE_FileSystemApiSaveBackgroundTest \
    DISABLED_FileSystemApiOpenBackgroundTest
#else
#define MAYBE_FileSystemApiOpenBackgroundTest FileSystemApiOpenBackgroundTest
#endif
IN_PROC_BROWSER_TEST_F(FileSystemApiTest,
                       MAYBE_FileSystemApiOpenBackgroundTest) {
  ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/open_background"))
      << message_;
}

IN_PROC_BROWSER_TEST_F(FileSystemApiTest, FileSystemApiSaveNewFileTest) {
  base::FilePath test_file = TempFilePath("save_new.txt", false);
  ASSERT_FALSE(test_file.empty());
  FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
      &test_file);
  ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/save_new"))
      << message_;
}

IN_PROC_BROWSER_TEST_F(FileSystemApiTest, FileSystemApiSaveExistingFileTest) {
  base::FilePath test_file = TempFilePath("save_existing.txt", true);
  ASSERT_FALSE(test_file.empty());
  FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
      &test_file);
  ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/save_existing"))
      << message_;
}

IN_PROC_BROWSER_TEST_F(FileSystemApiTest,
    FileSystemApiSaveNewFileWithWriteTest) {
  base::FilePath test_file = TempFilePath("save_new.txt", false);
  ASSERT_FALSE(test_file.empty());
  FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
      &test_file);
  ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/save_new_with_write"))
      << message_;
}

IN_PROC_BROWSER_TEST_F(FileSystemApiTest,
    FileSystemApiSaveExistingFileWithWriteTest) {
  base::FilePath test_file = TempFilePath("save_existing.txt", true);
  ASSERT_FALSE(test_file.empty());
  FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
      &test_file);
  ASSERT_TRUE(RunPlatformAppTest(
      "api_test/file_system/save_existing_with_write")) << message_;
}

IN_PROC_BROWSER_TEST_F(FileSystemApiTest, FileSystemApiSaveCancelTest) {
  FileSystemChooseEntryFunction::SkipPickerAndAlwaysCancelForTest();
  ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/save_cancel"))
      << message_;
}

#if defined(OS_LINUX)
// Disabled on linux due to crbug.com/178679.
#define MAYBE_FileSystemApiSaveBackgroundTest \
    DISABLED_FileSystemApiSaveBackgroundTest
#else
#define MAYBE_FileSystemApiSaveBackgroundTest FileSystemApiSaveBackgroundTest
#endif
IN_PROC_BROWSER_TEST_F(FileSystemApiTest,
                       MAYBE_FileSystemApiSaveBackgroundTest) {
  ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/save_background"))
      << message_;
}

IN_PROC_BROWSER_TEST_F(FileSystemApiTest, FileSystemApiGetWritableTest) {
  base::FilePath test_file = TempFilePath("writable.txt", true);
  ASSERT_FALSE(test_file.empty());
  FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
      &test_file);
  ASSERT_TRUE(RunPlatformAppTest(
      "api_test/file_system/get_writable_file_entry")) << message_;
}

IN_PROC_BROWSER_TEST_F(FileSystemApiTest,
    FileSystemApiGetWritableWithWriteTest) {
  base::FilePath test_file = TempFilePath("writable.txt", true);
  ASSERT_FALSE(test_file.empty());
  FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
      &test_file);
  ASSERT_TRUE(RunPlatformAppTest(
      "api_test/file_system/get_writable_file_entry_with_write")) << message_;
}

IN_PROC_BROWSER_TEST_F(FileSystemApiTest, FileSystemApiIsWritableTest) {
  base::FilePath test_file = TempFilePath("writable.txt", true);
  ASSERT_FALSE(test_file.empty());
  FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
      &test_file);
  ASSERT_TRUE(RunPlatformAppTest(
      "api_test/file_system/is_writable_file_entry")) << message_;
}

IN_PROC_BROWSER_TEST_F(FileSystemApiTest, FileSystemApiGetEntryId) {
  base::FilePath test_file = TempFilePath("writable.txt", true);
  ASSERT_FALSE(test_file.empty());
  FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
      &test_file);
  ASSERT_TRUE(RunPlatformAppTest(
      "api_test/file_system/get_entry_id")) << message_;
}
<|endoftext|>


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

#include "chrome/browser/ui/extensions/extension_action_view_controller.h"

#include "base/logging.h"
#include "base/prefs/pref_service.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/extensions/api/commands/command_service.h"
#include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
#include "chrome/browser/extensions/extension_action.h"
#include "chrome/browser/extensions/extension_view.h"
#include "chrome/browser/extensions/extension_view_host.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/sessions/session_tab_helper.h"
#include "chrome/browser/sidebar/sidebar_container.h"
#include "chrome/browser/sidebar/sidebar_manager.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/extensions/accelerator_priority.h"
#include "chrome/browser/ui/extensions/extension_action_platform_delegate.h"
#include "chrome/browser/ui/toolbar/toolbar_action_view_delegate.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/extensions/api/extension_action/action_info.h"
#include "extensions/browser/extension_host.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/common/extension.h"
#include "extensions/common/manifest_constants.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/image/image_skia_operations.h"

using extensions::ActionInfo;
using extensions::CommandService;

ExtensionActionViewController::ExtensionActionViewController(
    const extensions::Extension* extension,
    Browser* browser,
    ExtensionAction* extension_action)
    : extension_(extension),
      browser_(browser),
      extension_action_(extension_action),
      popup_host_(nullptr),
      view_delegate_(nullptr),
      platform_delegate_(ExtensionActionPlatformDelegate::Create(this)),
      icon_factory_(browser->profile(), extension, extension_action, this),
      icon_observer_(nullptr),
      extension_registry_(
          extensions::ExtensionRegistry::Get(browser_->profile())),
      popup_host_observer_(this) {
  DCHECK(extension_action);
  DCHECK(extension_action->action_type() == ActionInfo::TYPE_PAGE ||
         extension_action->action_type() == ActionInfo::TYPE_BROWSER);
  DCHECK(extension);
}

ExtensionActionViewController::~ExtensionActionViewController() {
  DCHECK(!is_showing_popup());

  SidebarManager::GetInstance()->RemoveObserver(this);
}

const std::string& ExtensionActionViewController::GetId() const {
  return extension_->id();
}

void ExtensionActionViewController::SetDelegate(
    ToolbarActionViewDelegate* delegate) {
  DCHECK((delegate == nullptr) ^ (view_delegate_ == nullptr));
  if (delegate) {
    view_delegate_ = delegate;
    platform_delegate_->OnDelegateSet();
  } else {
    if (is_showing_popup())
      HidePopup();
    platform_delegate_.reset();
    view_delegate_ = nullptr;
  }
}

gfx::Image ExtensionActionViewController::GetIcon(
    content::WebContents* web_contents) {
  if (!ExtensionIsValid())
    return gfx::Image();

  return icon_factory_.GetIcon(SessionTabHelper::IdForTab(web_contents));
}

gfx::ImageSkia ExtensionActionViewController::GetIconWithBadge() {
  if (!ExtensionIsValid())
    return gfx::ImageSkia();

  content::WebContents* web_contents = view_delegate_->GetCurrentWebContents();
  gfx::Size spacing(0, 3);
  gfx::ImageSkia icon = *GetIcon(web_contents).ToImageSkia();
  if (!IsEnabled(web_contents))
    icon = gfx::ImageSkiaOperations::CreateTransparentImage(icon, .25);
  return extension_action_->GetIconWithBadge(
      icon, SessionTabHelper::IdForTab(web_contents), spacing);
}

base::string16 ExtensionActionViewController::GetActionName() const {
  if (!ExtensionIsValid())
    return base::string16();

  return base::UTF8ToUTF16(extension_->name());
}

base::string16 ExtensionActionViewController::GetAccessibleName(
    content::WebContents* web_contents) const {
  if (!ExtensionIsValid())
    return base::string16();

  std::string title =
      extension_action()->GetTitle(SessionTabHelper::IdForTab(web_contents));
  return base::UTF8ToUTF16(title.empty() ? extension()->name() : title);
}

base::string16 ExtensionActionViewController::GetTooltip(
    content::WebContents* web_contents) const {
  return GetAccessibleName(web_contents);
}

bool ExtensionActionViewController::IsEnabled(
    content::WebContents* web_contents) const {
  if (!ExtensionIsValid())
    return false;

  return extension_action_->GetIsVisible(
      SessionTabHelper::IdForTab(web_contents)) ||
      extensions::ExtensionActionAPI::Get(browser_->profile())->
          ExtensionWantsToRun(extension(), web_contents);
}

bool ExtensionActionViewController::WantsToRun(
    content::WebContents* web_contents) const {
  return extensions::ExtensionActionAPI::Get(browser_->profile())->
      ExtensionWantsToRun(extension(), web_contents);
}

bool ExtensionActionViewController::HasPopup(
    content::WebContents* web_contents) const {
  if (!ExtensionIsValid())
    return false;

  int tab_id = SessionTabHelper::IdForTab(web_contents);
  return (tab_id < 0) ? false : extension_action_->HasPopup(tab_id);
}

void ExtensionActionViewController::HidePopup() {
  if (is_showing_popup()) {
    popup_host_->Close();
    // We need to do these actions synchronously (instead of closing and then
    // performing the rest of the cleanup in OnExtensionHostDestroyed()) because
    // the extension host can close asynchronously, and we need to keep the view
    // delegate up-to-date.
    OnPopupClosed();
  }
}

gfx::NativeView ExtensionActionViewController::GetPopupNativeView() {
  return popup_host_ ? popup_host_->view()->GetNativeView() : nullptr;
}

ui::MenuModel* ExtensionActionViewController::GetContextMenu() {
  if (!ExtensionIsValid() || !extension()->ShowConfigureContextMenus())
    return nullptr;

  // Reconstruct the menu every time because the menu's contents are dynamic.
  context_menu_model_ = make_scoped_refptr(new ExtensionContextMenuModel(
      extension(), browser_, this));
  return context_menu_model_.get();
}

bool ExtensionActionViewController::IsMenuRunning() const {
  return platform_delegate_->IsMenuRunning();
}

bool ExtensionActionViewController::CanDrag() const {
  return true;
}

bool ExtensionActionViewController::ExecuteAction(bool by_user) {
  return ExecuteAction(SHOW_POPUP, by_user);
}

void ExtensionActionViewController::UpdateState() {
  if (!ExtensionIsValid())
    return;

  view_delegate_->UpdateState();
}

bool ExtensionActionViewController::ExecuteAction(PopupShowAction show_action,
                                                  bool grant_tab_permissions) {
  if (!ExtensionIsValid())
    return false;

  if (extensions::ExtensionActionAPI::Get(browser_->profile())
          ->ExecuteExtensionAction(
              extension_, browser_, grant_tab_permissions) ==
      ExtensionAction::ACTION_SHOW_POPUP) {
    GURL popup_url = extension_action_->GetPopupUrl(
        SessionTabHelper::IdForTab(view_delegate_->GetCurrentWebContents()));
    return static_cast<ExtensionActionViewController*>(
               view_delegate_->GetPreferredPopupViewController())
        ->ShowPopupWithUrl(show_action, popup_url, grant_tab_permissions);
  }
  return false;
}

void ExtensionActionViewController::PaintExtra(
    gfx::Canvas* canvas,
    const gfx::Rect& bounds,
    content::WebContents* web_contents) const {
  if (!ExtensionIsValid())
    return;

  int tab_id = SessionTabHelper::IdForTab(web_contents);
  if (tab_id >= 0)
    extension_action_->PaintBadge(canvas, bounds, tab_id);
}

void ExtensionActionViewController::RegisterCommand() {
  if (!ExtensionIsValid())
    return;

  platform_delegate_->RegisterCommand();
}

void ExtensionActionViewController::InspectPopup() {
  ExecuteAction(SHOW_POPUP_AND_INSPECT, true);
}

void ExtensionActionViewController::OnIconUpdated() {
  if (icon_observer_)
    icon_observer_->OnIconUpdated();
  if (view_delegate_)
    view_delegate_->UpdateState();
}

void ExtensionActionViewController::OnExtensionHostDestroyed(
    const extensions::ExtensionHost* host) {
  OnPopupClosed();
}

bool ExtensionActionViewController::ExtensionIsValid() const {
  return extension_registry_->enabled_extensions().Contains(extension_->id());
}

bool ExtensionActionViewController::GetExtensionCommand(
    extensions::Command* command) {
  DCHECK(command);
  if (!ExtensionIsValid())
    return false;

  CommandService* command_service = CommandService::Get(browser_->profile());
  if (extension_action_->action_type() == ActionInfo::TYPE_PAGE) {
    return command_service->GetPageActionCommand(
        extension_->id(), CommandService::ACTIVE, command, NULL);
  }
  return command_service->GetBrowserActionCommand(
      extension_->id(), CommandService::ACTIVE, command, NULL);
}

bool ExtensionActionViewController::ShowPopupWithUrl(
    PopupShowAction show_action,
    const GURL& popup_url,
    bool grant_tab_permissions) {
  if (!ExtensionIsValid())
    return false;

  bool already_showing = is_showing_popup();

  // Always hide the current popup, even if it's not owned by this extension.
  // Only one popup should be visible at a time.
  platform_delegate_->CloseActivePopup();

  // If we were showing a popup already, then we treat the action to open the
  // same one as a desire to close it (like clicking a menu button that was
  // already open).
  if (already_showing)
    return false;

  bool use_sidebar =
      browser()->profile()->GetPrefs()->GetBoolean(prefs::kShowPopupInSidebar);

  if (use_sidebar) {
    SidebarManager* sidebar_manager = SidebarManager::GetInstance();
    content::WebContents* web_contents = view_delegate_->GetCurrentWebContents();

    if (active_in_webcontents_.find(web_contents) != active_in_webcontents_.end()) {
      sidebar_manager->HideSidebar(
          web_contents, GetId());
      return false;
    }

    active_in_webcontents_.insert(web_contents);
    sidebar_manager->AddObserver(this);
    sidebar_manager->ShowSidebar(
        web_contents, GetId());
    sidebar_manager->NavigateSidebar(
        web_contents, GetId(), popup_url);
    return true;
  }

  popup_host_ = platform_delegate_->ShowPopupWithUrl(
      show_action, popup_url, grant_tab_permissions);
  if (popup_host_) {
    popup_host_observer_.Add(popup_host_);
    view_delegate_->OnPopupShown(grant_tab_permissions);
  }

  return is_showing_popup();
}

void ExtensionActionViewController::OnPopupClosed() {
  popup_host_observer_.Remove(popup_host_);
  popup_host_ = nullptr;
  view_delegate_->OnPopupClosed();
}

void ExtensionActionViewController::OnSidebarShown(content::WebContents* tab,
                                                   const std::string& content_id) {
  if (view_delegate_->GetCurrentWebContents() == tab &&
    content_id == GetId())
    // Without the popup corner arrow indicator, marking the browserAction icon
    // is necessary for extension attribution
    view_delegate_->OnPopupShown(true);
}

void ExtensionActionViewController::OnSidebarHidden(content::WebContents* tab,
                                                    const std::string& content_id) {
  if (view_delegate_->GetCurrentWebContents() == tab &&
    content_id == GetId()) {
    view_delegate_->OnPopupClosed();
    active_in_webcontents_.erase(active_in_webcontents_.find(
                                     view_delegate_->GetCurrentWebContents()));
    if (active_in_webcontents_.size() == 0)
        SidebarManager::GetInstance()->RemoveObserver(this);
  }
}

void ExtensionActionViewController::OnSidebarSwitched(content::WebContents* old_tab,
                                                      const std::string& old_content_id,
                                                      content::WebContents* new_tab,
                                                      const std::string& new_content_id) {
    if (view_delegate_->GetCurrentWebContents() == new_tab &&
        new_content_id == GetId())
        // Without the popup corner arrow indicator, marking the browserAction icon
        // is necessary for extension attribution
        view_delegate_->OnPopupShown(true);
    else
        view_delegate_->OnPopupClosed();
}
<commit_msg>Handle depressed button for multiple windows / multiple tabs<commit_after>// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/extensions/extension_action_view_controller.h"

#include "base/logging.h"
#include "base/prefs/pref_service.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/extensions/api/commands/command_service.h"
#include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
#include "chrome/browser/extensions/extension_action.h"
#include "chrome/browser/extensions/extension_view.h"
#include "chrome/browser/extensions/extension_view_host.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/sessions/session_tab_helper.h"
#include "chrome/browser/sidebar/sidebar_container.h"
#include "chrome/browser/sidebar/sidebar_manager.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/extensions/accelerator_priority.h"
#include "chrome/browser/ui/extensions/extension_action_platform_delegate.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
#include "chrome/browser/ui/toolbar/toolbar_action_view_delegate.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/extensions/api/extension_action/action_info.h"
#include "extensions/browser/extension_host.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/common/extension.h"
#include "extensions/common/manifest_constants.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/image/image_skia_operations.h"

using extensions::ActionInfo;
using extensions::CommandService;

ExtensionActionViewController::ExtensionActionViewController(
    const extensions::Extension* extension,
    Browser* browser,
    ExtensionAction* extension_action)
    : extension_(extension),
      browser_(browser),
      extension_action_(extension_action),
      popup_host_(nullptr),
      view_delegate_(nullptr),
      platform_delegate_(ExtensionActionPlatformDelegate::Create(this)),
      icon_factory_(browser->profile(), extension, extension_action, this),
      icon_observer_(nullptr),
      extension_registry_(
          extensions::ExtensionRegistry::Get(browser_->profile())),
      popup_host_observer_(this) {
  DCHECK(extension_action);
  DCHECK(extension_action->action_type() == ActionInfo::TYPE_PAGE ||
         extension_action->action_type() == ActionInfo::TYPE_BROWSER);
  DCHECK(extension);
}

ExtensionActionViewController::~ExtensionActionViewController() {
  DCHECK(!is_showing_popup());

  SidebarManager::GetInstance()->RemoveObserver(this);
}

const std::string& ExtensionActionViewController::GetId() const {
  return extension_->id();
}

void ExtensionActionViewController::SetDelegate(
    ToolbarActionViewDelegate* delegate) {
  DCHECK((delegate == nullptr) ^ (view_delegate_ == nullptr));
  if (delegate) {
    view_delegate_ = delegate;
    platform_delegate_->OnDelegateSet();
  } else {
    if (is_showing_popup())
      HidePopup();
    platform_delegate_.reset();
    view_delegate_ = nullptr;
  }
}

gfx::Image ExtensionActionViewController::GetIcon(
    content::WebContents* web_contents) {
  if (!ExtensionIsValid())
    return gfx::Image();

  return icon_factory_.GetIcon(SessionTabHelper::IdForTab(web_contents));
}

gfx::ImageSkia ExtensionActionViewController::GetIconWithBadge() {
  if (!ExtensionIsValid())
    return gfx::ImageSkia();

  content::WebContents* web_contents = view_delegate_->GetCurrentWebContents();
  gfx::Size spacing(0, 3);
  gfx::ImageSkia icon = *GetIcon(web_contents).ToImageSkia();
  if (!IsEnabled(web_contents))
    icon = gfx::ImageSkiaOperations::CreateTransparentImage(icon, .25);
  return extension_action_->GetIconWithBadge(
      icon, SessionTabHelper::IdForTab(web_contents), spacing);
}

base::string16 ExtensionActionViewController::GetActionName() const {
  if (!ExtensionIsValid())
    return base::string16();

  return base::UTF8ToUTF16(extension_->name());
}

base::string16 ExtensionActionViewController::GetAccessibleName(
    content::WebContents* web_contents) const {
  if (!ExtensionIsValid())
    return base::string16();

  std::string title =
      extension_action()->GetTitle(SessionTabHelper::IdForTab(web_contents));
  return base::UTF8ToUTF16(title.empty() ? extension()->name() : title);
}

base::string16 ExtensionActionViewController::GetTooltip(
    content::WebContents* web_contents) const {
  return GetAccessibleName(web_contents);
}

bool ExtensionActionViewController::IsEnabled(
    content::WebContents* web_contents) const {
  if (!ExtensionIsValid())
    return false;

  return extension_action_->GetIsVisible(
      SessionTabHelper::IdForTab(web_contents)) ||
      extensions::ExtensionActionAPI::Get(browser_->profile())->
          ExtensionWantsToRun(extension(), web_contents);
}

bool ExtensionActionViewController::WantsToRun(
    content::WebContents* web_contents) const {
  return extensions::ExtensionActionAPI::Get(browser_->profile())->
      ExtensionWantsToRun(extension(), web_contents);
}

bool ExtensionActionViewController::HasPopup(
    content::WebContents* web_contents) const {
  if (!ExtensionIsValid())
    return false;

  int tab_id = SessionTabHelper::IdForTab(web_contents);
  return (tab_id < 0) ? false : extension_action_->HasPopup(tab_id);
}

void ExtensionActionViewController::HidePopup() {
  if (is_showing_popup()) {
    popup_host_->Close();
    // We need to do these actions synchronously (instead of closing and then
    // performing the rest of the cleanup in OnExtensionHostDestroyed()) because
    // the extension host can close asynchronously, and we need to keep the view
    // delegate up-to-date.
    OnPopupClosed();
  }
}

gfx::NativeView ExtensionActionViewController::GetPopupNativeView() {
  return popup_host_ ? popup_host_->view()->GetNativeView() : nullptr;
}

ui::MenuModel* ExtensionActionViewController::GetContextMenu() {
  if (!ExtensionIsValid() || !extension()->ShowConfigureContextMenus())
    return nullptr;

  // Reconstruct the menu every time because the menu's contents are dynamic.
  context_menu_model_ = make_scoped_refptr(new ExtensionContextMenuModel(
      extension(), browser_, this));
  return context_menu_model_.get();
}

bool ExtensionActionViewController::IsMenuRunning() const {
  return platform_delegate_->IsMenuRunning();
}

bool ExtensionActionViewController::CanDrag() const {
  return true;
}

bool ExtensionActionViewController::ExecuteAction(bool by_user) {
  return ExecuteAction(SHOW_POPUP, by_user);
}

void ExtensionActionViewController::UpdateState() {
  if (!ExtensionIsValid())
    return;

  view_delegate_->UpdateState();
}

bool ExtensionActionViewController::ExecuteAction(PopupShowAction show_action,
                                                  bool grant_tab_permissions) {
  if (!ExtensionIsValid())
    return false;

  if (extensions::ExtensionActionAPI::Get(browser_->profile())
          ->ExecuteExtensionAction(
              extension_, browser_, grant_tab_permissions) ==
      ExtensionAction::ACTION_SHOW_POPUP) {
    GURL popup_url = extension_action_->GetPopupUrl(
        SessionTabHelper::IdForTab(view_delegate_->GetCurrentWebContents()));
    return static_cast<ExtensionActionViewController*>(
               view_delegate_->GetPreferredPopupViewController())
        ->ShowPopupWithUrl(show_action, popup_url, grant_tab_permissions);
  }
  return false;
}

void ExtensionActionViewController::PaintExtra(
    gfx::Canvas* canvas,
    const gfx::Rect& bounds,
    content::WebContents* web_contents) const {
  if (!ExtensionIsValid())
    return;

  int tab_id = SessionTabHelper::IdForTab(web_contents);
  if (tab_id >= 0)
    extension_action_->PaintBadge(canvas, bounds, tab_id);
}

void ExtensionActionViewController::RegisterCommand() {
  if (!ExtensionIsValid())
    return;

  platform_delegate_->RegisterCommand();
}

void ExtensionActionViewController::InspectPopup() {
  ExecuteAction(SHOW_POPUP_AND_INSPECT, true);
}

void ExtensionActionViewController::OnIconUpdated() {
  if (icon_observer_)
    icon_observer_->OnIconUpdated();
  if (view_delegate_)
    view_delegate_->UpdateState();
}

void ExtensionActionViewController::OnExtensionHostDestroyed(
    const extensions::ExtensionHost* host) {
  OnPopupClosed();
}

bool ExtensionActionViewController::ExtensionIsValid() const {
  return extension_registry_->enabled_extensions().Contains(extension_->id());
}

bool ExtensionActionViewController::GetExtensionCommand(
    extensions::Command* command) {
  DCHECK(command);
  if (!ExtensionIsValid())
    return false;

  CommandService* command_service = CommandService::Get(browser_->profile());
  if (extension_action_->action_type() == ActionInfo::TYPE_PAGE) {
    return command_service->GetPageActionCommand(
        extension_->id(), CommandService::ACTIVE, command, NULL);
  }
  return command_service->GetBrowserActionCommand(
      extension_->id(), CommandService::ACTIVE, command, NULL);
}

bool ExtensionActionViewController::ShowPopupWithUrl(
    PopupShowAction show_action,
    const GURL& popup_url,
    bool grant_tab_permissions) {
  if (!ExtensionIsValid())
    return false;

  bool already_showing = is_showing_popup();

  // Always hide the current popup, even if it's not owned by this extension.
  // Only one popup should be visible at a time.
  platform_delegate_->CloseActivePopup();

  // If we were showing a popup already, then we treat the action to open the
  // same one as a desire to close it (like clicking a menu button that was
  // already open).
  if (already_showing)
    return false;

  bool use_sidebar =
      browser()->profile()->GetPrefs()->GetBoolean(prefs::kShowPopupInSidebar);

  if (use_sidebar) {
    SidebarManager* sidebar_manager = SidebarManager::GetInstance();
    content::WebContents* web_contents = view_delegate_->GetCurrentWebContents();

    if (active_in_webcontents_.find(web_contents) != active_in_webcontents_.end()) {
      sidebar_manager->HideSidebar(
          web_contents, GetId());
      return false;
    }

    active_in_webcontents_.insert(web_contents);
    sidebar_manager->AddObserver(this);
    sidebar_manager->ShowSidebar(
        web_contents, GetId());
    sidebar_manager->NavigateSidebar(
        web_contents, GetId(), popup_url);
    return true;
  }

  popup_host_ = platform_delegate_->ShowPopupWithUrl(
      show_action, popup_url, grant_tab_permissions);
  if (popup_host_) {
    popup_host_observer_.Add(popup_host_);
    view_delegate_->OnPopupShown(grant_tab_permissions);
  }

  return is_showing_popup();
}

void ExtensionActionViewController::OnPopupClosed() {
  popup_host_observer_.Remove(popup_host_);
  popup_host_ = nullptr;
  view_delegate_->OnPopupClosed();
}

void ExtensionActionViewController::OnSidebarShown(content::WebContents* tab,
                                                   const std::string& content_id) {
  if (view_delegate_->GetCurrentWebContents() == tab &&
    content_id == GetId())
    // Without the popup corner arrow indicator, marking the browserAction icon
    // is necessary for extension attribution
    view_delegate_->OnPopupShown(true);
}

void ExtensionActionViewController::OnSidebarHidden(content::WebContents* tab,
                                                    const std::string& content_id) {
  if (view_delegate_->GetCurrentWebContents() == tab &&
    content_id == GetId()) {
    view_delegate_->OnPopupClosed();
    active_in_webcontents_.erase(active_in_webcontents_.find(
                                     view_delegate_->GetCurrentWebContents()));
    if (active_in_webcontents_.size() == 0)
        SidebarManager::GetInstance()->RemoveObserver(this);
  }
}

void ExtensionActionViewController::OnSidebarSwitched(content::WebContents* old_tab,
                                                      const std::string& old_content_id,
                                                      content::WebContents* new_tab,
                                                      const std::string& new_content_id) {
    if (browser_->tab_strip_model()->GetIndexOfWebContents(new_tab ? new_tab : old_tab) == TabStripModel::kNoTab)
        return;

    if (view_delegate_->GetCurrentWebContents() == new_tab &&
        new_content_id == GetId())
        // Without the popup corner arrow indicator, marking the browserAction icon
        // is necessary for extension attribution
        view_delegate_->OnPopupShown(true);
    else
        view_delegate_->OnPopupClosed();
}
<|endoftext|>


<commit_before>/*
 *  GLMeshBuffer.cpp
 *  moFlo
 *
 *  Created by Scott Downie on 01/10/2010.
 *  Copyright 2010 Tag Games. All rights reserved.
 *
 */

#include <ChilliSource/Backend/Rendering/OpenGL/Base/MeshBuffer.h>
#include <ChilliSource/Backend/Rendering/OpenGL/Base/RenderSystem.h>

namespace ChilliSource
{
	namespace OpenGL
	{
        CMeshBuffer* CMeshBuffer::pCurrentlyBoundBuffer = nullptr;

		//-----------------------------------------------------
		/// Constructor
		///
		/// Create a vertex buffer and index buffer from
		/// the given buffer description
		/// @param Buffer desciption
		//-----------------------------------------------------
		CMeshBuffer::CMeshBuffer(ChilliSource::Rendering::BufferDescription &inBuffDesc)
        : ChilliSource::Rendering::MeshBuffer(inBuffDesc), mVertexBuffer(0), mIndexBuffer(0), mBufferUsage(0), mBufferAccess(0),
          mpVertexData(nullptr), mpIndexData(nullptr), mpVertexDataBackup(nullptr), mpIndexDataBackup(nullptr), mbMapBufferAvailable(false), mbCacheValid(false)
		{
			glGenBuffers(1, &mVertexBuffer);

            if(mBufferDesc.IndexDataCapacity > 0)
                glGenBuffers(1, &mIndexBuffer);

			switch(mBufferDesc.eUsageFlag)
			{
				case Rendering::BufferUsage::k_dynamic:
					mBufferUsage = GL_DYNAMIC_DRAW;
					break;
				case Rendering::BufferUsage::k_static:
					mBufferUsage = GL_STATIC_DRAW;
					break;
			};
			switch(mBufferDesc.eAccessFlag)
			{
				case Rendering::BufferAccess::k_write:
#ifdef MOFLOW_OPENGL
					mBufferAccess = GL_WRITE_ONLY;
#elif defined MOFLOW_OPENGLES2
					mBufferAccess = GL_WRITE_ONLY_OES;
#endif
					break;
				case Rendering::BufferAccess::k_read:
#ifdef MOFLOW_OPENGL
					mBufferAccess = GL_WRITE_ONLY;
#elif defined MOFLOW_OPENGLES2
					mBufferAccess = GL_WRITE_ONLY_OES;
#endif
					break;
				case Rendering::BufferAccess::k_readWrite:
				default:
#ifdef MOFLOW_OPENGL
					mBufferAccess = GL_WRITE_ONLY;
#elif defined MOFLOW_OPENGLES2
					mBufferAccess = GL_WRITE_ONLY_OES;
#endif
					break;
			};

			glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
			glBufferData(GL_ARRAY_BUFFER, mBufferDesc.VertexDataCapacity, nullptr, mBufferUsage);

            if(mIndexBuffer != 0)
            {
                glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
                glBufferData(GL_ELEMENT_ARRAY_BUFFER, mBufferDesc.IndexDataCapacity, nullptr, mBufferUsage);
            }

            CMeshBuffer::pCurrentlyBoundBuffer = this;
		}
		//-----------------------------------------------------
		/// Bind
		///
		/// Set the active buffer by binding to the context
		//-----------------------------------------------------
		void CMeshBuffer::Bind()
		{
            if(CMeshBuffer::pCurrentlyBoundBuffer != this)
            {
                glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
                glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);

                CMeshBuffer::pCurrentlyBoundBuffer = this;
            }
		}
		//-----------------------------------------------------
		/// Lock Vertex
		///
		/// Obtain a handle to the buffer memory in order
		/// to map data
		/// @param Outputs the pointer to the buffer
		/// @param The offset to the subset of the buffer
		/// @param The vertex layout stride
		/// @return If successful
		//-----------------------------------------------------
		bool CMeshBuffer::LockVertex(f32** outppBuffer, u32 inDataOffset, u32 inDataStride)
		{
			if(mbMapBufferAvailable)
			{
				if (mBufferDesc.eUsageFlag == Rendering::BufferUsage::k_dynamic)
				{
					glBufferData(GL_ARRAY_BUFFER, mBufferDesc.VertexDataCapacity, nullptr, mBufferUsage);
				}

#ifdef MOFLOW_OPENGL
				(*outppBuffer) = static_cast<f32*>(glMapBuffer(GL_ARRAY_BUFFER, mBufferAccess));
#elif defined MOFLOW_OPENGLES2
				(*outppBuffer) = static_cast<f32*>(glMapBufferOES(GL_ARRAY_BUFFER, mBufferAccess));
#endif
				mpVertexData = (*outppBuffer);
			}
			else
			{
				if(!mpVertexData)
				{
					mpVertexData = (f32*)new u8[mBufferDesc.VertexDataCapacity];
				}

				(*outppBuffer) = mpVertexData;
			}
            mbCacheValid = false;
			return ((*outppBuffer));
		}
		//-----------------------------------------------------
		/// Lock Index
		///
		/// Obtain a handle to the buffer memory in order
		/// to map data
		/// @param Outputs the pointer to the buffer
		/// @param The offset to the subset of the buffer
		/// @param The vertex layout stride
		/// @return If successful
		//-----------------------------------------------------
		bool CMeshBuffer::LockIndex(u16** outppBuffer, u32 inDataOffset, u32 inDataStride)
		{
            if(!mIndexBuffer)
            {
                (*outppBuffer) = nullptr;
                return false;
            }

			if(mbMapBufferAvailable)
			{
#ifdef MOFLOW_OPENGL
				(*outppBuffer) = static_cast<u16*>(glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, mBufferAccess));
#elif defined MOFLOW_OPENGLES2
				(*outppBuffer) = static_cast<u16*>(glMapBufferOES(GL_ELEMENT_ARRAY_BUFFER, mBufferAccess));
#endif
				mpIndexData = (*outppBuffer);
			}
			else
			{
				if(!mpIndexData)
				{
					mpIndexData = (u16*)new u8[mBufferDesc.IndexDataCapacity];
				}

				(*outppBuffer) = mpIndexData;
			}
            mbCacheValid = false;
            return ((*outppBuffer));
		}
		//-----------------------------------------------------
		/// Unlock Vertex
		///
		/// Releases the buffer from mapping
		/// @return If successful
		//-----------------------------------------------------
		bool CMeshBuffer::UnlockVertex()
		{
			if(mbMapBufferAvailable)
			{
				mpVertexData = nullptr;
#ifdef MOFLOW_OPENGL
				return glUnmapBuffer(GL_ARRAY_BUFFER);
#elif defined MOFLOW_OPENGLES2
				return glUnmapBufferOES(GL_ARRAY_BUFFER);
#endif
			}
			else
			{
				glBufferData(GL_ARRAY_BUFFER, mBufferDesc.VertexDataCapacity, mpVertexData, mBufferUsage);
				return true;
			}
		}
		//-----------------------------------------------------
		/// Unlock Index
		///
		/// Releases the buffer from mapping
		/// @return If successful
		//-----------------------------------------------------
		bool CMeshBuffer::UnlockIndex()
		{
            if(!mIndexBuffer)
                return false;

			if(mbMapBufferAvailable)
			{
				mpIndexData = nullptr;
#ifdef MOFLOW_OPENGL
				return glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
#elif defined MOFLOW_OPENGLES2
				return glUnmapBufferOES(GL_ELEMENT_ARRAY_BUFFER);
#endif
			}
			else
			{
				glBufferData(GL_ELEMENT_ARRAY_BUFFER, mBufferDesc.IndexDataCapacity, mpIndexData, mBufferUsage);
				return true;
			}
		}
		//-----------------------------------------------------
		/// Set Map Buffer Available
		///
		/// @param Whether the GL implementation supports
		/// the map buffer extension
		//-----------------------------------------------------
		void CMeshBuffer::SetMapBufferAvailable(bool inbEnabled)
		{
			mbMapBufferAvailable = inbEnabled;
		}
		//-----------------------------------------------------
		/// Backup
		///
		/// Backs up the data in the mesh buffer to make
		/// sure it is not lost on context loss
		//-----------------------------------------------------
		void CMeshBuffer::Backup()
		{

			if(!mpIndexDataBackup)
			{
				mpIndexDataBackup = (u16*)new u8[mBufferDesc.IndexDataCapacity];
			}

			//Fill the backup
			Bind();

			if(!mpVertexDataBackup)
			{
				mpVertexDataBackup = (f32*)new u8[mBufferDesc.VertexDataCapacity];
			}
			f32* pVBuffer = nullptr;
			LockVertex(&pVBuffer, 0, 0);
			memcpy(mpVertexDataBackup, pVBuffer, GetVertexCapacity());
			UnlockVertex();

            if(mIndexBuffer != 0)
            {
                if(!mpIndexDataBackup)
                {
                    mpIndexDataBackup = (u16*)new u8[mBufferDesc.IndexDataCapacity];
                }
                u16* pIBuffer = nullptr;
                LockIndex(&pIBuffer, 0, 0);
                memcpy(mpIndexDataBackup, pIBuffer, GetIndexCapacity());
                UnlockIndex();
            }

            mVertexBuffer = 0;
			mIndexBuffer = 0;
		}
		//-----------------------------------------------------
		/// Restore
		///
		/// Restore the mesh buffer data from the last
		/// backup after the context has been re-created
		//-----------------------------------------------------
		void CMeshBuffer::Restore()
		{
            //Force bind as we may have been bound from before context destruction
            CMeshBuffer::pCurrentlyBoundBuffer = nullptr;

            if(mpVertexDataBackup == nullptr)
            {
                return;
            }

            //Check for backups
            if(mpVertexDataBackup)
            {
               glGenBuffers(1, &mVertexBuffer);
            }
            if(mpIndexDataBackup)
            {
                glGenBuffers(1, &mIndexBuffer);
            }

            Bind();

			f32* pVBuffer = nullptr;
			LockVertex(&pVBuffer, 0, 0);
			memcpy(pVBuffer, mpVertexDataBackup, GetVertexCapacity());
			UnlockVertex();

            if(mIndexBuffer != 0)
            {
                u16* pIBuffer = nullptr;
                LockIndex(&pIBuffer, 0, 0);
                memcpy(pIBuffer, mpIndexDataBackup, GetIndexCapacity());
                UnlockIndex();
            }

			CS_SAFE_DELETE_ARRAY(mpVertexDataBackup);
			CS_SAFE_DELETE_ARRAY(mpIndexDataBackup);
		}
		//-----------------------------------------------------
		/// Set Owning Render System
		///
		/// The owning render system so we may inform it
		/// when this mesh buffer is destroyed
		///
		/// @param Pointer to render system
		//-----------------------------------------------------
		void CMeshBuffer::SetOwningRenderSystem(CRenderSystem* inpSystem)
		{
			mpRenderSystem = inpSystem;
		}

        //-----------------------------------------------------
        /// Is Cache Valid
        ///
        /// The owning render system needs to know if the
        /// buffer has changed and needs to apply vertex pointers
        ///
        /// @return Has mesh buffer been modifier
        //-----------------------------------------------------
        bool CMeshBuffer::IsCacheValid() const
        {
            return mbCacheValid;
        }
        //-----------------------------------------------------
        /// Set Cache Valid
        ///
        /// The owning render system has seen that the
        /// buffer has changed and applied vertex pointers
        //-----------------------------------------------------
        void CMeshBuffer::SetCacheValid()
        {
            mbCacheValid = true;
        }
		//-----------------------------------------------------
		/// Destructor
		///
		//-----------------------------------------------------
		CMeshBuffer::~CMeshBuffer()
		{
			if(mpRenderSystem)
			{
				mpRenderSystem->RemoveBuffer(this);
			}

            if(CMeshBuffer::pCurrentlyBoundBuffer == this)
            {
                CMeshBuffer::pCurrentlyBoundBuffer = nullptr;
            }

			glDeleteBuffers(1, &mVertexBuffer);
            if(mIndexBuffer != 0)
            {
                glDeleteBuffers(1, &mIndexBuffer);
            }

			mVertexBuffer = 0;
			mIndexBuffer  = 0;

			CS_SAFE_DELETE_ARRAY(mpVertexData);
			CS_SAFE_DELETE_ARRAY(mpIndexData);
			CS_SAFE_DELETE_ARRAY(mpVertexDataBackup);
			CS_SAFE_DELETE_ARRAY(mpIndexDataBackup);
		}
	}
}
<commit_msg>Added fix for Android mesh buffer restore issue found in moFlow.<commit_after>/*
 *  GLMeshBuffer.cpp
 *  moFlo
 *
 *  Created by Scott Downie on 01/10/2010.
 *  Copyright 2010 Tag Games. All rights reserved.
 *
 */

#include <ChilliSource/Backend/Rendering/OpenGL/Base/MeshBuffer.h>
#include <ChilliSource/Backend/Rendering/OpenGL/Base/RenderSystem.h>

namespace ChilliSource
{
	namespace OpenGL
	{
        CMeshBuffer* CMeshBuffer::pCurrentlyBoundBuffer = nullptr;

		//-----------------------------------------------------
		/// Constructor
		///
		/// Create a vertex buffer and index buffer from
		/// the given buffer description
		/// @param Buffer desciption
		//-----------------------------------------------------
		CMeshBuffer::CMeshBuffer(ChilliSource::Rendering::BufferDescription &inBuffDesc)
        : ChilliSource::Rendering::MeshBuffer(inBuffDesc), mVertexBuffer(0), mIndexBuffer(0), mBufferUsage(0), mBufferAccess(0),
          mpVertexData(nullptr), mpIndexData(nullptr), mpVertexDataBackup(nullptr), mpIndexDataBackup(nullptr), mbMapBufferAvailable(false), mbCacheValid(false)
		{
			glGenBuffers(1, &mVertexBuffer);

            if(mBufferDesc.IndexDataCapacity > 0)
                glGenBuffers(1, &mIndexBuffer);

			switch(mBufferDesc.eUsageFlag)
			{
				case Rendering::BufferUsage::k_dynamic:
					mBufferUsage = GL_DYNAMIC_DRAW;
					break;
				case Rendering::BufferUsage::k_static:
					mBufferUsage = GL_STATIC_DRAW;
					break;
			};
			switch(mBufferDesc.eAccessFlag)
			{
				case Rendering::BufferAccess::k_write:
#ifdef MOFLOW_OPENGL
					mBufferAccess = GL_WRITE_ONLY;
#elif defined MOFLOW_OPENGLES2
					mBufferAccess = GL_WRITE_ONLY_OES;
#endif
					break;
				case Rendering::BufferAccess::k_read:
#ifdef MOFLOW_OPENGL
					mBufferAccess = GL_WRITE_ONLY;
#elif defined MOFLOW_OPENGLES2
					mBufferAccess = GL_WRITE_ONLY_OES;
#endif
					break;
				case Rendering::BufferAccess::k_readWrite:
				default:
#ifdef MOFLOW_OPENGL
					mBufferAccess = GL_WRITE_ONLY;
#elif defined MOFLOW_OPENGLES2
					mBufferAccess = GL_WRITE_ONLY_OES;
#endif
					break;
			};

			glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
			glBufferData(GL_ARRAY_BUFFER, mBufferDesc.VertexDataCapacity, nullptr, mBufferUsage);

            if(mIndexBuffer != 0)
            {
                glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
                glBufferData(GL_ELEMENT_ARRAY_BUFFER, mBufferDesc.IndexDataCapacity, nullptr, mBufferUsage);
            }

            CMeshBuffer::pCurrentlyBoundBuffer = this;
		}
		//-----------------------------------------------------
		/// Bind
		///
		/// Set the active buffer by binding to the context
		//-----------------------------------------------------
		void CMeshBuffer::Bind()
		{
            if(CMeshBuffer::pCurrentlyBoundBuffer != this)
            {
                glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
                glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);

                CMeshBuffer::pCurrentlyBoundBuffer = this;
            }
		}
		//-----------------------------------------------------
		/// Lock Vertex
		///
		/// Obtain a handle to the buffer memory in order
		/// to map data
		/// @param Outputs the pointer to the buffer
		/// @param The offset to the subset of the buffer
		/// @param The vertex layout stride
		/// @return If successful
		//-----------------------------------------------------
		bool CMeshBuffer::LockVertex(f32** outppBuffer, u32 inDataOffset, u32 inDataStride)
		{
			if(mbMapBufferAvailable)
			{
				if (mBufferDesc.eUsageFlag == Rendering::BufferUsage::k_dynamic)
				{
					glBufferData(GL_ARRAY_BUFFER, mBufferDesc.VertexDataCapacity, nullptr, mBufferUsage);
				}

#ifdef MOFLOW_OPENGL
				(*outppBuffer) = static_cast<f32*>(glMapBuffer(GL_ARRAY_BUFFER, mBufferAccess));
#elif defined MOFLOW_OPENGLES2
				(*outppBuffer) = static_cast<f32*>(glMapBufferOES(GL_ARRAY_BUFFER, mBufferAccess));
#endif
				mpVertexData = (*outppBuffer);
			}
			else
			{
				if(!mpVertexData)
				{
					mpVertexData = (f32*)new u8[mBufferDesc.VertexDataCapacity];
				}

				(*outppBuffer) = mpVertexData;
			}
            mbCacheValid = false;
			return ((*outppBuffer));
		}
		//-----------------------------------------------------
		/// Lock Index
		///
		/// Obtain a handle to the buffer memory in order
		/// to map data
		/// @param Outputs the pointer to the buffer
		/// @param The offset to the subset of the buffer
		/// @param The vertex layout stride
		/// @return If successful
		//-----------------------------------------------------
		bool CMeshBuffer::LockIndex(u16** outppBuffer, u32 inDataOffset, u32 inDataStride)
		{
            if(!mIndexBuffer)
            {
                (*outppBuffer) = nullptr;
                return false;
            }

			if(mbMapBufferAvailable)
			{
#ifdef MOFLOW_OPENGL
				(*outppBuffer) = static_cast<u16*>(glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, mBufferAccess));
#elif defined MOFLOW_OPENGLES2
				(*outppBuffer) = static_cast<u16*>(glMapBufferOES(GL_ELEMENT_ARRAY_BUFFER, mBufferAccess));
#endif
				mpIndexData = (*outppBuffer);
			}
			else
			{
				if(!mpIndexData)
				{
					mpIndexData = (u16*)new u8[mBufferDesc.IndexDataCapacity];
				}

				(*outppBuffer) = mpIndexData;
			}
            mbCacheValid = false;
            return ((*outppBuffer));
		}
		//-----------------------------------------------------
		/// Unlock Vertex
		///
		/// Releases the buffer from mapping
		/// @return If successful
		//-----------------------------------------------------
		bool CMeshBuffer::UnlockVertex()
		{
			if(mbMapBufferAvailable)
			{
				mpVertexData = nullptr;
#ifdef MOFLOW_OPENGL
				return glUnmapBuffer(GL_ARRAY_BUFFER);
#elif defined MOFLOW_OPENGLES2
				return glUnmapBufferOES(GL_ARRAY_BUFFER);
#endif
			}
			else
			{
				glBufferData(GL_ARRAY_BUFFER, mBufferDesc.VertexDataCapacity, mpVertexData, mBufferUsage);
				return true;
			}
		}
		//-----------------------------------------------------
		/// Unlock Index
		///
		/// Releases the buffer from mapping
		/// @return If successful
		//-----------------------------------------------------
		bool CMeshBuffer::UnlockIndex()
		{
            if(!mIndexBuffer)
                return false;

			if(mbMapBufferAvailable)
			{
				mpIndexData = nullptr;
#ifdef MOFLOW_OPENGL
				return glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
#elif defined MOFLOW_OPENGLES2
				return glUnmapBufferOES(GL_ELEMENT_ARRAY_BUFFER);
#endif
			}
			else
			{
				glBufferData(GL_ELEMENT_ARRAY_BUFFER, mBufferDesc.IndexDataCapacity, mpIndexData, mBufferUsage);
				return true;
			}
		}
		//-----------------------------------------------------
		/// Set Map Buffer Available
		///
		/// @param Whether the GL implementation supports
		/// the map buffer extension
		//-----------------------------------------------------
		void CMeshBuffer::SetMapBufferAvailable(bool inbEnabled)
		{
			mbMapBufferAvailable = inbEnabled;
		}
		//-----------------------------------------------------
		/// Backup
		///
		/// Backs up the data in the mesh buffer to make
		/// sure it is not lost on context loss
		//-----------------------------------------------------
		void CMeshBuffer::Backup()
		{

			if(!mpIndexDataBackup)
			{
				mpIndexDataBackup = (u16*)new u8[mBufferDesc.IndexDataCapacity];
			}

			//Fill the backup
			Bind();

			if(!mpVertexDataBackup)
			{
				mpVertexDataBackup = (f32*)new u8[mBufferDesc.VertexDataCapacity];
			}
			f32* pVBuffer = nullptr;
			LockVertex(&pVBuffer, 0, 0);
			memcpy(mpVertexDataBackup, pVBuffer, GetVertexCapacity());
			UnlockVertex();

            if(mIndexBuffer != 0)
            {
                if(!mpIndexDataBackup)
                {
                    mpIndexDataBackup = (u16*)new u8[mBufferDesc.IndexDataCapacity];
                }
                u16* pIBuffer = nullptr;
                LockIndex(&pIBuffer, 0, 0);
                memcpy(mpIndexDataBackup, pIBuffer, GetIndexCapacity());
                UnlockIndex();
            }

            mVertexBuffer = 0;
			mIndexBuffer = 0;
		}
		//-----------------------------------------------------
		/// Restore
		///
		/// Restore the mesh buffer data from the last
		/// backup after the context has been re-created
		//-----------------------------------------------------
		void CMeshBuffer::Restore()
		{
            //Force bind as we may have been bound from before context destruction
            CMeshBuffer::pCurrentlyBoundBuffer = nullptr;

            if(mpVertexDataBackup == nullptr)
            {
                return;
            }

            //Check for backups
            if(mpVertexDataBackup)
            {
               glGenBuffers(1, &mVertexBuffer);
            }
            if(mpIndexDataBackup)
            {
                glGenBuffers(1, &mIndexBuffer);
            }

            Bind();

            glBufferData(GL_ARRAY_BUFFER, mBufferDesc.VertexDataCapacity, nullptr, mBufferUsage);
			f32* pVBuffer = nullptr;
			LockVertex(&pVBuffer, 0, 0);
			memcpy(pVBuffer, mpVertexDataBackup, GetVertexCapacity());
			UnlockVertex();

            if(mIndexBuffer != 0)
            {
                glBufferData(GL_ELEMENT_ARRAY_BUFFER, mBufferDesc.IndexDataCapacity, nullptr, mBufferUsage);
                u16* pIBuffer = nullptr;
                LockIndex(&pIBuffer, 0, 0);
                memcpy(pIBuffer, mpIndexDataBackup, GetIndexCapacity());
                UnlockIndex();
            }

			CS_SAFE_DELETE_ARRAY(mpVertexDataBackup);
			CS_SAFE_DELETE_ARRAY(mpIndexDataBackup);
		}
		//-----------------------------------------------------
		/// Set Owning Render System
		///
		/// The owning render system so we may inform it
		/// when this mesh buffer is destroyed
		///
		/// @param Pointer to render system
		//-----------------------------------------------------
		void CMeshBuffer::SetOwningRenderSystem(CRenderSystem* inpSystem)
		{
			mpRenderSystem = inpSystem;
		}

        //-----------------------------------------------------
        /// Is Cache Valid
        ///
        /// The owning render system needs to know if the
        /// buffer has changed and needs to apply vertex pointers
        ///
        /// @return Has mesh buffer been modifier
        //-----------------------------------------------------
        bool CMeshBuffer::IsCacheValid() const
        {
            return mbCacheValid;
        }
        //-----------------------------------------------------
        /// Set Cache Valid
        ///
        /// The owning render system has seen that the
        /// buffer has changed and applied vertex pointers
        //-----------------------------------------------------
        void CMeshBuffer::SetCacheValid()
        {
            mbCacheValid = true;
        }
		//-----------------------------------------------------
		/// Destructor
		///
		//-----------------------------------------------------
		CMeshBuffer::~CMeshBuffer()
		{
			if(mpRenderSystem)
			{
				mpRenderSystem->RemoveBuffer(this);
			}

            if(CMeshBuffer::pCurrentlyBoundBuffer == this)
            {
                CMeshBuffer::pCurrentlyBoundBuffer = nullptr;
            }

			glDeleteBuffers(1, &mVertexBuffer);
            if(mIndexBuffer != 0)
            {
                glDeleteBuffers(1, &mIndexBuffer);
            }

			mVertexBuffer = 0;
			mIndexBuffer  = 0;

			CS_SAFE_DELETE_ARRAY(mpVertexData);
			CS_SAFE_DELETE_ARRAY(mpIndexData);
			CS_SAFE_DELETE_ARRAY(mpVertexDataBackup);
			CS_SAFE_DELETE_ARRAY(mpIndexDataBackup);
		}
	}
}
<|endoftext|>