<commit_before>// InteractiveNotifications.cpp : Defines the exported functions for the DLL application.
//

#include "stdafx.h"
#include "InteractiveNotifications.h"
#include <NotificationActivationCallback.h>

#include <Shellapi.h>
#include <string>
#include <iostream>
#include <SDKDDKVer.h>
#include <Windows.h>
#include <Psapi.h>
#include <strsafe.h>
#include <ShObjIdl.h>
#include <Shlobj.h>
#include <Pathcch.h>
#include <propvarutil.h>
#include <propkey.h>
#include <wchar.h>
#include <wrl.h>
#include <wrl\wrappers\corewrappers.h>
#include <windows.ui.notifications.h>

// Correct flow
// RegisterAppForNotificationSupport()
// RegisterActivator()

//  Name:     System.AppUserModel.ToastActivatorCLSID -- PKEY_AppUserModel_ToastActivatorCLSID
//  Type:     Guid -- VT_CLSID
//  FormatID: {9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}, 26
//
//  Used to CoCreate an INotificationActivationCallback interface to notify about toast activations.
EXTERN_C const PROPERTYKEY DECLSPEC_SELECTANY PKEY_AppUserModel_ToastActivatorCLSID = { { 0x9F4C2855, 0x9F79, 0x4B39,{ 0xA8, 0xD0, 0xE1, 0xD4, 0x2D, 0xE1, 0xD5, 0xF3 } }, 26 };

using namespace ABI::Windows::Data::Xml::Dom;
using namespace ABI::Windows::UI::Notifications;
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;

struct CoTaskMemStringTraits
{
	typedef PWSTR Type;

	inline static bool Close(_In_ Type h) throw() { ::CoTaskMemFree(h); return true; }

	inline static Type GetInvalidValue() throw() { return nullptr; }
};
typedef HandleT<CoTaskMemStringTraits> CoTaskMemString;

const wchar_t Shortcut[] = LR"(Microsoft\Windows\Start Menu\Slack.lnk)";

#define __CSID "B23D2B18-8DD7-403A-B9B7-152B40A1478C"

// For the app to be activated from Action Center, it needs to provide a COM server to be called
// when the notification is activated.  The CLSID of the object needs to be registered with the
// OS via its shortcut so that it knows who to call later.
class DECLSPEC_UUID(__CSID) NotificationActivator WrlSealed WrlFinal
: public RuntimeClass < RuntimeClassFlags<ClassicCom>,
	INotificationActivationCallback >
{
public:
	virtual HRESULT STDMETHODCALLTYPE Activate(
		_In_ LPCWSTR appUserModelId,
		_In_ LPCWSTR invokedArgs,
		_In_reads_(dataCount) const NOTIFICATION_USER_INPUT_DATA* data,
		ULONG dataCount) override
	{
		std::string args;

		for (int i = 0; i < dataCount; i++) {
			LPCWSTR lvalue = data[i].Value;
			LPCWSTR lkey = data[i].Key;

			std::wstring wvalue(lvalue);
			std::wstring wkey(lkey);

			std::string value(wvalue.begin(), wvalue.end());
			std::string key(wkey.begin(), wkey.end());

			args = args + "\"key\":\"" + key + "\"";
			args = args + ",\"value\":\"" + value + "\"";
		}

		std::wstring wToastArgs(invokedArgs);
		std::string toastArgs(wToastArgs.begin(), wToastArgs.end());

		// If you ever want to use system() or similar calls,
		// you'll need to escape stuff. We're using ShellExecute,
		// so we don't have to.

		// std::string escapedArgs = "";
		// for (char ch : args) {
		// 	switch (ch) {
		// 	case ' ': escapedArgs += "%20"; break;
		// 	case '&': escapedArgs += "^&"; break;
		// 	case '\\': escapedArgs += "^\\"; break;
		// 	case '<': escapedArgs += "^<"; break;
		// 	case '>': escapedArgs += "^>"; break;
		// 	case '|': escapedArgs += "^|"; break;
		// 	case '^': escapedArgs += "^^"; break;
		// 	case '"': escapedArgs += "^%22"; break;
		// 	default: escapedArgs += ch; break;
		// 	}
		// }
		//
		// std::string escapedToastArgs = "";
		// for (char ch : toastArgs) {
		// 	switch (ch) {
		// 	case ' ': escapedToastArgs += "%20"; break;
		// 	case '&': escapedToastArgs += "^&"; break;
		// 	case '\\': escapedToastArgs += "^\\"; break;
		// 	case '<': escapedToastArgs += "^<"; break;
		// 	case '>': escapedToastArgs += "^>"; break;
		// 	case '|': escapedToastArgs += "^|"; break;
		// 	case '^': escapedToastArgs += "^^"; break;
		// 	case '"': escapedToastArgs += "%22"; break;
		// 	default: escapedToastArgs += ch; break;
		// 	}
		// }

		// std::string systemCmd = "myapp://" + escapedToastArgs + "^&userData=[{" + escapedArgs + "}]";

		std::string cmd = "myapp://" + toastArgs + "&userData=[{" + args + "}]";
		std::wstring wCmd = InteractiveNotifications::s2ws(cmd);

		ShellExecute(NULL,
			TEXT("open"),
			wCmd.c_str(),
			NULL,
			NULL,
			SW_SHOWNORMAL);
	}
};
CoCreatableClass(NotificationActivator);

namespace InteractiveNotifications
{
	INTERACTIVENOTIFICATIONS_API HRESULT RegisterAppForNotificationSupport(PCWSTR shortcut, PCWSTR appId)
	{
		CoTaskMemString appData;
		auto hr = ::SHGetKnownFolderPath(FOLDERID_RoamingAppData, 0, nullptr, appData.GetAddressOf());

		if (SUCCEEDED(hr))
		{
			wchar_t shortcutPath[MAX_PATH];
			// Todo: Don't hardcode the path
			hr = ::PathCchCombine(shortcutPath, ARRAYSIZE(shortcutPath), appData.Get(), shortcut);

			if (SUCCEEDED(hr))
			{
				DWORD attributes = ::GetFileAttributes(shortcutPath);
				bool fileExists = attributes < 0xFFFFFFF;

				if (!fileExists)
				{
					// Todo: This is probably the wrong path bc Squirrel
					wchar_t exePath[MAX_PATH];
					DWORD charWritten = ::GetModuleFileName(nullptr, exePath, ARRAYSIZE(exePath));
					hr = charWritten > 0 ? S_OK : HRESULT_FROM_WIN32(::GetLastError());

					if (SUCCEEDED(hr))
					{
						hr = InstallShortcut(shortcutPath, exePath, appId);
						if (SUCCEEDED(hr))
						{
							hr = RegisterComServer(exePath);
						}
					}
				}
			}
		}
		return hr;
	}

	_Use_decl_annotations_
	INTERACTIVENOTIFICATIONS_API HRESULT InstallShortcut(PCWSTR shortcutPath, PCWSTR exePath, PCWSTR appId)
	{
		ComPtr<IShellLink> shellLink;
		HRESULT hr = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&shellLink));

		if (!SUCCEEDED(hr)) return hr;
		hr = shellLink->SetPath(exePath);

		if (!SUCCEEDED(hr)) return hr;
		ComPtr<IPropertyStore> propertyStore;
		hr = shellLink.As(&propertyStore);

		if (!SUCCEEDED(hr)) return hr;
		PROPVARIANT propVar;
		propVar.vt = VT_LPWSTR;
		propVar.pwszVal = const_cast<PWSTR>(appId); // for _In_ scenarios, we don't need a copy
		hr = propertyStore->SetValue(PKEY_AppUserModel_ID, propVar);

		if (!SUCCEEDED(hr)) return hr;
		propVar.vt = VT_CLSID;
		propVar.puuid = const_cast<CLSID*>(&__uuidof(NotificationActivator));
		hr = propertyStore->SetValue(PKEY_AppUserModel_ToastActivatorCLSID, propVar);

		if (!SUCCEEDED(hr)) return hr;
		hr = propertyStore->Commit();

		if (!SUCCEEDED(hr)) return hr;
		ComPtr<IPersistFile> persistFile;
		hr = shellLink.As(&persistFile);

		if (!SUCCEEDED(hr)) return hr;
		hr = persistFile->Save(shortcutPath, TRUE);

		return hr;
	}

	_Use_decl_annotations_
	INTERACTIVENOTIFICATIONS_API HRESULT RegisterComServer(PCWSTR exePath)
	{
		// We don't need to worry about overflow here as ::GetModuleFileName won't
		// return anything bigger than the max file system path (much fewer than max of DWORD).
		DWORD dataSize = static_cast<DWORD>((::wcslen(exePath) + 1) * sizeof(WCHAR));
		auto key = LR"(SOFTWARE\Classes\CLSID\{B23D2B18-8DD7-403A-B9B7-152B40A1478C}\LocalServer32)";

		return HRESULT_FROM_WIN32(::RegSetKeyValue(
			HKEY_CURRENT_USER,
			key,
			nullptr,
			REG_SZ,
			reinterpret_cast<const BYTE*>(exePath),
			dataSize));
	}

	_Use_decl_annotations_
	INTERACTIVENOTIFICATIONS_API HRESULT RegisterActivator()
	{
		// Module<OutOfProc> needs a callback registered before it can be used.
		// Since we don't care about when it shuts down, we'll pass an empty lambda here.
		// If we need to clean up, do it here (we probably don't have to)
		Module<OutOfProc>::Create([] {});

		// If a local server process only hosts the COM object then COM expects
		// the COM server host to shutdown when the references drop to zero.
		// Since the user might still be using the program after activating the notification,
		// we don't want to shutdown immediately.  Incrementing the object count tells COM that
		// we aren't done yet.
		Module<OutOfProc>::GetModule().IncrementObjectCount();

		return Module<OutOfProc>::GetModule().RegisterObjects();
	}

	_Use_decl_annotations_
	INTERACTIVENOTIFICATIONS_API void UnregisterActivator()
	{
		Module<OutOfProc>::GetModule().UnregisterObjects();
		Module<OutOfProc>::GetModule().DecrementObjectCount();
	}

	INTERACTIVENOTIFICATIONS_API std::wstring s2ws(const std::string& s)
	{
		int len;
		int slength = (int)s.length() + 1;

		len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0);

		wchar_t* buf = new wchar_t[len];

		MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
		std::wstring r(buf);
		delete[] buf;

		return r;
	}
}

extern "C"
{
	__declspec(dllexport) void CRegisterForNotificationSupport(PCWSTR shortcut, PCWSTR appId)
	{
		InteractiveNotifications::RegisterAppForNotificationSupport(shortcut, appId);
	}

	__declspec(dllexport) void CRegisterActivator()
	{
		InteractiveNotifications::RegisterActivator();
	}

	__declspec(dllexport) void CUnregisterActivator()
	{
		InteractiveNotifications::UnregisterActivator();
	}
}<commit_msg>:wrench: Return HRESULT from Activator<commit_after>// InteractiveNotifications.cpp : Defines the exported functions for the DLL application.
//

#include "stdafx.h"
#include "InteractiveNotifications.h"
#include <NotificationActivationCallback.h>

#include <Shellapi.h>
#include <string>
#include <iostream>
#include <SDKDDKVer.h>
#include <Windows.h>
#include <Psapi.h>
#include <strsafe.h>
#include <ShObjIdl.h>
#include <Shlobj.h>
#include <Pathcch.h>
#include <propvarutil.h>
#include <propkey.h>
#include <wchar.h>
#include <wrl.h>
#include <wrl\wrappers\corewrappers.h>
#include <windows.ui.notifications.h>

// Correct flow
// RegisterAppForNotificationSupport()
// RegisterActivator()

//  Name:     System.AppUserModel.ToastActivatorCLSID -- PKEY_AppUserModel_ToastActivatorCLSID
//  Type:     Guid -- VT_CLSID
//  FormatID: {9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}, 26
//
//  Used to CoCreate an INotificationActivationCallback interface to notify about toast activations.
EXTERN_C const PROPERTYKEY DECLSPEC_SELECTANY PKEY_AppUserModel_ToastActivatorCLSID = { { 0x9F4C2855, 0x9F79, 0x4B39,{ 0xA8, 0xD0, 0xE1, 0xD4, 0x2D, 0xE1, 0xD5, 0xF3 } }, 26 };

