<commit_before>#include "PropertyWidgetEx.h"

#include <QMouseEvent>
#include <QApplication>
#include <QMimeData>
#include <QDrag>
#include <QShortcut>
#include <QClipboard>
#include <QAction>
#include <QDebug>

static const QString kTextPlain = "text/plain";
const QString *pTextPlain = &kTextPlain;

QtnPropertyWidgetEx::QtnPropertyWidgetEx(QWidget *parent)
	: QtnPropertyWidget(parent)
	, dragged_property(nullptr)
	, drop_action(Qt::IgnoreAction)
	, can_remove(false)
{
	for (auto child : children())
	{
		auto vbox = dynamic_cast<QVBoxLayout *>(child);

		if (nullptr != vbox)
		{
			vbox->setContentsMargins(0, 0, 0, 0);
			vbox->setMargin(0);
			vbox->setSpacing(0);
		}
	}

	setAcceptDrops(true);
	propertyView()->installEventFilter(this);
}

void QtnPropertyWidgetEx::connectRemoveAction(QAction *action, bool connect)
{
	internalConnect(action, &QtnPropertyWidgetEx::removeActiveProperty, connect);
}

void QtnPropertyWidgetEx::connectCutAction(QAction *action, bool connect)
{
	internalConnect(action, &QtnPropertyWidgetEx::cutToClipboard, connect);
}

void QtnPropertyWidgetEx::connectCopyAction(QAction *action, bool connect)
{
	internalConnect(action, &QtnPropertyWidgetEx::copyToClipboard, connect);
}

void QtnPropertyWidgetEx::connectPasteAction(QAction *action, bool connect)
{
	internalConnect(action, &QtnPropertyWidgetEx::pasteFromClipboard, connect);
}

bool QtnPropertyWidgetEx::canRemoveActiveProperty()
{
	return canRemoveProperty(propertyView()->activeProperty());
}

bool QtnPropertyWidgetEx::canRemoveProperty(QtnPropertyBase *)
{
	return false;
}

bool QtnPropertyWidgetEx::canCutToClipboard()
{
	return false;
}

bool QtnPropertyWidgetEx::canCopyToClipboard()
{
	return (nullptr != propertyView()->activeProperty());
}

bool QtnPropertyWidgetEx::canPasteFromClipboard()
{
	return dataHasSupportedFormats(QApplication::clipboard()->mimeData())
		&& (nullptr != propertyView()->activeProperty());
}

bool QtnPropertyWidgetEx::dataHasSupportedFormats(const QMimeData *data)
{
	return (nullptr != data && data->hasFormat(kTextPlain));
}

void QtnPropertyWidgetEx::removeActiveProperty()
{
	removeProperty(propertyView()->activeProperty());
}

void QtnPropertyWidgetEx::cutToClipboard()
{
	copyToClipboard();
	removeActiveProperty();
}

void QtnPropertyWidgetEx::copyToClipboard()
{
	auto property = propertyView()->activeProperty();
	if (nullptr != property)
	{
		auto mime = getPropertyDataForAction(property, Qt::IgnoreAction);
		if (nullptr != mime)
			QApplication::clipboard()->setMimeData(mime);
	}
}

void QtnPropertyWidgetEx::pasteFromClipboard()
{
	auto data = QApplication::clipboard()->mimeData();
	if (dataHasSupportedFormats(data))
	{
		applyPropertyData(data,
						  propertyView()->activeProperty(),
						  QtnApplyPosition::Over);
	}
}

void QtnPropertyWidgetEx::removeProperty(QtnPropertyBase *)
{
	// do nothing
}

QMimeData *QtnPropertyWidgetEx::getPropertyDataForAction(QtnPropertyBase *property,
														 Qt::DropAction)
{
	QString str;
	if (property->toStr(str))
	{
		auto mime = new QMimeData;
		mime->setText(str);
		return mime;
	}

	return nullptr;
}

bool QtnPropertyWidgetEx::applyPropertyData(const QMimeData *data,
											QtnPropertyBase *destination,
											QtnApplyPosition)
{
	if (nullptr != destination)
	{
		Q_ASSERT(nullptr != data);
		return destination->fromStr(data->text());
	}

	return false;
}

bool QtnPropertyWidgetEx::eventFilter(QObject *obj, QEvent *event)
{
	switch (event->type())
	{
		case QEvent::MouseButtonPress:
		{
			auto mevent = static_cast<QMouseEvent *>(event);
			if (mevent->button() == Qt::LeftButton)
			{
				drag_start_pos = mevent->pos();
				dragged_property = propertyView()->getPropertyAt(drag_start_pos);
				can_remove = canRemoveProperty(dragged_property);
				return true;
			}
		}	break;

		case QEvent::MouseMove:
		{
			auto mevent = static_cast<QMouseEvent *>(event);
			if (nullptr != dragged_property
			&&	0 != (mevent->buttons() & Qt::LeftButton))
			{
				if ((mevent->pos() - drag_start_pos).manhattanLength()
					 < QApplication::startDragDistance())
				{
					drop_action = Qt::IgnoreAction;
					if (dragAndDrop())
						return true;
				}
			}
		}	break;

		default:
			break;
	}

	return QtnPropertyWidget::eventFilter(obj, event);
}

void QtnPropertyWidgetEx::dragEnterEvent(QDragEnterEvent *event)
{
	if (dataHasSupportedFormats(event->mimeData()))
		event->acceptProposedAction();
}

void QtnPropertyWidgetEx::dragMoveEvent(QDragMoveEvent *event)
{
	if (Qt::ControlModifier == QApplication::keyboardModifiers()
	||	!can_remove)
	{
		event->setDropAction(Qt::CopyAction);
	} else
	{
		event->setDropAction(Qt::MoveAction);
	}

	drop_action = event->dropAction();

	event->accept();
}

void QtnPropertyWidgetEx::dropEvent(QDropEvent *event)
{
	switch (event->dropAction())
	{
		case Qt::MoveAction:
		case Qt::CopyAction:
		{
			auto view = propertyView();
			auto pos = view->mapFrom(this, event->pos());
			QRect rect;
			auto property = view->getPropertyAt(pos, &rect);
			int part_height = view->itemHeight() / 4;

			QtnApplyPosition apply_position;
			if (QRect(rect.left(), rect.top(),
					  rect.width(), part_height).contains(pos))
				apply_position = QtnApplyPosition::Before;
			else if (QRect(rect.left(), rect.bottom() - part_height,
						   rect.width(), part_height).contains(pos))
				apply_position = QtnApplyPosition::After;
			else
				apply_position = QtnApplyPosition::Over;

			auto data = event->mimeData();
			if (property != dragged_property
			&&	dataHasSupportedFormats(data)
			&&	applyPropertyData(data, property, apply_position))
				event->accept();
		}	break;

		default:
			break;
	}
}

bool QtnPropertyWidgetEx::dragAndDrop()
{
	auto data = getPropertyDataForAction(dragged_property, Qt::CopyAction);
	if (nullptr != data)
	{
		auto drag = new QDrag(this);

		drag->setMimeData(data);

		// TODO generate cursor

		drag->exec(Qt::CopyAction | Qt::MoveAction);

		if (Qt::MoveAction == drop_action)
			removeProperty(dragged_property);
		return true;
	}

	return false;
}

void QtnPropertyWidgetEx::internalConnect(QAction *action,
										  void (QtnPropertyWidgetEx::*slot)(),
										  bool connect)
{
	if (connect)
		QObject::connect(action, &QAction::triggered, this, slot);
	else
		QObject::disconnect(action, &QAction::triggered, this, slot);
}

<commit_msg>Drag & Drop bug fixes<commit_after>#include "PropertyWidgetEx.h"

#include <QMouseEvent>
#include <QApplication>
#include <QMimeData>
#include <QDrag>
#include <QShortcut>
#include <QClipboard>
#include <QAction>
#include <QDebug>

static const QString kTextPlain = "text/plain";
const QString *pTextPlain = &kTextPlain;

QtnPropertyWidgetEx::QtnPropertyWidgetEx(QWidget *parent)
	: QtnPropertyWidget(parent)
	, dragged_property(nullptr)
	, drop_action(Qt::IgnoreAction)
	, can_remove(false)
{
	for (auto child : children())
	{
		auto vbox = dynamic_cast<QVBoxLayout *>(child);

		if (nullptr != vbox)
		{
			vbox->setContentsMargins(0, 0, 0, 0);
			vbox->setMargin(0);
			vbox->setSpacing(0);
		}
	}

	setAcceptDrops(true);
	propertyView()->installEventFilter(this);
}

void QtnPropertyWidgetEx::connectRemoveAction(QAction *action, bool connect)
{
	internalConnect(action, &QtnPropertyWidgetEx::removeActiveProperty, connect);
}

void QtnPropertyWidgetEx::connectCutAction(QAction *action, bool connect)
{
	internalConnect(action, &QtnPropertyWidgetEx::cutToClipboard, connect);
}

void QtnPropertyWidgetEx::connectCopyAction(QAction *action, bool connect)
{
	internalConnect(action, &QtnPropertyWidgetEx::copyToClipboard, connect);
}

void QtnPropertyWidgetEx::connectPasteAction(QAction *action, bool connect)
{
	internalConnect(action, &QtnPropertyWidgetEx::pasteFromClipboard, connect);
}

bool QtnPropertyWidgetEx::canRemoveActiveProperty()
{
	return canRemoveProperty(propertyView()->activeProperty());
}

bool QtnPropertyWidgetEx::canRemoveProperty(QtnPropertyBase *)
{
	return false;
}

bool QtnPropertyWidgetEx::canCutToClipboard()
{
	return false;
}

bool QtnPropertyWidgetEx::canCopyToClipboard()
{
	return (nullptr != propertyView()->activeProperty());
}

bool QtnPropertyWidgetEx::canPasteFromClipboard()
{
	return dataHasSupportedFormats(QApplication::clipboard()->mimeData())
		&& (nullptr != propertyView()->activeProperty());
}

bool QtnPropertyWidgetEx::dataHasSupportedFormats(const QMimeData *data)
{
	return (nullptr != data && data->hasFormat(kTextPlain));
}

void QtnPropertyWidgetEx::removeActiveProperty()
{
	removeProperty(propertyView()->activeProperty());
}

void QtnPropertyWidgetEx::cutToClipboard()
{
	copyToClipboard();
	removeActiveProperty();
}

void QtnPropertyWidgetEx::copyToClipboard()
{
	auto property = propertyView()->activeProperty();
	if (nullptr != property)
	{
		auto mime = getPropertyDataForAction(property, Qt::IgnoreAction);
		if (nullptr != mime)
			QApplication::clipboard()->setMimeData(mime);
	}
}

void QtnPropertyWidgetEx::pasteFromClipboard()
{
	auto data = QApplication::clipboard()->mimeData();
	if (dataHasSupportedFormats(data))
	{
		applyPropertyData(data,
						  propertyView()->activeProperty(),
						  QtnApplyPosition::Over);
	}
}

void QtnPropertyWidgetEx::removeProperty(QtnPropertyBase *)
{
	// do nothing
}

QMimeData *QtnPropertyWidgetEx::getPropertyDataForAction(QtnPropertyBase *property,
														 Qt::DropAction)
{
	QString str;
	if (property->toStr(str))
	{
		auto mime = new QMimeData;
		mime->setText(str);
		return mime;
	}

	return nullptr;
}

bool QtnPropertyWidgetEx::applyPropertyData(const QMimeData *data,
											QtnPropertyBase *destination,
											QtnApplyPosition)
{
	if (nullptr != destination)
	{
		Q_ASSERT(nullptr != data);
		return destination->fromStr(data->text());
	}

	return false;
}

bool QtnPropertyWidgetEx::eventFilter(QObject *obj, QEvent *event)
{
	switch (event->type())
	{
		case QEvent::MouseButtonPress:
		{
			auto mevent = static_cast<QMouseEvent *>(event);
			if (mevent->button() == Qt::LeftButton)
			{
				drag_start_pos = mevent->pos();
				dragged_property = propertyView()->getPropertyAt(drag_start_pos);
				can_remove = canRemoveProperty(dragged_property);
				return true;
			}
		}	break;

		case QEvent::MouseMove:
		{
			auto mevent = static_cast<QMouseEvent *>(event);
			if (nullptr != dragged_property
			&&	0 != (mevent->buttons() & Qt::LeftButton))
			{
				if ((mevent->pos() - drag_start_pos).manhattanLength()
					 < QApplication::startDragDistance())
				{
					drop_action = Qt::IgnoreAction;
					if (dragAndDrop())
						return true;
				}
			}
		}	break;

		default:
			break;
	}

	return QtnPropertyWidget::eventFilter(obj, event);
}

void QtnPropertyWidgetEx::dragEnterEvent(QDragEnterEvent *event)
{
	if (dataHasSupportedFormats(event->mimeData()))
		event->acceptProposedAction();
}

void QtnPropertyWidgetEx::dragMoveEvent(QDragMoveEvent *event)
{
	if (Qt::ControlModifier == QApplication::keyboardModifiers()
	||	!can_remove)
	{
		event->setDropAction(Qt::CopyAction);
		drop_action = Qt::CopyAction;
	} else
	{
		event->setDropAction(Qt::MoveAction);
		drop_action = Qt::MoveAction;
	}

	event->accept();
}

