<commit_before>//-----------------------------------------------
//
//	This file is part of the Siv3D Engine.
//
//	Copyright (c) 2008-2021 Ryo Suzuki
//	Copyright (c) 2016-2021 OpenSiv3D Project
//
//	Licensed under the MIT License.
//
//-----------------------------------------------

# include <Siv3D/Error.hpp>
# include <Siv3D/EngineLog.hpp>
# include <Siv3D/FormatLiteral.hpp>
# include <Siv3D/Utility.hpp>
# include <Siv3D/UserAction.hpp>
# include <Siv3D/Scene.hpp>
# include <Siv3D/Monitor.hpp>
# include <Siv3D/Renderer/IRenderer.hpp>
# include <Siv3D/Profiler/IProfiler.hpp>
# include <Siv3D/UserAction/IUserAction.hpp>
# include <Siv3D/Common/Siv3DEngine.hpp>
# include "CWindow.hpp"

namespace s3d
{
	namespace detail
	{
		static void ErrorCallback(const int error, const char* description)
		{
			std::cerr << U"Error: {}. "_fmt(error) << description << '\n';
		}
	}

	CWindow::CWindow()
	{

	}

	CWindow::~CWindow()
	{
		LOG_SCOPED_TRACE(U"CWindow::~CWindow()");

		::glfwTerminate();
	}

	void CWindow::init()
	{
		LOG_SCOPED_TRACE(U"CWindow::init()");

		::glfwSetErrorCallback(detail::ErrorCallback);

		if (!::glfwInit())
		{
			throw EngineError(U"glfwInit() failed");
		}

		const bool useGLES = (g_engineOptions.renderer == EngineOption::Renderer::WebGL2);

		if (useGLES)
		{
			// OpenGL ES 3.0
			::glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
			::glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
			// GLES 3.0 does not support context profiles
			//::glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
			//::glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
			//::glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, SIV3D_BUILD(DEBUG) ? GLFW_TRUE : GLFW_FALSE);
		}
		else
		{
			// OpenGL 4.1
			::glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
			::glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
			::glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
			::glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
			::glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, SIV3D_BUILD(DEBUG) ? GLFW_TRUE : GLFW_FALSE);
		}

		::glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);

		// ウィンドウを作成
		{
			m_window = ::glfwCreateWindow(m_state.virtualSize.x, m_state.virtualSize.y,
										  m_actualTitle.narrow().c_str(), nullptr, nullptr);

			if (!m_window)
			{
				throw EngineError(U"glfwCreateWindow() failed");
			}
		}

		::glfwSetWindowSizeLimits(m_window, m_state.minFrameBufferSize.x, m_state.minFrameBufferSize.y,
								  GLFW_DONT_CARE, GLFW_DONT_CARE);
		::glfwSetWindowUserPointer(m_window, this);
		::glfwSetWindowPosCallback(m_window, CWindow::OnMove);
		::glfwSetWindowSizeCallback(m_window, CWindow::OnResize);
		::glfwSetFramebufferSizeCallback(m_window, CWindow::OnFrameBufferSize);
		::glfwSetWindowContentScaleCallback(m_window, CWindow::OnScalingChange);
		::glfwSetWindowIconifyCallback(m_window, CWindow::OnIconify);
		::glfwSetWindowMaximizeCallback(m_window, CWindow::OnMaximize);
		::glfwSetWindowFocusCallback(m_window, CWindow::OnFocus);

		updateState();
	}

	void CWindow::update()
	{
		::glfwPollEvents();

		updateState();

		if (::glfwWindowShouldClose(m_window))
		{
			SIV3D_ENGINE(UserAction)->reportUserActions(UserAction::CloseButtonClicked);
			::glfwSetWindowShouldClose(m_window, GLFW_FALSE);
		}

		if constexpr (SIV3D_BUILD(DEBUG))
		{
			setWindowTitle(m_title);
		}
	}

	void CWindow::setWindowTitle(const String& title)
	{
		String newActualTitle = title;

		if constexpr (SIV3D_BUILD(DEBUG))
		{
			const String statistics = SIV3D_ENGINE(Profiler)->getSimpleStatistics();
			newActualTitle += U" (Debug Build) | ";
			newActualTitle += statistics;
		}

		if (m_actualTitle != newActualTitle)
		{
			::glfwSetWindowTitle(m_window, newActualTitle.narrow().c_str());
			m_actualTitle.swap(newActualTitle);
		}

		m_title = title;
	}

	const String& CWindow::getWindowTitle() const noexcept
	{
		return m_title;
	}

	void* CWindow::getHandle() const noexcept
	{
		return m_window;
	}

	const WindowState& CWindow::getState() const noexcept
	{
		return m_state;
	}

	void CWindow::setStyle(const WindowStyle style)
	{
		LOG_TRACE(U"CWindow::setStyle(style = {})"_fmt(FromEnum(style)));

		if (m_state.fullscreen)
		{
			m_state.style = style;
			//setFullscreen(false, unspecified, WindowResizeOption::KeepSceneSize);
			return;
		}

		if (m_state.style == style)
		{
			return;
		}

		if (style == WindowStyle::Fixed)
		{
			::glfwSetWindowAttrib(m_window, GLFW_RESIZABLE, GLFW_FALSE);
			::glfwSetWindowAttrib(m_window, GLFW_DECORATED, GLFW_TRUE);
		}
		else if (style == WindowStyle::Sizable)
		{
			::glfwSetWindowAttrib(m_window, GLFW_RESIZABLE, GLFW_TRUE);
			::glfwSetWindowAttrib(m_window, GLFW_DECORATED, GLFW_TRUE);
		}
		else if (style == WindowStyle::Frameless)
		{
			::glfwSetWindowAttrib(m_window, GLFW_RESIZABLE, GLFW_FALSE);
			::glfwSetWindowAttrib(m_window, GLFW_DECORATED, GLFW_FALSE);
		}

		m_state.style = style;
	}

	void CWindow::setPos(const Point& pos)
	{
		LOG_TRACE(U"CWindow::setPos(pos = {})"_fmt(pos));

		if (m_state.fullscreen)
		{
			return;
		}

		::glfwSetWindowPos(m_window, pos.x, pos.y + m_state.titleBarHeight);
	}

	void CWindow::maximize()
	{
		LOG_TRACE(U"CWindow::maximize()");

		if (m_state.style == WindowStyle::Fixed)
		{
			//LOG_FAIL(U"A window with WindowStyle::Fixed cannot be maximized");
			return;
		}

		::glfwMaximizeWindow(m_window);
	}

	void CWindow::restore()
	{
		LOG_TRACE(U"CWindow::restore()");
		::glfwRestoreWindow(m_window);
	}

	void CWindow::minimize()
	{
		LOG_TRACE(U"CWindow::minimize()");
		::glfwIconifyWindow(m_window);
	}

	bool CWindow::resizeByVirtualSize(const Size& virtualSize)
	{
		LOG_TRACE(U"CWindow::resizeByVirtualSize({})"_fmt(virtualSize));

		::glfwSetWindowSize(m_window, virtualSize.x, virtualSize.y);
		return true;
	}

	bool CWindow::resizeByFrameBufferSize(const Size& frameBufferSize)
	{
		LOG_TRACE(U"CWindow::resizeByFrameBufferSize({})"_fmt(frameBufferSize));

		const double scaling = m_state.scaling;
		const Size newVirtualSize = (frameBufferSize * (1.0 / scaling)).asPoint();
		return resizeByVirtualSize(newVirtualSize);
	}

	void CWindow::setMinimumFrameBufferSize(const Size& size)
	{
		LOG_TRACE(U"CWindow::setMinimumFrameBufferSize({})"_fmt(size));

		m_state.minFrameBufferSize = size;
		::glfwSetWindowSizeLimits(m_window, size.x, size.y, GLFW_DONT_CARE, GLFW_DONT_CARE);
	}

	void CWindow::setFullscreen(const bool fullscreen, size_t monitorIndex)
	{
		LOG_TRACE(U"CWindow::setFullscreen(fullscreen = {}, monitorIndex = {})"_fmt(fullscreen, monitorIndex));

		if (fullscreen == m_state.fullscreen)
		{
			return;
		}

		if (m_state.fullscreen == false) // 現在ウィンドウモード
		{
			const auto monitors = System::EnumerateMonitors();

			if (monitors.size() <= monitorIndex)
			{
				monitorIndex = System::GetCurrentMonitorIndex();
			}

			::glfwGetWindowPos(m_window, &m_storedWindowRect.x, &m_storedWindowRect.y);
			::glfwGetWindowSize(m_window, &m_storedWindowRect.w, &m_storedWindowRect.h);

			const Size fullscreenResolution = monitors[monitorIndex].fullscreenResolution;

			int32 numMonitors;
			if (GLFWmonitor** monitors = ::glfwGetMonitors(&numMonitors))
			{
				::glfwSetWindowMonitor(m_window, monitors[monitorIndex], 0, 0, fullscreenResolution.x, fullscreenResolution.y, GLFW_DONT_CARE);
			}
		}
		else
		{
			::glfwSetWindowMonitor(m_window, nullptr, m_storedWindowRect.x, m_storedWindowRect.y,
								   m_storedWindowRect.w, m_storedWindowRect.h, GLFW_DONT_CARE);
		}

		m_state.fullscreen = fullscreen;

		if (Scene::GetResizeMode() != ResizeMode::Keep)
		{
			SIV3D_ENGINE(Renderer)->updateSceneSize();
		}
	}

	void CWindow::setToggleFullscreenEnabled(bool) {}

	bool CWindow::isToggleFullscreenEnabled() const
	{
		return false;
	}

	void CWindow::updateState()
	{
		// frameBufferSize
		::glfwGetFramebufferSize(m_window, &m_state.frameBufferSize.x, &m_state.frameBufferSize.y);

		// scaling
		float xScale, yScale;
		::glfwGetWindowContentScale(m_window, &xScale, &yScale);
		m_state.scaling = Max(xScale, yScale);

		// titleBarHeight
		// [Siv3D ToDo]

		// bounds
		int32 windowPosX, windowPosY, windowSizeX, windowSizeY;
		::glfwGetWindowPos(m_window, &windowPosX, &windowPosY);
		::glfwGetWindowSize(m_window, &windowSizeX, &windowSizeY);

		m_state.bounds.pos = Size(windowPosX, (windowPosY - m_state.titleBarHeight));
		m_state.bounds.size = Size(windowSizeX, (windowSizeY + m_state.titleBarHeight));

		// minimized
		m_state.maximized = (::glfwGetWindowAttrib(m_window, GLFW_ICONIFIED) == GLFW_TRUE);

		// maximized
		m_state.maximized = (::glfwGetWindowAttrib(m_window, GLFW_MAXIMIZED) == GLFW_TRUE)
			&& (m_state.style == WindowStyle::Sizable);

		// focused
		m_state.focused = (::glfwGetWindowAttrib(m_window, GLFW_FOCUSED) == GLFW_TRUE);

		// sizeMove
		m_state.sizeMove = false; // [Siv3D ToDo]
	}

	void CWindow::OnMove(GLFWwindow* window, const int x, const int y)
	{
		LOG_TRACE(U"CWindow::OnMove({})"_fmt(Point(x, y)));

		CWindow* pWindow = static_cast<CWindow*>(::glfwGetWindowUserPointer(window));
		pWindow->m_state.bounds.pos = Point(x, y);
	}

	void CWindow::OnResize(GLFWwindow* window, const int width, const int height)
	{
		LOG_TRACE(U"CWindow::OnResize({})"_fmt(Size(width, height)));

		CWindow* pWindow = static_cast<CWindow*>(::glfwGetWindowUserPointer(window));
		pWindow->m_state.bounds.size = Size(width, height);
		pWindow->m_state.virtualSize = Size(width, height);
	}

	void CWindow::OnFrameBufferSize(GLFWwindow* window, const int width, const int height)
	{
		LOG_TRACE(U"CWindow::OnFrameBufferSize({})"_fmt(Size(width, height)));

		CWindow* pWindow = static_cast<CWindow*>(::glfwGetWindowUserPointer(window));
		pWindow->m_state.frameBufferSize = Size(width, height);
		//pWindow->m_state.clientSize.set(width, height);
	}

	void CWindow::OnScalingChange(GLFWwindow* window, const float sx, const float sy)
	{
		LOG_TRACE(U"CWindow::OnScalingChange({}, {})"_fmt(sx, sy));

		CWindow* pWindow = static_cast<CWindow*>(::glfwGetWindowUserPointer(window));

		pWindow->m_state.scaling = Max(sx, sy);
	}

	void CWindow::OnIconify(GLFWwindow* window, const int iconified)
	{
		LOG_TRACE(U"CWindow::OnIconify({})"_fmt((iconified == GLFW_TRUE)));

		CWindow* pWindow = static_cast<CWindow*>(::glfwGetWindowUserPointer(window));

		if (iconified)
		{
			pWindow->m_state.minimized = true;
			pWindow->m_state.maximized = false;
		}
		else
		{
			pWindow->m_state.minimized = false;
			pWindow->m_state.maximized = false;
		}
	}

	void CWindow::OnMaximize(GLFWwindow* window, const int maximized)
	{
		LOG_TRACE(U"CWindow::OnMaximize({})"_fmt((maximized == GLFW_TRUE)));

		CWindow* pWindow = static_cast<CWindow*>(::glfwGetWindowUserPointer(window));

		if (maximized)
		{
			pWindow->m_state.minimized = false;
			pWindow->m_state.maximized = true;
		}
		else
		{
			pWindow->m_state.minimized = false;
			pWindow->m_state.maximized = false;
		}
	}

	void CWindow::OnFocus(GLFWwindow* window, const int focused)
	{
		LOG_TRACE(U"CWindow::OnFocus({})"_fmt((focused == GLFW_TRUE)));

		CWindow* pWindow = static_cast<CWindow*>(::glfwGetWindowUserPointer(window));
		pWindow->m_state.focused = (focused == GLFW_TRUE);

		if (!focused)
		{
			SIV3D_ENGINE(UserAction)->reportUserActions(UserAction::WindowDeactivated);
		}
	}
}
<commit_msg>Fix GLES3 initialization on Linux<commit_after>//-----------------------------------------------
//
//	This file is part of the Siv3D Engine.
//
//	Copyright (c) 2008-2021 Ryo Suzuki
//	Copyright (c) 2016-2021 OpenSiv3D Project
//
//	Licensed under the MIT License.
//
//-----------------------------------------------