using namespace ABI::Windows::Data::Xml::Dom;
using namespace ABI::Windows::UI::Notifications;
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;

struct CoTaskMemStringTraits
{
	typedef PWSTR Type;

	inline static bool Close(_In_ Type h) throw() { ::CoTaskMemFree(h); return true; }

	inline static Type GetInvalidValue() throw() { return nullptr; }
};
typedef HandleT<CoTaskMemStringTraits> CoTaskMemString;

const wchar_t Shortcut[] = LR"(Microsoft\Windows\Start Menu\Slack.lnk)";

#define __CSID "B23D2B18-8DD7-403A-B9B7-152B40A1478C"

// For the app to be activated from Action Center, it needs to provide a COM server to be called
// when the notification is activated.  The CLSID of the object needs to be registered with the
// OS via its shortcut so that it knows who to call later.
class DECLSPEC_UUID(__CSID) NotificationActivator WrlSealed WrlFinal
: public RuntimeClass < RuntimeClassFlags<ClassicCom>,
	INotificationActivationCallback >
{
public:
	virtual HRESULT STDMETHODCALLTYPE Activate(
		_In_ LPCWSTR appUserModelId,
		_In_ LPCWSTR invokedArgs,
		_In_reads_(dataCount) const NOTIFICATION_USER_INPUT_DATA* data,
		ULONG dataCount) override
	{
		std::string args;

		for (int i = 0; i < dataCount; i++) {
			LPCWSTR lvalue = data[i].Value;
			LPCWSTR lkey = data[i].Key;

			std::wstring wvalue(lvalue);
			std::wstring wkey(lkey);

			std::string value(wvalue.begin(), wvalue.end());
			std::string key(wkey.begin(), wkey.end());

			args = args + "\"key\":\"" + key + "\"";
			args = args + ",\"value\":\"" + value + "\"";
		}

		std::wstring wToastArgs(invokedArgs);
		std::string toastArgs(wToastArgs.begin(), wToastArgs.end());

		// If you ever want to use system() or similar calls,
		// you'll need to escape stuff. We're using ShellExecute,
		// so we don't have to.

		// std::string escapedArgs = "";
		// for (char ch : args) {
		// 	switch (ch) {
		// 	case ' ': escapedArgs += "%20"; break;
		// 	case '&': escapedArgs += "^&"; break;
		// 	case '\\': escapedArgs += "^\\"; break;
		// 	case '<': escapedArgs += "^<"; break;
		// 	case '>': escapedArgs += "^>"; break;
		// 	case '|': escapedArgs += "^|"; break;
		// 	case '^': escapedArgs += "^^"; break;
		// 	case '"': escapedArgs += "^%22"; break;
		// 	default: escapedArgs += ch; break;
		// 	}
		// }
		//
		// std::string escapedToastArgs = "";
		// for (char ch : toastArgs) {
		// 	switch (ch) {
		// 	case ' ': escapedToastArgs += "%20"; break;
		// 	case '&': escapedToastArgs += "^&"; break;
		// 	case '\\': escapedToastArgs += "^\\"; break;
		// 	case '<': escapedToastArgs += "^<"; break;
		// 	case '>': escapedToastArgs += "^>"; break;
		// 	case '|': escapedToastArgs += "^|"; break;
		// 	case '^': escapedToastArgs += "^^"; break;
		// 	case '"': escapedToastArgs += "%22"; break;
		// 	default: escapedToastArgs += ch; break;
		// 	}
		// }

		// std::string systemCmd = "myapp://" + escapedToastArgs + "^&userData=[{" + escapedArgs + "}]";

		std::string cmd = "myapp://" + toastArgs + "&userData=[{" + args + "}]";
		std::wstring wCmd = InteractiveNotifications::s2ws(cmd);

		ShellExecute(NULL,
			TEXT("open"),
			wCmd.c_str(),
			NULL,
			NULL,
			SW_SHOWNORMAL);

		return HRESULT();
	}
};
CoCreatableClass(NotificationActivator);

namespace InteractiveNotifications
{
	INTERACTIVENOTIFICATIONS_API HRESULT RegisterAppForNotificationSupport(PCWSTR shortcut, PCWSTR appId)
	{
		CoTaskMemString appData;
		auto hr = ::SHGetKnownFolderPath(FOLDERID_RoamingAppData, 0, nullptr, appData.GetAddressOf());

		if (SUCCEEDED(hr))
		{
			wchar_t shortcutPath[MAX_PATH];
			// Todo: Don't hardcode the path
			hr = ::PathCchCombine(shortcutPath, ARRAYSIZE(shortcutPath), appData.Get(), shortcut);

			if (SUCCEEDED(hr))
			{
				DWORD attributes = ::GetFileAttributes(shortcutPath);
				bool fileExists = attributes < 0xFFFFFFF;

				if (!fileExists)
				{
					// Todo: This is probably the wrong path bc Squirrel
					wchar_t exePath[MAX_PATH];
					DWORD charWritten = ::GetModuleFileName(nullptr, exePath, ARRAYSIZE(exePath));
					hr = charWritten > 0 ? S_OK : HRESULT_FROM_WIN32(::GetLastError());

					if (SUCCEEDED(hr))
					{
						hr = InstallShortcut(shortcutPath, exePath, appId);
						if (SUCCEEDED(hr))
						{
							hr = RegisterComServer(exePath);
						}
					}
				}
			}
		}
		return hr;
	}

	_Use_decl_annotations_
	INTERACTIVENOTIFICATIONS_API HRESULT InstallShortcut(PCWSTR shortcutPath, PCWSTR exePath, PCWSTR appId)
	{
		ComPtr<IShellLink> shellLink;
		HRESULT hr = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&shellLink));

		if (!SUCCEEDED(hr)) return hr;
		hr = shellLink->SetPath(exePath);

		if (!SUCCEEDED(hr)) return hr;
		ComPtr<IPropertyStore> propertyStore;
		hr = shellLink.As(&propertyStore);

		if (!SUCCEEDED(hr)) return hr;
		PROPVARIANT propVar;
		propVar.vt = VT_LPWSTR;
		propVar.pwszVal = const_cast<PWSTR>(appId); // for _In_ scenarios, we don't need a copy
		hr = propertyStore->SetValue(PKEY_AppUserModel_ID, propVar);

		if (!SUCCEEDED(hr)) return hr;
		propVar.vt = VT_CLSID;
		propVar.puuid = const_cast<CLSID*>(&__uuidof(NotificationActivator));
		hr = propertyStore->SetValue(PKEY_AppUserModel_ToastActivatorCLSID, propVar);

		if (!SUCCEEDED(hr)) return hr;
		hr = propertyStore->Commit();

		if (!SUCCEEDED(hr)) return hr;
		ComPtr<IPersistFile> persistFile;
		hr = shellLink.As(&persistFile);

		if (!SUCCEEDED(hr)) return hr;
		hr = persistFile->Save(shortcutPath, TRUE);

		return hr;
	}

	_Use_decl_annotations_
	INTERACTIVENOTIFICATIONS_API HRESULT RegisterComServer(PCWSTR exePath)
	{
		// We don't need to worry about overflow here as ::GetModuleFileName won't
		// return anything bigger than the max file system path (much fewer than max of DWORD).
		DWORD dataSize = static_cast<DWORD>((::wcslen(exePath) + 1) * sizeof(WCHAR));
		auto key = LR"(SOFTWARE\Classes\CLSID\{B23D2B18-8DD7-403A-B9B7-152B40A1478C}\LocalServer32)";

		return HRESULT_FROM_WIN32(::RegSetKeyValue(
			HKEY_CURRENT_USER,
			key,
			nullptr,
			REG_SZ,
			reinterpret_cast<const BYTE*>(exePath),
			dataSize));
	}

	_Use_decl_annotations_
	INTERACTIVENOTIFICATIONS_API HRESULT RegisterActivator()
	{
		// Module<OutOfProc> needs a callback registered before it can be used.
		// Since we don't care about when it shuts down, we'll pass an empty lambda here.
		// If we need to clean up, do it here (we probably don't have to)
		Module<OutOfProc>::Create([] {});

		// If a local server process only hosts the COM object then COM expects
		// the COM server host to shutdown when the references drop to zero.
		// Since the user might still be using the program after activating the notification,
		// we don't want to shutdown immediately.  Incrementing the object count tells COM that
		// we aren't done yet.
		Module<OutOfProc>::GetModule().IncrementObjectCount();

		return Module<OutOfProc>::GetModule().RegisterObjects();
	}

	_Use_decl_annotations_
	INTERACTIVENOTIFICATIONS_API void UnregisterActivator()
	{
		Module<OutOfProc>::GetModule().UnregisterObjects();
		Module<OutOfProc>::GetModule().DecrementObjectCount();
	}

	INTERACTIVENOTIFICATIONS_API std::wstring s2ws(const std::string& s)
	{
		int len;
		int slength = (int)s.length() + 1;

		len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0);

		wchar_t* buf = new wchar_t[len];

		MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
		std::wstring r(buf);
		delete[] buf;

		return r;
	}
}

extern "C"
{
	__declspec(dllexport) void CRegisterForNotificationSupport(PCWSTR shortcut, PCWSTR appId)
	{
		InteractiveNotifications::RegisterAppForNotificationSupport(shortcut, appId);
	}

	__declspec(dllexport) void CRegisterActivator()
	{
		InteractiveNotifications::RegisterActivator();
	}

	__declspec(dllexport) void CUnregisterActivator()
	{
		InteractiveNotifications::UnregisterActivator();
	}
}<|endoftext|>