void QtnPropertyWidgetEx::dropEvent(QDropEvent *event)
{
	switch (event->dropAction())
	{
		case Qt::MoveAction:
		case Qt::CopyAction:
		{
			auto view = propertyView();
			auto pos = view->mapFrom(this, event->pos());
			QRect rect;
			auto property = view->getPropertyAt(pos, &rect);
			int part_height = view->itemHeight() / 4;

			QtnApplyPosition apply_position;
			if (QRect(rect.left(), rect.top(),
					  rect.width(), part_height).contains(pos))
				apply_position = QtnApplyPosition::Before;
			else if (QRect(rect.left(), rect.bottom() - part_height,
						   rect.width(), part_height).contains(pos))
				apply_position = QtnApplyPosition::After;
			else
				apply_position = QtnApplyPosition::Over;

			if (property == dragged_property
			||	nullptr == property)
			{
				dragged_property = nullptr;
			}

			auto data = event->mimeData();
			if (nullptr != dragged_property
			&&	dataHasSupportedFormats(data)
			&&	applyPropertyData(data, property, apply_position))
				event->accept();
		}	break;

		default:
			break;
	}
}

bool QtnPropertyWidgetEx::dragAndDrop()
{
	auto data = getPropertyDataForAction(dragged_property, Qt::CopyAction);
	if (nullptr != data)
	{
		auto drag = new QDrag(this);

		drag->setMimeData(data);

		// TODO generate cursor

		drag->exec(Qt::CopyAction | Qt::MoveAction);

		if (nullptr != dragged_property)
		{
			if (Qt::MoveAction == drop_action)
				removeProperty(dragged_property);
		}
		return true;
	}

	return false;
}

void QtnPropertyWidgetEx::internalConnect(QAction *action,
										  void (QtnPropertyWidgetEx::*slot)(),
										  bool connect)
{
	if (connect)
		QObject::connect(action, &QAction::triggered, this, slot);
	else
		QObject::disconnect(action, &QAction::triggered, this, slot);
}

<|endoftext|>


<commit_before>#include "ScriptObject.h"
#include "../Scene.h"
#include "../Application.h"

#include <regex>

namespace fse
{
	ScriptObject::ScriptObject(const std::string& scriptName) : FSEObject(), script_name_(scriptName)
	{

	}

	ScriptObject::ScriptObject(const std::string& scriptName, const sf::Vector2f& spawnPos) : FSEObject(spawnPos), script_name_(scriptName)
	{
	}

	void ScriptObject::spawned()
	{
		try {
			auto chai = scene_->getApplication()->getChai();
			chai->use(script_name_);

			std::smatch match;
			std::regex_search(script_name_, match, std::regex(R"((?!.*(?=\/|\\)).*(?=\.chai))"));

			const std::string classname = match.str();

			chai->set_global(chaiscript::var(std::ref(*scene_)), "scriptObjectScene");
			script_child_ = chai->eval(std::string(
				classname + "(scriptObjectScene.getObjectWithId("+  std::to_string(getID()) + "));"));

			initialized_ = true;

			if (spawnedFun != nullptr)
				spawnedFun(script_child_);
		}
		catch (const std::exception& e)
		{
			std::cerr << e.what() << "\n";
			FSEObject::destroy();
		}
	}

	void ScriptObject::onDespawn()
	{
		try {
			if (onDespawnFun != nullptr)
				onDespawnFun(script_child_);
		}
		catch (const std::exception& e)
		{
			std::cerr << e.what() << "\n";
		}
	}

	void ScriptObject::update(float deltaTime)
	{
		try {
			if (updateFun != nullptr)
				updateFun(script_child_, deltaTime);
		}
		catch (const std::exception& e)
		{
			std::cerr << e.what() << "\n";
		}
	}

	void ScriptObject::draw(sf::RenderTarget& target)
	{
		try
		{
			if (drawFun != nullptr)
				drawFun(script_child_, target);
		}
		catch (const std::exception& e)
		{
			std::cerr << e.what() << "\n";
		}
	}

	void ScriptObject::drawNormals(sf::RenderTarget& target)
	{
		try {
			if (drawNormalsFun != nullptr)
				drawNormalsFun(script_child_, target);
		}
		catch (const std::exception& e)
		{
			std::cerr << e.what() << "\n";
		}
	}

	void ScriptObject::drawSpecular(sf::RenderTarget& target)
	{
		try {
			if (drawSpecularFun != nullptr)
				drawSpecularFun(script_child_, target);
		}
		catch (const std::exception& e)
		{
			std::cerr << e.what() << "\n";
		}
	}

	void ScriptObject::setPosition(const sf::Vector2f position)
	{
		try {
			if (setPositionFun != nullptr)
				setPositionFun(script_child_, position);
		}
		catch (const std::exception& e)
		{
			std::cerr << e.what() << "\n";
		}
	}

	sf::Vector2f ScriptObject::getPosition()
	{
		try {
			if (getPositionFun != nullptr)
				return getPositionFun(script_child_);
		}
		catch (const std::exception& e)
		{
			std::cerr << e.what() << "\n";
		}
		return FSEObject::getPosition();
	}

	sf::FloatRect ScriptObject::GetAABBs() const
	{
		try {
			if (getAABBsFun != nullptr)
				return getAABBsFun(script_child_);
		}
		catch (const std::exception& e)
		{
			std::cerr << e.what() << "\n";
		}
		return FSEObject::GetAABBs();
	}

	void ScriptObject::BeginContact(FSEObject* otherObject, b2Contact* contact)
	{
		try {
			if (beginContactFun != nullptr)
				beginContactFun(script_child_, otherObject, contact);
		}
		catch (const std::exception& e)
		{
			std::cerr << e.what() << "\n";
		}
	}

	void ScriptObject::EndContact(FSEObject* otherObject, b2Contact* contact)
	{
		try {
			if (endContactFun != nullptr)
				endContactFun(script_child_, otherObject, contact);
		}
		catch (const std::exception& e)
		{
			std::cerr << e.what() << "\n";
		}
	}

	void ScriptObject::PreSolve(FSEObject* otherObject, b2Contact* contact, const b2Manifold* oldManifold)
	{
		try
		{
			if (preSolveFun != nullptr)
				preSolveFun(script_child_, otherObject, contact, oldManifold);
		}
		catch (const std::exception& e)
		{
			std::cerr << e.what() << "\n";
		}
	}

	void ScriptObject::PostSolve(FSEObject* otherObject, b2Contact* contact, const b2ContactImpulse* impulse)
	{
		try {
			if (postSolveFun != nullptr)
				postSolveFun(script_child_, otherObject, contact, impulse);
		}
		catch (const std::exception& e)
		{
			std::cerr << e.what() << "\n";
		}
	}

	bool ScriptObject::destroy()
	{
		try {
			if (destroyFun != nullptr)
				return destroyFun(script_child_);
		}
		catch (const std::exception& e)
		{
			std::cerr << e.what() << "\n";
		}
		return FSEObject::destroy();
	}

	void ScriptObject::BeginContactComponents(FSEObject* otherObject, b2Contact* contact)
	{
		try {
			if (beginContactComponentsFun != nullptr)
				beginContactComponentsFun(script_child_, otherObject, contact);
		}
		catch (const std::exception& e)
		{
			std::cerr << e.what() << "\n";
		}
	}

	void ScriptObject::EndContactComponents(FSEObject* otherObject, b2Contact* contact)
	{
		try {
			if (endContactComponentsFun != nullptr)
				endContactComponentsFun(script_child_, otherObject, contact);
		}
		catch (const std::exception& e)
		{
			std::cerr << e.what() << "\n";
		}
	}

	void ScriptObject::PreSolveComponents(FSEObject* otherObject, b2Contact* contact, const b2Manifold* oldManifold)
	{
		try {
		if (preSolveComponentsFun != nullptr)
			preSolveComponentsFun(script_child_, otherObject, contact, oldManifold);
		}
		catch (const std::exception& e)
		{
			std::cerr << e.what() << "\n";
		}
	}

	void ScriptObject::PostSolveComponents(FSEObject* otherObject, b2Contact* contact, const b2ContactImpulse* impulse)
	{
		try {
		if (postSolveComponentsFun != nullptr)
			postSolveComponentsFun(script_child_, otherObject, contact, impulse);
		}
		catch (const std::exception& e)
		{
			std::cerr << e.what() << "\n";
		}
	}

	FSE_CHAI_REGISTER(ScriptObject)
	{
		RegisterChaiUserTypeFromRTTR<ScriptObject>(chai);
		chai.add(chaiscript::base_class<fse::FSEObject, ScriptObject>());
		chai.add(chaiscript::constructor<ScriptObject(const std::string&)>(), "ScriptObject");
		chai.add(chaiscript::fun([](const ScriptObject* object)
		{
			return object->initialized_;
		}), "isInitialized");

		chai.add(chaiscript::fun([](const ScriptObject* object)
		{
			return object->script_name_;
		}), "getScriptName");

		chai.add(chaiscript::fun([](const ScriptObject* object)
		{
			return object->script_child_;
		}), "_child");

		chai.add(chaiscript::fun(&ScriptObject::spawnedFun), "spawnedCallback");
		chai.add(chaiscript::fun(&ScriptObject::onDespawnFun), "onDespawnCallback");

		chai.add(chaiscript::fun(&ScriptObject::updateFun), "updateCallback");
		chai.add(chaiscript::fun(&ScriptObject::drawFun), "drawCallback");
		chai.add(chaiscript::fun(&ScriptObject::drawNormalsFun), "drawNormalsCallback");
		chai.add(chaiscript::fun(&ScriptObject::drawSpecularFun), "drawSpecularCallback");

		chai.add(chaiscript::fun(&ScriptObject::setPositionFun), "setPositionCallback");
		chai.add(chaiscript::fun(&ScriptObject::getPositionFun), "getPositionCallback");
		chai.add(chaiscript::fun(&ScriptObject::getAABBsFun), "getAABBsCallback");

		chai.add(chaiscript::fun(&ScriptObject::beginContactFun), "beginContactCallback");
		chai.add(chaiscript::fun(&ScriptObject::endContactFun), "endContactCallback");

		chai.add(chaiscript::fun(&ScriptObject::preSolveFun), "preSolveCallback");
		chai.add(chaiscript::fun(&ScriptObject::postSolveFun), "postSolveCallback");

		chai.add(chaiscript::fun(&ScriptObject::destroyFun), "destroyCallback");

		chai.add(chaiscript::fun(&ScriptObject::beginContactComponentsFun), "beginContactComponentsCallback");
		chai.add(chaiscript::fun(&ScriptObject::endContactComponentsFun), "endContactComponentsCallback");

		chai.add(chaiscript::fun(&ScriptObject::preSolveComponentsFun), "preSolveComponentsCallback");
		chai.add(chaiscript::fun(&ScriptObject::postSolveComponentsFun), "postSolveComponentsCallback");

	}

}

#include <rttr/registration>
RTTR_REGISTRATION
{
	using namespace rttr;
	using namespace fse;
	registration::class_<ScriptObject>("fse::ScriptObject")
		.constructor<const std::string& >()
		(
			policy::ctor::as_std_shared_ptr,
			parameter_names("script name")
			)
		.constructor<const std::string&, const sf::Vector2f&>()
		(
			policy::ctor::as_std_shared_ptr,
			parameter_names("script name", "spawn position")
			)
		.property_readonly("script_name_", &ScriptObject::script_name_)
		.property_readonly("initialized_", &ScriptObject::initialized_)
		.property_readonly("script_child_", &ScriptObject::script_child_)
		;
}
<commit_msg>ScriptObject: cleanup<commit_after>#include "ScriptObject.h"
#include "../Scene.h"
#include "../Application.h"

#include <regex>

namespace fse
{
	ScriptObject::ScriptObject(const std::string& scriptName) : FSEObject(), script_name_(scriptName)
	{

	}

	ScriptObject::ScriptObject(const std::string& scriptName, const sf::Vector2f& spawnPos) : FSEObject(spawnPos), script_name_(scriptName)
	{
	}

	void ScriptObject::spawned()
	{
		try {
			auto chai = getChai();
			chai->use(script_name_);

			std::smatch match;
			std::regex_search(script_name_, match, std::regex(R"((?!.*(?=\/|\\)).*(?=\.chai))"));

			const std::string classname = match.str();

			chai->set_global(chaiscript::var(std::ref(*scene_)), "scriptObjectScene");
			script_child_ = chai->eval(std::string(
				classname + "(scriptObjectScene.getObjectWithId("+  std::to_string(getID()) + "));"));

			initialized_ = true;

			if (spawnedFun != nullptr)
				spawnedFun(script_child_);
		}
		catch (const std::exception& e)
		{
			std::cerr << e.what() << "\n";
			FSEObject::destroy();
		}
	}

	void ScriptObject::onDespawn()
	{
		try {
			if (onDespawnFun != nullptr)
				onDespawnFun(script_child_);
		}
		catch (const std::exception& e)
		{
			std::cerr << e.what() << "\n";
		}
	}