# include <Siv3D/Error.hpp>
# include <Siv3D/EngineLog.hpp>
# include <Siv3D/FormatLiteral.hpp>
# include <Siv3D/Utility.hpp>
# include <Siv3D/UserAction.hpp>
# include <Siv3D/Scene.hpp>
# include <Siv3D/Monitor.hpp>
# include <Siv3D/Renderer/IRenderer.hpp>
# include <Siv3D/Profiler/IProfiler.hpp>
# include <Siv3D/UserAction/IUserAction.hpp>
# include <Siv3D/Common/Siv3DEngine.hpp>
# include "CWindow.hpp"

namespace s3d
{
	namespace detail
	{
		static void ErrorCallback(const int error, const char* description)
		{
			std::cerr << U"Error: {}. "_fmt(error) << description << '\n';
		}
	}

	CWindow::CWindow()
	{

	}

	CWindow::~CWindow()
	{
		LOG_SCOPED_TRACE(U"CWindow::~CWindow()");

		::glfwTerminate();
	}

	void CWindow::init()
	{
		LOG_SCOPED_TRACE(U"CWindow::init()");

		::glfwSetErrorCallback(detail::ErrorCallback);

		if (!::glfwInit())
		{
			throw EngineError(U"glfwInit() failed");
		}

		const bool useGLES = (g_engineOptions.renderer == EngineOption::Renderer::WebGL2);

		if (useGLES)
		{
			// OpenGL ES 3.0
			::glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
			::glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
			::glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
			// GLES 3.0 does not support context profiles
			//::glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
			//::glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
			::glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, SIV3D_BUILD(DEBUG) ? GLFW_TRUE : GLFW_FALSE);
		}
		else
		{
			// OpenGL 4.1
			::glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
			::glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
			::glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
			::glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
			::glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, SIV3D_BUILD(DEBUG) ? GLFW_TRUE : GLFW_FALSE);
		}

		::glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);

		// ウィンドウを作成
		{
			m_window = ::glfwCreateWindow(m_state.virtualSize.x, m_state.virtualSize.y,
										  m_actualTitle.narrow().c_str(), nullptr, nullptr);

			if (!m_window)
			{
				throw EngineError(U"glfwCreateWindow() failed");
			}
		}

		::glfwSetWindowSizeLimits(m_window, m_state.minFrameBufferSize.x, m_state.minFrameBufferSize.y,
								  GLFW_DONT_CARE, GLFW_DONT_CARE);
		::glfwSetWindowUserPointer(m_window, this);
		::glfwSetWindowPosCallback(m_window, CWindow::OnMove);
		::glfwSetWindowSizeCallback(m_window, CWindow::OnResize);
		::glfwSetFramebufferSizeCallback(m_window, CWindow::OnFrameBufferSize);
		::glfwSetWindowContentScaleCallback(m_window, CWindow::OnScalingChange);
		::glfwSetWindowIconifyCallback(m_window, CWindow::OnIconify);
		::glfwSetWindowMaximizeCallback(m_window, CWindow::OnMaximize);
		::glfwSetWindowFocusCallback(m_window, CWindow::OnFocus);

		updateState();
	}

	void CWindow::update()
	{
		::glfwPollEvents();

		updateState();

		if (::glfwWindowShouldClose(m_window))
		{
			SIV3D_ENGINE(UserAction)->reportUserActions(UserAction::CloseButtonClicked);
			::glfwSetWindowShouldClose(m_window, GLFW_FALSE);
		}

		if constexpr (SIV3D_BUILD(DEBUG))
		{
			setWindowTitle(m_title);
		}
	}

	void CWindow::setWindowTitle(const String& title)
	{
		String newActualTitle = title;

		if constexpr (SIV3D_BUILD(DEBUG))
		{
			const String statistics = SIV3D_ENGINE(Profiler)->getSimpleStatistics();
			newActualTitle += U" (Debug Build) | ";
			newActualTitle += statistics;
		}

		if (m_actualTitle != newActualTitle)
		{
			::glfwSetWindowTitle(m_window, newActualTitle.narrow().c_str());
			m_actualTitle.swap(newActualTitle);
		}

		m_title = title;
	}

	const String& CWindow::getWindowTitle() const noexcept
	{
		return m_title;
	}

	void* CWindow::getHandle() const noexcept
	{
		return m_window;
	}

	const WindowState& CWindow::getState() const noexcept
	{
		return m_state;
	}

	void CWindow::setStyle(const WindowStyle style)
	{
		LOG_TRACE(U"CWindow::setStyle(style = {})"_fmt(FromEnum(style)));

		if (m_state.fullscreen)
		{
			m_state.style = style;
			//setFullscreen(false, unspecified, WindowResizeOption::KeepSceneSize);
			return;
		}

		if (m_state.style == style)
		{
			return;
		}

		if (style == WindowStyle::Fixed)
		{
			::glfwSetWindowAttrib(m_window, GLFW_RESIZABLE, GLFW_FALSE);
			::glfwSetWindowAttrib(m_window, GLFW_DECORATED, GLFW_TRUE);
		}
		else if (style == WindowStyle::Sizable)
		{
			::glfwSetWindowAttrib(m_window, GLFW_RESIZABLE, GLFW_TRUE);
			::glfwSetWindowAttrib(m_window, GLFW_DECORATED, GLFW_TRUE);
		}
		else if (style == WindowStyle::Frameless)
		{
			::glfwSetWindowAttrib(m_window, GLFW_RESIZABLE, GLFW_FALSE);
			::glfwSetWindowAttrib(m_window, GLFW_DECORATED, GLFW_FALSE);
		}

		m_state.style = style;
	}

	void CWindow::setPos(const Point& pos)
	{
		LOG_TRACE(U"CWindow::setPos(pos = {})"_fmt(pos));

		if (m_state.fullscreen)
		{
			return;
		}

		::glfwSetWindowPos(m_window, pos.x, pos.y + m_state.titleBarHeight);
	}

	void CWindow::maximize()
	{
		LOG_TRACE(U"CWindow::maximize()");

		if (m_state.style == WindowStyle::Fixed)
		{
			//LOG_FAIL(U"A window with WindowStyle::Fixed cannot be maximized");
			return;
		}

		::glfwMaximizeWindow(m_window);
	}

	void CWindow::restore()
	{
		LOG_TRACE(U"CWindow::restore()");
		::glfwRestoreWindow(m_window);
	}

	void CWindow::minimize()
	{
		LOG_TRACE(U"CWindow::minimize()");
		::glfwIconifyWindow(m_window);
	}

	bool CWindow::resizeByVirtualSize(const Size& virtualSize)
	{
		LOG_TRACE(U"CWindow::resizeByVirtualSize({})"_fmt(virtualSize));

		::glfwSetWindowSize(m_window, virtualSize.x, virtualSize.y);
		return true;
	}

	bool CWindow::resizeByFrameBufferSize(const Size& frameBufferSize)
	{
		LOG_TRACE(U"CWindow::resizeByFrameBufferSize({})"_fmt(frameBufferSize));

		const double scaling = m_state.scaling;
		const Size newVirtualSize = (frameBufferSize * (1.0 / scaling)).asPoint();
		return resizeByVirtualSize(newVirtualSize);
	}

	void CWindow::setMinimumFrameBufferSize(const Size& size)
	{
		LOG_TRACE(U"CWindow::setMinimumFrameBufferSize({})"_fmt(size));

		m_state.minFrameBufferSize = size;
		::glfwSetWindowSizeLimits(m_window, size.x, size.y, GLFW_DONT_CARE, GLFW_DONT_CARE);
	}

	void CWindow::setFullscreen(const bool fullscreen, size_t monitorIndex)
	{
		LOG_TRACE(U"CWindow::setFullscreen(fullscreen = {}, monitorIndex = {})"_fmt(fullscreen, monitorIndex));

		if (fullscreen == m_state.fullscreen)
		{
			return;
		}

		if (m_state.fullscreen == false) // 現在ウィンドウモード
		{
			const auto monitors = System::EnumerateMonitors();

			if (monitors.size() <= monitorIndex)
			{
				monitorIndex = System::GetCurrentMonitorIndex();
			}

			::glfwGetWindowPos(m_window, &m_storedWindowRect.x, &m_storedWindowRect.y);
			::glfwGetWindowSize(m_window, &m_storedWindowRect.w, &m_storedWindowRect.h);

			const Size fullscreenResolution = monitors[monitorIndex].fullscreenResolution;

			int32 numMonitors;
			if (GLFWmonitor** monitors = ::glfwGetMonitors(&numMonitors))
			{
				::glfwSetWindowMonitor(m_window, monitors[monitorIndex], 0, 0, fullscreenResolution.x, fullscreenResolution.y, GLFW_DONT_CARE);
			}
		}
		else
		{
			::glfwSetWindowMonitor(m_window, nullptr, m_storedWindowRect.x, m_storedWindowRect.y,
								   m_storedWindowRect.w, m_storedWindowRect.h, GLFW_DONT_CARE);
		}

		m_state.fullscreen = fullscreen;

		if (Scene::GetResizeMode() != ResizeMode::Keep)
		{
			SIV3D_ENGINE(Renderer)->updateSceneSize();
		}
	}

	void CWindow::setToggleFullscreenEnabled(bool) {}

	bool CWindow::isToggleFullscreenEnabled() const
	{
		return false;
	}

	void CWindow::updateState()
	{
		// frameBufferSize
		::glfwGetFramebufferSize(m_window, &m_state.frameBufferSize.x, &m_state.frameBufferSize.y);

		// scaling
		float xScale, yScale;
		::glfwGetWindowContentScale(m_window, &xScale, &yScale);
		m_state.scaling = Max(xScale, yScale);

		// titleBarHeight
		// [Siv3D ToDo]

		// bounds
		int32 windowPosX, windowPosY, windowSizeX, windowSizeY;
		::glfwGetWindowPos(m_window, &windowPosX, &windowPosY);
		::glfwGetWindowSize(m_window, &windowSizeX, &windowSizeY);

		m_state.bounds.pos = Size(windowPosX, (windowPosY - m_state.titleBarHeight));
		m_state.bounds.size = Size(windowSizeX, (windowSizeY + m_state.titleBarHeight));

		// minimized
		m_state.maximized = (::glfwGetWindowAttrib(m_window, GLFW_ICONIFIED) == GLFW_TRUE);

		// maximized
		m_state.maximized = (::glfwGetWindowAttrib(m_window, GLFW_MAXIMIZED) == GLFW_TRUE)
			&& (m_state.style == WindowStyle::Sizable);

		// focused
		m_state.focused = (::glfwGetWindowAttrib(m_window, GLFW_FOCUSED) == GLFW_TRUE);

		// sizeMove
		m_state.sizeMove = false; // [Siv3D ToDo]
	}

	void CWindow::OnMove(GLFWwindow* window, const int x, const int y)
	{
		LOG_TRACE(U"CWindow::OnMove({})"_fmt(Point(x, y)));

		CWindow* pWindow = static_cast<CWindow*>(::glfwGetWindowUserPointer(window));
		pWindow->m_state.bounds.pos = Point(x, y);
	}

	void CWindow::OnResize(GLFWwindow* window, const int width, const int height)
	{
		LOG_TRACE(U"CWindow::OnResize({})"_fmt(Size(width, height)));

		CWindow* pWindow = static_cast<CWindow*>(::glfwGetWindowUserPointer(window));
		pWindow->m_state.bounds.size = Size(width, height);
		pWindow->m_state.virtualSize = Size(width, height);
	}

	void CWindow::OnFrameBufferSize(GLFWwindow* window, const int width, const int height)
	{
		LOG_TRACE(U"CWindow::OnFrameBufferSize({})"_fmt(Size(width, height)));

		CWindow* pWindow = static_cast<CWindow*>(::glfwGetWindowUserPointer(window));
		pWindow->m_state.frameBufferSize = Size(width, height);
		//pWindow->m_state.clientSize.set(width, height);
	}

	void CWindow::OnScalingChange(GLFWwindow* window, const float sx, const float sy)
	{
		LOG_TRACE(U"CWindow::OnScalingChange({}, {})"_fmt(sx, sy));

		CWindow* pWindow = static_cast<CWindow*>(::glfwGetWindowUserPointer(window));

		pWindow->m_state.scaling = Max(sx, sy);
	}

	void CWindow::OnIconify(GLFWwindow* window, const int iconified)
	{
		LOG_TRACE(U"CWindow::OnIconify({})"_fmt((iconified == GLFW_TRUE)));

		CWindow* pWindow = static_cast<CWindow*>(::glfwGetWindowUserPointer(window));

		if (iconified)
		{
			pWindow->m_state.minimized = true;
			pWindow->m_state.maximized = false;
		}
		else
		{
			pWindow->m_state.minimized = false;
			pWindow->m_state.maximized = false;
		}
	}

	void CWindow::OnMaximize(GLFWwindow* window, const int maximized)
	{
		LOG_TRACE(U"CWindow::OnMaximize({})"_fmt((maximized == GLFW_TRUE)));

		CWindow* pWindow = static_cast<CWindow*>(::glfwGetWindowUserPointer(window));

		if (maximized)
		{
			pWindow->m_state.minimized = false;
			pWindow->m_state.maximized = true;
		}
		else
		{
			pWindow->m_state.minimized = false;
			pWindow->m_state.maximized = false;
		}
	}

	void CWindow::OnFocus(GLFWwindow* window, const int focused)
	{
		LOG_TRACE(U"CWindow::OnFocus({})"_fmt((focused == GLFW_TRUE)));

		CWindow* pWindow = static_cast<CWindow*>(::glfwGetWindowUserPointer(window));
		pWindow->m_state.focused = (focused == GLFW_TRUE);

		if (!focused)
		{
			SIV3D_ENGINE(UserAction)->reportUserActions(UserAction::WindowDeactivated);
		}
	}
}
<|endoftext|>