<commit_before><commit_msg>TFileMerger _actually_ delete directory only if we induced its creation/loading<commit_after><|endoftext|>


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

  Program:   Fit 2D plane to a set of 3D points
  Language:  C++
  Author:    Junichi Tokuda, Ph.D. (Brigham and Women's Hospital)

  Copyright (c) Brigham and Women's Hospital. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

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

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

#include <complex>
#include "itkListSample.h"
#include "itkCovarianceSampleFilter.h"
#include "itkSymmetricEigenAnalysis.h"
#include "itkImage.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"

typedef std::vector<double> CoordType;
typedef std::vector<CoordType> CoordSetType;

typedef itk::Vector< double, 3 > VectorType;
typedef itk::Statistics::ListSample< VectorType > PointListType;

int CalcIntersectionOfPerpendicularBisectors2D(VectorType& p1, VectorType& p2, VectorType& p3, VectorType& intersec, double radius);

// Load points from the csv file. If successful, return > 0
int LoadPoints(const char* filename, PointListType* points)
{
  std::string line;
  std::ifstream configfile (filename);
  if (!configfile.is_open())
    {
    std::cerr << "Unable to open file" << std::endl;
    return 0;
    }

  points->Clear();

  VectorType point;

  std::cout << "Marker Configuration File: " << filename << std::endl;
  while ( configfile.good() )
    {
    int pointId = 0;
    while(std::getline(configfile,line))
      {
      std::vector<double> values;
      std::stringstream  lineStream(line);
      std::string        cell;
      values.clear();
      while(std::getline(lineStream,cell,','))
        {
        values.push_back(::atof(cell.c_str()));
        }
      if (values.size() == 3)
        {
        point[0] = values[0];
        point[1] = values[1];
        point[2] = values[2];
        points->PushBack(point);
        std::cout << "Fiducial #" << pointId << ": "
                  << "Point=("  << point[0] << ", " << point[1] << ", " << point[2] << "); "
                  << std::endl;
        pointId ++;
        }
      else
        {
        if (values.size() != 0)
          {
          std::cout << "Invalid format!" << std::endl;
          return 0;
          }
        }

      }
    }
  configfile.close();

  return 1;
}

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

  if( argc < 2 )
    {
    std::cerr << "Usage: " << std::endl;
    std::cerr << argv[0] << " pointData [radius]" << std::endl;
    return EXIT_FAILURE;
    }
  const unsigned int Dimension = 2;

  typedef std::complex< float >              PixelType;

  PointListType::Pointer points;
  points = PointListType::New();

  double radius = -1.0;
  if (argc > 2)
    {
    radius = atof(argv[2]);
    }

  //----------------------------------------
  // Load the points
  LoadPoints(argv[1], points);

  //----------------------------------------
  // Perform PCA
  typedef itk::Statistics::CovarianceSampleFilter< PointListType >
    CovarianceAlgorithmType;
  CovarianceAlgorithmType::Pointer covarianceAlgorithm =
    CovarianceAlgorithmType::New();

  covarianceAlgorithm->SetInput( points );
  covarianceAlgorithm->Update();

  //std::cout << "Sample covariance = " << std::endl ;
  //std::cout << covarianceAlgorithm->GetCovarianceMatrix() << std::endl;

  // Perform Symmetric Eigen Analysis
  typedef itk::FixedArray< double, 3 > EigenValuesArrayType;
  typedef itk::Matrix< double, 3, 3 > EigenVectorMatrixType;
  typedef itk::SymmetricEigenAnalysis< CovarianceAlgorithmType::MatrixType,
    EigenValuesArrayType, EigenVectorMatrixType > SymmetricEigenAnalysisType;
  SymmetricEigenAnalysisType analysis ( 3 );
  EigenValuesArrayType eigenValues;
  EigenVectorMatrixType eigenMatrix;
  analysis.SetOrderEigenMagnitudes( true );
  analysis.ComputeEigenValuesAndVectors( covarianceAlgorithm->GetCovarianceMatrix(),
                                         eigenValues, eigenMatrix );

  // Print out the result of PCA
  std::cout << eigenValues << std::endl;
  std::cout << eigenMatrix << std::endl;

  //----------------------------------------
  // Extract the normal vector
  // The first eigen vector (with the minimal eigenvalue) is
  // the normal vector of the fitted plane.

  VectorType principalVector = eigenMatrix[0];
  std::cout << principalVector << std::endl;

  //----------------------------------------
  // Calculate the average position of the all points.
  // This is used as the origin of the new coordinate system on the
  // fitted plane.

  CovarianceAlgorithmType::MeasurementVectorType meanPoint;
  meanPoint = covarianceAlgorithm->GetMean();
  std::cout << "Sample mean = " << meanPoint << std::endl ;

  //----------------------------------------
  // Project all the points to the fitted plane.

  PointListType::Pointer transPoints = PointListType::New();
  typedef PointListType::Iterator IteratorType;
  IteratorType iter = points->Begin();

  VectorType nx =  eigenMatrix[2];
  VectorType ny =  eigenMatrix[1];
  VectorType nz =  eigenMatrix[0];

  while (iter != points->End())
    {
    VectorType p1;
    VectorType p2;
    p1 = iter.GetMeasurementVector() - meanPoint;
    p2[0] = p1*nx;
    p2[1] = p1*ny;
    //p2[2] = p1*nz;
    p2[2] = 0.0;
    transPoints->PushBack(p2);
    ++ iter;
    }

  // Pick up every combination of three points from the list and calculate
  // the intersection of the perpendicular bisectors of the two chords connecting
  // the three points.

  VectorType meanIntersect;
  meanIntersect[0] = 0.0;
  meanIntersect[1] = 0.0;
  meanIntersect[2] = 0.0;

  int nPoints = 0;
  int nPointsUsed = 0;

  for (IteratorType iter1 = transPoints->Begin(); iter1 != transPoints->End(); ++ iter1)
    {
    IteratorType iter2 = iter1;
    for (++ iter2; iter2 != transPoints->End(); ++ iter2)
      {
      IteratorType iter3 = iter2;
      for (++ iter3; iter3 != transPoints->End(); ++ iter3)
        {
        VectorType p1 = iter1.GetMeasurementVector();
        VectorType p2 = iter2.GetMeasurementVector();
        VectorType p3 = iter3.GetMeasurementVector();
        VectorType c;

        nPoints ++;
        if (CalcIntersectionOfPerpendicularBisectors2D(p1, p2, p3, c, radius) > 0)
          {
          meanIntersect = meanIntersect + c;
          nPointsUsed ++;
          }
        }
      }
    }

  meanIntersect = meanIntersect / nPointsUsed;

  // Transform the center point to the original coordinate system
  VectorType center = meanIntersect[0] * nx + meanIntersect[1] * ny + meanIntersect[2] * nz + meanPoint;

  std::cout << "Number of estimated center points: " << nPoints << std::endl;
  std::cout << "Number of estimated center points used: " << nPointsUsed << std::endl;
  std::cout << "Center = " << center << std::endl;

  return EXIT_SUCCESS;
}