	void ScriptObject::update(float deltaTime)
	{
		try {
			if (updateFun != nullptr)
				updateFun(script_child_, deltaTime);
		}
		catch (const std::exception& e)
		{
			std::cerr << e.what() << "\n";
		}
	}

	void ScriptObject::draw(sf::RenderTarget& target)
	{
		try
		{
			if (drawFun != nullptr)
				drawFun(script_child_, target);
		}
		catch (const std::exception& e)
		{
			std::cerr << e.what() << "\n";
		}
	}

	void ScriptObject::drawNormals(sf::RenderTarget& target)
	{
		try {
			if (drawNormalsFun != nullptr)
				drawNormalsFun(script_child_, target);
		}
		catch (const std::exception& e)
		{
			std::cerr << e.what() << "\n";
		}
	}

	void ScriptObject::drawSpecular(sf::RenderTarget& target)
	{
		try {
			if (drawSpecularFun != nullptr)
				drawSpecularFun(script_child_, target);
		}
		catch (const std::exception& e)
		{
			std::cerr << e.what() << "\n";
		}
	}

	void ScriptObject::setPosition(const sf::Vector2f position)
	{
		try {
			if (setPositionFun != nullptr)
				setPositionFun(script_child_, position);
		}
		catch (const std::exception& e)
		{
			std::cerr << e.what() << "\n";
		}
	}

	sf::Vector2f ScriptObject::getPosition()
	{
		try {
			if (getPositionFun != nullptr)
				return getPositionFun(script_child_);
		}
		catch (const std::exception& e)
		{
			std::cerr << e.what() << "\n";
		}
		return FSEObject::getPosition();
	}

	sf::FloatRect ScriptObject::GetAABBs() const
	{
		try {
			if (getAABBsFun != nullptr)
				return getAABBsFun(script_child_);
		}
		catch (const std::exception& e)
		{
			std::cerr << e.what() << "\n";
		}
		return FSEObject::GetAABBs();
	}

	void ScriptObject::BeginContact(FSEObject* otherObject, b2Contact* contact)
	{
		try {
			if (beginContactFun != nullptr)
				beginContactFun(script_child_, otherObject, contact);
		}
		catch (const std::exception& e)
		{
			std::cerr << e.what() << "\n";
		}
	}

	void ScriptObject::EndContact(FSEObject* otherObject, b2Contact* contact)
	{
		try {
			if (endContactFun != nullptr)
				endContactFun(script_child_, otherObject, contact);
		}
		catch (const std::exception& e)
		{
			std::cerr << e.what() << "\n";
		}
	}

	void ScriptObject::PreSolve(FSEObject* otherObject, b2Contact* contact, const b2Manifold* oldManifold)
	{
		try
		{
			if (preSolveFun != nullptr)
				preSolveFun(script_child_, otherObject, contact, oldManifold);
		}
		catch (const std::exception& e)
		{
			std::cerr << e.what() << "\n";
		}
	}

	void ScriptObject::PostSolve(FSEObject* otherObject, b2Contact* contact, const b2ContactImpulse* impulse)
	{
		try {
			if (postSolveFun != nullptr)
				postSolveFun(script_child_, otherObject, contact, impulse);
		}
		catch (const std::exception& e)
		{
			std::cerr << e.what() << "\n";
		}
	}

	bool ScriptObject::destroy()
	{
		try {
			if (destroyFun != nullptr)
				return destroyFun(script_child_);
		}
		catch (const std::exception& e)
		{
			std::cerr << e.what() << "\n";
		}
		return FSEObject::destroy();
	}

	void ScriptObject::BeginContactComponents(FSEObject* otherObject, b2Contact* contact)
	{
		try {
			if (beginContactComponentsFun != nullptr)
				beginContactComponentsFun(script_child_, otherObject, contact);
		}
		catch (const std::exception& e)
		{
			std::cerr << e.what() << "\n";
		}
	}

	void ScriptObject::EndContactComponents(FSEObject* otherObject, b2Contact* contact)
	{
		try {
			if (endContactComponentsFun != nullptr)
				endContactComponentsFun(script_child_, otherObject, contact);
		}
		catch (const std::exception& e)
		{
			std::cerr << e.what() << "\n";
		}
	}

	void ScriptObject::PreSolveComponents(FSEObject* otherObject, b2Contact* contact, const b2Manifold* oldManifold)
	{
		try {
		if (preSolveComponentsFun != nullptr)
			preSolveComponentsFun(script_child_, otherObject, contact, oldManifold);
		}
		catch (const std::exception& e)
		{
			std::cerr << e.what() << "\n";
		}
	}

	void ScriptObject::PostSolveComponents(FSEObject* otherObject, b2Contact* contact, const b2ContactImpulse* impulse)
	{
		try {
		if (postSolveComponentsFun != nullptr)
			postSolveComponentsFun(script_child_, otherObject, contact, impulse);
		}
		catch (const std::exception& e)
		{
			std::cerr << e.what() << "\n";
		}
	}

	FSE_CHAI_REGISTER(ScriptObject)
	{
		RegisterChaiUserTypeFromRTTR<ScriptObject>(chai);
		chai.add(chaiscript::base_class<fse::FSEObject, ScriptObject>());
		chai.add(chaiscript::constructor<ScriptObject(const std::string&)>(), "ScriptObject");
		chai.add(chaiscript::fun([](const ScriptObject* object)
		{
			return object->initialized_;
		}), "isInitialized");

		chai.add(chaiscript::fun([](const ScriptObject* object)
		{
			return object->script_name_;
		}), "getScriptName");

		chai.add(chaiscript::fun([](const ScriptObject* object)
		{
			return object->script_child_;
		}), "_child");

		chai.add(chaiscript::fun(&ScriptObject::spawnedFun), "spawnedCallback");
		chai.add(chaiscript::fun(&ScriptObject::onDespawnFun), "onDespawnCallback");

		chai.add(chaiscript::fun(&ScriptObject::updateFun), "updateCallback");
		chai.add(chaiscript::fun(&ScriptObject::drawFun), "drawCallback");
		chai.add(chaiscript::fun(&ScriptObject::drawNormalsFun), "drawNormalsCallback");
		chai.add(chaiscript::fun(&ScriptObject::drawSpecularFun), "drawSpecularCallback");

		chai.add(chaiscript::fun(&ScriptObject::setPositionFun), "setPositionCallback");
		chai.add(chaiscript::fun(&ScriptObject::getPositionFun), "getPositionCallback");
		chai.add(chaiscript::fun(&ScriptObject::getAABBsFun), "getAABBsCallback");

		chai.add(chaiscript::fun(&ScriptObject::beginContactFun), "beginContactCallback");
		chai.add(chaiscript::fun(&ScriptObject::endContactFun), "endContactCallback");

		chai.add(chaiscript::fun(&ScriptObject::preSolveFun), "preSolveCallback");
		chai.add(chaiscript::fun(&ScriptObject::postSolveFun), "postSolveCallback");

		chai.add(chaiscript::fun(&ScriptObject::destroyFun), "destroyCallback");

		chai.add(chaiscript::fun(&ScriptObject::beginContactComponentsFun), "beginContactComponentsCallback");
		chai.add(chaiscript::fun(&ScriptObject::endContactComponentsFun), "endContactComponentsCallback");

		chai.add(chaiscript::fun(&ScriptObject::preSolveComponentsFun), "preSolveComponentsCallback");
		chai.add(chaiscript::fun(&ScriptObject::postSolveComponentsFun), "postSolveComponentsCallback");

	}

}

#include <rttr/registration>
RTTR_REGISTRATION
{
	using namespace rttr;
	using namespace fse;
	registration::class_<ScriptObject>("fse::ScriptObject")
		.constructor<const std::string& >()
		(
			policy::ctor::as_std_shared_ptr,
			parameter_names("script name")
			)
		.constructor<const std::string&, const sf::Vector2f&>()
		(
			policy::ctor::as_std_shared_ptr,
			parameter_names("script name", "spawn position")
			)
		.property_readonly("script_name_", &ScriptObject::script_name_)
		.property_readonly("initialized_", &ScriptObject::initialized_)
		.property_readonly("script_child_", &ScriptObject::script_child_)
		;
}
<|endoftext|>


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

#include "ui/gfx/gtk_preserve_window.h"

#include <gdk/gdkwindow.h>
#include <gtk/gtk.h>
#include <gtk/gtkwidget.h>
#include <gtk/gtkfixed.h>

G_BEGIN_DECLS

#define GTK_PRESERVE_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
                                            GTK_TYPE_PRESERVE_WINDOW, \
                                            GtkPreserveWindowPrivate))

typedef struct _GtkPreserveWindowPrivate GtkPreserveWindowPrivate;

struct _GtkPreserveWindowPrivate {
  // If true, don't create/destroy windows on realize/unrealize.
  gboolean preserve_window;

  // Whether or not we delegate the resize of the GdkWindow
  // to someone else.
  gboolean delegate_resize;
};

G_DEFINE_TYPE(GtkPreserveWindow, gtk_preserve_window, GTK_TYPE_FIXED)

static void gtk_preserve_window_destroy(GtkObject* object);
static void gtk_preserve_window_realize(GtkWidget* widget);
static void gtk_preserve_window_unrealize(GtkWidget* widget);
static void gtk_preserve_window_size_allocate(GtkWidget* widget,
                                              GtkAllocation* allocation);

static void gtk_preserve_window_class_init(GtkPreserveWindowClass *klass) {
  GtkWidgetClass* widget_class = reinterpret_cast<GtkWidgetClass*>(klass);
  widget_class->realize = gtk_preserve_window_realize;
  widget_class->unrealize = gtk_preserve_window_unrealize;
  widget_class->size_allocate = gtk_preserve_window_size_allocate;

  GtkObjectClass* object_class = reinterpret_cast<GtkObjectClass*>(klass);
  object_class->destroy = gtk_preserve_window_destroy;

  GObjectClass* gobject_class = G_OBJECT_CLASS(klass);
  g_type_class_add_private(gobject_class, sizeof(GtkPreserveWindowPrivate));
}

static void gtk_preserve_window_init(GtkPreserveWindow* widget) {
  GtkPreserveWindowPrivate* priv = GTK_PRESERVE_WINDOW_GET_PRIVATE(widget);
  priv->preserve_window = FALSE;

  // These widgets always have their own window.
  gtk_fixed_set_has_window(GTK_FIXED(widget), TRUE);
}

GtkWidget* gtk_preserve_window_new() {
  return GTK_WIDGET(g_object_new(GTK_TYPE_PRESERVE_WINDOW, NULL));
}

static void gtk_preserve_window_destroy(GtkObject* object) {
  GtkWidget* widget = reinterpret_cast<GtkWidget*>(object);
  GtkPreserveWindowPrivate* priv = GTK_PRESERVE_WINDOW_GET_PRIVATE(widget);

  if (widget->window) {
    gdk_window_set_user_data(widget->window, NULL);
    // If the window is preserved, someone else must destroy it.
    if (!priv->preserve_window)
      gdk_window_destroy(widget->window);
    widget->window = NULL;
  }

  GTK_OBJECT_CLASS(gtk_preserve_window_parent_class)->destroy(object);
}

static void gtk_preserve_window_realize(GtkWidget* widget) {
  g_return_if_fail(GTK_IS_PRESERVE_WINDOW(widget));

  if (widget->window) {
    gdk_window_reparent(widget->window,
                        gtk_widget_get_parent_window(widget),
                        widget->allocation.x,
                        widget->allocation.y);
    widget->style = gtk_style_attach(widget->style, widget->window);
    gtk_style_set_background(widget->style, widget->window, GTK_STATE_NORMAL);

    gint event_mask = gtk_widget_get_events(widget);
    event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK;
    gdk_window_set_events(widget->window, (GdkEventMask) event_mask);
    gdk_window_set_user_data(widget->window, widget);

    // Deprecated as of GTK 2.22. Used for compatibility.
    // It should be: gtk_widget_set_realized(widget, TRUE)
    GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
  } else {
    GTK_WIDGET_CLASS(gtk_preserve_window_parent_class)->realize(widget);
  }
}

static void gtk_preserve_window_unrealize(GtkWidget* widget) {
  g_return_if_fail(GTK_IS_PRESERVE_WINDOW(widget));

  GtkPreserveWindowPrivate* priv = GTK_PRESERVE_WINDOW_GET_PRIVATE(widget);
  if (priv->preserve_window) {
    GtkWidgetClass* widget_class =
        GTK_WIDGET_CLASS(gtk_preserve_window_parent_class);
    GtkContainerClass* container_class =
        GTK_CONTAINER_CLASS(gtk_preserve_window_parent_class);

    // Deprecated as of GTK 2.22. Used for compatibility.
    // It should be: gtk_widget_get_mapped()
    if (GTK_WIDGET_MAPPED(widget)) {
      widget_class->unmap(widget);

      // Deprecated as of GTK 2.22. Used for compatibility.
      // It should be: gtk_widget_set_mapped(widget, FALSE)
      GTK_WIDGET_UNSET_FLAGS(widget, GTK_MAPPED);
    }

    // This is the behavior from GtkWidget, inherited by GtkFixed.
    // It is unclear why we should not call the potentially overridden
    // unrealize method (via the callback), but doing so causes errors.
    container_class->forall(
        GTK_CONTAINER(widget), FALSE,
        reinterpret_cast<GtkCallback>(gtk_widget_unrealize), NULL);

    gtk_style_detach(widget->style);
    gdk_window_reparent(widget->window, gdk_get_default_root_window(), 0, 0);
    gtk_selection_remove_all(widget);
    gdk_window_set_user_data(widget->window, NULL);

    // Deprecated as of GTK 2.22. Used for compatibility.
    // It should be: gtk_widget_set_realized(widget, FALSE)
    GTK_WIDGET_UNSET_FLAGS(widget, GTK_REALIZED);
  } else {
    GTK_WIDGET_CLASS(gtk_preserve_window_parent_class)->unrealize(widget);
  }
}