<commit_before>#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <kms++/kms++.h>
#include <kms++util/kms++util.h>

namespace py = pybind11;

using namespace kms;
using namespace std;

void init_pykmstest(py::module &m)
{
	py::class_<RGB>(m, "RGB")
			.def(py::init<>())
			.def(py::init<uint8_t, uint8_t, uint8_t&>())
			.def(py::init<uint8_t, uint8_t, uint8_t, uint8_t&>())
			.def_property_readonly("rgb888", &RGB::rgb888)
			.def_property_readonly("argb8888", &RGB::argb8888)
			.def_property_readonly("abgr8888", &RGB::abgr8888)
			.def_property_readonly("rgb565", &RGB::rgb565)
			;

	py::class_<ResourceManager>(m, "ResourceManager")
			.def(py::init<Card&>())
			.def("reset", &ResourceManager::reset)
			.def("reserve_connector", (Connector* (ResourceManager::*)(const string& name))&ResourceManager::reserve_connector,
			     py::arg("name") = string())
			.def("reserve_crtc", &ResourceManager::reserve_crtc)
			.def("reserve_plane", &ResourceManager::reserve_plane,
			     py::arg("crtc"),
			     py::arg("type"),
			     py::arg("format") = PixelFormat::Undefined)
			.def("reserve_generic_plane", &ResourceManager::reserve_generic_plane,
			     py::arg("crtc"),
			     py::arg("format") = PixelFormat::Undefined)
			.def("reserve_primary_plane", &ResourceManager::reserve_primary_plane,
			     py::arg("crtc"),
			     py::arg("format") = PixelFormat::Undefined)
			.def("reserve_overlay_plane", &ResourceManager::reserve_overlay_plane,
			     py::arg("crtc"),
			     py::arg("format") = PixelFormat::Undefined)
			;

	// Use lambdas to handle IMappedFramebuffer
	m.def("draw_test_pattern", [](MappedFramebuffer& fb) { draw_test_pattern(fb); } );
	m.def("draw_color_bar", [](MappedFramebuffer& fb, int old_xpos, int xpos, int width) {
		draw_color_bar(fb, old_xpos, xpos, width);
	} );
	m.def("draw_rect", [](MappedFramebuffer& fb, uint32_t x, uint32_t y, uint32_t w, uint32_t h, RGB color) {
		draw_rect(fb, x, y, w, h, color);
	} );
}
<commit_msg>pykmsutil: add draw_text()<commit_after>#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <kms++/kms++.h>
#include <kms++util/kms++util.h>

namespace py = pybind11;

using namespace kms;
using namespace std;

void init_pykmstest(py::module &m)
{
	py::class_<RGB>(m, "RGB")
			.def(py::init<>())
			.def(py::init<uint8_t, uint8_t, uint8_t&>())
			.def(py::init<uint8_t, uint8_t, uint8_t, uint8_t&>())
			.def_property_readonly("rgb888", &RGB::rgb888)
			.def_property_readonly("argb8888", &RGB::argb8888)
			.def_property_readonly("abgr8888", &RGB::abgr8888)
			.def_property_readonly("rgb565", &RGB::rgb565)
			;

	py::class_<ResourceManager>(m, "ResourceManager")
			.def(py::init<Card&>())
			.def("reset", &ResourceManager::reset)
			.def("reserve_connector", (Connector* (ResourceManager::*)(const string& name))&ResourceManager::reserve_connector,
			     py::arg("name") = string())
			.def("reserve_crtc", &ResourceManager::reserve_crtc)
			.def("reserve_plane", &ResourceManager::reserve_plane,
			     py::arg("crtc"),
			     py::arg("type"),
			     py::arg("format") = PixelFormat::Undefined)
			.def("reserve_generic_plane", &ResourceManager::reserve_generic_plane,
			     py::arg("crtc"),
			     py::arg("format") = PixelFormat::Undefined)
			.def("reserve_primary_plane", &ResourceManager::reserve_primary_plane,
			     py::arg("crtc"),
			     py::arg("format") = PixelFormat::Undefined)
			.def("reserve_overlay_plane", &ResourceManager::reserve_overlay_plane,
			     py::arg("crtc"),
			     py::arg("format") = PixelFormat::Undefined)
			;

	// Use lambdas to handle IMappedFramebuffer
	m.def("draw_test_pattern", [](MappedFramebuffer& fb) { draw_test_pattern(fb); } );
	m.def("draw_color_bar", [](MappedFramebuffer& fb, int old_xpos, int xpos, int width) {
		draw_color_bar(fb, old_xpos, xpos, width);
	} );
	m.def("draw_rect", [](MappedFramebuffer& fb, uint32_t x, uint32_t y, uint32_t w, uint32_t h, RGB color) {
		draw_rect(fb, x, y, w, h, color);
	} );
	m.def("draw_text", [](MappedFramebuffer& fb, uint32_t x, uint32_t y, const string& str, RGB color) {
		draw_text(fb, x, y, str, color); } );
}
<|endoftext|>


<commit_before>#include "label.h"

#include <QtGui/QTextCursor>

#include "umllib/nodeElement.h"
#include "umllib/edgeElement.h"
#include "brandManager/brandManager.h"

using namespace qReal;

Label::Label(models::GraphicalModelAssistApi &graphicalAssistApi, Id const &elementId
		, int index, qreal x, qreal y, QString const &text, qreal rotation)
	: mFocusIn(false), mReadOnly(true), mScalingX(false), mScalingY(false), mRotation(rotation)
	, mPoint(x, y), mBinding(""), mBackground(Qt::transparent), mIsStretched(false), mIsHard(false)
	, mParentIsSelected(false), mWasMoved(false), mShouldMove(false)
	, mIndex(index)
	, mId(elementId)
	, mGraphicalModelAssistApi(graphicalAssistApi)
{
	setText(text);
	init();
}

Label::Label(models::GraphicalModelAssistApi &graphicalAssistApi, Id const &elementId
		, int index, qreal x, qreal y, QString const &binding, bool readOnly, qreal rotation)
	: mFocusIn(false), mReadOnly(readOnly), mScalingX(false), mScalingY(false), mRotation(rotation)
	, mPoint(x, y), mBinding(binding), mBackground(Qt::transparent), mIsStretched(false), mIsHard(false)
	, mParentIsSelected(false), mWasMoved(false), mShouldMove(false)
	, mIndex(index)
	, mId(elementId)
	, mGraphicalModelAssistApi(graphicalAssistApi)
{
	init();
}

Label::~Label()
{
}

void Label::init()
{
	QGraphicsTextItem::setFlags(ItemIsSelectable);
	QGraphicsTextItem::setFlag(ItemIsMovable, SettingsManager::value("MoveLabels", true).toBool());

	setTitleFont();
	setRotation(mRotation);
	if (!mBinding.isEmpty()) {
		QList<QPair<QString, QString>> const values = mGraphicalModelAssistApi
				.editorManagerInterface().enumValues(mId, mBinding);
		for (QPair<QString, QString> const &pair : values) {
			mEnumValues[pair.first] = pair.second;
		}
	}
}

void Label::moveToParentCenter()
{
	if (mWasMoved) {
		// now it has user defined position, don't center automatically
		return;
	}

	if (orientation() == Qt::Horizontal) {
		qreal parentCenter = mParentContents.x() + mParentContents.width() / 2;
		qreal titleCenter = x() + mContents.width() / 2;
		qreal diff = parentCenter - titleCenter;

		setX(x() + diff);
	} else if (orientation() == Qt::Vertical) {
		qreal parentCenter = mParentContents.y() + mParentContents.height() / 2;
		qreal titleCenter = y() - mContents.width() / 2;
		qreal diff = parentCenter - titleCenter;

		setY(y() + diff);
	}
}

Qt::Orientation Label::orientation()
{
	if (abs(rotation()) == 90) {
		return Qt::Vertical;
	}

	return Qt::Horizontal;
}

void Label::setText(QString const &text)
{
	setPlainText(text);
}