// Return 0, if the data set may not give a good estimate.
int CalcIntersectionOfPerpendicularBisectors2D(VectorType& p1, VectorType& p2, VectorType& p3, VectorType& intersect, double radius)
{

  const double posErr = 5.0;

  // Compute the bisecting points between p1 and p2 (m1), and p2 and p3 (m2)
  VectorType m1 = (p1+p2)/2.0;
  VectorType m2 = (p2+p3)/2.0;

  // Compute the normal vectors along the perpendicular bisectors
  VectorType v12 = (p2-p1);
  VectorType v23 = (p3-p2);

  if (v12.GetNorm() < posErr || v23.GetNorm() < posErr)
    {
    return 0;
    }

  v12.Normalize();
  v23.Normalize();

  VectorType n1;
  n1[0] = -v12[1];
  n1[1] = v12[0];
  n1[2] = v12[2];

  VectorType n2;
  n2[0] = -v23[1];
  n2[1] = v23[0];
  n2[2] = v23[2];

  // Compute the projection of m2 onto the perpendicular bisector of p1p2
  VectorType h = m1 + ((m2-m1)*n1)*n1;

  // The intersecting point of the two perpendicular bisectors (= estimated
  // center of fitted circle) is 'c' can be written as:
  //
  //    <c> = <m2> + a * <n2>
  //
  // where 'a' is a scalar value. Projection of 'c' on the m2h is 'h'
  //
  //    a * <n2> * (<h> - <m2>)/(|<h> - <m2>|) = |<h> - <m2>|
  //    a = |<h> - <m2>|^2 / {<n2> * (<h> - <m2>)}
  //

  VectorType m2h = h-m2;
  VectorType::RealValueType a = m2h.GetSquaredNorm() / (n2 * m2h);

  intersect = m2 + a * n2;

  // Validate by radius, if radius is greater than 0
  if (radius > 0)
    {
    VectorType d1 = p1-intersect;
    VectorType d2 = p2-intersect;
    VectorType d3 = p3-intersect;

    if (fabs(d1.GetNorm()-radius) > posErr ||
        fabs(d2.GetNorm()-radius) > posErr ||
        fabs(d3.GetNorm()-radius) > posErr)
      {
      return 0;
      }
    }

  return 1;
}
<commit_msg>ENH: Implemented code to bring original points into circle plane and rotate it to find best fitting angle (minimum average distance) STYLE: Cleaned source code<commit_after>/*=========================================================================

  Program:   Fit 2D plane to a set of 3D points
  Language:  C++
  Author:    Junichi Tokuda, Ph.D. (Brigham and Women's Hospital)

  Copyright (c) Brigham and Women's Hospital. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

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

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

#include <complex>
#include "itkListSample.h"
#include "itkCovarianceSampleFilter.h"
#include "itkSymmetricEigenAnalysis.h"
#include "itkAffineTransform.h"
#include "itkImage.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"

typedef std::vector<double> CoordType;
typedef std::vector<CoordType> CoordSetType;

typedef itk::Vector< double, 3 > VectorType;
typedef itk::Point< double, 3> PointType;
typedef itk::Matrix< double, 3, 3 > MatrixType;
typedef itk::FixedArray< double, 3 > ArrayType;
typedef itk::AffineTransform< double, 3 > TransformType;
typedef itk::Statistics::ListSample< VectorType > PointListType;
typedef PointListType::Iterator PointListIteratorType;
typedef itk::Statistics::CovarianceSampleFilter< PointListType > CovarianceAlgorithmType;
typedef itk::SymmetricEigenAnalysis< CovarianceAlgorithmType::MatrixType, ArrayType, MatrixType > SymmetricEigenAnalysisType;

int CalcIntersectionOfPerpendicularBisectors2D(VectorType& p1, VectorType& p2, VectorType& p3, VectorType& intersec, double radius);
double CalcAverageMinDistanceOfRotatedPoints(PointListType::Pointer rotatingPoints, PointListType::Pointer fixedPoints,
					     VectorType& principalVector, int angle,
					     MatrixType& rotationMatrix);

// Load points from the csv file. If successful, return > 0
int LoadPoints(const char* filename, PointListType* points)
{
  std::string line;
  std::ifstream configfile (filename);
  if (!configfile.is_open())
    {
    std::cerr << "Unable to open file" << std::endl;
    return 0;
    }

  points->Clear();

  VectorType point;

  std::cout << "Marker Configuration File: " << filename << std::endl;
  while ( configfile.good() )
    {
    int pointId = 0;
    while(std::getline(configfile,line))
      {
      std::vector<double> values;
      std::stringstream  lineStream(line);
      std::string        cell;
      values.clear();
      while(std::getline(lineStream,cell,','))
        {
        values.push_back(::atof(cell.c_str()));
        }
      if (values.size() == 3)
        {
        point[0] = values[0];
        point[1] = values[1];
        point[2] = values[2];
        points->PushBack(point);
        std::cout << "Fiducial #" << pointId << ": "
                  << "Point=("  << point[0] << ", " << point[1] << ", " << point[2] << "); "
                  << std::endl;
        pointId ++;
        }
      else
        {
        if (values.size() != 0)
          {
          std::cout << "Invalid format!" << std::endl;
          return 0;
          }
        }
      }
    }
  std::cout << std::endl;
  configfile.close();

  return 1;
}

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

  if( argc < 2 )
    {
    std::cerr << "Usage: " << std::endl;
    std::cerr << argv[0] << " srcPoints dstPoints [radius]" << std::endl;
    return EXIT_FAILURE;
    }
  const unsigned int Dimension = 2;

  double radius = -1.0;
  if (argc > 3)
    {
    radius = atof(argv[3]);
    }

  //----------------------------------------
  // Load the points

  PointListType::Pointer srcPoints, dstPoints;
  srcPoints = PointListType::New();
  dstPoints = PointListType::New();

  LoadPoints(argv[1], srcPoints);
  LoadPoints(argv[2], dstPoints);

  //----------------------------------------
  // Perform PCA

  CovarianceAlgorithmType::Pointer covarianceAlgorithm =
    CovarianceAlgorithmType::New();

  covarianceAlgorithm->SetInput( dstPoints );
  covarianceAlgorithm->Update();

  // Perform Symmetric Eigen Analysis
  SymmetricEigenAnalysisType analysis ( 3 );
  ArrayType eigenValues;
  MatrixType eigenMatrix;
  analysis.SetOrderEigenMagnitudes( true );
  analysis.ComputeEigenValuesAndVectors( covarianceAlgorithm->GetCovarianceMatrix(),
                                         eigenValues, eigenMatrix );

  //----------------------------------------
  // Extract the normal vector
  // The first eigen vector (with the minimal eigenvalue) is
  // the normal vector of the fitted plane.

  VectorType nx =  eigenMatrix[2];
  VectorType ny =  eigenMatrix[1];
  VectorType nz =  eigenMatrix[0];
  VectorType principalVector = nz;

  //----------------------------------------
  // Calculate the average position of the all points.
  // This is used as the origin of the new coordinate system on the
  // fitted plane.

  CovarianceAlgorithmType::MeasurementVectorType meanPoint;
  meanPoint = covarianceAlgorithm->GetMean();

  //----------------------------------------
  // Project all the points to the fitted plane.

  PointListType::Pointer projectedPoints = PointListType::New();
  for (PointListIteratorType iter = dstPoints->Begin(); iter != dstPoints->End(); ++iter)
    {
    VectorType p1;
    VectorType p2;
    p1 = iter.GetMeasurementVector() - meanPoint;
    p2[0] = p1*nx;
    p2[1] = p1*ny;
    p2[2] = 0.0;
    projectedPoints->PushBack(p2);
    }

  //----------------------------------------
  // Pick up every combination of three points from the list and calculate
  // the intersection of the perpendicular bisectors of the two chords connecting
  // the three points.

  VectorType meanIntersect;
  meanIntersect[0] = 0.0;
  meanIntersect[1] = 0.0;
  meanIntersect[2] = 0.0;

  int nPoints = 0;
  int nPointsUsed = 0;

  for (PointListIteratorType iter1 = projectedPoints->Begin(); iter1 != projectedPoints->End(); ++iter1)
    {
    PointListIteratorType iter2 = iter1;
    for (++iter2; iter2 != projectedPoints->End(); ++iter2)
      {
      PointListIteratorType iter3 = iter2;
      for (++iter3; iter3 != projectedPoints->End(); ++iter3)
        {
        VectorType p1 = iter1.GetMeasurementVector();
        VectorType p2 = iter2.GetMeasurementVector();
        VectorType p3 = iter3.GetMeasurementVector();
        VectorType c;

        nPoints ++;
        if (CalcIntersectionOfPerpendicularBisectors2D(p1, p2, p3, c, radius) > 0)
          {
          meanIntersect = meanIntersect + c;
          nPointsUsed ++;
          }
        }
      }
    }
  meanIntersect = meanIntersect / nPointsUsed;

  //----------------------------------------
  // Transform the center point to the original coordinate system

  VectorType center = meanIntersect[0] * nx + meanIntersect[1] * ny + meanIntersect[2] * nz + meanPoint;

  std::cout << "Number of estimated center points: " << nPoints << std::endl;
  std::cout << "Number of estimated center points used: " << nPointsUsed << std::endl;
  std::cout << "Center = " << center << std::endl;
  std::cout << std::endl;

  //----------------------------------------
  // Calculate matrix from original coordinate system to plane coordinate system

  MatrixType originalToPlaneMatrix;
  for (int i = 0; i < 3; ++i)
    {
    originalToPlaneMatrix[i][0] = nx[i];
    originalToPlaneMatrix[i][1] = ny[i];
    originalToPlaneMatrix[i][2] = nz[i];
    }

  //----------------------------------------
  // Rotate points from original position to in-plane position

  PointListType::Pointer inPlanePoints = PointListType::New();
  for (PointListIteratorType iter = srcPoints->Begin(); iter != srcPoints->End(); ++iter)
    {
    VectorType pp = originalToPlaneMatrix*iter.GetMeasurementVector() + center;
    inPlanePoints->PushBack(pp);
    }

  //----------------------------------------
  // Rotate point around principal vector and compute average minimum distance

  double globalAverageMinimumDistance = -1.0;
  MatrixType tmpRotationMatrix;
  MatrixType globalRotationMatrix;
  double globalRotationAngle = 0.0;
  bool circleFlipped = false;

  // TODO: Optimize. Use a step of 3 degrees (for example) and find minimum average distance.
  //       When found, use a step of 1 degree between the 3 degrees previously found.
  //       Step of 1 = 360 iterations
  //       Optimized (step of 3) = (360 / 3) + 3 = 123 iterations
  //       Optimized (step of 10) = (360 / 10) + 10 = 46 iterations
  //       If step is too big though, average minimum can be missed, and registration fail
  for (int angle = 0; angle < 360; ++angle)
    {
    double averageMinDistance = CalcAverageMinDistanceOfRotatedPoints(inPlanePoints, dstPoints,
								      principalVector, angle,
								      tmpRotationMatrix);

    if (globalAverageMinimumDistance < 0 || averageMinDistance < globalAverageMinimumDistance)
      {
      globalAverageMinimumDistance = averageMinDistance;
      globalRotationMatrix = tmpRotationMatrix;
      globalRotationAngle = angle;
      }
    }

  //----------------------------------------
  // Rotate circle around one of the other axis, nx or ny, and recalculate average minimum distance
  // to also find the global minimum (including symmetry)

  TransformType::Pointer flippingTransform = TransformType::New();
  flippingTransform->Rotate3D(nx, M_PI);

  PointListType::Pointer flippedInPlanePoints = PointListType::New();
  for (PointListIteratorType iter = inPlanePoints->Begin(); iter != inPlanePoints->End(); ++iter)
    {
    flippedInPlanePoints->PushBack(flippingTransform->GetMatrix()*iter.GetMeasurementVector());
    }

  for (int angle = 0; angle < 360; ++angle)
    {
    double averageMinDistance = CalcAverageMinDistanceOfRotatedPoints(flippedInPlanePoints, dstPoints,
								      principalVector, angle,
								      tmpRotationMatrix);

    if (globalAverageMinimumDistance < 0 || averageMinDistance < globalAverageMinimumDistance)
      {
      globalAverageMinimumDistance = averageMinDistance;
      globalRotationMatrix = tmpRotationMatrix;
      globalRotationAngle = angle;
      circleFlipped = true;
      }
    }

  std::cout << "Best Fitting angle: " << globalRotationAngle << " (" << (circleFlipped ? "Flipped" : "Not flipped") << ")" << std::endl
	    << "Average Minimum Distance: " << globalAverageMinimumDistance << std::endl;

  MatrixType registrationMatrix = circleFlipped ?
    globalRotationMatrix*flippingTransform->GetMatrix()*originalToPlaneMatrix :
    globalRotationMatrix*originalToPlaneMatrix;
  std::cout << "Registration Matrix: " << std::endl << registrationMatrix << std::endl;

  //----------------------------------------
  // Output registered points for checking

  std::ofstream outputFile("registeredPoints.csv");
  for (PointListIteratorType iter = srcPoints->Begin(); iter != srcPoints->End(); ++iter)
    {
    VectorType tmpVector = center + registrationMatrix*iter.GetMeasurementVector();
    outputFile << tmpVector[0] << "," << tmpVector[1] << "," << tmpVector[2] << std::endl;
    }
  outputFile.close();

  return EXIT_SUCCESS;
}

//--------------------------------------------------------------------------------
// Return 0, if the data set may not give a good estimate.
int CalcIntersectionOfPerpendicularBisectors2D(VectorType& p1, VectorType& p2, VectorType& p3, VectorType& intersect, double radius)
{

  const double posErr = 5.0;

  // Compute the bisecting points between p1 and p2 (m1), and p2 and p3 (m2)
  VectorType m1 = (p1+p2)/2.0;
  VectorType m2 = (p2+p3)/2.0;

  // Compute the normal vectors along the perpendicular bisectors
  VectorType v12 = (p2-p1);
  VectorType v23 = (p3-p2);

  if (v12.GetNorm() < posErr || v23.GetNorm() < posErr)
    {
    return 0;
    }

  v12.Normalize();
  v23.Normalize();

  VectorType n1;
  n1[0] = -v12[1];
  n1[1] = v12[0];
  n1[2] = v12[2];

  VectorType n2;
  n2[0] = -v23[1];
  n2[1] = v23[0];
  n2[2] = v23[2];

  // Compute the projection of m2 onto the perpendicular bisector of p1p2
  VectorType h = m1 + ((m2-m1)*n1)*n1;

  // The intersecting point of the two perpendicular bisectors (= estimated
  // center of fitted circle) is 'c' can be written as:
  //
  //    <c> = <m2> + a * <n2>
  //
  // where 'a' is a scalar value. Projection of 'c' on the m2h is 'h'
  //
  //    a * <n2> * (<h> - <m2>)/(|<h> - <m2>|) = |<h> - <m2>|
  //    a = |<h> - <m2>|^2 / {<n2> * (<h> - <m2>)}
  //

  VectorType m2h = h-m2;
  VectorType::RealValueType a = m2h.GetSquaredNorm() / (n2 * m2h);

  intersect = m2 + a * n2;

  // Validate by radius, if radius is greater than 0
  if (radius > 0)
    {
    VectorType d1 = p1-intersect;
    VectorType d2 = p2-intersect;
    VectorType d3 = p3-intersect;

    if (fabs(d1.GetNorm()-radius) > posErr ||
        fabs(d2.GetNorm()-radius) > posErr ||
        fabs(d3.GetNorm()-radius) > posErr)
      {
      return 0;
      }
    }

  return 1;
}

//--------------------------------------------------------------------------------
// Return average minimum distance between rotated and fixed pointsets,
// as well as the rotation matrix used
double CalcAverageMinDistanceOfRotatedPoints(PointListType::Pointer rotatingPoints, PointListType::Pointer fixedPoints,
					   VectorType& principalVector, int angle,
					   MatrixType& rotationMatrix)
{
  // Rotate points
  TransformType::Pointer rotationTransform = TransformType::New();
  rotationTransform->Rotate3D(principalVector, angle * M_PI / 180);
  rotationMatrix = rotationTransform->GetMatrix();

  double averageMinDistance = 0.0;
  int numberOfPoints = 0;
  for (PointListIteratorType iter1 = rotatingPoints->Begin(); iter1 != rotatingPoints->End(); ++iter1)
    {
    // Rotate point
    VectorType rp = rotationMatrix*iter1.GetMeasurementVector();

    // Compute minDistance
    double minDistance = -1.0;
    for (PointListIteratorType iter2 = fixedPoints->Begin(); iter2 != fixedPoints->End(); ++iter2)
      {
      VectorType fp = iter2.GetMeasurementVector();

      double distance = std::sqrt(std::pow(rp[0]-fp[0],2) +
				  std::pow(rp[1]-fp[1],2) +
				  std::pow(rp[2]-fp[2],2));
      if (minDistance < 0 || distance < minDistance)
	{
	minDistance = distance;
	}
      }
    averageMinDistance += minDistance;
    numberOfPoints++;
    }
  averageMinDistance /= numberOfPoints;
  return averageMinDistance;
}
<|endoftext|>


<commit_before>// Copyright (c) 2011 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 "webkit/plugins/ppapi/ppb_var_deprecated_impl.h"

#include <limits>

#include "ppapi/c/dev/ppb_var_deprecated.h"
#include "ppapi/c/ppb_var.h"
#include "ppapi/c/pp_var.h"
#include "ppapi/shared_impl/ppb_var_shared.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebBindings.h"
#include "webkit/plugins/ppapi/common.h"
#include "webkit/plugins/ppapi/host_globals.h"
#include "webkit/plugins/ppapi/npapi_glue.h"
#include "webkit/plugins/ppapi/npobject_var.h"
#include "webkit/plugins/ppapi/plugin_module.h"
#include "webkit/plugins/ppapi/plugin_object.h"
#include "webkit/plugins/ppapi/ppapi_plugin_instance.h"

using ppapi::NPObjectVar;
using ppapi::PpapiGlobals;
using ppapi::StringVar;
using ppapi::Var;
using WebKit::WebBindings;

namespace webkit {
namespace ppapi {

namespace {

const char kInvalidObjectException[] = "Error: Invalid object";
const char kInvalidPropertyException[] = "Error: Invalid property";
const char kInvalidValueException[] = "Error: Invalid value";
const char kUnableToGetPropertyException[] = "Error: Unable to get property";
const char kUnableToSetPropertyException[] = "Error: Unable to set property";
const char kUnableToRemovePropertyException[] =
    "Error: Unable to remove property";
const char kUnableToGetAllPropertiesException[] =
    "Error: Unable to get all properties";
const char kUnableToCallMethodException[] = "Error: Unable to call method";
const char kUnableToConstructException[] = "Error: Unable to construct";

// ---------------------------------------------------------------------------
// Utilities

// Converts the given PP_Var to an NPVariant, returning true on success.
// False means that the given variant is invalid. In this case, the result
// NPVariant will be set to a void one.
//
// The contents of the PP_Var will NOT be copied, so you need to ensure that
// the PP_Var remains valid while the resultant NPVariant is in use.
bool PPVarToNPVariantNoCopy(PP_Var var, NPVariant* result) {
  switch (var.type) {
    case PP_VARTYPE_UNDEFINED:
      VOID_TO_NPVARIANT(*result);
      break;
    case PP_VARTYPE_NULL:
      NULL_TO_NPVARIANT(*result);
      break;
    case PP_VARTYPE_BOOL:
      BOOLEAN_TO_NPVARIANT(var.value.as_bool, *result);
      break;
    case PP_VARTYPE_INT32:
      INT32_TO_NPVARIANT(var.value.as_int, *result);
      break;
    case PP_VARTYPE_DOUBLE:
      DOUBLE_TO_NPVARIANT(var.value.as_double, *result);
      break;
    case PP_VARTYPE_STRING: {
      StringVar* string = StringVar::FromPPVar(var);
      if (!string) {
        VOID_TO_NPVARIANT(*result);
        return false;
      }
      const std::string& value = string->value();
      STRINGN_TO_NPVARIANT(value.c_str(), value.size(), *result);
      break;
    }
    case PP_VARTYPE_OBJECT: {
      scoped_refptr<NPObjectVar> object(NPObjectVar::FromPPVar(var));
      if (!object) {
        VOID_TO_NPVARIANT(*result);
        return false;
      }
      OBJECT_TO_NPVARIANT(object->np_object(), *result);
      break;
    }
    default:
      VOID_TO_NPVARIANT(*result);
      return false;
  }
  return true;
}

// ObjectAccessorTryCatch ------------------------------------------------------

// Automatically sets up a TryCatch for accessing the object identified by the
// given PP_Var. The module from the object will be used for the exception
// strings generated by the TryCatch.
//
// This will automatically retrieve the ObjectVar from the object and throw
// an exception if it's invalid. At the end of construction, if there is no
// exception, you know that there is no previously set exception, that the
// object passed in is valid and ready to use (via the object() getter), and
// that the TryCatch's pp_module() getter is also set up properly and ready to
// use.
class ObjectAccessorTryCatch : public TryCatch {
 public:
  ObjectAccessorTryCatch(PP_Var object, PP_Var* exception)
      : TryCatch(exception),
        object_(NPObjectVar::FromPPVar(object)) {
    if (!object_) {
      SetException(kInvalidObjectException);
    }
  }

  NPObjectVar* object() { return object_.get(); }

  PluginInstance* GetPluginInstance() {
    return HostGlobals::Get()->GetInstance(object()->pp_instance());
  }

 protected:
  scoped_refptr<NPObjectVar> object_;

  DISALLOW_COPY_AND_ASSIGN(ObjectAccessorTryCatch);
};

// ObjectAccessiorWithIdentifierTryCatch ---------------------------------------

// Automatically sets up a TryCatch for accessing the identifier on the given
// object. This just extends ObjectAccessorTryCatch to additionally convert
// the given identifier to an NPIdentifier and validate it, throwing an
// exception if it's invalid.
//
// At the end of construction, if there is no exception, you know that there is
// no previously set exception, that the object passed in is valid and ready to
// use (via the object() getter), that the identifier is valid and ready to
// use (via the identifier() getter), and that the TryCatch's pp_module() getter
// is also set up properly and ready to use.
class ObjectAccessorWithIdentifierTryCatch : public ObjectAccessorTryCatch {
 public:
  ObjectAccessorWithIdentifierTryCatch(PP_Var object,
                                       PP_Var identifier,
                                       PP_Var* exception)
      : ObjectAccessorTryCatch(object, exception),
        identifier_(0) {
    if (!has_exception()) {
      identifier_ = PPVarToNPIdentifier(identifier);
      if (!identifier_)
        SetException(kInvalidPropertyException);
    }
  }

  NPIdentifier identifier() const { return identifier_; }

 private:
  NPIdentifier identifier_;

  DISALLOW_COPY_AND_ASSIGN(ObjectAccessorWithIdentifierTryCatch);
};

PP_Bool HasProperty(PP_Var var,
                    PP_Var name,
                    PP_Var* exception) {
  ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception);
  if (accessor.has_exception())
    return PP_FALSE;
  return BoolToPPBool(WebBindings::hasProperty(NULL,
                                               accessor.object()->np_object(),
                                               accessor.identifier()));
}

bool HasPropertyDeprecated(PP_Var var,
                           PP_Var name,
                           PP_Var* exception) {
  return PPBoolToBool(HasProperty(var, name, exception));
}

bool HasMethodDeprecated(PP_Var var,
                         PP_Var name,
                         PP_Var* exception) {
  ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception);
  if (accessor.has_exception())
    return false;
  return WebBindings::hasMethod(NULL, accessor.object()->np_object(),
                                accessor.identifier());
}

PP_Var GetProperty(PP_Var var,
                   PP_Var name,
                   PP_Var* exception) {
  ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception);
  if (accessor.has_exception())
    return PP_MakeUndefined();

  NPVariant result;
  if (!WebBindings::getProperty(NULL, accessor.object()->np_object(),
                                accessor.identifier(), &result)) {
    // An exception may have been raised.
    accessor.SetException(kUnableToGetPropertyException);
    return PP_MakeUndefined();
  }

  PP_Var ret = NPVariantToPPVar(accessor.GetPluginInstance(), &result);
  WebBindings::releaseVariantValue(&result);
  return ret;
}

void EnumerateProperties(PP_Var var,
                         uint32_t* property_count,
                         PP_Var** properties,
                         PP_Var* exception) {
  *properties = NULL;
  *property_count = 0;

  ObjectAccessorTryCatch accessor(var, exception);
  if (accessor.has_exception())
    return;

  NPIdentifier* identifiers = NULL;
  uint32_t count = 0;
  if (!WebBindings::enumerate(NULL, accessor.object()->np_object(),
                              &identifiers, &count)) {
    accessor.SetException(kUnableToGetAllPropertiesException);
    return;
  }

  if (count == 0)
    return;

  *property_count = count;
  *properties = static_cast<PP_Var*>(malloc(sizeof(PP_Var) * count));
  for (uint32_t i = 0; i < count; ++i) {
    (*properties)[i] = NPIdentifierToPPVar(identifiers[i]);
  }
  free(identifiers);
}

void SetPropertyDeprecated(PP_Var var,
                           PP_Var name,
                           PP_Var value,
                           PP_Var* exception) {
  ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception);
  if (accessor.has_exception())
    return;

  NPVariant variant;
  if (!PPVarToNPVariantNoCopy(value, &variant)) {
    accessor.SetException(kInvalidValueException);
    return;
  }
  if (!WebBindings::setProperty(NULL, accessor.object()->np_object(),
                                accessor.identifier(), &variant))
    accessor.SetException(kUnableToSetPropertyException);
}

void DeletePropertyDeprecated(PP_Var var,
                              PP_Var name,
                              PP_Var* exception) {
  ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception);
  if (accessor.has_exception())
    return;

  if (!WebBindings::removeProperty(NULL, accessor.object()->np_object(),
                                   accessor.identifier()))
    accessor.SetException(kUnableToRemovePropertyException);
}

PP_Var CallDeprecated(PP_Var var,
                      PP_Var method_name,
                      uint32_t argc,
                      PP_Var* argv,
                      PP_Var* exception) {
  ObjectAccessorTryCatch accessor(var, exception);
  if (accessor.has_exception())
    return PP_MakeUndefined();

  NPIdentifier identifier;
  if (method_name.type == PP_VARTYPE_UNDEFINED) {
    identifier = NULL;
  } else if (method_name.type == PP_VARTYPE_STRING) {
    // Specifically allow only string functions to be called.
    identifier = PPVarToNPIdentifier(method_name);
    if (!identifier) {
      accessor.SetException(kInvalidPropertyException);
      return PP_MakeUndefined();
    }
  } else {
    accessor.SetException(kInvalidPropertyException);
    return PP_MakeUndefined();
  }

  scoped_array<NPVariant> args;
  if (argc) {
    args.reset(new NPVariant[argc]);
    for (uint32_t i = 0; i < argc; ++i) {
      if (!PPVarToNPVariantNoCopy(argv[i], &args[i])) {
        // This argument was invalid, throw an exception & give up.
        accessor.SetException(kInvalidValueException);
        return PP_MakeUndefined();
      }
    }
  }

  bool ok;

  NPVariant result;
  if (identifier) {
    ok = WebBindings::invoke(NULL, accessor.object()->np_object(),
                             identifier, args.get(), argc, &result);
  } else {
    ok = WebBindings::invokeDefault(NULL, accessor.object()->np_object(),
                                    args.get(), argc, &result);
  }

  if (!ok) {
    // An exception may have been raised.
    accessor.SetException(kUnableToCallMethodException);
    return PP_MakeUndefined();
  }

  PP_Var ret = NPVariantToPPVar(accessor.GetPluginInstance(), &result);
  WebBindings::releaseVariantValue(&result);
  return ret;
}

PP_Var Construct(PP_Var var,
                 uint32_t argc,
                 PP_Var* argv,
                 PP_Var* exception) {
  ObjectAccessorTryCatch accessor(var, exception);
  if (accessor.has_exception())
    return PP_MakeUndefined();

  scoped_array<NPVariant> args;
  if (argc) {
    args.reset(new NPVariant[argc]);
    for (uint32_t i = 0; i < argc; ++i) {
      if (!PPVarToNPVariantNoCopy(argv[i], &args[i])) {
        // This argument was invalid, throw an exception & give up.
        accessor.SetException(kInvalidValueException);
        return PP_MakeUndefined();
      }
    }
  }

  NPVariant result;
  if (!WebBindings::construct(NULL, accessor.object()->np_object(),
                              args.get(), argc, &result)) {
    // An exception may have been raised.
    accessor.SetException(kUnableToConstructException);
    return PP_MakeUndefined();
  }

  PP_Var ret = NPVariantToPPVar(accessor.GetPluginInstance(), &result);
  WebBindings::releaseVariantValue(&result);
  return ret;
}

bool IsInstanceOfDeprecated(PP_Var var,
                            const PPP_Class_Deprecated* ppp_class,
                            void** ppp_class_data) {
  scoped_refptr<NPObjectVar> object(NPObjectVar::FromPPVar(var));
  if (!object)
    return false;  // Not an object at all.

  return PluginObject::IsInstanceOf(object->np_object(),
                                    ppp_class, ppp_class_data);
}

PP_Var CreateObjectDeprecated(PP_Instance pp_instance,
                              const PPP_Class_Deprecated* ppp_class,
                              void* ppp_class_data) {
  PluginInstance* instance = HostGlobals::Get()->GetInstance(pp_instance);
  if (!instance) {
    DLOG(ERROR) << "Create object passed an invalid instance.";
    return PP_MakeNull();
  }
  return PluginObject::Create(instance, ppp_class, ppp_class_data);
}

PP_Var CreateObjectWithModuleDeprecated(PP_Module pp_module,
                                        const PPP_Class_Deprecated* ppp_class,
                                        void* ppp_class_data) {
  PluginModule* module = HostGlobals::Get()->GetModule(pp_module);
  if (!module)
    return PP_MakeNull();
  return PluginObject::Create(module->GetSomeInstance(),
                              ppp_class, ppp_class_data);
}

}  // namespace

// static
const PPB_Var_Deprecated* PPB_Var_Deprecated_Impl::GetVarDeprecatedInterface() {
  static const PPB_Var_Deprecated var_deprecated_interface = {
    ::ppapi::PPB_Var_Shared::GetVarInterface1_0()->AddRef,
    ::ppapi::PPB_Var_Shared::GetVarInterface1_0()->Release,
    ::ppapi::PPB_Var_Shared::GetVarInterface1_0()->VarFromUtf8,
    ::ppapi::PPB_Var_Shared::GetVarInterface1_0()->VarToUtf8,
    &HasPropertyDeprecated,
    &HasMethodDeprecated,
    &GetProperty,
    &EnumerateProperties,
    &SetPropertyDeprecated,
    &DeletePropertyDeprecated,
    &CallDeprecated,
    &Construct,
    &IsInstanceOfDeprecated,
    &CreateObjectDeprecated,
    &CreateObjectWithModuleDeprecated,
  };

  return &var_deprecated_interface;
}

}  // namespace ppapi
}  // namespace webkit

<commit_msg>Fix user gesture for scripting calls from Pepper plugins.<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 "webkit/plugins/ppapi/ppb_var_deprecated_impl.h"

#include <limits>

#include "ppapi/c/dev/ppb_var_deprecated.h"
#include "ppapi/c/ppb_var.h"
#include "ppapi/c/pp_var.h"
#include "ppapi/shared_impl/ppb_var_shared.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebBindings.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebScopedUserGesture.h"
#include "webkit/plugins/ppapi/common.h"
#include "webkit/plugins/ppapi/host_globals.h"
#include "webkit/plugins/ppapi/npapi_glue.h"
#include "webkit/plugins/ppapi/npobject_var.h"
#include "webkit/plugins/ppapi/plugin_module.h"
#include "webkit/plugins/ppapi/plugin_object.h"
#include "webkit/plugins/ppapi/ppapi_plugin_instance.h"

using ppapi::NPObjectVar;
using ppapi::PpapiGlobals;
using ppapi::StringVar;
using ppapi::Var;
using WebKit::WebBindings;

namespace webkit {
namespace ppapi {

namespace {

const char kInvalidObjectException[] = "Error: Invalid object";
const char kInvalidPropertyException[] = "Error: Invalid property";
const char kInvalidValueException[] = "Error: Invalid value";
const char kUnableToGetPropertyException[] = "Error: Unable to get property";
const char kUnableToSetPropertyException[] = "Error: Unable to set property";
const char kUnableToRemovePropertyException[] =
    "Error: Unable to remove property";
const char kUnableToGetAllPropertiesException[] =
    "Error: Unable to get all properties";
const char kUnableToCallMethodException[] = "Error: Unable to call method";
const char kUnableToConstructException[] = "Error: Unable to construct";

// ---------------------------------------------------------------------------
// Utilities

// Converts the given PP_Var to an NPVariant, returning true on success.
// False means that the given variant is invalid. In this case, the result
// NPVariant will be set to a void one.
//
// The contents of the PP_Var will NOT be copied, so you need to ensure that
// the PP_Var remains valid while the resultant NPVariant is in use.
bool PPVarToNPVariantNoCopy(PP_Var var, NPVariant* result) {
  switch (var.type) {
    case PP_VARTYPE_UNDEFINED:
      VOID_TO_NPVARIANT(*result);
      break;
    case PP_VARTYPE_NULL:
      NULL_TO_NPVARIANT(*result);
      break;
    case PP_VARTYPE_BOOL:
      BOOLEAN_TO_NPVARIANT(var.value.as_bool, *result);
      break;
    case PP_VARTYPE_INT32:
      INT32_TO_NPVARIANT(var.value.as_int, *result);
      break;
    case PP_VARTYPE_DOUBLE:
      DOUBLE_TO_NPVARIANT(var.value.as_double, *result);
      break;
    case PP_VARTYPE_STRING: {
      StringVar* string = StringVar::FromPPVar(var);
      if (!string) {
        VOID_TO_NPVARIANT(*result);
        return false;
      }
      const std::string& value = string->value();
      STRINGN_TO_NPVARIANT(value.c_str(), value.size(), *result);
      break;
    }
    case PP_VARTYPE_OBJECT: {
      scoped_refptr<NPObjectVar> object(NPObjectVar::FromPPVar(var));
      if (!object) {
        VOID_TO_NPVARIANT(*result);
        return false;
      }
      OBJECT_TO_NPVARIANT(object->np_object(), *result);
      break;
    }
    default:
      VOID_TO_NPVARIANT(*result);
      return false;
  }
  return true;
}

// ObjectAccessorTryCatch ------------------------------------------------------

// Automatically sets up a TryCatch for accessing the object identified by the
// given PP_Var. The module from the object will be used for the exception
// strings generated by the TryCatch.
//
// This will automatically retrieve the ObjectVar from the object and throw
// an exception if it's invalid. At the end of construction, if there is no
// exception, you know that there is no previously set exception, that the
// object passed in is valid and ready to use (via the object() getter), and
// that the TryCatch's pp_module() getter is also set up properly and ready to
// use.
class ObjectAccessorTryCatch : public TryCatch {
 public:
  ObjectAccessorTryCatch(PP_Var object, PP_Var* exception)
      : TryCatch(exception),
        object_(NPObjectVar::FromPPVar(object)) {
    if (!object_) {
      SetException(kInvalidObjectException);
    }
  }

  NPObjectVar* object() { return object_.get(); }

  PluginInstance* GetPluginInstance() {
    return HostGlobals::Get()->GetInstance(object()->pp_instance());
  }

 protected:
  scoped_refptr<NPObjectVar> object_;

  DISALLOW_COPY_AND_ASSIGN(ObjectAccessorTryCatch);
};

// ObjectAccessiorWithIdentifierTryCatch ---------------------------------------

// Automatically sets up a TryCatch for accessing the identifier on the given
// object. This just extends ObjectAccessorTryCatch to additionally convert
// the given identifier to an NPIdentifier and validate it, throwing an
// exception if it's invalid.
//
// At the end of construction, if there is no exception, you know that there is
// no previously set exception, that the object passed in is valid and ready to
// use (via the object() getter), that the identifier is valid and ready to
// use (via the identifier() getter), and that the TryCatch's pp_module() getter
// is also set up properly and ready to use.
class ObjectAccessorWithIdentifierTryCatch : public ObjectAccessorTryCatch {
 public:
  ObjectAccessorWithIdentifierTryCatch(PP_Var object,
                                       PP_Var identifier,
                                       PP_Var* exception)
      : ObjectAccessorTryCatch(object, exception),
        identifier_(0) {
    if (!has_exception()) {
      identifier_ = PPVarToNPIdentifier(identifier);
      if (!identifier_)
        SetException(kInvalidPropertyException);
    }
  }

  NPIdentifier identifier() const { return identifier_; }

 private:
  NPIdentifier identifier_;

  DISALLOW_COPY_AND_ASSIGN(ObjectAccessorWithIdentifierTryCatch);
};

PP_Bool HasProperty(PP_Var var,
                    PP_Var name,
                    PP_Var* exception) {
  ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception);
  if (accessor.has_exception())
    return PP_FALSE;
  return BoolToPPBool(WebBindings::hasProperty(NULL,
                                               accessor.object()->np_object(),
                                               accessor.identifier()));
}

bool HasPropertyDeprecated(PP_Var var,
                           PP_Var name,
                           PP_Var* exception) {
  return PPBoolToBool(HasProperty(var, name, exception));
}

bool HasMethodDeprecated(PP_Var var,
                         PP_Var name,
                         PP_Var* exception) {
  ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception);
  if (accessor.has_exception())
    return false;
  return WebBindings::hasMethod(NULL, accessor.object()->np_object(),
                                accessor.identifier());
}

PP_Var GetProperty(PP_Var var,
                   PP_Var name,
                   PP_Var* exception) {
  ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception);
  if (accessor.has_exception())
    return PP_MakeUndefined();

  NPVariant result;
  if (!WebBindings::getProperty(NULL, accessor.object()->np_object(),
                                accessor.identifier(), &result)) {
    // An exception may have been raised.
    accessor.SetException(kUnableToGetPropertyException);
    return PP_MakeUndefined();
  }

  PP_Var ret = NPVariantToPPVar(accessor.GetPluginInstance(), &result);
  WebBindings::releaseVariantValue(&result);
  return ret;
}

void EnumerateProperties(PP_Var var,
                         uint32_t* property_count,
                         PP_Var** properties,
                         PP_Var* exception) {
  *properties = NULL;
  *property_count = 0;

  ObjectAccessorTryCatch accessor(var, exception);
  if (accessor.has_exception())
    return;

  NPIdentifier* identifiers = NULL;
  uint32_t count = 0;
  if (!WebBindings::enumerate(NULL, accessor.object()->np_object(),
                              &identifiers, &count)) {
    accessor.SetException(kUnableToGetAllPropertiesException);
    return;
  }

  if (count == 0)
    return;

  *property_count = count;
  *properties = static_cast<PP_Var*>(malloc(sizeof(PP_Var) * count));
  for (uint32_t i = 0; i < count; ++i) {
    (*properties)[i] = NPIdentifierToPPVar(identifiers[i]);
  }
  free(identifiers);
}

void SetPropertyDeprecated(PP_Var var,
                           PP_Var name,
                           PP_Var value,
                           PP_Var* exception) {
  ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception);
  if (accessor.has_exception())
    return;

  NPVariant variant;
  if (!PPVarToNPVariantNoCopy(value, &variant)) {
    accessor.SetException(kInvalidValueException);
    return;
  }
  if (!WebBindings::setProperty(NULL, accessor.object()->np_object(),
                                accessor.identifier(), &variant))
    accessor.SetException(kUnableToSetPropertyException);
}

void DeletePropertyDeprecated(PP_Var var,
                              PP_Var name,
                              PP_Var* exception) {
  ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception);
  if (accessor.has_exception())
    return;

  if (!WebBindings::removeProperty(NULL, accessor.object()->np_object(),
                                   accessor.identifier()))
    accessor.SetException(kUnableToRemovePropertyException);
}

PP_Var InternalCallDeprecated(ObjectAccessorTryCatch* accessor,
                              PP_Var method_name,
                              uint32_t argc,
                              PP_Var* argv,
                              PP_Var* exception) {
  NPIdentifier identifier;
  if (method_name.type == PP_VARTYPE_UNDEFINED) {
    identifier = NULL;
  } else if (method_name.type == PP_VARTYPE_STRING) {
    // Specifically allow only string functions to be called.
    identifier = PPVarToNPIdentifier(method_name);
    if (!identifier) {
      accessor->SetException(kInvalidPropertyException);
      return PP_MakeUndefined();
    }
  } else {
    accessor->SetException(kInvalidPropertyException);
    return PP_MakeUndefined();
  }

  scoped_array<NPVariant> args;
  if (argc) {
    args.reset(new NPVariant[argc]);
    for (uint32_t i = 0; i < argc; ++i) {
      if (!PPVarToNPVariantNoCopy(argv[i], &args[i])) {
        // This argument was invalid, throw an exception & give up.
        accessor->SetException(kInvalidValueException);
        return PP_MakeUndefined();
      }
    }
  }

  bool ok;

  NPVariant result;
  if (identifier) {
    ok = WebBindings::invoke(NULL, accessor->object()->np_object(),
                             identifier, args.get(), argc, &result);
  } else {
    ok = WebBindings::invokeDefault(NULL, accessor->object()->np_object(),
                                    args.get(), argc, &result);
  }

  if (!ok) {
    // An exception may have been raised.
    accessor->SetException(kUnableToCallMethodException);
    return PP_MakeUndefined();
  }

  PP_Var ret = NPVariantToPPVar(accessor->GetPluginInstance(), &result);
  WebBindings::releaseVariantValue(&result);
  return ret;
}

PP_Var CallDeprecated(PP_Var var,
                      PP_Var method_name,
                      uint32_t argc,
                      PP_Var* argv,
                      PP_Var* exception) {
  ObjectAccessorTryCatch accessor(var, exception);
  if (accessor.has_exception())
    return PP_MakeUndefined();
  PluginInstance* plugin = accessor.GetPluginInstance();
  if (plugin && plugin->IsProcessingUserGesture()) {
    WebKit::WebScopedUserGesture user_gesture;
    return InternalCallDeprecated(&accessor, method_name, argc, argv,
                                  exception);
  }
  return InternalCallDeprecated(&accessor, method_name, argc, argv, exception);
}

PP_Var Construct(PP_Var var,
                 uint32_t argc,
                 PP_Var* argv,
                 PP_Var* exception) {
  ObjectAccessorTryCatch accessor(var, exception);
  if (accessor.has_exception())
    return PP_MakeUndefined();

  scoped_array<NPVariant> args;
  if (argc) {
    args.reset(new NPVariant[argc]);
    for (uint32_t i = 0; i < argc; ++i) {
      if (!PPVarToNPVariantNoCopy(argv[i], &args[i])) {
        // This argument was invalid, throw an exception & give up.
        accessor.SetException(kInvalidValueException);
        return PP_MakeUndefined();
      }
    }
  }

  NPVariant result;
  if (!WebBindings::construct(NULL, accessor.object()->np_object(),
                              args.get(), argc, &result)) {
    // An exception may have been raised.
    accessor.SetException(kUnableToConstructException);
    return PP_MakeUndefined();
  }

  PP_Var ret = NPVariantToPPVar(accessor.GetPluginInstance(), &result);
  WebBindings::releaseVariantValue(&result);
  return ret;
}

bool IsInstanceOfDeprecated(PP_Var var,
                            const PPP_Class_Deprecated* ppp_class,
                            void** ppp_class_data) {
  scoped_refptr<NPObjectVar> object(NPObjectVar::FromPPVar(var));
  if (!object)
    return false;  // Not an object at all.

  return PluginObject::IsInstanceOf(object->np_object(),
                                    ppp_class, ppp_class_data);
}

PP_Var CreateObjectDeprecated(PP_Instance pp_instance,
                              const PPP_Class_Deprecated* ppp_class,
                              void* ppp_class_data) {
  PluginInstance* instance = HostGlobals::Get()->GetInstance(pp_instance);
  if (!instance) {
    DLOG(ERROR) << "Create object passed an invalid instance.";
    return PP_MakeNull();
  }
  return PluginObject::Create(instance, ppp_class, ppp_class_data);
}

PP_Var CreateObjectWithModuleDeprecated(PP_Module pp_module,
                                        const PPP_Class_Deprecated* ppp_class,
                                        void* ppp_class_data) {
  PluginModule* module = HostGlobals::Get()->GetModule(pp_module);
  if (!module)
    return PP_MakeNull();
  return PluginObject::Create(module->GetSomeInstance(),
                              ppp_class, ppp_class_data);
}

}  // namespace

// static
const PPB_Var_Deprecated* PPB_Var_Deprecated_Impl::GetVarDeprecatedInterface() {
  static const PPB_Var_Deprecated var_deprecated_interface = {
    ::ppapi::PPB_Var_Shared::GetVarInterface1_0()->AddRef,
    ::ppapi::PPB_Var_Shared::GetVarInterface1_0()->Release,
    ::ppapi::PPB_Var_Shared::GetVarInterface1_0()->VarFromUtf8,
    ::ppapi::PPB_Var_Shared::GetVarInterface1_0()->VarToUtf8,
    &HasPropertyDeprecated,
    &HasMethodDeprecated,
    &GetProperty,
    &EnumerateProperties,
    &SetPropertyDeprecated,
    &DeletePropertyDeprecated,
    &CallDeprecated,
    &Construct,
    &IsInstanceOfDeprecated,
    &CreateObjectDeprecated,
    &CreateObjectWithModuleDeprecated,
  };

  return &var_deprecated_interface;
}

}  // namespace ppapi
}  // namespace webkit

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: verbosetrace.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: kz $ $Date: 2006-12-13 14:35:46 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef INCLUDED_CANVAS_VERBOSETRACE_HXX
#define INCLUDED_CANVAS_VERBOSETRACE_HXX

#if defined(VERBOSE) && defined(DBG_UTIL)
/// Wrap OSL_TRACE with a verbosity switch
#define VERBOSE_TRACE     OSL_TRACE
#else
#define VERBOSE_TRACE     1 ? ((void)0) : OSL_TRACE
#endif

#endif /* INCLUDED_CANVAS_VERBOSETRACE_HXX */
<commit_msg>INTEGRATION: CWS changefileheader (1.5.80); FILE MERGED 2008/03/28 16:34:52 rt 1.5.80.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: verbosetrace.hxx,v $
 * $Revision: 1.6 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef INCLUDED_CANVAS_VERBOSETRACE_HXX