gboolean gtk_preserve_window_get_preserve(GtkPreserveWindow* window) {
  g_return_val_if_fail(GTK_IS_PRESERVE_WINDOW(window), FALSE);
  GtkPreserveWindowPrivate* priv = GTK_PRESERVE_WINDOW_GET_PRIVATE(window);

  return priv->preserve_window;
}

void gtk_preserve_window_set_preserve(GtkPreserveWindow* window,
                                      gboolean value) {
  g_return_if_fail(GTK_IS_PRESERVE_WINDOW(window));
  GtkPreserveWindowPrivate* priv = GTK_PRESERVE_WINDOW_GET_PRIVATE(window);
  priv->preserve_window = value;

  GtkWidget* widget = GTK_WIDGET(window);
  if (value && !widget->window) {
    GdkWindowAttr attributes;
    gint attributes_mask;

    // We may not know the width and height, so we rely on the fact
    // that a size-allocation will resize it later.
    attributes.width = 1;
    attributes.height = 1;

    attributes.window_type = GDK_WINDOW_CHILD;
    attributes.wclass = GDK_INPUT_OUTPUT;

    attributes.visual = gtk_widget_get_visual(widget);
    attributes.colormap = gtk_widget_get_colormap(widget);

    attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;
    widget->window = gdk_window_new(
        gdk_get_default_root_window(), &attributes, attributes_mask);
  } else if (!value && widget->window && !GTK_WIDGET_REALIZED(widget)) {
    gdk_window_destroy(widget->window);
    widget->window = NULL;
  }
}

void gtk_preserve_window_size_allocate(GtkWidget* widget,
                                       GtkAllocation* allocation) {
  g_return_if_fail(GTK_IS_PRESERVE_WINDOW(widget));
  GtkPreserveWindowPrivate* priv = GTK_PRESERVE_WINDOW_GET_PRIVATE(widget);

  if (priv->delegate_resize) {
    // Just update the state. Someone else will gdk_window_resize the
    // associated GdkWindow.
    widget->allocation = *allocation;
  } else {
    GTK_WIDGET_CLASS(gtk_preserve_window_parent_class)->size_allocate(
        widget, allocation);
  }
}

void gtk_preserve_window_delegate_resize(GtkPreserveWindow* widget,
                                         gboolean delegate) {
  GtkPreserveWindowPrivate* priv = GTK_PRESERVE_WINDOW_GET_PRIVATE(widget);
  priv->delegate_resize = delegate;
}

G_END_DECLS
<commit_msg>To prevent damage to the back-buffer, it's only necessary to defer resize.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/gfx/gtk_preserve_window.h"

#include <gdk/gdkwindow.h>
#include <gtk/gtk.h>
#include <gtk/gtkwidget.h>
#include <gtk/gtkfixed.h>

G_BEGIN_DECLS

#define GTK_PRESERVE_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
                                            GTK_TYPE_PRESERVE_WINDOW, \
                                            GtkPreserveWindowPrivate))

typedef struct _GtkPreserveWindowPrivate GtkPreserveWindowPrivate;

struct _GtkPreserveWindowPrivate {
  // If true, don't create/destroy windows on realize/unrealize.
  gboolean preserve_window;

  // Whether or not we delegate the resize of the GdkWindow
  // to someone else.
  gboolean delegate_resize;
};

G_DEFINE_TYPE(GtkPreserveWindow, gtk_preserve_window, GTK_TYPE_FIXED)

static void gtk_preserve_window_destroy(GtkObject* object);
static void gtk_preserve_window_realize(GtkWidget* widget);
static void gtk_preserve_window_unrealize(GtkWidget* widget);
static void gtk_preserve_window_size_allocate(GtkWidget* widget,
                                              GtkAllocation* allocation);

static void gtk_preserve_window_class_init(GtkPreserveWindowClass *klass) {
  GtkWidgetClass* widget_class = reinterpret_cast<GtkWidgetClass*>(klass);
  widget_class->realize = gtk_preserve_window_realize;
  widget_class->unrealize = gtk_preserve_window_unrealize;
  widget_class->size_allocate = gtk_preserve_window_size_allocate;

  GtkObjectClass* object_class = reinterpret_cast<GtkObjectClass*>(klass);
  object_class->destroy = gtk_preserve_window_destroy;

  GObjectClass* gobject_class = G_OBJECT_CLASS(klass);
  g_type_class_add_private(gobject_class, sizeof(GtkPreserveWindowPrivate));
}

static void gtk_preserve_window_init(GtkPreserveWindow* widget) {
  GtkPreserveWindowPrivate* priv = GTK_PRESERVE_WINDOW_GET_PRIVATE(widget);
  priv->preserve_window = FALSE;

  // These widgets always have their own window.
  gtk_fixed_set_has_window(GTK_FIXED(widget), TRUE);
}

GtkWidget* gtk_preserve_window_new() {
  return GTK_WIDGET(g_object_new(GTK_TYPE_PRESERVE_WINDOW, NULL));
}

static void gtk_preserve_window_destroy(GtkObject* object) {
  GtkWidget* widget = reinterpret_cast<GtkWidget*>(object);
  GtkPreserveWindowPrivate* priv = GTK_PRESERVE_WINDOW_GET_PRIVATE(widget);

  if (widget->window) {
    gdk_window_set_user_data(widget->window, NULL);
    // If the window is preserved, someone else must destroy it.
    if (!priv->preserve_window)
      gdk_window_destroy(widget->window);
    widget->window = NULL;
  }

  GTK_OBJECT_CLASS(gtk_preserve_window_parent_class)->destroy(object);
}

static void gtk_preserve_window_realize(GtkWidget* widget) {
  g_return_if_fail(GTK_IS_PRESERVE_WINDOW(widget));

  if (widget->window) {
    gdk_window_reparent(widget->window,
                        gtk_widget_get_parent_window(widget),
                        widget->allocation.x,
                        widget->allocation.y);
    widget->style = gtk_style_attach(widget->style, widget->window);
    gtk_style_set_background(widget->style, widget->window, GTK_STATE_NORMAL);

    gint event_mask = gtk_widget_get_events(widget);
    event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK;
    gdk_window_set_events(widget->window, (GdkEventMask) event_mask);
    gdk_window_set_user_data(widget->window, widget);

    // Deprecated as of GTK 2.22. Used for compatibility.
    // It should be: gtk_widget_set_realized(widget, TRUE)
    GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
  } else {
    GTK_WIDGET_CLASS(gtk_preserve_window_parent_class)->realize(widget);
  }
}

static void gtk_preserve_window_unrealize(GtkWidget* widget) {
  g_return_if_fail(GTK_IS_PRESERVE_WINDOW(widget));

  GtkPreserveWindowPrivate* priv = GTK_PRESERVE_WINDOW_GET_PRIVATE(widget);
  if (priv->preserve_window) {
    GtkWidgetClass* widget_class =
        GTK_WIDGET_CLASS(gtk_preserve_window_parent_class);
    GtkContainerClass* container_class =
        GTK_CONTAINER_CLASS(gtk_preserve_window_parent_class);

    // Deprecated as of GTK 2.22. Used for compatibility.
    // It should be: gtk_widget_get_mapped()
    if (GTK_WIDGET_MAPPED(widget)) {
      widget_class->unmap(widget);

      // Deprecated as of GTK 2.22. Used for compatibility.
      // It should be: gtk_widget_set_mapped(widget, FALSE)
      GTK_WIDGET_UNSET_FLAGS(widget, GTK_MAPPED);
    }

    // This is the behavior from GtkWidget, inherited by GtkFixed.
    // It is unclear why we should not call the potentially overridden
    // unrealize method (via the callback), but doing so causes errors.
    container_class->forall(
        GTK_CONTAINER(widget), FALSE,
        reinterpret_cast<GtkCallback>(gtk_widget_unrealize), NULL);

    gtk_style_detach(widget->style);
    gdk_window_reparent(widget->window, gdk_get_default_root_window(), 0, 0);
    gtk_selection_remove_all(widget);
    gdk_window_set_user_data(widget->window, NULL);

    // Deprecated as of GTK 2.22. Used for compatibility.
    // It should be: gtk_widget_set_realized(widget, FALSE)
    GTK_WIDGET_UNSET_FLAGS(widget, GTK_REALIZED);
  } else {
    GTK_WIDGET_CLASS(gtk_preserve_window_parent_class)->unrealize(widget);
  }
}

gboolean gtk_preserve_window_get_preserve(GtkPreserveWindow* window) {
  g_return_val_if_fail(GTK_IS_PRESERVE_WINDOW(window), FALSE);
  GtkPreserveWindowPrivate* priv = GTK_PRESERVE_WINDOW_GET_PRIVATE(window);

  return priv->preserve_window;
}

void gtk_preserve_window_set_preserve(GtkPreserveWindow* window,
                                      gboolean value) {
  g_return_if_fail(GTK_IS_PRESERVE_WINDOW(window));
  GtkPreserveWindowPrivate* priv = GTK_PRESERVE_WINDOW_GET_PRIVATE(window);
  priv->preserve_window = value;

  GtkWidget* widget = GTK_WIDGET(window);
  if (value && !widget->window) {
    GdkWindowAttr attributes;
    gint attributes_mask;

    // We may not know the width and height, so we rely on the fact
    // that a size-allocation will resize it later.
    attributes.width = 1;
    attributes.height = 1;

    attributes.window_type = GDK_WINDOW_CHILD;
    attributes.wclass = GDK_INPUT_OUTPUT;

    attributes.visual = gtk_widget_get_visual(widget);
    attributes.colormap = gtk_widget_get_colormap(widget);

    attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;
    widget->window = gdk_window_new(
        gdk_get_default_root_window(), &attributes, attributes_mask);
  } else if (!value && widget->window && !GTK_WIDGET_REALIZED(widget)) {
    gdk_window_destroy(widget->window);
    widget->window = NULL;
  }
}

void gtk_preserve_window_size_allocate(GtkWidget* widget,
                                       GtkAllocation* allocation) {
  g_return_if_fail(GTK_IS_PRESERVE_WINDOW(widget));
  GtkPreserveWindowPrivate* priv = GTK_PRESERVE_WINDOW_GET_PRIVATE(widget);

  if (priv->delegate_resize) {
    widget->allocation = *allocation;
    // Only update the position. Someone else will call gdk_window_resize.
    if (GTK_WIDGET_REALIZED(widget)) {
      gdk_window_move(widget->window, allocation->x, allocation->y);
    }
  } else {
    GTK_WIDGET_CLASS(gtk_preserve_window_parent_class)->size_allocate(
        widget, allocation);
  }
}

void gtk_preserve_window_delegate_resize(GtkPreserveWindow* widget,
                                         gboolean delegate) {
  GtkPreserveWindowPrivate* priv = GTK_PRESERVE_WINDOW_GET_PRIVATE(widget);
  priv->delegate_resize = delegate;
}

G_END_DECLS
<|endoftext|>


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

#include "chrome/browser/bookmarks/chrome_bookmark_client.h"

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/logging.h"
#include "base/values.h"
#include "chrome/browser/favicon/favicon_service.h"
#include "chrome/browser/favicon/favicon_service_factory.h"
#include "chrome/browser/history/history_service.h"
#include "chrome/browser/policy/profile_policy_connector.h"
#include "chrome/browser/policy/profile_policy_connector_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "components/bookmarks/browser/bookmark_model.h"
#include "components/bookmarks/browser/bookmark_node.h"
#include "components/bookmarks/browser/bookmark_utils.h"
#include "components/history/core/browser/url_database.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/user_metrics.h"
#include "grit/components_strings.h"
#include "policy/policy_constants.h"
#include "ui/base/l10n/l10n_util.h"

using bookmarks::BookmarkModel;
using bookmarks::BookmarkNode;
using bookmarks::BookmarkPermanentNode;

namespace {

void RunCallbackWithImage(
    const favicon_base::FaviconImageCallback& callback,
    const favicon_base::FaviconRawBitmapResult& bitmap_result) {
  favicon_base::FaviconImageResult result;
  if (bitmap_result.is_valid()) {
    result.image = gfx::Image::CreateFrom1xPNGBytes(
        bitmap_result.bitmap_data->front(), bitmap_result.bitmap_data->size());
    result.icon_url = bitmap_result.icon_url;
    callback.Run(result);
    return;
  }
  callback.Run(result);
}

void LoadInitialContents(BookmarkPermanentNode* node,
                         base::ListValue* initial_bookmarks,
                         int64* next_node_id) {
  // Load the initial contents of the |node| now, and assign it an unused ID.
  int64 id = *next_node_id;
  node->set_id(id);
  *next_node_id = policy::ManagedBookmarksTracker::LoadInitial(
      node, initial_bookmarks, id + 1);
  node->set_visible(!node->empty());
}

}  // namespace