void Label::setTextFromRepo(QString const &text)
{
	QString const friendlyText = mEnumValues.isEmpty() ? text : mEnumValues[text];
	if (friendlyText != toPlainText()) {
		QGraphicsTextItem::setPlainText(friendlyText);
		setText(toPlainText());
		updateData();
	}
}

void Label::setParentSelected(bool isSelected)
{
	mParentIsSelected = isSelected;
}

void Label::setParentContents(QRectF const &contents)
{
	mParentContents = contents;
	scaleCoordinates(contents);
}

void Label::setShouldCenter(bool shouldCenter)
{
	mWasMoved = !shouldCenter;
}

void Label::scaleCoordinates(QRectF const &contents)
{
	if (mWasMoved) {
		return;
	}

	qreal const x = mPoint.x() * (!mScalingX ? mContents.width() : contents.width());
	qreal const y = mPoint.y() * (!mScalingX ? mContents.height() : contents.height());

	setPos(x, y);
}

void Label::setFlags(GraphicsItemFlags flags)
{
	QGraphicsTextItem::setFlags(flags);
}

void Label::setTextInteractionFlags(Qt::TextInteractionFlags flags)
{
	QGraphicsTextItem::setTextInteractionFlags(flags);
}

void Label::setHtml(QString const &html)
{
	QGraphicsTextItem::setHtml(html);
}

void Label::setPlainText(QString const &text)
{
	QGraphicsTextItem::setPlainText(text);
}

void Label::updateData(bool withUndoRedo)
{
	QString const value = toPlainText();
	NodeElement * const parent = static_cast<NodeElement*>(parentItem());
	if (mBinding == "name") {
		parent->setName(value, withUndoRedo);
	} else if (mEnumValues.isEmpty()) {
		parent->setLogicalProperty(mBinding, value, withUndoRedo);
	} else {
		parent->setLogicalProperty(mBinding, mEnumValues.key(value), withUndoRedo);
	}

	mGraphicalModelAssistApi.setLabelPosition(mId, mIndex, pos());
	mGraphicalModelAssistApi.setLabelSize(mId, mIndex, this->boundingRect().size());
}

void Label::setTitleFont()
{
	setFont(BrandManager::fonts()->sceneLabelsFont());
}

void Label::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
	if (!mShouldMove) {
		QGraphicsTextItem::mousePressEvent(event);
		event->ignore();
		return;
	}

	mIsStretched = (event->pos().x() >= boundingRect().right() - 10
			&& event->pos().y() >= boundingRect().bottom() - 10);

	QGraphicsTextItem::mousePressEvent(event);
	event->accept();
}

void Label::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
	if (!mShouldMove) {
		setSelected(false);
		return;
	}

	QPointF cursorPoint = mapToItem(this, event->pos());

	if (mIsStretched && SettingsManager::value("ResizeLabels", true).toBool()) {
		updateRect(cursorPoint);
		return;
	}

	if (!SettingsManager::value("MoveLabels", true).toBool()) {
		event->ignore();
		return;
	}

	mWasMoved = true;

	if (!labelMovingRect().contains(event->pos())) {
		event->ignore();
		return;
	}

	QGraphicsTextItem::mouseMoveEvent(event);
	event->accept();
}

void Label::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
	mShouldMove = true;

	updateData();

	QGraphicsTextItem::mouseReleaseEvent(event);
	setSelected(true);
}

void Label::init(QRectF const &contents)
{
	mContents = contents;
	mParentContents = contents;

	if (mGraphicalModelAssistApi.hasLabel(mId, mIndex)) {
		QPointF const currentPos = mGraphicalModelAssistApi.labelPosition(mId, mIndex);
		mPoint.setX(currentPos.x() / mContents.width());
		mPoint.setY(currentPos.y() / mContents.height());
		setPos(currentPos);
	} else {
		qreal const x = mPoint.x() * mContents.width();
		qreal const y = mPoint.y() * mContents.height();
		setPos(x, y);
		mGraphicalModelAssistApi.createLabel(mId, mIndex, QPointF(x, y), this->boundingRect().size());
	}
}

void Label::setScaling(bool scalingX, bool scalingY)
{
	mScalingX = scalingX;
	mScalingY = scalingY;
}

void Label::setBackground(QColor const &background)
{
	mBackground = background;
}

bool Label::isHard() const
{
	return mIsHard;
}

void Label::setHard(bool hard)
{
	mIsHard = hard;
}

bool Label::isReadOnly() const
{
	return mReadOnly;
}

void Label::focusOutEvent(QFocusEvent *event)
{
	QGraphicsTextItem::focusOutEvent(event);
	setTextInteractionFlags(Qt::NoTextInteraction);

	// Clear selection
	QTextCursor cursor = textCursor();
	cursor.clearSelection();
	setTextCursor(cursor);

	unsetCursor();

	if (mReadOnly) {
		return;
	}

	if (mOldText != toPlainText()) {
		updateData(true);
	}
}

void Label::keyPressEvent(QKeyEvent *event)
{
	int const keyEvent = event->key();
	if (keyEvent == Qt::Key_Escape) {
		// Restore previous text and loose focus
		setText(mOldText);
		clearFocus();
		return;
	}

	if ((event->modifiers() & Qt::ShiftModifier) && (event->key() == Qt::Key_Return)) {
		// Line feed
		QTextCursor cursor = textCursor();
		QString currentText = toPlainText();
		int const oldPos = cursor.position();
		currentText.insert(oldPos, "\n");
		setText(currentText);
		cursor.movePosition(QTextCursor::Start);
		cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::MoveAnchor, oldPos + 1);
		setTextCursor(cursor);
		return;
	}

	if (keyEvent == Qt::Key_Enter || keyEvent == Qt::Key_Return) {
		// Loose focus: new name will be applied in focusOutEvent
		clearFocus();
		return;
	}

	QGraphicsTextItem::keyPressEvent(event);
}

void Label::startTextInteraction()
{
	// Already interacting?
	if (hasFocus()) {
		return;
	}

	mOldText = toPlainText();

	setTextInteractionFlags(mReadOnly ? Qt::TextBrowserInteraction : Qt::TextEditorInteraction);
	setFocus(Qt::OtherFocusReason);

	// Set full text selection
	QTextCursor cursor = QTextCursor(document());
	cursor.select(QTextCursor::Document);
	setTextCursor(cursor);
	setCursor(Qt::IBeamCursor);
}

void Label::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
	QString text = toPlainText();

	if (text.isEmpty() && !mParentIsSelected && !isSelected()) {
		return;
	}

	painter->save();
	painter->setBrush(QBrush(mBackground));

	if ((mParentIsSelected && toPlainText().isEmpty()) || isSelected()) {
		painter->setPen(QPen(Qt::DotLine));
	} else if (!toPlainText().isEmpty()) {
		painter->setPen(QPen(Qt::transparent));
	}

	painter->drawRect(boundingRect());
	painter->restore();

	QGraphicsTextItem::paint(painter, option, widget);
}

void Label::updateRect(QPointF newBottomRightPoint)
{
	mContents.setBottomRight(newBottomRightPoint);
	setTextWidth(mContents.width());
}

void Label::clearMoveFlag()
{
	mShouldMove = false;
}

QRectF Label::labelMovingRect() const
{
	int const distance = SettingsManager::value("LabelsDistance").toInt();
	return mapFromItem(parentItem(), parentItem()->boundingRect()).boundingRect()
			.adjusted(-distance, -distance, distance, distance);
}
<commit_msg>Added edge element selection even on accidental click on its label<commit_after>#include "label.h"

#include <QtGui/QTextCursor>

#include "umllib/nodeElement.h"
#include "umllib/edgeElement.h"
#include "brandManager/brandManager.h"

using namespace qReal;

Label::Label(models::GraphicalModelAssistApi &graphicalAssistApi, Id const &elementId
		, int index, qreal x, qreal y, QString const &text, qreal rotation)
	: mFocusIn(false), mReadOnly(true), mScalingX(false), mScalingY(false), mRotation(rotation)
	, mPoint(x, y), mBinding(""), mBackground(Qt::transparent), mIsStretched(false), mIsHard(false)
	, mParentIsSelected(false), mWasMoved(false), mShouldMove(false)
	, mIndex(index)
	, mId(elementId)
	, mGraphicalModelAssistApi(graphicalAssistApi)
{
	setText(text);
	init();
}

Label::Label(models::GraphicalModelAssistApi &graphicalAssistApi, Id const &elementId
		, int index, qreal x, qreal y, QString const &binding, bool readOnly, qreal rotation)
	: mFocusIn(false), mReadOnly(readOnly), mScalingX(false), mScalingY(false), mRotation(rotation)
	, mPoint(x, y), mBinding(binding), mBackground(Qt::transparent), mIsStretched(false), mIsHard(false)
	, mParentIsSelected(false), mWasMoved(false), mShouldMove(false)
	, mIndex(index)
	, mId(elementId)
	, mGraphicalModelAssistApi(graphicalAssistApi)
{
	init();
}

Label::~Label()
{
}

void Label::init()
{
	QGraphicsTextItem::setFlags(ItemIsSelectable);
	QGraphicsTextItem::setFlag(ItemIsMovable, SettingsManager::value("MoveLabels", true).toBool());

	setTitleFont();
	setRotation(mRotation);
	if (!mBinding.isEmpty()) {
		QList<QPair<QString, QString>> const values = mGraphicalModelAssistApi
				.editorManagerInterface().enumValues(mId, mBinding);
		for (QPair<QString, QString> const &pair : values) {
			mEnumValues[pair.first] = pair.second;
		}
	}
}

void Label::moveToParentCenter()
{
	if (mWasMoved) {
		// now it has user defined position, don't center automatically
		return;
	}

	if (orientation() == Qt::Horizontal) {
		qreal parentCenter = mParentContents.x() + mParentContents.width() / 2;
		qreal titleCenter = x() + mContents.width() / 2;
		qreal diff = parentCenter - titleCenter;

		setX(x() + diff);
	} else if (orientation() == Qt::Vertical) {
		qreal parentCenter = mParentContents.y() + mParentContents.height() / 2;
		qreal titleCenter = y() - mContents.width() / 2;
		qreal diff = parentCenter - titleCenter;

		setY(y() + diff);
	}
}

Qt::Orientation Label::orientation()
{
	if (abs(rotation()) == 90) {
		return Qt::Vertical;
	}

	return Qt::Horizontal;
}

void Label::setText(QString const &text)
{
	setPlainText(text);
}

void Label::setTextFromRepo(QString const &text)
{
	QString const friendlyText = mEnumValues.isEmpty() ? text : mEnumValues[text];
	if (friendlyText != toPlainText()) {
		QGraphicsTextItem::setPlainText(friendlyText);
		setText(toPlainText());
		updateData();
	}
}

void Label::setParentSelected(bool isSelected)
{
	mParentIsSelected = isSelected;
}

void Label::setParentContents(QRectF const &contents)
{
	mParentContents = contents;
	scaleCoordinates(contents);
}

void Label::setShouldCenter(bool shouldCenter)
{
	mWasMoved = !shouldCenter;
}

void Label::scaleCoordinates(QRectF const &contents)
{
	if (mWasMoved) {
		return;
	}

	qreal const x = mPoint.x() * (!mScalingX ? mContents.width() : contents.width());
	qreal const y = mPoint.y() * (!mScalingX ? mContents.height() : contents.height());

	setPos(x, y);
}

void Label::setFlags(GraphicsItemFlags flags)
{
	QGraphicsTextItem::setFlags(flags);
}

void Label::setTextInteractionFlags(Qt::TextInteractionFlags flags)
{
	QGraphicsTextItem::setTextInteractionFlags(flags);
}

void Label::setHtml(QString const &html)
{
	QGraphicsTextItem::setHtml(html);
}

void Label::setPlainText(QString const &text)
{
	QGraphicsTextItem::setPlainText(text);
}

void Label::updateData(bool withUndoRedo)
{
	QString const value = toPlainText();
	NodeElement * const parent = static_cast<NodeElement *>(parentItem());
	if (mBinding == "name") {
		parent->setName(value, withUndoRedo);
	} else if (mEnumValues.isEmpty()) {
		parent->setLogicalProperty(mBinding, value, withUndoRedo);
	} else {
		parent->setLogicalProperty(mBinding, mEnumValues.key(value), withUndoRedo);
	}

	mGraphicalModelAssistApi.setLabelPosition(mId, mIndex, pos());
	mGraphicalModelAssistApi.setLabelSize(mId, mIndex, this->boundingRect().size());
}