#define INCLUDED_CANVAS_VERBOSETRACE_HXX

#if defined(VERBOSE) && defined(DBG_UTIL)
/// Wrap OSL_TRACE with a verbosity switch
#define VERBOSE_TRACE     OSL_TRACE
#else
#define VERBOSE_TRACE     1 ? ((void)0) : OSL_TRACE
#endif

#endif /* INCLUDED_CANVAS_VERBOSETRACE_HXX */
<|endoftext|>


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

  Program:   Monteverdi2
  Language:  C++

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See Copyright.txt for details.

  Monteverdi2 is distributed under the CeCILL licence version 2. See
  Licence_CeCILL_V2-en.txt or
  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt for more details.

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

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

/*****************************************************************************/
/* INCLUDE SECTION                                                           */

//
// Qt includes (sorted by alphabetic order)
//// Must be included before system/custom includes.

//
// System includes (sorted by alphabetic order)

//
// ITK includes (sorted by alphabetic order)

//
// OTB includes (sorted by alphabetic order)
#include "otbWrapperQtWidgetProgressReport.h"
#include "otbWrapperQtWidgetSimpleProgressReport.h"
#include "otbWrapperQtWidgetOutputImageParameter.h"
#include "otbWrapperApplicationHtmlDocGenerator.h"