ChromeBookmarkClient::ChromeBookmarkClient(Profile* profile)
    : profile_(profile),
      history_service_(NULL),
      model_(NULL),
      managed_node_(NULL),
      supervised_node_(NULL) {
}

ChromeBookmarkClient::~ChromeBookmarkClient() {
}

void ChromeBookmarkClient::Init(BookmarkModel* model) {
  DCHECK(model);
  DCHECK(!model_);
  model_ = model;
  model_->AddObserver(this);

  managed_bookmarks_tracker_.reset(new policy::ManagedBookmarksTracker(
      model_,
      profile_->GetPrefs(),
      false,
      base::Bind(&ChromeBookmarkClient::GetManagedBookmarksDomain,
                 base::Unretained(this))));
  supervised_bookmarks_tracker_.reset(new policy::ManagedBookmarksTracker(
      model_,
      profile_->GetPrefs(),
      true,
      base::Callback<std::string()>()));
}

void ChromeBookmarkClient::Shutdown() {
  favicon_changed_subscription_.reset();
  if (model_) {
    model_->RemoveObserver(this);
    model_ = NULL;
  }
  BookmarkClient::Shutdown();
}

bool ChromeBookmarkClient::PreferTouchIcon() {
#if !defined(OS_IOS)
  return false;
#else
  return true;
#endif
}

base::CancelableTaskTracker::TaskId
ChromeBookmarkClient::GetFaviconImageForPageURL(
    const GURL& page_url,
    favicon_base::IconType type,
    const favicon_base::FaviconImageCallback& callback,
    base::CancelableTaskTracker* tracker) {
  FaviconService* favicon_service = FaviconServiceFactory::GetForProfile(
      profile_, ServiceAccessType::EXPLICIT_ACCESS);
  if (!favicon_service)
    return base::CancelableTaskTracker::kBadTaskId;
  if (type == favicon_base::FAVICON) {
    return favicon_service->GetFaviconImageForPageURL(
        page_url, callback, tracker);
  } else {
    return favicon_service->GetRawFaviconForPageURL(
        page_url,
        type,
        0,
        base::Bind(&RunCallbackWithImage, callback),
        tracker);
  }
}

bool ChromeBookmarkClient::SupportsTypedCountForNodes() {
  return true;
}

void ChromeBookmarkClient::GetTypedCountForNodes(
    const NodeSet& nodes,
    NodeTypedCountPairs* node_typed_count_pairs) {
  history::URLDatabase* url_db =
      history_service_ ? history_service_->InMemoryDatabase() : NULL;
  for (NodeSet::const_iterator i = nodes.begin(); i != nodes.end(); ++i) {
    int typed_count = 0;

    // If |url_db| is the InMemoryDatabase, it might not cache all URLRows, but
    // it guarantees to contain those with |typed_count| > 0. Thus, if we cannot
    // fetch the URLRow, it is safe to assume that its |typed_count| is 0.
    history::URLRow url;
    if (url_db && url_db->GetRowForURL((*i)->url(), &url))
      typed_count = url.typed_count();

    NodeTypedCountPair pair(*i, typed_count);
    node_typed_count_pairs->push_back(pair);
  }
}

bool ChromeBookmarkClient::IsPermanentNodeVisible(
    const BookmarkPermanentNode* node) {
  DCHECK(node->type() == BookmarkNode::BOOKMARK_BAR ||
         node->type() == BookmarkNode::OTHER_NODE ||
         node->type() == BookmarkNode::MOBILE ||
         node == managed_node_ ||
         node == supervised_node_);
  if (node == managed_node_ || node == supervised_node_)
    return false;
#if !defined(OS_IOS)
  return node->type() != BookmarkNode::MOBILE;
#else
  return node->type() == BookmarkNode::MOBILE;
#endif
}

void ChromeBookmarkClient::RecordAction(const base::UserMetricsAction& action) {
  content::RecordAction(action);
}

bookmarks::LoadExtraCallback ChromeBookmarkClient::GetLoadExtraNodesCallback() {
  // Create the managed_node_ and supervised_node_ with a temporary ID of 0 now.
  // They will be populated (and assigned proper IDs) in the LoadExtraNodes
  // callback.
  // The ownership of managed_node_ and supervised_node_ is in limbo until
  // LoadExtraNodes runs, so we leave them in the care of the closure meanwhile.
  scoped_ptr<BookmarkPermanentNode> managed(new BookmarkPermanentNode(0));
  managed_node_ = managed.get();
  scoped_ptr<BookmarkPermanentNode> supervised(new BookmarkPermanentNode(0));
  supervised_node_ = supervised.get();

  return base::Bind(
      &ChromeBookmarkClient::LoadExtraNodes,
      base::Passed(&managed),
      base::Passed(managed_bookmarks_tracker_->GetInitialManagedBookmarks()),
      base::Passed(&supervised),
      base::Passed(
          supervised_bookmarks_tracker_->GetInitialManagedBookmarks()));
}

bool ChromeBookmarkClient::CanSetPermanentNodeTitle(
    const BookmarkNode* permanent_node) {
  // The |managed_node_| can have its title updated if the user signs in or
  // out, since the name of the managed domain can appear in it. The
  // |supervised_node_| has a fixed title which can never be updated.
  return (!bookmarks::IsDescendantOf(permanent_node, managed_node_) &&
          !bookmarks::IsDescendantOf(permanent_node, supervised_node_)) ||
         permanent_node == managed_node_;
}

bool ChromeBookmarkClient::CanSyncNode(const BookmarkNode* node) {
  return !bookmarks::IsDescendantOf(node, managed_node_) &&
         !bookmarks::IsDescendantOf(node, supervised_node_);
}

bool ChromeBookmarkClient::CanBeEditedByUser(const BookmarkNode* node) {
  return !bookmarks::IsDescendantOf(node, managed_node_) &&
         !bookmarks::IsDescendantOf(node, supervised_node_);
}

void ChromeBookmarkClient::SetHistoryService(HistoryService* history_service) {
  DCHECK(history_service);
  history_service_ = history_service;
  favicon_changed_subscription_ = history_service_->AddFaviconChangedCallback(
      base::Bind(&BookmarkModel::OnFaviconChanged, base::Unretained(model_)));
}

void ChromeBookmarkClient::BookmarkModelChanged() {
}

void ChromeBookmarkClient::BookmarkNodeRemoved(
    BookmarkModel* model,
    const BookmarkNode* parent,
    int old_index,
    const BookmarkNode* node,
    const std::set<GURL>& removed_urls) {
  if (history_service_)
    history_service_->URLsNoLongerBookmarked(removed_urls);
}

void ChromeBookmarkClient::BookmarkAllUserNodesRemoved(
    BookmarkModel* model,
    const std::set<GURL>& removed_urls) {
  if (history_service_)
    history_service_->URLsNoLongerBookmarked(removed_urls);
}

void ChromeBookmarkClient::BookmarkModelLoaded(BookmarkModel* model,
                                               bool ids_reassigned) {
  // Start tracking the managed and supervised bookmarks. This will detect any
  // changes that may have occurred while the initial managed and supervised
  // bookmarks were being loaded on the background.
  managed_bookmarks_tracker_->Init(managed_node_);
  supervised_bookmarks_tracker_->Init(supervised_node_);
}

// static
bookmarks::BookmarkPermanentNodeList ChromeBookmarkClient::LoadExtraNodes(
    scoped_ptr<BookmarkPermanentNode> managed_node,
    scoped_ptr<base::ListValue> initial_managed_bookmarks,
    scoped_ptr<BookmarkPermanentNode> supervised_node,
    scoped_ptr<base::ListValue> initial_supervised_bookmarks,
    int64* next_node_id) {
  LoadInitialContents(
      managed_node.get(), initial_managed_bookmarks.get(), next_node_id);
  managed_node->SetTitle(l10n_util::GetStringUTF16(
      IDS_BOOKMARK_BAR_MANAGED_FOLDER_DEFAULT_NAME));

  LoadInitialContents(
      supervised_node.get(), initial_supervised_bookmarks.get(), next_node_id);
  supervised_node->SetTitle(l10n_util::GetStringUTF16(
      IDS_BOOKMARK_BAR_SUPERVISED_FOLDER_DEFAULT_NAME));

  bookmarks::BookmarkPermanentNodeList extra_nodes;
  // Ownership of the managed and supervised nodes passed to the caller.
  extra_nodes.push_back(managed_node.release());
  extra_nodes.push_back(supervised_node.release());

  return extra_nodes.Pass();
}

std::string ChromeBookmarkClient::GetManagedBookmarksDomain() {
  policy::ProfilePolicyConnector* connector =
      policy::ProfilePolicyConnectorFactory::GetForBrowserContext(profile_);
  if (connector->IsPolicyFromCloudPolicy(policy::key::kManagedBookmarks))
    return connector->GetManagementDomain();
  return std::string();
}
<commit_msg>Make ChromeBookmarkClient::CanSetPermanentNodeTitle say true for the supervised node.<commit_after>// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/bookmarks/chrome_bookmark_client.h"

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/logging.h"
#include "base/values.h"
#include "chrome/browser/favicon/favicon_service.h"
#include "chrome/browser/favicon/favicon_service_factory.h"
#include "chrome/browser/history/history_service.h"
#include "chrome/browser/policy/profile_policy_connector.h"
#include "chrome/browser/policy/profile_policy_connector_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "components/bookmarks/browser/bookmark_model.h"
#include "components/bookmarks/browser/bookmark_node.h"
#include "components/bookmarks/browser/bookmark_utils.h"
#include "components/history/core/browser/url_database.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/user_metrics.h"
#include "grit/components_strings.h"
#include "policy/policy_constants.h"
#include "ui/base/l10n/l10n_util.h"

using bookmarks::BookmarkModel;
using bookmarks::BookmarkNode;
using bookmarks::BookmarkPermanentNode;

namespace {

void RunCallbackWithImage(
    const favicon_base::FaviconImageCallback& callback,
    const favicon_base::FaviconRawBitmapResult& bitmap_result) {
  favicon_base::FaviconImageResult result;
  if (bitmap_result.is_valid()) {
    result.image = gfx::Image::CreateFrom1xPNGBytes(
        bitmap_result.bitmap_data->front(), bitmap_result.bitmap_data->size());
    result.icon_url = bitmap_result.icon_url;
    callback.Run(result);
    return;
  }
  callback.Run(result);
}

void LoadInitialContents(BookmarkPermanentNode* node,
                         base::ListValue* initial_bookmarks,
                         int64* next_node_id) {
  // Load the initial contents of the |node| now, and assign it an unused ID.
  int64 id = *next_node_id;
  node->set_id(id);
  *next_node_id = policy::ManagedBookmarksTracker::LoadInitial(
      node, initial_bookmarks, id + 1);
  node->set_visible(!node->empty());
}

}  // namespace

ChromeBookmarkClient::ChromeBookmarkClient(Profile* profile)
    : profile_(profile),
      history_service_(NULL),
      model_(NULL),
      managed_node_(NULL),
      supervised_node_(NULL) {
}

ChromeBookmarkClient::~ChromeBookmarkClient() {
}

void ChromeBookmarkClient::Init(BookmarkModel* model) {
  DCHECK(model);
  DCHECK(!model_);
  model_ = model;
  model_->AddObserver(this);

  managed_bookmarks_tracker_.reset(new policy::ManagedBookmarksTracker(
      model_,
      profile_->GetPrefs(),
      false,
      base::Bind(&ChromeBookmarkClient::GetManagedBookmarksDomain,
                 base::Unretained(this))));
  supervised_bookmarks_tracker_.reset(new policy::ManagedBookmarksTracker(
      model_,
      profile_->GetPrefs(),
      true,
      base::Callback<std::string()>()));
}

void ChromeBookmarkClient::Shutdown() {
  favicon_changed_subscription_.reset();
  if (model_) {
    model_->RemoveObserver(this);
    model_ = NULL;
  }
  BookmarkClient::Shutdown();
}

bool ChromeBookmarkClient::PreferTouchIcon() {
#if !defined(OS_IOS)
  return false;
#else
  return true;
#endif
}

base::CancelableTaskTracker::TaskId
ChromeBookmarkClient::GetFaviconImageForPageURL(
    const GURL& page_url,
    favicon_base::IconType type,
    const favicon_base::FaviconImageCallback& callback,
    base::CancelableTaskTracker* tracker) {
  FaviconService* favicon_service = FaviconServiceFactory::GetForProfile(
      profile_, ServiceAccessType::EXPLICIT_ACCESS);
  if (!favicon_service)
    return base::CancelableTaskTracker::kBadTaskId;
  if (type == favicon_base::FAVICON) {
    return favicon_service->GetFaviconImageForPageURL(
        page_url, callback, tracker);
  } else {
    return favicon_service->GetRawFaviconForPageURL(
        page_url,
        type,
        0,
        base::Bind(&RunCallbackWithImage, callback),
        tracker);
  }
}