void Label::setTitleFont()
{
	setFont(BrandManager::fonts()->sceneLabelsFont());
}

void Label::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
	if (dynamic_cast<EdgeElement *>(parentItem())) {
		// Passing event to edge because users usially want to edit its property when clicking on it.
		QGraphicsItem::mousePressEvent(event);
		return;
	}

	if (!mShouldMove) {
		QGraphicsTextItem::mousePressEvent(event);
		event->ignore();
		return;
	}

	mIsStretched = (event->pos().x() >= boundingRect().right() - 10
			&& event->pos().y() >= boundingRect().bottom() - 10);

	QGraphicsTextItem::mousePressEvent(event);
	event->accept();
}

void Label::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
	if (!mShouldMove) {
		setSelected(false);
		return;
	}

	QPointF cursorPoint = mapToItem(this, event->pos());

	if (mIsStretched && SettingsManager::value("ResizeLabels", true).toBool()) {
		updateRect(cursorPoint);
		return;
	}

	if (!SettingsManager::value("MoveLabels", true).toBool()) {
		event->ignore();
		return;
	}

	mWasMoved = true;

	if (!labelMovingRect().contains(event->pos())) {
		event->ignore();
		return;
	}

	QGraphicsTextItem::mouseMoveEvent(event);
	event->accept();
}

void Label::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
	mShouldMove = true;

	updateData();

	QGraphicsTextItem::mouseReleaseEvent(event);
	setSelected(true);
}

void Label::init(QRectF const &contents)
{
	mContents = contents;
	mParentContents = contents;

	if (mGraphicalModelAssistApi.hasLabel(mId, mIndex)) {
		QPointF const currentPos = mGraphicalModelAssistApi.labelPosition(mId, mIndex);
		mPoint.setX(currentPos.x() / mContents.width());
		mPoint.setY(currentPos.y() / mContents.height());
		setPos(currentPos);
	} else {
		qreal const x = mPoint.x() * mContents.width();
		qreal const y = mPoint.y() * mContents.height();
		setPos(x, y);
		mGraphicalModelAssistApi.createLabel(mId, mIndex, QPointF(x, y), this->boundingRect().size());
	}
}

void Label::setScaling(bool scalingX, bool scalingY)
{
	mScalingX = scalingX;
	mScalingY = scalingY;
}

void Label::setBackground(QColor const &background)
{
	mBackground = background;
}

bool Label::isHard() const
{
	return mIsHard;
}

void Label::setHard(bool hard)
{
	mIsHard = hard;
}

bool Label::isReadOnly() const
{
	return mReadOnly;
}

void Label::focusOutEvent(QFocusEvent *event)
{
	QGraphicsTextItem::focusOutEvent(event);
	setTextInteractionFlags(Qt::NoTextInteraction);

	// Clear selection
	QTextCursor cursor = textCursor();
	cursor.clearSelection();
	setTextCursor(cursor);

	unsetCursor();

	if (mReadOnly) {
		return;
	}

	if (mOldText != toPlainText()) {
		updateData(true);
	}
}

void Label::keyPressEvent(QKeyEvent *event)
{
	int const keyEvent = event->key();
	if (keyEvent == Qt::Key_Escape) {
		// Restore previous text and loose focus
		setText(mOldText);
		clearFocus();
		return;
	}

	if ((event->modifiers() & Qt::ShiftModifier) && (event->key() == Qt::Key_Return)) {
		// Line feed
		QTextCursor cursor = textCursor();
		QString currentText = toPlainText();
		int const oldPos = cursor.position();
		currentText.insert(oldPos, "\n");
		setText(currentText);
		cursor.movePosition(QTextCursor::Start);
		cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::MoveAnchor, oldPos + 1);
		setTextCursor(cursor);
		return;
	}

	if (keyEvent == Qt::Key_Enter || keyEvent == Qt::Key_Return) {
		// Loose focus: new name will be applied in focusOutEvent
		clearFocus();
		return;
	}

	QGraphicsTextItem::keyPressEvent(event);
}

void Label::startTextInteraction()
{
	// Already interacting?
	if (hasFocus()) {
		return;
	}

	mOldText = toPlainText();

	setTextInteractionFlags(mReadOnly ? Qt::TextBrowserInteraction : Qt::TextEditorInteraction);
	setFocus(Qt::OtherFocusReason);

	// Set full text selection
	QTextCursor cursor = QTextCursor(document());
	cursor.select(QTextCursor::Document);
	setTextCursor(cursor);
	setCursor(Qt::IBeamCursor);
}

void Label::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
	QString text = toPlainText();

	if (text.isEmpty() && !mParentIsSelected && !isSelected()) {
		return;
	}

	painter->save();
	painter->setBrush(QBrush(mBackground));

	if ((mParentIsSelected && toPlainText().isEmpty()) || isSelected()) {
		painter->setPen(QPen(Qt::DotLine));
	} else if (!toPlainText().isEmpty()) {
		painter->setPen(QPen(Qt::transparent));
	}

	painter->drawRect(boundingRect());
	painter->restore();

	QGraphicsTextItem::paint(painter, option, widget);
}

void Label::updateRect(QPointF newBottomRightPoint)
{
	mContents.setBottomRight(newBottomRightPoint);
	setTextWidth(mContents.width());
}

void Label::clearMoveFlag()
{
	mShouldMove = false;
}

QRectF Label::labelMovingRect() const
{
	int const distance = SettingsManager::value("LabelsDistance").toInt();
	return mapFromItem(parentItem(), parentItem()->boundingRect()).boundingRect()
			.adjusted(-distance, -distance, distance, distance);
}
<|endoftext|>


<commit_before>#include <gtest/gtest.h>
#include <rai/node.hpp>

#include <thread>

TEST (system, generate_mass_activity)
{
    rai::system system (24000, 1);
    system.wallet (0)->insert (rai::test_genesis_key.prv);
    size_t count (20);
    system.generate_mass_activity (count, *system.nodes [0]);
    size_t accounts (0);
	rai::transaction transaction (system.nodes [0]->store.environment, nullptr, false);
    for (auto i (system.nodes [0]->store.latest_begin (transaction)), n (system.nodes [0]->store.latest_end ()); i != n; ++i)
    {
        ++accounts;
    }
    ASSERT_GT (accounts, count / 10);
}

TEST (system, generate_mass_activity_long)
{
	std::vector <std::thread> threads;
	{
		rai::system system (24000, 1);
		for (auto i (0), n (4); i != n; ++i)
		{
			threads.push_back (std::thread ([&system] ()
			{
				system.service->run ();
			}));
		}
		for (auto i (0), n (4); i != n; ++i)
		{
			threads.push_back (std::thread ([&system] ()
			{
				system.processor.run ();
			}));
		}
		system.wallet (0)->insert (rai::test_genesis_key.prv);
		size_t count (10000);
		system.generate_mass_activity (count, *system.nodes [0]);
		size_t accounts (0);
		rai::transaction transaction (system.nodes [0]->store.environment, nullptr, false);
		for (auto i (system.nodes [0]->store.latest_begin (transaction)), n (system.nodes [0]->store.latest_end ()); i != n; ++i)
		{
			++accounts;
		}
		ASSERT_GT (accounts, count / 10);
	}
	for (auto i (threads.begin ()), n (threads.end ()); i != n; ++i)
	{
		i->join ();
	}
}

TEST (ledger, deep_account_compute)
{
	bool init (false);
	rai::block_store store (init, rai::unique_path ());
	ASSERT_FALSE (init);
	rai::ledger ledger (store);
	rai::genesis genesis;
	rai::transaction transaction (store.environment, nullptr, true);
	genesis.initialize (transaction, store);
	rai::keypair key;
	auto balance (rai::genesis_amount - 1);
	rai::send_block send (genesis.hash (), key.pub, balance, rai::test_genesis_key.prv, rai::test_genesis_key.pub, 0);
	ASSERT_EQ (rai::process_result::progress, ledger.process (transaction, send).code);
	rai::open_block open (send.hash (), rai::test_genesis_key.pub, key.pub, key.prv, key.pub, 0);
	ASSERT_EQ (rai::process_result::progress, ledger.process (transaction, open).code);
	auto sprevious (send.hash ());
	auto rprevious (open.hash ());
	for (auto i (0), n (100000); i != n; ++i)
	{
		balance -= 1;
		rai::send_block send (sprevious, key.pub, balance, rai::test_genesis_key.prv, rai::test_genesis_key.pub, 0);
		ASSERT_EQ (rai::process_result::progress, ledger.process (transaction, send).code);
		sprevious = send.hash ();
		rai::receive_block receive (rprevious, send.hash (), key.prv, key.pub, 0);
		ASSERT_EQ (rai::process_result::progress, ledger.process (transaction, receive).code);
		rprevious = receive.hash ();
		if (i % 100 == 0)
		{
			std::cerr << i << ' ';
		}
		auto account (ledger.account (transaction, sprevious));
		auto balance (ledger.balance (transaction, rprevious));
	}
}<commit_msg>Adding multithreaded wallet test.<commit_after>#include <gtest/gtest.h>
#include <rai/node.hpp>

#include <thread>

TEST (system, generate_mass_activity)
{
    rai::system system (24000, 1);
    system.wallet (0)->insert (rai::test_genesis_key.prv);
    size_t count (20);
    system.generate_mass_activity (count, *system.nodes [0]);
    size_t accounts (0);
	rai::transaction transaction (system.nodes [0]->store.environment, nullptr, false);
    for (auto i (system.nodes [0]->store.latest_begin (transaction)), n (system.nodes [0]->store.latest_end ()); i != n; ++i)
    {
        ++accounts;
    }
    ASSERT_GT (accounts, count / 10);
}

TEST (system, generate_mass_activity_long)
{
	std::vector <std::thread> threads;
	{
		rai::system system (24000, 1);
		for (auto i (0), n (4); i != n; ++i)
		{
			threads.push_back (std::thread ([&system] ()
			{
				system.service->run ();
			}));
		}
		for (auto i (0), n (4); i != n; ++i)
		{
			threads.push_back (std::thread ([&system] ()
			{
				system.processor.run ();
			}));
		}
		system.wallet (0)->insert (rai::test_genesis_key.prv);
		size_t count (10000);
		system.generate_mass_activity (count, *system.nodes [0]);
		size_t accounts (0);
		rai::transaction transaction (system.nodes [0]->store.environment, nullptr, false);
		for (auto i (system.nodes [0]->store.latest_begin (transaction)), n (system.nodes [0]->store.latest_end ()); i != n; ++i)
		{
			++accounts;
		}
		ASSERT_GT (accounts, count / 10);
	}
	for (auto i (threads.begin ()), n (threads.end ()); i != n; ++i)
	{
		i->join ();
	}
}

TEST (ledger, deep_account_compute)
{
	bool init (false);
	rai::block_store store (init, rai::unique_path ());
	ASSERT_FALSE (init);
	rai::ledger ledger (store);
	rai::genesis genesis;
	rai::transaction transaction (store.environment, nullptr, true);
	genesis.initialize (transaction, store);
	rai::keypair key;
	auto balance (rai::genesis_amount - 1);
	rai::send_block send (genesis.hash (), key.pub, balance, rai::test_genesis_key.prv, rai::test_genesis_key.pub, 0);
	ASSERT_EQ (rai::process_result::progress, ledger.process (transaction, send).code);
	rai::open_block open (send.hash (), rai::test_genesis_key.pub, key.pub, key.prv, key.pub, 0);
	ASSERT_EQ (rai::process_result::progress, ledger.process (transaction, open).code);
	auto sprevious (send.hash ());
	auto rprevious (open.hash ());
	for (auto i (0), n (100000); i != n; ++i)
	{
		balance -= 1;
		rai::send_block send (sprevious, key.pub, balance, rai::test_genesis_key.prv, rai::test_genesis_key.pub, 0);
		ASSERT_EQ (rai::process_result::progress, ledger.process (transaction, send).code);
		sprevious = send.hash ();
		rai::receive_block receive (rprevious, send.hash (), key.prv, key.pub, 0);
		ASSERT_EQ (rai::process_result::progress, ledger.process (transaction, receive).code);
		rprevious = receive.hash ();
		if (i % 100 == 0)
		{
			std::cerr << i << ' ';
		}
		auto account (ledger.account (transaction, sprevious));
		auto balance (ledger.balance (transaction, rprevious));
	}
}