#include "otbWrapperTypes.h"
#include "otbWrapperOutputImageParameter.h"
#include "otbWrapperComplexOutputImageParameter.h" // TODO : handle
                                                   // this param to
                                                   // get the outfname

//
// Monteverdi includes (sorted by alphabetic order)
#include "mvdWrapperQtWidgetParameterFactory.h"
//
#include "Core/mvdI18nCoreApplication.h"

namespace mvd
{
namespace Wrapper
{
/*
  TRANSLATOR mvd::ApplicationLauncher

  Necessary for lupdate to be aware of C++ namespaces.

  Context comment for translator.
*/

/*****************************************************************************/
/* CONSTANTS                                                                 */

/*****************************************************************************/
/* STATIC IMPLEMENTATION SECTION                                             */

/*****************************************************************************/
/* CLASS IMPLEMENTATION SECTION                                              */

/*******************************************************************************/
QtWidgetView::QtWidgetView(otb::Wrapper::Application* app)
{
  m_Model = new otb::Wrapper::QtWidgetModel(app);
  m_Application = app;
}

/*******************************************************************************/
QtWidgetView::~QtWidgetView()
{

}

/*******************************************************************************/
void QtWidgetView::CreateGui()
{
  // Create a VBoxLayout with the header, the input widgets, and the footer
  QVBoxLayout *mainLayout = new QVBoxLayout();
  QTabWidget *tab = new QTabWidget();
  tab->addTab(CreateInputWidgets(), "Parameters");

  //QTextEdit *log = new QTextEdit();
  //connect( m_Model->GetLogOutput(), SIGNAL(NewContentLog(QString)), log, SLOT(append(QString) ) );
  //tab->addTab(log, "Logs");
  //otb::Wrapper::QtWidgetProgressReport* prog =  new otb::Wrapper::QtWidgetProgressReport(m_Model);
  //prog->SetApplication(m_Application);
  //tab->addTab(prog, "Progress");
  tab->addTab(CreateDoc(), "Documentation");
  mainLayout->addWidget(tab);

  m_Message = new QLabel("Select parameters");
  connect( m_Model, SIGNAL(SetApplicationReady(bool)), this, SLOT(UpdateMessageAfterApplicationReady(bool)) );
  mainLayout->addWidget(m_Message);

  otb::Wrapper::QtWidgetSimpleProgressReport * progressReport =  new otb::Wrapper::QtWidgetSimpleProgressReport(m_Model);
  progressReport->SetApplication(m_Application);

  QHBoxLayout *footLayout = new QHBoxLayout;
  footLayout->addWidget(progressReport);
  footLayout->addWidget(CreateFooter());
  mainLayout->addLayout(footLayout);

  QGroupBox *mainGroup = new QGroupBox();
  mainGroup->setLayout(mainLayout);

  QVBoxLayout  *finalLayout = new QVBoxLayout();
  finalLayout->addWidget(mainGroup);

  // Make the final layout to the widget
  this->setLayout(finalLayout);
}

/*******************************************************************************/
QWidget* QtWidgetView::CreateInputWidgets()
{
  QScrollArea *scrollArea = new QScrollArea;
  // Put the main group inside a scroll area
  QWidget * widgets =
    mvd::Wrapper::QtWidgetParameterFactory::CreateQtWidget(m_Model->GetApplication()->GetParameterList(),
                                                           m_Model);

  scrollArea->setWidget(widgets);
  scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
  scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
  scrollArea->setWidgetResizable(true);

  //
  // need to be connected to the end of a process
  QObject::connect(m_Model, SIGNAL( SetProgressReportDone() ),
                   this,
                   SLOT ( OnApplicationExecutionDone() )
    );

  //
  // setup the default output in Widgets OutputImageParameter
  FillOTBAppDefaultOutputImageParameter(widgets);

  return scrollArea;
}

/*******************************************************************************/
QWidget* QtWidgetView::CreateFooter()
{
  // an HLayout with two buttons : Execute and Quit
  QGroupBox *footerGroup = new QGroupBox;
  QHBoxLayout *footerLayout = new QHBoxLayout;

  footerGroup->setFixedHeight(40);
  footerGroup->setContentsMargins(0, 0, 0, 0);
  footerLayout->setContentsMargins(5, 5, 5, 5);

  m_ExecButton = new QPushButton(footerGroup);
  m_ExecButton->setDefault(true);
  m_ExecButton->setEnabled(false);
  m_ExecButton->setText(QObject::tr("Execute"));
  connect( m_ExecButton, SIGNAL(clicked()), m_Model, SLOT(ExecuteAndWriteOutputSlot() ) );
  connect( m_Model, SIGNAL(SetApplicationReady(bool)), m_ExecButton, SLOT(setEnabled(bool)) );
  connect( m_ExecButton, SIGNAL(clicked()), this, SLOT(UpdateMessageAfterExcuteClicked() ) );

  m_QuitButton = new QPushButton(footerGroup);
  m_QuitButton->setText(QObject::tr("Quit"));
  connect( m_QuitButton, SIGNAL(clicked()), this, SLOT(CloseSlot()) );

  // Put the buttons on the right
  footerLayout->addStretch();
  footerLayout->addWidget(m_ExecButton);
  footerLayout->addWidget(m_QuitButton);

  footerGroup->setLayout(footerLayout);

  return footerGroup;
}

/*******************************************************************************/
QWidget* QtWidgetView::CreateDoc()
{
  QTextEdit *text = new QTextEdit;
  text->setReadOnly(true);

  QTextDocument * doc = new QTextDocument();

  std::string docContain;
  otb::Wrapper::ApplicationHtmlDocGenerator::GenerateDoc( m_Application, docContain);

  doc->setHtml(docContain.c_str());

  text->setDocument(doc);

  return text;
}

/*******************************************************************************/
void
QtWidgetView::FillOTBAppDefaultOutputImageParameter( QWidget * widgets)
{
  //
  // Get the cache dir
  // get the const instance of the application.
  I18nCoreApplication* app = I18nCoreApplication::Instance();

  //
  // get the OTB application widget layout
  QLayout * layout = widgets->layout();

  for (int idx = 0; idx < layout->count(); idx++ )
    {
    QWidget * currentWidget = layout->itemAt(idx)->widget();

    // is it a QtWidgetOutputImageParameter ?
    otb::Wrapper::QtWidgetOutputImageParameter * outParam
      = qobject_cast<otb::Wrapper::QtWidgetOutputImageParameter *>(currentWidget);

    if (outParam)
      {
      // generate a default output fname for the current
      // OutputImageParameter
      QString outfname =
        app->GetResultsDir().absolutePath()
        + "/"+ m_Application->GetName()
        +"_"+ GenerateIdentifier() +".tif";

      // use it
      outParam->SetFileName(outfname);
      outParam->UpdateGUI();
      } // else is it a {Group/Choice}Parameter Widget containing
        // QtWidgetOutputImageParameters ?
    else
      {
      //
      QList< otb::Wrapper::QtWidgetOutputImageParameter *> outParameterWidget
        = currentWidget->findChildren<otb::Wrapper::QtWidgetOutputImageParameter*>();

      QList<otb::Wrapper::QtWidgetOutputImageParameter *>::iterator  it = outParameterWidget.begin();

      //
      while(it != outParameterWidget.end())
        {
        if (*it)
          {
          // generate a default output fname for the current
          // OutputImageParameter
          QString outfname =
            app->GetResultsDir().absolutePath() + "/"+ m_Application->GetName()+"_"+GenerateIdentifier()+".tif";

          // use the outfname
          (*it)->SetFileName(outfname);
          (*it)->UpdateGUI();
          }
        ++it;
        }
      }
    }

}

/*******************************************************************************/
const QString
QtWidgetView::GenerateIdentifier()
{
  //
  // get an unique identifier  and remove braces
  QString  identifier = QUuid::createUuid().toString();
  identifier.replace("{", "");
  identifier.replace("}", "");

  return identifier;
}

/*******************************************************************************/
/* SLOTS                                                                       */
/*******************************************************************************/
void QtWidgetView::CloseSlot()
{
  // Close the widget
  this->close();

  // Emit a signal to close any widget that this gui belonging to
  emit QuitSignal();
}

/*******************************************************************************/
void QtWidgetView::UpdateMessageAfterExcuteClicked()
{
  m_Message->setText("Running");
}

/*******************************************************************************/
void QtWidgetView::UpdateMessageAfterApplicationReady( bool val )
{
  if(val == true)
    m_Message->setText("Ready to run");
  else
    m_Message->setText("Select parameters");
}

/*******************************************************************************/
void QtWidgetView::OnApplicationExecutionDone()
{
  //
  // detect if this application has outputImageParameter. emit
  // the output filenames if any
  std::vector<std::string> paramList = m_Model->GetApplication()->GetParametersKeys(true);

  // iterate on the application parameters
  for (std::vector<std::string>::const_iterator it = paramList.begin();
          it != paramList.end();
          ++it)
    {
    // parameter key
    std::string key = *it;

    // get a valid outputParameter
    if (m_Model->GetApplication()->GetParameterType(key) == otb::Wrapper::ParameterType_OutputImage &&
        m_Model->GetApplication()->IsParameterEnabled(key) &&
        m_Model->GetApplication()->HasValue(key) )
        {
        // get the parameter
        otb::Wrapper::Parameter* param = m_Model->GetApplication()->GetParameterByKey(key);

        // try to cast it
        otb::Wrapper::OutputImageParameter* outputParam =
          dynamic_cast<otb::Wrapper::OutputImageParameter*>(param);

        // emit the output image filename selected
        if (outputParam)
          {
          emit OTBApplicationOutputImageChanged( QString ( m_Model->GetApplication()->GetName() ),// app
                                                 QString ( outputParam->GetFileName() )          // outfname

            );
          }
        }
    }
}

}
}
<commit_msg>ENH: uncomment definition of Log tab in application window<commit_after>/*=========================================================================

  Program:   Monteverdi2
  Language:  C++

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See Copyright.txt for details.

  Monteverdi2 is distributed under the CeCILL licence version 2. See
  Licence_CeCILL_V2-en.txt or
  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt for more details.

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

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

/*****************************************************************************/
/* INCLUDE SECTION                                                           */