bool ChromeBookmarkClient::SupportsTypedCountForNodes() {
  return true;
}

void ChromeBookmarkClient::GetTypedCountForNodes(
    const NodeSet& nodes,
    NodeTypedCountPairs* node_typed_count_pairs) {
  history::URLDatabase* url_db =
      history_service_ ? history_service_->InMemoryDatabase() : NULL;
  for (NodeSet::const_iterator i = nodes.begin(); i != nodes.end(); ++i) {
    int typed_count = 0;

    // If |url_db| is the InMemoryDatabase, it might not cache all URLRows, but
    // it guarantees to contain those with |typed_count| > 0. Thus, if we cannot
    // fetch the URLRow, it is safe to assume that its |typed_count| is 0.
    history::URLRow url;
    if (url_db && url_db->GetRowForURL((*i)->url(), &url))
      typed_count = url.typed_count();

    NodeTypedCountPair pair(*i, typed_count);
    node_typed_count_pairs->push_back(pair);
  }
}

bool ChromeBookmarkClient::IsPermanentNodeVisible(
    const BookmarkPermanentNode* node) {
  DCHECK(node->type() == BookmarkNode::BOOKMARK_BAR ||
         node->type() == BookmarkNode::OTHER_NODE ||
         node->type() == BookmarkNode::MOBILE ||
         node == managed_node_ ||
         node == supervised_node_);
  if (node == managed_node_ || node == supervised_node_)
    return false;
#if !defined(OS_IOS)
  return node->type() != BookmarkNode::MOBILE;
#else
  return node->type() == BookmarkNode::MOBILE;
#endif
}

void ChromeBookmarkClient::RecordAction(const base::UserMetricsAction& action) {
  content::RecordAction(action);
}

bookmarks::LoadExtraCallback ChromeBookmarkClient::GetLoadExtraNodesCallback() {
  // Create the managed_node_ and supervised_node_ with a temporary ID of 0 now.
  // They will be populated (and assigned proper IDs) in the LoadExtraNodes
  // callback.
  // The ownership of managed_node_ and supervised_node_ is in limbo until
  // LoadExtraNodes runs, so we leave them in the care of the closure meanwhile.
  scoped_ptr<BookmarkPermanentNode> managed(new BookmarkPermanentNode(0));
  managed_node_ = managed.get();
  scoped_ptr<BookmarkPermanentNode> supervised(new BookmarkPermanentNode(0));
  supervised_node_ = supervised.get();

  return base::Bind(
      &ChromeBookmarkClient::LoadExtraNodes,
      base::Passed(&managed),
      base::Passed(managed_bookmarks_tracker_->GetInitialManagedBookmarks()),
      base::Passed(&supervised),
      base::Passed(
          supervised_bookmarks_tracker_->GetInitialManagedBookmarks()));
}

bool ChromeBookmarkClient::CanSetPermanentNodeTitle(
    const BookmarkNode* permanent_node) {
  // The |managed_node_| can have its title updated if the user signs in or
  // out, since the name of the managed domain can appear in it.
  // Also, both |managed_node_| and |supervised_node_| can have their title
  // updated on locale changes (crbug.com/459448).
  return (!bookmarks::IsDescendantOf(permanent_node, managed_node_) &&
          !bookmarks::IsDescendantOf(permanent_node, supervised_node_)) ||
         permanent_node == managed_node_ ||
         permanent_node == supervised_node_;
}

bool ChromeBookmarkClient::CanSyncNode(const BookmarkNode* node) {
  return !bookmarks::IsDescendantOf(node, managed_node_) &&
         !bookmarks::IsDescendantOf(node, supervised_node_);
}

bool ChromeBookmarkClient::CanBeEditedByUser(const BookmarkNode* node) {
  return !bookmarks::IsDescendantOf(node, managed_node_) &&
         !bookmarks::IsDescendantOf(node, supervised_node_);
}

void ChromeBookmarkClient::SetHistoryService(HistoryService* history_service) {
  DCHECK(history_service);
  history_service_ = history_service;
  favicon_changed_subscription_ = history_service_->AddFaviconChangedCallback(
      base::Bind(&BookmarkModel::OnFaviconChanged, base::Unretained(model_)));
}

void ChromeBookmarkClient::BookmarkModelChanged() {
}

void ChromeBookmarkClient::BookmarkNodeRemoved(
    BookmarkModel* model,
    const BookmarkNode* parent,
    int old_index,
    const BookmarkNode* node,
    const std::set<GURL>& removed_urls) {
  if (history_service_)
    history_service_->URLsNoLongerBookmarked(removed_urls);
}

void ChromeBookmarkClient::BookmarkAllUserNodesRemoved(
    BookmarkModel* model,
    const std::set<GURL>& removed_urls) {
  if (history_service_)
    history_service_->URLsNoLongerBookmarked(removed_urls);
}

void ChromeBookmarkClient::BookmarkModelLoaded(BookmarkModel* model,
                                               bool ids_reassigned) {
  // Start tracking the managed and supervised bookmarks. This will detect any
  // changes that may have occurred while the initial managed and supervised
  // bookmarks were being loaded on the background.
  managed_bookmarks_tracker_->Init(managed_node_);
  supervised_bookmarks_tracker_->Init(supervised_node_);
}

// static
bookmarks::BookmarkPermanentNodeList ChromeBookmarkClient::LoadExtraNodes(
    scoped_ptr<BookmarkPermanentNode> managed_node,
    scoped_ptr<base::ListValue> initial_managed_bookmarks,
    scoped_ptr<BookmarkPermanentNode> supervised_node,
    scoped_ptr<base::ListValue> initial_supervised_bookmarks,
    int64* next_node_id) {
  LoadInitialContents(
      managed_node.get(), initial_managed_bookmarks.get(), next_node_id);
  managed_node->SetTitle(l10n_util::GetStringUTF16(
      IDS_BOOKMARK_BAR_MANAGED_FOLDER_DEFAULT_NAME));

  LoadInitialContents(
      supervised_node.get(), initial_supervised_bookmarks.get(), next_node_id);
  supervised_node->SetTitle(l10n_util::GetStringUTF16(
      IDS_BOOKMARK_BAR_SUPERVISED_FOLDER_DEFAULT_NAME));

  bookmarks::BookmarkPermanentNodeList extra_nodes;
  // Ownership of the managed and supervised nodes passed to the caller.
  extra_nodes.push_back(managed_node.release());
  extra_nodes.push_back(supervised_node.release());

  return extra_nodes.Pass();
}

std::string ChromeBookmarkClient::GetManagedBookmarksDomain() {
  policy::ProfilePolicyConnector* connector =
      policy::ProfilePolicyConnectorFactory::GetForBrowserContext(profile_);
  if (connector->IsPolicyFromCloudPolicy(policy::key::kManagedBookmarks))
    return connector->GetManagementDomain();
  return std::string();
}
<|endoftext|>


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

#include "chrome/browser/chromeos/cros/cryptohome_library.h"

#include "base/hash_tables.h"
#include "base/message_loop.h"
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/chromeos/cros/cros_library.h"

namespace chromeos {

// This class handles the interaction with the ChromeOS cryptohome library APIs.
class CryptohomeLibraryImpl : public CryptohomeLibrary {
 public:
  CryptohomeLibraryImpl() {
    if (CrosLibrary::Get()->EnsureLoaded())
      Init();
  }
  virtual ~CryptohomeLibraryImpl() {}

  bool CheckKey(const std::string& user_email, const std::string& passhash) {
    return chromeos::CryptohomeCheckKey(user_email.c_str(), passhash.c_str());
  }

  bool AsyncCheckKey(const std::string& user_email,
                     const std::string& passhash,
                     Delegate* d) {
    return CacheCallback(
        chromeos::CryptohomeAsyncCheckKey(user_email.c_str(), passhash.c_str()),
        d,
        "Couldn't initiate async check of user's key.");
  }

  bool MigrateKey(const std::string& user_email,
                  const std::string& old_hash,
                  const std::string& new_hash) {
    return chromeos::CryptohomeMigrateKey(user_email.c_str(),
                                          old_hash.c_str(),
                                          new_hash.c_str());
  }

  bool AsyncMigrateKey(const std::string& user_email,
                       const std::string& old_hash,
                       const std::string& new_hash,
                       Delegate* d) {
    return CacheCallback(
        chromeos::CryptohomeAsyncMigrateKey(user_email.c_str(),
                                            old_hash.c_str(),
                                            new_hash.c_str()),
        d,
        "Couldn't initiate aync migration of user's key");
  }

  bool Mount(const std::string& user_email,
             const std::string& passhash,
             int* error_code) {
    return chromeos::CryptohomeMountAllowFail(user_email.c_str(),
                                              passhash.c_str(),
                                              error_code);
  }

  bool AsyncMount(const std::string& user_email,
                  const std::string& passhash,
                  Delegate* d) {
    return CacheCallback(
        chromeos::CryptohomeAsyncMount(user_email.c_str(), passhash.c_str()),
        d,
        "Couldn't initiate async mount of cryptohome.");
  }

  bool MountForBwsi(int* error_code) {
    return chromeos::CryptohomeMountGuest(error_code);
  }

  bool AsyncMountForBwsi(Delegate* d) {
    return CacheCallback(chromeos::CryptohomeAsyncMountGuest(),
                         d,
                         "Couldn't initiate async mount of cryptohome.");
  }

  bool Remove(const std::string& user_email) {
    return chromeos::CryptohomeRemove(user_email.c_str());
  }

  bool AsyncRemove(const std::string& user_email, Delegate* d) {
    return CacheCallback(
        chromeos::CryptohomeAsyncRemove(user_email.c_str()),
        d,
        "Couldn't initiate async removal of cryptohome.");
  }

  bool IsMounted() {
    return chromeos::CryptohomeIsMounted();
  }

  CryptohomeBlob GetSystemSalt() {
    return chromeos::CryptohomeGetSystemSalt();
  }

 private:
  static void Handler(const chromeos::CryptohomeAsyncCallStatus& event,
                      void* cryptohome_library) {
    CryptohomeLibraryImpl* library =
        reinterpret_cast<CryptohomeLibraryImpl*>(cryptohome_library);
    library->Dispatch(event);
  }

  void Init() {
    cryptohome_connection_ = chromeos::CryptohomeMonitorSession(&Handler, this);
  }

  void Dispatch(const chromeos::CryptohomeAsyncCallStatus& event) {
    callback_map_[event.async_id]->OnComplete(event.return_status,
                                              event.return_code);
    callback_map_[event.async_id] = NULL;
  }

  bool CacheCallback(int async_id,
                     Delegate* d,
                     const char* error) {
    if (async_id == 0) {
      LOG(ERROR) << error;
      return false;
    }
    callback_map_[async_id] = d;
    return true;
  }

  typedef base::hash_map<int, Delegate*> CallbackMap;
  mutable CallbackMap callback_map_;

  void* cryptohome_connection_;

  DISALLOW_COPY_AND_ASSIGN(CryptohomeLibraryImpl);
};

class CryptohomeLibraryStubImpl : public CryptohomeLibrary {
 public:
  CryptohomeLibraryStubImpl() {}
  virtual ~CryptohomeLibraryStubImpl() {}

  bool CheckKey(const std::string& user_email, const std::string& passhash) {
    return true;
  }

  bool AsyncCheckKey(const std::string& user_email,
                     const std::string& passhash,
                     Delegate* callback) {
    ChromeThread::PostTask(
        ChromeThread::UI, FROM_HERE,
        NewRunnableFunction(&DoStubCallback, callback));
    return true;
  }

  bool MigrateKey(const std::string& user_email,
                  const std::string& old_hash,
                  const std::string& new_hash) {
    return true;
  }

  bool AsyncMigrateKey(const std::string& user_email,
                       const std::string& old_hash,
                       const std::string& new_hash,
                       Delegate* callback) {
    ChromeThread::PostTask(
        ChromeThread::UI, FROM_HERE,
        NewRunnableFunction(&DoStubCallback, callback));
    return true;
  }

  bool Remove(const std::string& user_email) {
    return true;
  }

  bool AsyncRemove(const std::string& user_email, Delegate* callback) {
    ChromeThread::PostTask(
        ChromeThread::UI, FROM_HERE,
        NewRunnableFunction(&DoStubCallback, callback));
    return true;
  }

  bool Mount(const std::string& user_email,
             const std::string& passhash,
             int* error_code) {
    return true;
  }

  bool AsyncMount(const std::string& user_email,
                  const std::string& passhash,
                  Delegate* callback) {
    ChromeThread::PostTask(
        ChromeThread::UI, FROM_HERE,
        NewRunnableFunction(&DoStubCallback, callback));
    return true;
  }

  bool MountForBwsi(int* error_code) {
    return true;
  }

  bool AsyncMountForBwsi(Delegate* callback) {
    ChromeThread::PostTask(
        ChromeThread::UI, FROM_HERE,
        NewRunnableFunction(&DoStubCallback, callback));
    return true;
  }

  bool IsMounted() {
    return true;
  }