TEST (wallet, multithreaded_send)
{
	std::vector <std::thread> threads;
	{
		rai::system system (24000, 1);
		rai::keypair key;
		auto wallet_l (system.wallet (0));
		wallet_l->insert (rai::test_genesis_key.prv);
		for (auto i (0); i < 20; ++i)
		{
			threads.push_back (std::thread ([wallet_l, &key] ()
			{
				for (auto i (0); i < 1000; ++i)
				{
					wallet_l->send_sync (rai::test_genesis_key.pub, key.pub, 1000);
				}
			}));
		}
		while (system.nodes [0]->balance(rai::test_genesis_key.pub) != (rai::genesis_amount - 20 * 1000 * 1000))
		{
			system.poll ();
		}
	}
	for (auto i (threads.begin ()), n (threads.end ()); i != n; ++i)
	{
		i->join ();
	}
}<|endoftext|>


<commit_before>#pragma once

#include "zyre.h"

#include <string>
#include <exception>
#include <vector>

namespace zyre
{
    class error_t : public std::runtime_error
    {
    public:
        error_t(const std::string& what) : std::runtime_error(what) {}
    };

    class event_t
    {
    public:
        event_t(zyre_event_t* self) : m_self(self) {};

        ~event_t()
        {
            if (m_self)
                zyre_event_destroy(&m_self);
        }

        event_t(const event_t& other) = delete;
        event_t operator=(const event_t& other) = delete;

        event_t(event_t&& other)
        {
            m_self = other.m_self;
            other.m_self = nullptr;
        }

        event_t& operator=(event_t&& other)
        {
            if (&other != this)
            {
                m_self = other.m_self;
                other.m_self = nullptr;
            }
            return *this;
        }

        void print() const
        {
            zyre_event_print(m_self);
        }

        zyre_event_type_t type() const
        {
            return zyre_event_type(m_self);
        }

        std::string sender() const
        {
            return zyre_event_sender(m_self);
        }

        std::string name() const
        {
            return zyre_event_name(m_self);
        }

        std::string address() const
        {
            return zyre_event_address(m_self);
        }

        std::string header_value(const std::string& key) const
        {
            return zyre_event_header(m_self, key.c_str());
        }

        std::string group() const
        {
            return zyre_event_group(m_self);
        }

        zmsg_t* message() const
        {
            return zyre_event_msg(m_self);
        }

    private:
        zyre_event_t* m_self;
    };

    class node_t
    {
    public:
        node_t(const std::string& name = "")
        {
            if (name != "")
                m_self = zyre_new(NULL);
            else
                m_self = zyre_new(name.c_str());
        }

        ~node_t()
        {
            if (m_self)
                zyre_destroy(&m_self);
        }

        node_t(const node_t& other) = delete;
        node_t operator=(const node_t& other) = delete;

        node_t(node_t&& other)
        {
            m_self = other.m_self;
            other.m_self = nullptr;
        }

        node_t& operator=(node_t&& other)
        {
            if (&other != this)
            {
                m_self = other.m_self;
                other.m_self = nullptr;
            }
            return *this;
        }

        void print() const
        {
            zyre_print(m_self);
        }

        std::string uuid() const
        {
            return zyre_uuid(m_self);
        }

        std::string name() const
        {
            return zyre_name(m_self);
        }

        void set_header(const std::string key, const std::string& value) const
        {
            zyre_set_header(m_self, key.c_str(), value.c_str());
        }

        void set_verbose() const
        {
            zyre_set_verbose(m_self);
        }

        void set_port(int value) const
        {
            zyre_set_port(m_self, value);
        }

        void set_interval(size_t value) const
        {
            zyre_set_interval(m_self, value);
        }

        void set_interface(const std::string& value) const
        {
            zyre_set_interface(m_self, value.c_str());
        }

        void start() const
        {
            int rc = zyre_start(m_self);
            if (rc == -1)
                throw error_t("Failed to start Zyre node");
        }

        void stop() const
        {
            zyre_stop(m_self);
        }

        void join(const std::string& group) const
        {
            zyre_join(m_self, group.c_str());
        }

        void leave(const std::string& group) const
        {
            zyre_leave(m_self, group.c_str());
        }

        void whisper(const std::string& peer, zmsg_t* msg) const
        {
            zyre_whisper(m_self, peer.c_str(), &msg);
        }

        void shout(const std::string& group, zmsg_t* msg) const
        {
            zyre_shout(m_self, group.c_str(), &msg);
        }

        zmsg_t* recv() const
        {
            return zyre_recv(m_self);
        }

        event_t event() const
        {
            return event_t(zyre_event_new(m_self));
        }

        std::vector<std::string> peers() const
        {
            zlist_t* peers = zyre_peers(m_self);
            std::vector<std::string> ret = to_vector(peers);
            zlist_destroy(&peers);
            return ret;
        }

        std::vector<std::string> own_groups() const
        {
            zlist_t* ownGroups = zyre_own_groups(m_self);
            std::vector<std::string> ret = to_vector(ownGroups);
            zlist_destroy(&ownGroups);
            return ret;
        }

        std::vector<std::string> peer_groups() const
        {
            zlist_t* peerGroups = zyre_peer_groups(m_self);
            std::vector<std::string> ret = to_vector(peerGroups);
            zlist_destroy(&peerGroups);
            return ret;
        }

        std::string peer_address(const std::string& peer) const
        {
            char* val = zyre_peer_address(m_self, peer.c_str());
            std::string ret(val);
            if (val != NULL)
                delete val;
            return ret;
        }

        std::string peer_header_value(const std::string& peer, const std::string& name)
        {
            char* val = zyre_peer_header_value(m_self, peer.c_str(), peer.c_str());
            std::string ret(val);
            if (val != NULL)
                delete val;
            return ret;
        }

        zsock_t* socket() const
        {
            return zyre_socket(m_self);
        }

        static void version(int& major, int& minor, int& patch)
        {
            zyre_version(&major, &minor, &patch);
        }

    private:
        std::vector<std::string> to_vector(zlist_t* list) const
        {
            std::vector<std::string> ret;
            void* cursor = zlist_first(list);
            while (cursor != NULL)
            {
                ret.emplace_back(static_cast<char*>(cursor));
                cursor = zlist_next(list);
            }
            return ret;
        }

        zyre_t* m_self;
    };
}<commit_msg>Updated to reflect the latest zyre version.<commit_after>#pragma once

#include "zyre.h"

#include <string>
#include <exception>
#include <vector>

namespace zyre
{
    class error_t : public std::runtime_error
    {
    public:
        error_t(const std::string& what) : std::runtime_error(what) {}
    };

    class event_t
    {
    public:
        event_t(zyre_event_t* self) : m_self(self) {};

        ~event_t()
        {
            if (m_self)
                zyre_event_destroy(&m_self);
        }

        event_t(const event_t& other) = delete;
        event_t operator=(const event_t& other) = delete;

        event_t(event_t&& other)
        {
            m_self = other.m_self;
            other.m_self = nullptr;
        }

        event_t& operator=(event_t&& other)
        {
            if (&other != this)
            {
                m_self = other.m_self;
                other.m_self = nullptr;
            }
            return *this;
        }

        void print() const
        {
            zyre_event_print(m_self);
        }

        std::string type() const
        {
            return zyre_event_type(m_self);
        }

        std::string sender() const
        {
            return zyre_event_peer_uuid(m_self);
        }

        std::string name() const
        {
            return zyre_event_peer_name(m_self);
        }

        std::string address() const
        {
            return zyre_event_peer_addr(m_self);
        }

        std::string header_value(const std::string& key) const
        {
            return zyre_event_header(m_self, key.c_str());
        }

        std::string group() const
        {
            return zyre_event_group(m_self);
        }

        zmsg_t* message() const
        {
            return zyre_event_msg(m_self);
        }

    private:
        zyre_event_t* m_self;
    };

    class node_t
    {
    public:
        node_t(const std::string& name = "")
        {
            if (name != "")
                m_self = zyre_new(NULL);
            else
                m_self = zyre_new(name.c_str());
        }

        ~node_t()
        {
            if (m_self)
                zyre_destroy(&m_self);
        }

        node_t(const node_t& other) = delete;
        node_t operator=(const node_t& other) = delete;

        node_t(node_t&& other)
        {
            m_self = other.m_self;
            other.m_self = nullptr;
        }

        node_t& operator=(node_t&& other)
        {
            if (&other != this)
            {
                m_self = other.m_self;
                other.m_self = nullptr;
            }
            return *this;
        }

        void print() const
        {
            zyre_print(m_self);
        }

        std::string uuid() const
        {
            return zyre_uuid(m_self);
        }

        std::string name() const
        {
            return zyre_name(m_self);
        }

        void set_header(const std::string key, const std::string& value) const
        {
            zyre_set_header(m_self, key.c_str(), value.c_str());
        }

        void set_verbose() const
        {
            zyre_set_verbose(m_self);
        }

        void set_port(int value) const
        {
            zyre_set_port(m_self, value);
        }

        void set_interval(size_t value) const
        {
            zyre_set_interval(m_self, value);
        }

        void set_interface(const std::string& value) const
        {
            zyre_set_interface(m_self, value.c_str());
        }

        void start() const
        {
            int rc = zyre_start(m_self);
            if (rc == -1)
                throw error_t("Failed to start Zyre node");
        }

        void stop() const
        {
            zyre_stop(m_self);
        }

        void join(const std::string& group) const
        {
            zyre_join(m_self, group.c_str());
        }

        void leave(const std::string& group) const
        {
            zyre_leave(m_self, group.c_str());
        }

        void whisper(const std::string& peer, zmsg_t* msg) const
        {
            zyre_whisper(m_self, peer.c_str(), &msg);
        }

        void shout(const std::string& group, zmsg_t* msg) const
        {
            zyre_shout(m_self, group.c_str(), &msg);
        }

        zmsg_t* recv() const
        {
            return zyre_recv(m_self);
        }

        event_t event() const
        {
            return event_t(zyre_event_new(m_self));
        }

        std::vector<std::string> peers() const
        {
            zlist_t* peers = zyre_peers(m_self);
            std::vector<std::string> ret = to_vector(peers);
            zlist_destroy(&peers);
            return ret;
        }

        std::vector<std::string> own_groups() const
        {
            zlist_t* ownGroups = zyre_own_groups(m_self);
            std::vector<std::string> ret = to_vector(ownGroups);
            zlist_destroy(&ownGroups);
            return ret;
        }

        std::vector<std::string> peer_groups() const
        {
            zlist_t* peerGroups = zyre_peer_groups(m_self);
            std::vector<std::string> ret = to_vector(peerGroups);
            zlist_destroy(&peerGroups);
            return ret;
        }

        std::string peer_address(const std::string& peer) const
        {
            char* val = zyre_peer_address(m_self, peer.c_str());
            std::string ret(val);
            if (val != NULL)
                delete val;
            return ret;
        }

        std::string peer_header_value(const std::string& peer, const std::string& name)
        {
            char* val = zyre_peer_header_value(m_self, peer.c_str(), peer.c_str());
            std::string ret(val);
            if (val != NULL)
                delete val;
            return ret;
        }

        zsock_t* socket() const
        {
            return zyre_socket(m_self);
        }

        static int version()
        {
            return zyre_version();
        }

    private:
        std::vector<std::string> to_vector(zlist_t* list) const
        {
            std::vector<std::string> ret;
            void* cursor = zlist_first(list);
            while (cursor != NULL)
            {
                ret.emplace_back(static_cast<char*>(cursor));
                cursor = zlist_next(list);
            }
            return ret;
        }

        zyre_t* m_self;
    };
}
<|endoftext|>