//
// Qt includes (sorted by alphabetic order)
//// Must be included before system/custom includes.

//
// System includes (sorted by alphabetic order)

//
// ITK includes (sorted by alphabetic order)

//
// OTB includes (sorted by alphabetic order)
#include "otbWrapperQtWidgetProgressReport.h"
#include "otbWrapperQtWidgetSimpleProgressReport.h"
#include "otbWrapperQtWidgetOutputImageParameter.h"
#include "otbWrapperApplicationHtmlDocGenerator.h"

#include "otbWrapperTypes.h"
#include "otbWrapperOutputImageParameter.h"
#include "otbWrapperComplexOutputImageParameter.h" // TODO : handle
                                                   // this param to
                                                   // get the outfname

//
// Monteverdi includes (sorted by alphabetic order)
#include "mvdWrapperQtWidgetParameterFactory.h"
//
#include "Core/mvdI18nCoreApplication.h"

namespace mvd
{
namespace Wrapper
{
/*
  TRANSLATOR mvd::ApplicationLauncher

  Necessary for lupdate to be aware of C++ namespaces.

  Context comment for translator.
*/

/*****************************************************************************/
/* CONSTANTS                                                                 */

/*****************************************************************************/
/* STATIC IMPLEMENTATION SECTION                                             */

/*****************************************************************************/
/* CLASS IMPLEMENTATION SECTION                                              */

/*******************************************************************************/
QtWidgetView::QtWidgetView(otb::Wrapper::Application* app)
{
  m_Model = new otb::Wrapper::QtWidgetModel(app);
  m_Application = app;
}

/*******************************************************************************/
QtWidgetView::~QtWidgetView()
{

}

/*******************************************************************************/
void QtWidgetView::CreateGui()
{
  // Create a VBoxLayout with the header, the input widgets, and the footer
  QVBoxLayout *mainLayout = new QVBoxLayout();
  QTabWidget *tab = new QTabWidget();
  tab->addTab(CreateInputWidgets(), "Parameters");

  //otb::Wrapper::QtWidgetProgressReport* prog =  new otb::Wrapper::QtWidgetProgressReport(m_Model);
  //prog->SetApplication(m_Application);
  //tab->addTab(prog, "Progress");
  tab->addTab(CreateDoc(), "Documentation");
  mainLayout->addWidget(tab);

  QTextEdit *log = new QTextEdit();
  connect( m_Model->GetLogOutput(), SIGNAL(NewContentLog(QString)), log, SLOT(append(QString) ) );
  tab->addTab(log, "Logs");

  m_Message = new QLabel("Select parameters");
  connect( m_Model, SIGNAL(SetApplicationReady(bool)), this, SLOT(UpdateMessageAfterApplicationReady(bool)) );
  mainLayout->addWidget(m_Message);

  otb::Wrapper::QtWidgetSimpleProgressReport * progressReport =  new otb::Wrapper::QtWidgetSimpleProgressReport(m_Model);
  progressReport->SetApplication(m_Application);

  QHBoxLayout *footLayout = new QHBoxLayout;
  footLayout->addWidget(progressReport);
  footLayout->addWidget(CreateFooter());
  mainLayout->addLayout(footLayout);

  QGroupBox *mainGroup = new QGroupBox();
  mainGroup->setLayout(mainLayout);

  QVBoxLayout  *finalLayout = new QVBoxLayout();
  finalLayout->addWidget(mainGroup);

  // Make the final layout to the widget
  this->setLayout(finalLayout);
}

/*******************************************************************************/
QWidget* QtWidgetView::CreateInputWidgets()
{
  QScrollArea *scrollArea = new QScrollArea;
  // Put the main group inside a scroll area
  QWidget * widgets =
    mvd::Wrapper::QtWidgetParameterFactory::CreateQtWidget(m_Model->GetApplication()->GetParameterList(),
                                                           m_Model);

  scrollArea->setWidget(widgets);
  scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
  scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
  scrollArea->setWidgetResizable(true);

  //
  // need to be connected to the end of a process
  QObject::connect(m_Model, SIGNAL( SetProgressReportDone() ),
                   this,
                   SLOT ( OnApplicationExecutionDone() )
    );

  //
  // setup the default output in Widgets OutputImageParameter
  FillOTBAppDefaultOutputImageParameter(widgets);

  return scrollArea;
}

/*******************************************************************************/
QWidget* QtWidgetView::CreateFooter()
{
  // an HLayout with two buttons : Execute and Quit
  QGroupBox *footerGroup = new QGroupBox;
  QHBoxLayout *footerLayout = new QHBoxLayout;

  footerGroup->setFixedHeight(40);
  footerGroup->setContentsMargins(0, 0, 0, 0);
  footerLayout->setContentsMargins(5, 5, 5, 5);

  m_ExecButton = new QPushButton(footerGroup);
  m_ExecButton->setDefault(true);
  m_ExecButton->setEnabled(false);
  m_ExecButton->setText(QObject::tr("Execute"));
  connect( m_ExecButton, SIGNAL(clicked()), m_Model, SLOT(ExecuteAndWriteOutputSlot() ) );
  connect( m_Model, SIGNAL(SetApplicationReady(bool)), m_ExecButton, SLOT(setEnabled(bool)) );
  connect( m_ExecButton, SIGNAL(clicked()), this, SLOT(UpdateMessageAfterExcuteClicked() ) );

  m_QuitButton = new QPushButton(footerGroup);
  m_QuitButton->setText(QObject::tr("Quit"));
  connect( m_QuitButton, SIGNAL(clicked()), this, SLOT(CloseSlot()) );

  // Put the buttons on the right
  footerLayout->addStretch();
  footerLayout->addWidget(m_ExecButton);
  footerLayout->addWidget(m_QuitButton);

  footerGroup->setLayout(footerLayout);

  return footerGroup;
}

/*******************************************************************************/
QWidget* QtWidgetView::CreateDoc()
{
  QTextEdit *text = new QTextEdit;
  text->setReadOnly(true);

  QTextDocument * doc = new QTextDocument();

  std::string docContain;
  otb::Wrapper::ApplicationHtmlDocGenerator::GenerateDoc( m_Application, docContain);

  doc->setHtml(docContain.c_str());

  text->setDocument(doc);

  return text;
}

/*******************************************************************************/
void
QtWidgetView::FillOTBAppDefaultOutputImageParameter( QWidget * widgets)
{
  //
  // Get the cache dir
  // get the const instance of the application.
  I18nCoreApplication* app = I18nCoreApplication::Instance();

  //
  // get the OTB application widget layout
  QLayout * layout = widgets->layout();

  for (int idx = 0; idx < layout->count(); idx++ )
    {
    QWidget * currentWidget = layout->itemAt(idx)->widget();

    // is it a QtWidgetOutputImageParameter ?
    otb::Wrapper::QtWidgetOutputImageParameter * outParam
      = qobject_cast<otb::Wrapper::QtWidgetOutputImageParameter *>(currentWidget);

    if (outParam)
      {
      // generate a default output fname for the current
      // OutputImageParameter
      QString outfname =
        app->GetResultsDir().absolutePath()
        + "/"+ m_Application->GetName()
        +"_"+ GenerateIdentifier() +".tif";

      // use it
      outParam->SetFileName(outfname);
      outParam->UpdateGUI();
      } // else is it a {Group/Choice}Parameter Widget containing
        // QtWidgetOutputImageParameters ?
    else
      {
      //
      QList< otb::Wrapper::QtWidgetOutputImageParameter *> outParameterWidget
        = currentWidget->findChildren<otb::Wrapper::QtWidgetOutputImageParameter*>();

      QList<otb::Wrapper::QtWidgetOutputImageParameter *>::iterator  it = outParameterWidget.begin();

      //
      while(it != outParameterWidget.end())
        {
        if (*it)
          {
          // generate a default output fname for the current
          // OutputImageParameter
          QString outfname =
            app->GetResultsDir().absolutePath() + "/"+ m_Application->GetName()+"_"+GenerateIdentifier()+".tif";

          // use the outfname
          (*it)->SetFileName(outfname);
          (*it)->UpdateGUI();
          }
        ++it;
        }
      }
    }

}

/*******************************************************************************/
const QString
QtWidgetView::GenerateIdentifier()
{
  //
  // get an unique identifier  and remove braces
  QString  identifier = QUuid::createUuid().toString();
  identifier.replace("{", "");
  identifier.replace("}", "");

  return identifier;
}

/*******************************************************************************/
/* SLOTS                                                                       */
/*******************************************************************************/
void QtWidgetView::CloseSlot()
{
  // Close the widget
  this->close();

  // Emit a signal to close any widget that this gui belonging to
  emit QuitSignal();
}

/*******************************************************************************/
void QtWidgetView::UpdateMessageAfterExcuteClicked()
{
  m_Message->setText("Running");
}

/*******************************************************************************/
void QtWidgetView::UpdateMessageAfterApplicationReady( bool val )
{
  if(val == true)
    m_Message->setText("Ready to run");
  else
    m_Message->setText("Select parameters");
}

/*******************************************************************************/
void QtWidgetView::OnApplicationExecutionDone()
{
  //
  // detect if this application has outputImageParameter. emit
  // the output filenames if any
  std::vector<std::string> paramList = m_Model->GetApplication()->GetParametersKeys(true);

  // iterate on the application parameters
  for (std::vector<std::string>::const_iterator it = paramList.begin();
          it != paramList.end();
          ++it)
    {
    // parameter key
    std::string key = *it;

    // get a valid outputParameter
    if (m_Model->GetApplication()->GetParameterType(key) == otb::Wrapper::ParameterType_OutputImage &&
        m_Model->GetApplication()->IsParameterEnabled(key) &&
        m_Model->GetApplication()->HasValue(key) )
        {
        // get the parameter
        otb::Wrapper::Parameter* param = m_Model->GetApplication()->GetParameterByKey(key);

        // try to cast it
        otb::Wrapper::OutputImageParameter* outputParam =
          dynamic_cast<otb::Wrapper::OutputImageParameter*>(param);

        // emit the output image filename selected
        if (outputParam)
          {
          emit OTBApplicationOutputImageChanged( QString ( m_Model->GetApplication()->GetName() ),// app
                                                 QString ( outputParam->GetFileName() )          // outfname

            );
          }
        }
    }
}

}
}
<|endoftext|>