  CryptohomeBlob GetSystemSalt() {
    CryptohomeBlob salt = CryptohomeBlob();
    salt.push_back(0);
    salt.push_back(0);
    return salt;
  }

 private:
  static void DoStubCallback(Delegate* callback) {
    callback->OnComplete(true, kCryptohomeMountErrorNone);
  }
  DISALLOW_COPY_AND_ASSIGN(CryptohomeLibraryStubImpl);
};

// static
CryptohomeLibrary* CryptohomeLibrary::GetImpl(bool stub) {
  if (stub)
    return new CryptohomeLibraryStubImpl();
  else
    return new CryptohomeLibraryImpl();
}

} // namespace chromeos
<commit_msg>[Chrome OS] Update to use new CryptohomeAsyncMount function signature<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/chromeos/cros/cryptohome_library.h"

#include "base/hash_tables.h"
#include "base/message_loop.h"
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/chromeos/cros/cros_library.h"

namespace chromeos {

// This class handles the interaction with the ChromeOS cryptohome library APIs.
class CryptohomeLibraryImpl : public CryptohomeLibrary {
 public:
  CryptohomeLibraryImpl() {
    if (CrosLibrary::Get()->EnsureLoaded())
      Init();
  }
  virtual ~CryptohomeLibraryImpl() {}

  bool CheckKey(const std::string& user_email, const std::string& passhash) {
    return chromeos::CryptohomeCheckKey(user_email.c_str(), passhash.c_str());
  }

  bool AsyncCheckKey(const std::string& user_email,
                     const std::string& passhash,
                     Delegate* d) {
    return CacheCallback(
        chromeos::CryptohomeAsyncCheckKey(user_email.c_str(), passhash.c_str()),
        d,
        "Couldn't initiate async check of user's key.");
  }

  bool MigrateKey(const std::string& user_email,
                  const std::string& old_hash,
                  const std::string& new_hash) {
    return chromeos::CryptohomeMigrateKey(user_email.c_str(),
                                          old_hash.c_str(),
                                          new_hash.c_str());
  }

  bool AsyncMigrateKey(const std::string& user_email,
                       const std::string& old_hash,
                       const std::string& new_hash,
                       Delegate* d) {
    return CacheCallback(
        chromeos::CryptohomeAsyncMigrateKey(user_email.c_str(),
                                            old_hash.c_str(),
                                            new_hash.c_str()),
        d,
        "Couldn't initiate aync migration of user's key");
  }

  bool Mount(const std::string& user_email,
             const std::string& passhash,
             int* error_code) {
    return chromeos::CryptohomeMountAllowFail(user_email.c_str(),
                                              passhash.c_str(),
                                              error_code);
  }

  bool AsyncMount(const std::string& user_email,
                  const std::string& passhash,
                  Delegate* d) {
    return CacheCallback(
        chromeos::CryptohomeAsyncMount(user_email.c_str(),
                                       passhash.c_str(),
                                       true,
                                       "",
                                       std::vector<std::string>()),
        d,
        "Couldn't initiate async mount of cryptohome.");
  }

  bool MountForBwsi(int* error_code) {
    return chromeos::CryptohomeMountGuest(error_code);
  }

  bool AsyncMountForBwsi(Delegate* d) {
    return CacheCallback(chromeos::CryptohomeAsyncMountGuest(),
                         d,
                         "Couldn't initiate async mount of cryptohome.");
  }

  bool Remove(const std::string& user_email) {
    return chromeos::CryptohomeRemove(user_email.c_str());
  }

  bool AsyncRemove(const std::string& user_email, Delegate* d) {
    return CacheCallback(
        chromeos::CryptohomeAsyncRemove(user_email.c_str()),
        d,
        "Couldn't initiate async removal of cryptohome.");
  }

  bool IsMounted() {
    return chromeos::CryptohomeIsMounted();
  }

  CryptohomeBlob GetSystemSalt() {
    return chromeos::CryptohomeGetSystemSalt();
  }

 private:
  static void Handler(const chromeos::CryptohomeAsyncCallStatus& event,
                      void* cryptohome_library) {
    CryptohomeLibraryImpl* library =
        reinterpret_cast<CryptohomeLibraryImpl*>(cryptohome_library);
    library->Dispatch(event);
  }

  void Init() {
    cryptohome_connection_ = chromeos::CryptohomeMonitorSession(&Handler, this);
  }

  void Dispatch(const chromeos::CryptohomeAsyncCallStatus& event) {
    callback_map_[event.async_id]->OnComplete(event.return_status,
                                              event.return_code);
    callback_map_[event.async_id] = NULL;
  }

  bool CacheCallback(int async_id,
                     Delegate* d,
                     const char* error) {
    if (async_id == 0) {
      LOG(ERROR) << error;
      return false;
    }
    callback_map_[async_id] = d;
    return true;
  }

  typedef base::hash_map<int, Delegate*> CallbackMap;
  mutable CallbackMap callback_map_;

  void* cryptohome_connection_;

  DISALLOW_COPY_AND_ASSIGN(CryptohomeLibraryImpl);
};

class CryptohomeLibraryStubImpl : public CryptohomeLibrary {
 public:
  CryptohomeLibraryStubImpl() {}
  virtual ~CryptohomeLibraryStubImpl() {}

  bool CheckKey(const std::string& user_email, const std::string& passhash) {
    return true;
  }

  bool AsyncCheckKey(const std::string& user_email,
                     const std::string& passhash,
                     Delegate* callback) {
    ChromeThread::PostTask(
        ChromeThread::UI, FROM_HERE,
        NewRunnableFunction(&DoStubCallback, callback));
    return true;
  }

  bool MigrateKey(const std::string& user_email,
                  const std::string& old_hash,
                  const std::string& new_hash) {
    return true;
  }

  bool AsyncMigrateKey(const std::string& user_email,
                       const std::string& old_hash,
                       const std::string& new_hash,
                       Delegate* callback) {
    ChromeThread::PostTask(
        ChromeThread::UI, FROM_HERE,
        NewRunnableFunction(&DoStubCallback, callback));
    return true;
  }

  bool Remove(const std::string& user_email) {
    return true;
  }

  bool AsyncRemove(const std::string& user_email, Delegate* callback) {
    ChromeThread::PostTask(
        ChromeThread::UI, FROM_HERE,
        NewRunnableFunction(&DoStubCallback, callback));
    return true;
  }

  bool Mount(const std::string& user_email,
             const std::string& passhash,
             int* error_code) {
    return true;
  }

  bool AsyncMount(const std::string& user_email,
                  const std::string& passhash,
                  Delegate* callback) {
    ChromeThread::PostTask(
        ChromeThread::UI, FROM_HERE,
        NewRunnableFunction(&DoStubCallback, callback));
    return true;
  }

  bool MountForBwsi(int* error_code) {
    return true;
  }

  bool AsyncMountForBwsi(Delegate* callback) {
    ChromeThread::PostTask(
        ChromeThread::UI, FROM_HERE,
        NewRunnableFunction(&DoStubCallback, callback));
    return true;
  }

  bool IsMounted() {
    return true;
  }

  CryptohomeBlob GetSystemSalt() {
    CryptohomeBlob salt = CryptohomeBlob();
    salt.push_back(0);
    salt.push_back(0);
    return salt;
  }

 private:
  static void DoStubCallback(Delegate* callback) {
    callback->OnComplete(true, kCryptohomeMountErrorNone);
  }
  DISALLOW_COPY_AND_ASSIGN(CryptohomeLibraryStubImpl);
};

// static
CryptohomeLibrary* CryptohomeLibrary::GetImpl(bool stub) {
  if (stub)
    return new CryptohomeLibraryStubImpl();
  else
    return new CryptohomeLibraryImpl();
}

} // namespace chromeos
<|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 "chrome/browser/chromeos/login/oobe_progress_bar.h"

#include "base/logging.h"
#include "base/utf_string_conversions.h"
#include "grit/theme_resources.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/canvas_skia.h"

namespace chromeos {

// static
SkBitmap* OobeProgressBar::dot_current_ = NULL;
SkBitmap* OobeProgressBar::dot_empty_ = NULL;
SkBitmap* OobeProgressBar::dot_filled_ = NULL;
SkBitmap* OobeProgressBar::line_ = NULL;
SkBitmap* OobeProgressBar::line_left_ = NULL;
SkBitmap* OobeProgressBar::line_right_ = NULL;

static const SkColor kCurrentTextColor = SkColorSetRGB(255, 255, 255);
static const SkColor kEmptyTextColor = SkColorSetRGB(112, 115, 118);
static const SkColor kFilledTextColor = SkColorSetRGB(112, 115, 118);
static const int kTextPadding = 5;

OobeProgressBar::OobeProgressBar(const std::vector<int>& steps)
    : steps_(steps), progress_(0) {
  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
  font_ = rb.GetFont(ResourceBundle::BaseFont);
  InitClass();
}

OobeProgressBar::~OobeProgressBar() {}

// static
void OobeProgressBar::InitClass() {
  static bool initialized = false;
  if (!initialized) {
    ResourceBundle& rb = ResourceBundle::GetSharedInstance();

    // Load images.
    dot_current_ = rb.GetBitmapNamed(IDR_OOBE_PROGRESS_DOT_CURRENT);
    dot_empty_ = rb.GetBitmapNamed(IDR_OOBE_PROGRESS_DOT_EMPTY);
    dot_filled_ = rb.GetBitmapNamed(IDR_OOBE_PROGRESS_DOT_FILLED);
    line_ = rb.GetBitmapNamed(IDR_OOBE_PROGRESS_LINE);
    line_left_ = rb.GetBitmapNamed(IDR_OOBE_PROGRESS_LINE_LEFT);
    line_right_ = rb.GetBitmapNamed(IDR_OOBE_PROGRESS_LINE_RIGHT);

    initialized = true;
  }
}

void OobeProgressBar::OnPaint(gfx::Canvas* canvas) {
  gfx::Rect bounds = GetContentsBounds();

  int x = bounds.x();
  int y = bounds.y();

  double step_width = static_cast<double>(bounds.width()) / steps_.size();

  for (size_t i = 0; i < steps_.size(); ++i) {
    SkBitmap* dot;
    SkColor color;
    SkBitmap* line_before = line_;
    SkBitmap* line_after = line_;
    if (i < progress_) {
      dot = dot_filled_;
      color = kFilledTextColor;
    } else if (i == progress_) {
      dot = dot_current_;
      color = kCurrentTextColor;
      line_before = line_left_;
      line_after = line_right_;
    } else {
      dot = dot_empty_;
      color = kEmptyTextColor;
    }

    // x coordinate for next step.
    int next_x = static_cast<int>((i + 1) * step_width);

    // Offset of line origin from dot origin.
    int line_offset_y = (dot->height() - line_->height()) / 2;

    // Current x for painting.
    int ix = x;

    int line_width = ((next_x - x) -
        (line_before->width() + dot->width() + line_after->width())) / 2;
    if (i > 0) {
      canvas->TileImageInt(*line_, ix, y + line_offset_y,
                           line_width, line_->height());
    }
    ix += line_width;
    if (i > 0) {
      canvas->DrawBitmapInt(*line_before, ix, y + line_offset_y);
    }
    ix += line_before->width();

    canvas->DrawBitmapInt(*dot, ix, y);
    ix += dot->width();

    if (i != steps_.size() - 1)
      canvas->DrawBitmapInt(*line_after, ix, y + line_offset_y);
    ix += line_after->width();

    if (i != steps_.size() - 1) {
      canvas->TileImageInt(*line_, ix, y + line_offset_y,
                           next_x - ix, line_->height());
    }

    string16 str = l10n_util::GetStringUTF16(steps_[i]);
    canvas->DrawStringInt(str, font_, color,
        x + kTextPadding, y + dot->height() + kTextPadding,
        (next_x - x - 2 * kTextPadding),
        (bounds.height() - dot->height() - 2 * kTextPadding),
        gfx::Canvas::MULTI_LINE | gfx::Canvas::TEXT_ALIGN_CENTER |
            gfx::Canvas::TEXT_VALIGN_TOP);

    x = next_x;
  }
}

void OobeProgressBar::OnLocaleChanged() {
  font_ = ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BaseFont);
  SchedulePaint();
}

void OobeProgressBar::SetStep(int step) {
  for (size_t i = 0; i < steps_.size(); ++i) {
    if (steps_[i] == step) {
      progress_ = i;
      SchedulePaint();
      return;
    }
  }
  NOTREACHED();
}

}  // namespace chromeos
<commit_msg>Add NO_ELLIPSIS because TEXT_ALIGN_CENTER doesn't work without it<commit_after>// 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 "chrome/browser/chromeos/login/oobe_progress_bar.h"

#include "base/logging.h"
#include "base/utf_string_conversions.h"
#include "grit/theme_resources.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/canvas_skia.h"