<commit_before>/* Rapicorn
 * Copyright (C) 2005 Tim Janik
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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.
 *
 * A copy of the GNU Lesser General Public License should ship along
 * with this library; if not, see http://www.gnu.org/copyleft/.
 */
#include "appearance.hh"

namespace Rapicorn {

const Style::ColorSchemeKind &Style::STANDARD = *(ColorSchemeKind*) 0xC0FFEE41;
const Style::ColorSchemeKind &Style::SELECTED = *(ColorSchemeKind*) 0xC0FFEE42;
const Style::ColorSchemeKind &Style::INPUT = *(ColorSchemeKind*) 0xC0FFEE43;

Style::Style (Appearance     &appearance,
              const String   &name) :
  m_appearance (appearance),
  m_name (name)
{
  m_appearance.register_style (*this);
}

Style*
Style::create_style (const String   &style_name)
{
  return m_appearance.create_style (style_name);
}

const ColorScheme&
Style::color_scheme (const ColorSchemeKind &kind) const
{
  return ColorScheme::default_scheme();
}

Color
Style::standard_color (StateType      state,
                       ColorType      color_type) const
{
  return color_scheme (STANDARD).make_color (color_type);
}

Color
Style::selected_color (StateType      state,
                       ColorType      color_type) const
{
  return color_scheme (SELECTED).make_color (color_type);
}

Color
Style::input_color (StateType      state,
                    ColorType      color_type) const
{
  return color_scheme (INPUT).make_color (color_type);
}

Color
Style::resolve_color (const String &color_name,
                      StateType     state,
                      ColorType     color_type)
{
  EnumTypeColorType ect;
  if (color_name[0] == '#')
    {
      uint32 argb = string_to_int (&color_name[1], 16);
      /* invert alpha */
      Color c (argb);
      c.alpha (0xff - c.alpha());
      return c; // return argb;
    }
  const EnumClass::Value *value = ect.find_first (color_name);
  if (value)
    return standard_color (state, ColorType (value->value));
  else
    {
      Color parsed_color = Color::from_name (color_name);
      if (!parsed_color)
        parsed_color = standard_color (state, color_type);
      return parsed_color;
    }
}

Style::~Style ()
{
  m_appearance.unregister_style (*this);
}

Color
ColorScheme::make_light_color (Color source_color) const
{
  Color c = source_color;
  double hue, saturation, value;
  c.get_hsv (&hue, &saturation, &value);
  value *= 1.1;
  c.set_hsv (hue, saturation, value);
  return c;
}

Color
ColorScheme::make_dark_color (Color source_color) const
{
  Color c = source_color;
  double hue, saturation, value;
  c.get_hsv (&hue, &saturation, &value);
  value *= 0.9;
  c.set_hsv (hue, saturation, value);
  return c;
}

Color
ColorScheme::make_insensitive_color (Color     source_color,
                                     ColorType ctype) const
{
  Color c = source_color;
  double hue, saturation, value;
  c.get_hsv (&hue, &saturation, &value);
  saturation *= 0.8;
  value *= 1.075;
  c.set_hsv (hue, saturation, MIN (1, value));
  return c;
}

Color
ColorScheme::make_prelight_color (Color     source_color,
                                  ColorType ctype) const
{
  Color c = source_color;
  switch (ctype)
    {
    case COLOR_FOREGROUND:
    case COLOR_FOCUS:
    case COLOR_DEFAULT:
      return c;
    default: ;
    }
  double hue, saturation, value;
  c.get_hsv (&hue, &saturation, &value);
  saturation *= 1.2;
  c.set_hsv (hue, MIN (1, saturation), value);
  return c;
}

Color
ColorScheme::make_impressed_color (Color     source_color,
                                   ColorType ctype) const
{
  Color c = source_color;
  switch (ctype)
    {
    case COLOR_FOREGROUND:
    case COLOR_FOCUS:
    case COLOR_DEFAULT:
      return c;
    default: ;
    }
  double hue, saturation, value;
  c.get_hsv (&hue, &saturation, &value);
  value *= 0.8;
  c.set_hsv (hue, saturation, value);
  return c;
}

Color
ColorScheme::make_focus_state_color (Color     source_color,
                                     ColorType ctype) const
{
  Color c = source_color;
  return c;
}

Color
ColorScheme::make_default_state_color (Color     source_color,
                                       ColorType ctype) const
{
  Color c = source_color;
  return c;
}

Color
ColorScheme::make_state_color (StateType      state,
                               Color          color,
                               ColorType      ctype) const
{
  Color c = color;
  if (state & STATE_IMPRESSED)
    c = make_impressed_color (c, ctype);
  if (state & STATE_DEFAULT)
    c = make_default_state_color (c, ctype);
  if (state & STATE_FOCUS)
    c = make_focus_state_color (c, ctype);
  if (state & STATE_INSENSITIVE)
    c = make_insensitive_color (c, ctype);
  if ((state & STATE_PRELIGHT) &&
      !(state & STATE_INSENSITIVE))     /* ignore prelight if insensitive */
    c = make_prelight_color (c, ctype);
  return c;
}

Color
ColorScheme::generic_color (Color source_color) const
{
  return source_color;
}

const ColorScheme&
ColorScheme::default_scheme ()
{
  static const class DefaultColorScheme : public virtual ColorScheme {
    virtual Color
    make_color (ColorType color_type) const
    {
      Color c;
#if 1
      switch (color_type)
        {
        default:
        case COLOR_NONE:                    c = 0x00000000; break;
        case COLOR_FOREGROUND:              c = 0xff000000; break;
        case COLOR_BACKGROUND:              c = 0xffc0c0c0; break;
        case COLOR_FOCUS:                   c = 0xff000060; break;
        case COLOR_DEFAULT:                 c = 0xffd0d000; break;
        case COLOR_LIGHT_GLINT:             c = 0xffe0e0e0; break;
        case COLOR_LIGHT_SHADOW:            c = 0xffb0b0b0; break;
        case COLOR_DARK_GLINT:              c = 0xffb0b0b0; break;
        case COLOR_DARK_SHADOW:             c = 0xff808080; break;
        }
#elif 0
      switch (color_type)
        {
          double hue, saturation, value;
        default:
        case COLOR_NONE:                    c = 0x00000000; break;
        case COLOR_FOREGROUND:              c = 0xff000000; break;
        case COLOR_BACKGROUND:              c = 0xff6060c0; break;
        case COLOR_FOCUS:                   c = 0xff000000; break;
        case COLOR_DEFAULT:                 c = 0xffd0d000; break;
        case COLOR_LIGHT_GLINT:
          c = make_color (COLOR_BACKGROUND);
          c.get_hsv (&hue, &saturation, &value);
          value *= 1.3;
          c.set_hsv (hue, saturation, value);
          break;
        case COLOR_LIGHT_SHADOW:
          c = make_color (COLOR_BACKGROUND);
          c.get_hsv (&hue, &saturation, &value);
          value *= 1.15;
          c.set_hsv (hue, saturation, value);
          break;
        case COLOR_DARK_GLINT:
          c = make_color (COLOR_BACKGROUND);
          c.get_hsv (&hue, &saturation, &value);
          value *= 0.8;
          c.set_hsv (hue, saturation, value);
          break;
        case COLOR_DARK_SHADOW:
          c = make_color (COLOR_BACKGROUND);
          c.get_hsv (&hue, &saturation, &value);
          value *= 0.7;
          c.set_hsv (hue, saturation, value);
          break;
        }
#endif
      return Color (c);
    }
  } default_color_scheme;
  return default_color_scheme;
}

Appearance::Appearance (const String &name) :
  m_name (name)
{}

Style*
Appearance::create_style (const String &style_name)
{
  Style *style = m_styles[style_name];
  if (style)
    style->ref();
  else
    style = new Style (*this, "normal");
  return style;
}

void
Appearance::register_style (Style &style)
{
  Style *old = m_styles[style.name()];
  if (!old)
    ref();
  m_styles[style.name()] = &style;
}

void
Appearance::unregister_style (Style &style)
{
  Style *old = m_styles[style.name()];
  if (old == &style)
    {
      m_styles[style.name()] = NULL;
      unref();
    }
}

Appearance::~Appearance ()
{
  for (map<String,Style*>::iterator it = m_styles.begin(); it != m_styles.end(); it++)
    if (it->second)
      warning ("leaking: (Style*) %p", (Style*) it->second);
}

Appearance*
Appearance::create_default ()
{
  static Appearance *default_appearance = NULL;
  if (!default_appearance)
    {
      default_appearance = new Appearance ("default");
      default_appearance->ref_sink();
    }
  return ref (default_appearance);
}

Appearance*
Appearance::create_named (const String   &name)
{
  return create_default();
}

} // Rapicorn
<commit_msg>Made default color scheme warmer and increased border constrast.<commit_after>/* Rapicorn
 * Copyright (C) 2005 Tim Janik
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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.
 *
 * A copy of the GNU Lesser General Public License should ship along
 * with this library; if not, see http://www.gnu.org/copyleft/.
 */
#include "appearance.hh"