namespace chromeos {

// static
SkBitmap* OobeProgressBar::dot_current_ = NULL;
SkBitmap* OobeProgressBar::dot_empty_ = NULL;
SkBitmap* OobeProgressBar::dot_filled_ = NULL;
SkBitmap* OobeProgressBar::line_ = NULL;
SkBitmap* OobeProgressBar::line_left_ = NULL;
SkBitmap* OobeProgressBar::line_right_ = NULL;

static const SkColor kCurrentTextColor = SkColorSetRGB(255, 255, 255);
static const SkColor kEmptyTextColor = SkColorSetRGB(112, 115, 118);
static const SkColor kFilledTextColor = SkColorSetRGB(112, 115, 118);
static const int kTextPadding = 5;

OobeProgressBar::OobeProgressBar(const std::vector<int>& steps)
    : steps_(steps), progress_(0) {
  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
  font_ = rb.GetFont(ResourceBundle::BaseFont);
  InitClass();
}

OobeProgressBar::~OobeProgressBar() {}

// static
void OobeProgressBar::InitClass() {
  static bool initialized = false;
  if (!initialized) {
    ResourceBundle& rb = ResourceBundle::GetSharedInstance();

    // Load images.
    dot_current_ = rb.GetBitmapNamed(IDR_OOBE_PROGRESS_DOT_CURRENT);
    dot_empty_ = rb.GetBitmapNamed(IDR_OOBE_PROGRESS_DOT_EMPTY);
    dot_filled_ = rb.GetBitmapNamed(IDR_OOBE_PROGRESS_DOT_FILLED);
    line_ = rb.GetBitmapNamed(IDR_OOBE_PROGRESS_LINE);
    line_left_ = rb.GetBitmapNamed(IDR_OOBE_PROGRESS_LINE_LEFT);
    line_right_ = rb.GetBitmapNamed(IDR_OOBE_PROGRESS_LINE_RIGHT);

    initialized = true;
  }
}

void OobeProgressBar::OnPaint(gfx::Canvas* canvas) {
  gfx::Rect bounds = GetContentsBounds();

  int x = bounds.x();
  int y = bounds.y();

  double step_width = static_cast<double>(bounds.width()) / steps_.size();

  for (size_t i = 0; i < steps_.size(); ++i) {
    SkBitmap* dot;
    SkColor color;
    SkBitmap* line_before = line_;
    SkBitmap* line_after = line_;
    if (i < progress_) {
      dot = dot_filled_;
      color = kFilledTextColor;
    } else if (i == progress_) {
      dot = dot_current_;
      color = kCurrentTextColor;
      line_before = line_left_;
      line_after = line_right_;
    } else {
      dot = dot_empty_;
      color = kEmptyTextColor;
    }

    // x coordinate for next step.
    int next_x = static_cast<int>((i + 1) * step_width);

    // Offset of line origin from dot origin.
    int line_offset_y = (dot->height() - line_->height()) / 2;

    // Current x for painting.
    int ix = x;

    int line_width = ((next_x - x) -
        (line_before->width() + dot->width() + line_after->width())) / 2;
    if (i > 0) {
      canvas->TileImageInt(*line_, ix, y + line_offset_y,
                           line_width, line_->height());
    }
    ix += line_width;
    if (i > 0) {
      canvas->DrawBitmapInt(*line_before, ix, y + line_offset_y);
    }
    ix += line_before->width();

    canvas->DrawBitmapInt(*dot, ix, y);
    ix += dot->width();

    if (i != steps_.size() - 1)
      canvas->DrawBitmapInt(*line_after, ix, y + line_offset_y);
    ix += line_after->width();

    if (i != steps_.size() - 1) {
      canvas->TileImageInt(*line_, ix, y + line_offset_y,
                           next_x - ix, line_->height());
    }

    string16 str = l10n_util::GetStringUTF16(steps_[i]);
    canvas->DrawStringInt(str, font_, color,
        x + kTextPadding, y + dot->height() + kTextPadding,
        (next_x - x - 2 * kTextPadding),
        (bounds.height() - dot->height() - 2 * kTextPadding),
        gfx::Canvas::MULTI_LINE | gfx::Canvas::TEXT_ALIGN_CENTER |
            gfx::Canvas::TEXT_VALIGN_TOP | gfx::Canvas::NO_ELLIPSIS);

    x = next_x;
  }
}

void OobeProgressBar::OnLocaleChanged() {
  font_ = ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BaseFont);
  SchedulePaint();
}

void OobeProgressBar::SetStep(int step) {
  for (size_t i = 0; i < steps_.size(); ++i) {
    if (steps_[i] == step) {
      progress_ = i;
      SchedulePaint();
      return;
    }
  }
  NOTREACHED();
}

}  // namespace chromeos
<|endoftext|>


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

#include "chrome/browser/extensions/extension_apitest.h"

#include "chrome/browser/browser.h"
#include "chrome/browser/notifications/desktop_notification_service.h"
#include "chrome/browser/profile.h"

// Flaky, http://crbug.com/42314.
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, FLAKY_Notifications) {
#if defined(OS_LINUX) && defined(TOOLKIT_VIEWS)
  // Notifications not supported on linux/views yet.
#else
  ASSERT_TRUE(RunExtensionTest("notifications/has_not_permission")) << message_;
  ASSERT_TRUE(RunExtensionTest("notifications/has_permission_manifest"))
      << message_;
  browser()->profile()->GetDesktopNotificationService()
      ->GrantPermission(GURL(
          "chrome-extension://peoadpeiejnhkmpaakpnompolbglelel"));
  ASSERT_TRUE(RunExtensionTest("notifications/has_permission_prefs"))
      << message_;
#endif
}

<commit_msg>Disable a flaky test that seems to completely blow up with some frequency on the mac bots and seems to cause a ripple in hosing the bot in general. BUG=42314,50060 TEST=Mac test bots stay greener Review URL: http://codereview.chromium.org/2834069<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/extensions/extension_apitest.h"

#include "chrome/browser/browser.h"
#include "chrome/browser/notifications/desktop_notification_service.h"
#include "chrome/browser/profile.h"

// Fails and hoses bot, http://crbug.com/50060.
// Flaky, http://crbug.com/42314.
#if defined(OS_MACOSX)
#define MAYBE_Notifications DISABLED_Notifications
#else
#define MAYBE_Notifications FLAKY_Notifications
#endif
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_Notifications) {
#if defined(OS_LINUX) && defined(TOOLKIT_VIEWS)
  // Notifications not supported on linux/views yet.
#else
  ASSERT_TRUE(RunExtensionTest("notifications/has_not_permission")) << message_;
  ASSERT_TRUE(RunExtensionTest("notifications/has_permission_manifest"))
      << message_;
  browser()->profile()->GetDesktopNotificationService()
      ->GrantPermission(GURL(
          "chrome-extension://peoadpeiejnhkmpaakpnompolbglelel"));
  ASSERT_TRUE(RunExtensionTest("notifications/has_permission_prefs"))
      << message_;
#endif
}

<|endoftext|>


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

#include "chrome/browser/search_engines/search_terms_data.h"

#include "base/logging.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/google/google_url_tracker.h"
#include "googleurl/src/gurl.h"

#if defined(OS_WIN)
#include "chrome/browser/rlz/rlz.h"
#endif

SearchTermsData::SearchTermsData() {
}

SearchTermsData::~SearchTermsData() {
}

std::string SearchTermsData::GoogleBaseSuggestURLValue() const {
  // The suggest base URL we want at the end is something like
  // "http://clients1.google.TLD/complete/".  The key bit we want from the
  // original Google base URL is the TLD.

  // Start with the Google base URL.
  const GURL base_url(GoogleBaseURLValue());
  DCHECK(base_url.is_valid());

  // Change "www." to "clients1." in the hostname.  If no "www." was found, just
  // prepend "clients1.".
  const std::string base_host(base_url.host());
  GURL::Replacements repl;
  const std::string suggest_host("clients1." +
      (base_host.compare(0, 4, "www.") ? base_host : base_host.substr(4)));
  repl.SetHostStr(suggest_host);

  // Replace any existing path with "/complete/".
  static const std::string suggest_path("/complete/");
  repl.SetPathStr(suggest_path);

  // Clear the query and ref.
  repl.ClearQuery();
  repl.ClearRef();
  return base_url.ReplaceComponents(repl).spec();
}

// static
std::string* UIThreadSearchTermsData::google_base_url_ = NULL;

UIThreadSearchTermsData::UIThreadSearchTermsData() {
  // GoogleURLTracker::GoogleURL() DCHECKs this also, but adding it here helps
  // us catch bad behavior at a more common place in this code.
  DCHECK(!ChromeThread::IsWellKnownThread(ChromeThread::UI) ||
         ChromeThread::CurrentlyOn(ChromeThread::UI));
}

std::string UIThreadSearchTermsData::GoogleBaseURLValue() const {
  DCHECK(!ChromeThread::IsWellKnownThread(ChromeThread::UI) ||
         ChromeThread::CurrentlyOn(ChromeThread::UI));
  return google_base_url_ ?
    (*google_base_url_) : GoogleURLTracker::GoogleURL().spec();
}

std::string UIThreadSearchTermsData::GetApplicationLocale() const {
  DCHECK(!ChromeThread::IsWellKnownThread(ChromeThread::UI) ||
         ChromeThread::CurrentlyOn(ChromeThread::UI));
  return g_browser_process->GetApplicationLocale();
}

#if defined(OS_WIN) && defined(GOOGLE_CHROME_BUILD)
std::wstring UIThreadSearchTermsData::GetRlzParameterValue() const {
  DCHECK(!ChromeThread::IsWellKnownThread(ChromeThread::UI) ||
         ChromeThread::CurrentlyOn(ChromeThread::UI));
  std::wstring rlz_string;
  RLZTracker::GetAccessPointRlz(rlz_lib::CHROME_OMNIBOX, &rlz_string);
  return rlz_string;
}
#endif

// static
void UIThreadSearchTermsData::SetGoogleBaseURL(std::string* google_base_url) {
  delete google_base_url_;
  google_base_url_ = google_base_url;
}
<commit_msg>Do not include RLZ parameters in search requests for organic installs.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/search_engines/search_terms_data.h"

#include "base/logging.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/google/google_url_tracker.h"
#include "googleurl/src/gurl.h"

#if defined(OS_WIN)
#include "chrome/browser/rlz/rlz.h"
#endif

SearchTermsData::SearchTermsData() {
}

SearchTermsData::~SearchTermsData() {
}

std::string SearchTermsData::GoogleBaseSuggestURLValue() const {
  // The suggest base URL we want at the end is something like
  // "http://clients1.google.TLD/complete/".  The key bit we want from the
  // original Google base URL is the TLD.

  // Start with the Google base URL.
  const GURL base_url(GoogleBaseURLValue());
  DCHECK(base_url.is_valid());

  // Change "www." to "clients1." in the hostname.  If no "www." was found, just
  // prepend "clients1.".
  const std::string base_host(base_url.host());
  GURL::Replacements repl;
  const std::string suggest_host("clients1." +
      (base_host.compare(0, 4, "www.") ? base_host : base_host.substr(4)));
  repl.SetHostStr(suggest_host);

  // Replace any existing path with "/complete/".
  static const std::string suggest_path("/complete/");
  repl.SetPathStr(suggest_path);

  // Clear the query and ref.
  repl.ClearQuery();
  repl.ClearRef();
  return base_url.ReplaceComponents(repl).spec();
}

// static
std::string* UIThreadSearchTermsData::google_base_url_ = NULL;

UIThreadSearchTermsData::UIThreadSearchTermsData() {
  // GoogleURLTracker::GoogleURL() DCHECKs this also, but adding it here helps
  // us catch bad behavior at a more common place in this code.
  DCHECK(!ChromeThread::IsWellKnownThread(ChromeThread::UI) ||
         ChromeThread::CurrentlyOn(ChromeThread::UI));
}

std::string UIThreadSearchTermsData::GoogleBaseURLValue() const {
  DCHECK(!ChromeThread::IsWellKnownThread(ChromeThread::UI) ||
         ChromeThread::CurrentlyOn(ChromeThread::UI));
  return google_base_url_ ?
    (*google_base_url_) : GoogleURLTracker::GoogleURL().spec();
}

std::string UIThreadSearchTermsData::GetApplicationLocale() const {
  DCHECK(!ChromeThread::IsWellKnownThread(ChromeThread::UI) ||
         ChromeThread::CurrentlyOn(ChromeThread::UI));
  return g_browser_process->GetApplicationLocale();
}

#if defined(OS_WIN) && defined(GOOGLE_CHROME_BUILD)
std::wstring UIThreadSearchTermsData::GetRlzParameterValue() const {
  DCHECK(!ChromeThread::IsWellKnownThread(ChromeThread::UI) ||
         ChromeThread::CurrentlyOn(ChromeThread::UI));
  std::wstring rlz_string;
  // For organic brandcodes do not use rlz at all. Empty brandcode usually
  // means a chromium install. This is ok.
  std::wstring brand;
  if (GoogleUpdateSettings::GetBrand(&brand) && !brand.empty() &&
      !GoogleUpdateSettings::IsOrganic(brand))
    RLZTracker::GetAccessPointRlz(rlz_lib::CHROME_OMNIBOX, &rlz_string);
  return rlz_string;
}
#endif

// static
void UIThreadSearchTermsData::SetGoogleBaseURL(std::string* google_base_url) {
  delete google_base_url_;
  google_base_url_ = google_base_url;
}
<|endoftext|>