namespace Rapicorn {

const Style::ColorSchemeKind &Style::STANDARD = *(ColorSchemeKind*) 0xC0FFEE41;
const Style::ColorSchemeKind &Style::SELECTED = *(ColorSchemeKind*) 0xC0FFEE42;
const Style::ColorSchemeKind &Style::INPUT = *(ColorSchemeKind*) 0xC0FFEE43;

Style::Style (Appearance     &appearance,
              const String   &name) :
  m_appearance (appearance),
  m_name (name)
{
  m_appearance.register_style (*this);
}

Style*
Style::create_style (const String   &style_name)
{
  return m_appearance.create_style (style_name);
}

const ColorScheme&
Style::color_scheme (const ColorSchemeKind &kind) const
{
  return ColorScheme::default_scheme();
}

Color
Style::standard_color (StateType      state,
                       ColorType      color_type) const
{
  return color_scheme (STANDARD).make_color (color_type);
}

Color
Style::selected_color (StateType      state,
                       ColorType      color_type) const
{
  return color_scheme (SELECTED).make_color (color_type);
}

Color
Style::input_color (StateType      state,
                    ColorType      color_type) const
{
  return color_scheme (INPUT).make_color (color_type);
}

Color
Style::resolve_color (const String &color_name,
                      StateType     state,
                      ColorType     color_type)
{
  EnumTypeColorType ect;
  if (color_name[0] == '#')
    {
      uint32 argb = string_to_int (&color_name[1], 16);
      /* invert alpha */
      Color c (argb);
      c.alpha (0xff - c.alpha());
      return c; // return argb;
    }
  const EnumClass::Value *value = ect.find_first (color_name);
  if (value)
    return standard_color (state, ColorType (value->value));
  else
    {
      Color parsed_color = Color::from_name (color_name);
      if (!parsed_color)
        parsed_color = standard_color (state, color_type);
      return parsed_color;
    }
}

Style::~Style ()
{
  m_appearance.unregister_style (*this);
}

Color
ColorScheme::make_light_color (Color source_color) const
{
  Color c = source_color;
  double hue, saturation, value;
  c.get_hsv (&hue, &saturation, &value);
  value *= 1.1;
  c.set_hsv (hue, saturation, value);
  return c;
}

Color
ColorScheme::make_dark_color (Color source_color) const
{
  Color c = source_color;
  double hue, saturation, value;
  c.get_hsv (&hue, &saturation, &value);
  value *= 0.9;
  c.set_hsv (hue, saturation, value);
  return c;
}

Color
ColorScheme::make_insensitive_color (Color     source_color,
                                     ColorType ctype) const
{
  Color c = source_color;
  double hue, saturation, value;
  c.get_hsv (&hue, &saturation, &value);
  saturation *= 0.8;
  value *= 1.075;
  c.set_hsv (hue, saturation, MIN (1, value));
  return c;
}

Color
ColorScheme::make_prelight_color (Color     source_color,
                                  ColorType ctype) const
{
  Color c = source_color;
  switch (ctype)
    {
    case COLOR_FOREGROUND:
    case COLOR_FOCUS:
    case COLOR_DEFAULT:
      return c;
    default: ;
    }
  double hue, saturation, value;
  c.get_hsv (&hue, &saturation, &value);
  saturation *= 1.2;
  c.set_hsv (hue, MIN (1, saturation), value);
  return c;
}

Color
ColorScheme::make_impressed_color (Color     source_color,
                                   ColorType ctype) const
{
  Color c = source_color;
  switch (ctype)
    {
    case COLOR_FOREGROUND:
    case COLOR_FOCUS:
    case COLOR_DEFAULT:
      return c;
    default: ;
    }
  double hue, saturation, value;
  c.get_hsv (&hue, &saturation, &value);
  value *= 0.8;
  c.set_hsv (hue, saturation, value);
  return c;
}

Color
ColorScheme::make_focus_state_color (Color     source_color,
                                     ColorType ctype) const
{
  Color c = source_color;
  return c;
}

Color
ColorScheme::make_default_state_color (Color     source_color,
                                       ColorType ctype) const
{
  Color c = source_color;
  return c;
}

Color
ColorScheme::make_state_color (StateType      state,
                               Color          color,
                               ColorType      ctype) const
{
  Color c = color;
  if (state & STATE_IMPRESSED)
    c = make_impressed_color (c, ctype);
  if (state & STATE_DEFAULT)
    c = make_default_state_color (c, ctype);
  if (state & STATE_FOCUS)
    c = make_focus_state_color (c, ctype);
  if (state & STATE_INSENSITIVE)
    c = make_insensitive_color (c, ctype);
  if ((state & STATE_PRELIGHT) &&
      !(state & STATE_INSENSITIVE))     /* ignore prelight if insensitive */
    c = make_prelight_color (c, ctype);
  return c;
}

Color
ColorScheme::generic_color (Color source_color) const
{
  return source_color;
}

const ColorScheme&
ColorScheme::default_scheme ()
{
  static const class DefaultColorScheme : public virtual ColorScheme {
    virtual Color
    make_color (ColorType color_type) const
    {
      Color c;
#if 1
      switch (color_type)
        {
        default:
        case COLOR_NONE:                    c = 0x00000000; break;
        case COLOR_FOREGROUND:              c = 0xff000000; break;
        case COLOR_BACKGROUND:              c = 0xffdfdcd8; break;
        case COLOR_FOCUS:                   c = 0xff000060; break;
        case COLOR_DEFAULT:                 c = 0xffd0d000; break;
        case COLOR_LIGHT_GLINT:             c = 0xffefece8; break;
        case COLOR_LIGHT_SHADOW:            c = 0xffcfccc8; break;
        case COLOR_DARK_GLINT:              c = 0xffafaca8; break;
        case COLOR_DARK_SHADOW:             c = 0xff8f8c88; break;
        }
#elif 0
      switch (color_type)
        {
          double hue, saturation, value;
        default:
        case COLOR_NONE:                    c = 0x00000000; break;
        case COLOR_FOREGROUND:              c = 0xff000000; break;
        case COLOR_BACKGROUND:              c = 0xff6060c0; break;
        case COLOR_FOCUS:                   c = 0xff000000; break;
        case COLOR_DEFAULT:                 c = 0xffd0d000; break;
        case COLOR_LIGHT_GLINT:
          c = make_color (COLOR_BACKGROUND);
          c.get_hsv (&hue, &saturation, &value);
          value *= 1.3;
          c.set_hsv (hue, saturation, value);
          break;
        case COLOR_LIGHT_SHADOW:
          c = make_color (COLOR_BACKGROUND);
          c.get_hsv (&hue, &saturation, &value);
          value *= 1.15;
          c.set_hsv (hue, saturation, value);
          break;
        case COLOR_DARK_GLINT:
          c = make_color (COLOR_BACKGROUND);
          c.get_hsv (&hue, &saturation, &value);
          value *= 0.8;
          c.set_hsv (hue, saturation, value);
          break;
        case COLOR_DARK_SHADOW:
          c = make_color (COLOR_BACKGROUND);
          c.get_hsv (&hue, &saturation, &value);
          value *= 0.7;
          c.set_hsv (hue, saturation, value);
          break;
        }
#endif
      return Color (c);
    }
  } default_color_scheme;
  return default_color_scheme;
}

Appearance::Appearance (const String &name) :
  m_name (name)
{}

Style*
Appearance::create_style (const String &style_name)
{
  Style *style = m_styles[style_name];
  if (style)
    style->ref();
  else
    style = new Style (*this, "normal");
  return style;
}

void
Appearance::register_style (Style &style)
{
  Style *old = m_styles[style.name()];
  if (!old)
    ref();
  m_styles[style.name()] = &style;
}

void
Appearance::unregister_style (Style &style)
{
  Style *old = m_styles[style.name()];
  if (old == &style)
    {
      m_styles[style.name()] = NULL;
      unref();
    }
}

Appearance::~Appearance ()
{
  for (map<String,Style*>::iterator it = m_styles.begin(); it != m_styles.end(); it++)
    if (it->second)
      warning ("leaking: (Style*) %p", (Style*) it->second);
}

Appearance*
Appearance::create_default ()
{
  static Appearance *default_appearance = NULL;
  if (!default_appearance)
    {
      default_appearance = new Appearance ("default");
      default_appearance->ref_sink();
    }
  return ref (default_appearance);
}

Appearance*
Appearance::create_named (const String   &name)
{
  return create_default();
}

} // Rapicorn
<|endoftext|>


<commit_before>#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>

#include <tr1/unordered_set>

#include <boost/scoped_ptr.hpp>
#include <boost/filesystem.hpp>

#include <AlpinoCorpus/CorpusReader.hh>
#include <AlpinoCorpus/DbCorpusWriter.hh>
#include <AlpinoCorpus/Error.hh>

#include <iostream>
#include <stdexcept>

#include "ProgramOptions.hh"

using alpinocorpus::CorpusReader;
using alpinocorpus::DbCorpusWriter;

namespace bf = boost::filesystem;

void listCorpus(std::string const &treebank, std::string const &query)
{
  boost::scoped_ptr<CorpusReader> rd(CorpusReader::open(treebank));
  CorpusReader::EntryIterator i, end(rd->end());

  if (query.empty())
    i = rd->begin();
  else
    i = rd->query(CorpusReader::XPATH, query);

  std::copy(i, end, std::ostream_iterator<std::string>(std::cout, "\n"));
}

void usage(std::string const &programName)
{
    std::cerr << "Usage: " << programName << " [OPTION] treebank" <<
      std::endl << std::endl <<
      "  -c filename\tCreate a Dact dbxml archive" << std::endl <<
      "  -q query\tFilter the treebank using the given query" << std::endl << std::endl;
}

void writeDactCorpus(std::string const &treebank, std::string const &treebankOut,
    std::string const &query)
{
  if (bf::equivalent(treebankOut, treebank))
    throw std::runtime_error("Attempting to write to the source treebank.");

  boost::scoped_ptr<CorpusReader> rd(CorpusReader::open(treebank));

  DbCorpusWriter wr(treebankOut, true);
  CorpusReader::EntryIterator i, end(rd->end());
  if (query.empty())
    i = rd->begin();
  else
    i = rd->query(CorpusReader::XPATH, query);

  std::tr1::unordered_set<std::string> seen;
  for (; i != end; ++i)
    if (seen.find(*i) == seen.end()) {
        wr.write(*i, rd->read(*i));
      seen.insert(*i);
    }
}

int main(int argc, char *argv[])
{
  ProgramOptions opts(argc, const_cast<char const **>(argv), "c:lq:");

  if (opts.arguments().size() != 1)
  {
    usage(opts.programName());
    return 1;
  }

  if (opts.option('c') && opts.option('l')) {
    std::cerr << opts.programName() <<
      ": the '-c' and '-l' options cannot be used simultaneously." <<
      std::endl;
    return 1;
  }

  if (!opts.option('c') && !opts.option('l')) {
    std::cerr << opts.programName() <<
    ": either the '-c' or '-l' option should be used." <<
    std::endl;
    return 1;
  }

  std::string query;
  if (opts.option('q'))
    query = opts.optionValue('q');

  if (opts.option('c')) {
    try {
        std::string treebank = opts.arguments().at(0);
        std::string treebankOut = opts.optionValue('c').c_str();
      writeDactCorpus(treebank, treebankOut, query);
    } catch (std::runtime_error const &e) {
        std::cerr << opts.programName() <<
        ": error creating Dact treebank: " << e.what() << std::endl;
        return 1;
    }
  }

  if (opts.option('l')) {
    try {
        std::string treebank = opts.arguments().at(0).c_str();
        listCorpus(treebank, query);
    } catch (std::runtime_error const &e) {
        std::cerr << opts.programName() <<
        ": error listing treebank: " << e.what() << std::endl;
        return 1;
    }
  }

  return 0;
}
<commit_msg>Document the '-l' option of alpinocorpus-act.<commit_after>#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>

#include <tr1/unordered_set>

#include <boost/scoped_ptr.hpp>
#include <boost/filesystem.hpp>

#include <AlpinoCorpus/CorpusReader.hh>
#include <AlpinoCorpus/DbCorpusWriter.hh>
#include <AlpinoCorpus/Error.hh>

#include <iostream>
#include <stdexcept>

#include "ProgramOptions.hh"

using alpinocorpus::CorpusReader;
using alpinocorpus::DbCorpusWriter;

namespace bf = boost::filesystem;

void listCorpus(std::string const &treebank, std::string const &query)
{
  boost::scoped_ptr<CorpusReader> rd(CorpusReader::open(treebank));
  CorpusReader::EntryIterator i, end(rd->end());

  if (query.empty())
    i = rd->begin();
  else
    i = rd->query(CorpusReader::XPATH, query);

  std::copy(i, end, std::ostream_iterator<std::string>(std::cout, "\n"));
}

void usage(std::string const &programName)
{
    std::cerr << "Usage: " << programName << " [OPTION] treebank" <<
      std::endl << std::endl <<
      "  -c filename\tCreate a Dact dbxml archive" << std::endl <<
      "  -l\t\tList the entries of a treebank" << std::endl <<
      "  -q query\tFilter the treebank using the given query" << std::endl << std::endl;
}

void writeDactCorpus(std::string const &treebank, std::string const &treebankOut,
    std::string const &query)
{
  if (bf::equivalent(treebankOut, treebank))
    throw std::runtime_error("Attempting to write to the source treebank.");

  boost::scoped_ptr<CorpusReader> rd(CorpusReader::open(treebank));

  DbCorpusWriter wr(treebankOut, true);
  CorpusReader::EntryIterator i, end(rd->end());
  if (query.empty())
    i = rd->begin();
  else
    i = rd->query(CorpusReader::XPATH, query);

  std::tr1::unordered_set<std::string> seen;
  for (; i != end; ++i)
    if (seen.find(*i) == seen.end()) {
        wr.write(*i, rd->read(*i));
      seen.insert(*i);
    }
}

int main(int argc, char *argv[])
{
  ProgramOptions opts(argc, const_cast<char const **>(argv), "c:lq:");

  if (opts.arguments().size() != 1)
  {
    usage(opts.programName());
    return 1;
  }

  if (opts.option('c') && opts.option('l')) {
    std::cerr << opts.programName() <<
      ": the '-c' and '-l' options cannot be used simultaneously." <<
      std::endl;
    return 1;
  }

  if (!opts.option('c') && !opts.option('l')) {
    std::cerr << opts.programName() <<
    ": either the '-c' or '-l' option should be used." <<
    std::endl;
    return 1;
  }

  std::string query;
  if (opts.option('q'))
    query = opts.optionValue('q');

  if (opts.option('c')) {
    try {
        std::string treebank = opts.arguments().at(0);
        std::string treebankOut = opts.optionValue('c').c_str();
      writeDactCorpus(treebank, treebankOut, query);
    } catch (std::runtime_error const &e) {
        std::cerr << opts.programName() <<
        ": error creating Dact treebank: " << e.what() << std::endl;
        return 1;
    }
  }

  if (opts.option('l')) {
    try {
        std::string treebank = opts.arguments().at(0).c_str();
        listCorpus(treebank, query);
    } catch (std::runtime_error const &e) {
        std::cerr << opts.programName() <<
        ": error listing treebank: " << e.what() << std::endl;
        return 1;
    }
  }

  return 0;
}
<|endoftext|>