<commit_before>/*************************************************************************/
/*  dialogs.cpp                                                          */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                    http://www.godotengine.org                         */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur.                 */
/*                                                                       */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the       */
/* "Software"), to deal in the Software without restriction, including   */
/* without limitation the rights to use, copy, modify, merge, publish,   */
/* distribute, sublicense, and/or sell copies of the Software, and to    */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions:                                             */
/*                                                                       */
/* The above copyright notice and this permission notice shall be        */
/* included in all copies or substantial portions of the Software.       */
/*                                                                       */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
/*************************************************************************/
#include "dialogs.h"
#include "print_string.h"
#include "line_edit.h"
#include "translation.h"

void WindowDialog::_post_popup() {

	dragging=false; //just in case
}

bool WindowDialog::has_point(const Point2& p_point) const {

	int extra = get_constant("titlebar_height","WindowDialog");
	Rect2 r( Point2(), get_size() );
	r.pos.y-=extra;
	r.size.y+=extra;
	return r.has_point(p_point);

}

void WindowDialog::_input_event(const InputEvent& p_event) {

	if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==BUTTON_LEFT) {

		if (p_event.mouse_button.pressed && p_event.mouse_button.y < 0)
			dragging=true;
		else if (dragging && !p_event.mouse_button.pressed)
			dragging=false;
	}

	if (p_event.type == InputEvent::MOUSE_MOTION && dragging) {

		Point2 rel( p_event.mouse_motion.relative_x, p_event.mouse_motion.relative_y );
		Point2 pos = get_pos();

		pos+=rel;

		if (pos.y<0)
			pos.y=0;

		set_pos(pos);
	}
}

void WindowDialog::_notification(int p_what) {

	switch(p_what) {

		case NOTIFICATION_DRAW: {

			RID ci = get_canvas_item();
			Size2 s = get_size();
			Ref<StyleBox> st = get_stylebox("panel","WindowDialog");
			st->draw(ci,Rect2(Point2(),s));
			int th = get_constant("title_height","WindowDialog");
			Color tc = get_color("title_color","WindowDialog");
			Ref<Font> font = get_font("title_font","WindowDialog");
			int ofs = (s.width-font->get_string_size(title).width)/2;
			//int ofs = st->get_margin(MARGIN_LEFT);
			draw_string(font,Point2(ofs,-th+font->get_ascent()),title,tc,s.width - st->get_minimum_size().width);

		} break;
		case NOTIFICATION_THEME_CHANGED:
		case NOTIFICATION_ENTER_TREE: {

			close_button->set_normal_texture( get_icon("close","WindowDialog"));
			close_button->set_pressed_texture( get_icon("close","WindowDialog"));
			close_button->set_hover_texture( get_icon("close_hilite","WindowDialog"));
			close_button->set_anchor(MARGIN_LEFT,ANCHOR_END);
			close_button->set_begin( Point2( get_constant("close_h_ofs","WindowDialog"), -get_constant("close_v_ofs","WindowDialog") ));

		} break;
	}

}

void WindowDialog::_closed() {

	_close_pressed();
	hide();
}

void WindowDialog::set_title(const String& p_title) {

	title=XL_MESSAGE(p_title);
	update();
}

Size2 WindowDialog::get_minimum_size() const {

	Ref<Font> font = get_font("title_font","WindowDialog");
	int msx=close_button->get_combined_minimum_size().x;
	msx+=font->get_string_size(title).x;

	return Size2(msx,1);
}

String WindowDialog::get_title() const {

	return title;
}

TextureButton *WindowDialog::get_close_button() {

	return close_button;
}

void WindowDialog::_bind_methods() {

	ObjectTypeDB::bind_method( _MD("_input_event"),&WindowDialog::_input_event);
	ObjectTypeDB::bind_method( _MD("set_title","title"),&WindowDialog::set_title);
	ObjectTypeDB::bind_method( _MD("get_title"),&WindowDialog::get_title);
	ObjectTypeDB::bind_method( _MD("_closed"),&WindowDialog::_closed);
	ObjectTypeDB::bind_method( _MD("get_close_button:TextureButton"),&WindowDialog::get_close_button);

	ADD_PROPERTY( PropertyInfo(Variant::STRING,"window/title",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_DEFAULT_INTL),_SCS("set_title"),_SCS("get_title"));
}

WindowDialog::WindowDialog() {

	//title="Hello!";
	dragging=false;
	close_button = memnew( TextureButton );
	add_child(close_button);
	close_button->connect("pressed",this,"_closed");

}

WindowDialog::~WindowDialog(){

}

void PopupDialog::_notification(int p_what) {

	if (p_what==NOTIFICATION_DRAW) {

		RID ci = get_canvas_item();
		get_stylebox("panel","PopupMenu")->draw(ci,Rect2(Point2(),get_size()));
	}
}

PopupDialog::PopupDialog() {

}

PopupDialog::~PopupDialog() {

}

//

void AcceptDialog::_post_popup() {

	WindowDialog::_post_popup();
	get_ok()->grab_focus();

}

void AcceptDialog::_notification(int p_what) {

	if (p_what==NOTIFICATION_MODAL_CLOSE) {

		cancel_pressed();
	} if (p_what==NOTIFICATION_RESIZED) {

		_update_child_rect();
	}
}

void AcceptDialog::_builtin_text_entered(const String& p_text) {

	_ok_pressed();
}

void AcceptDialog::_ok_pressed() {

	if (hide_on_ok)
		hide();
	ok_pressed();
	emit_signal("confirmed");

}
void AcceptDialog::_close_pressed() {

	cancel_pressed();
}

String AcceptDialog::get_text() const {

	return label->get_text();
}
void AcceptDialog::set_text(String p_text) {

	label->set_text(p_text);
}

void AcceptDialog::set_hide_on_ok(bool p_hide) {

	hide_on_ok=p_hide;
}

bool AcceptDialog::get_hide_on_ok() const {

	return hide_on_ok;
}

void AcceptDialog::register_text_enter(Node *p_line_edit) {

	ERR_FAIL_NULL(p_line_edit);
	p_line_edit->connect("text_entered", this,"_builtin_text_entered");
}

void AcceptDialog::_update_child_rect() {

	int margin = get_constant("margin","Dialogs");
	Size2 size = get_size();
	Size2 hminsize = hbc->get_combined_minimum_size();

	Vector2 cpos(margin,margin);
	Vector2 csize(size.x-margin*2,size.y-margin*3-hminsize.y);
	label->set_pos(cpos);
	label->set_size(csize);

	if (child) {

		child->set_pos(cpos);
		child->set_size(csize);
	}

	cpos.y+=csize.y+margin;
	csize.y=hminsize.y;

	hbc->set_pos(cpos);
	hbc->set_size(csize);

}

Size2 AcceptDialog::get_minimum_size() const {

	int margin = get_constant("margin","Dialogs");
	Size2 minsize = label->get_combined_minimum_size();
	if (child) {

		Size2 cminsize = child->get_combined_minimum_size();
		minsize.x=MAX(cminsize.x,minsize.x);
		minsize.y=MAX(cminsize.y,minsize.y);
	}

	Size2 hminsize = hbc->get_combined_minimum_size();
	minsize.x = MAX(hminsize.x,minsize.x);
	minsize.y+=hminsize.y;
	minsize.x+=margin*2;
	minsize.y+=margin*3; //one as separation between hbc and child

	Size2 wmsize = WindowDialog::get_minimum_size();
	minsize.x=MAX(wmsize.x,minsize.x);
	return minsize;
}

void AcceptDialog::set_child_rect(Control *p_child) {

	ERR_FAIL_COND(p_child->get_parent()!=this);

	//p_child->set_area_as_parent_rect(get_constant("margin","Dialogs"));
	child=p_child;
	minimum_size_changed();
	_update_child_rect();
}

void AcceptDialog::remove_child_notify(Node *p_child) {

	if (p_child==child) {
		child=NULL;
	}
}

void AcceptDialog::_custom_action(const String& p_action) {

	emit_signal("custom_action",p_action);
	custom_action(p_action);
}

Button* AcceptDialog::add_button(const String& p_text,bool p_right,const String& p_action) {

	Button *button = memnew( Button );
	button->set_text(p_text);
	if (p_right) {
		hbc->add_child(button);
		hbc->add_spacer();
	} else {

		hbc->add_child(button);
		hbc->move_child(button,0);
		hbc->add_spacer(true);
	}

	if (p_action!="") {
		button->connect("pressed",this,"_custom_action",varray(p_action));
	}

	return button;
}

Button* AcceptDialog::add_cancel(const String &p_cancel) {

	String c = p_cancel;
	if (p_cancel=="")
		c=RTR("Cancel");
	Button *b = swap_ok_cancel ? add_button(c,true) : add_button(c);
	b->connect("pressed",this,"_closed");
	return b;
}

void AcceptDialog::_bind_methods() {

	ObjectTypeDB::bind_method(_MD("_ok"),&AcceptDialog::_ok_pressed);
	ObjectTypeDB::bind_method(_MD("get_ok"),&AcceptDialog::get_ok);
	ObjectTypeDB::bind_method(_MD("get_label"),&AcceptDialog::get_label);
	ObjectTypeDB::bind_method(_MD("set_hide_on_ok","enabled"),&AcceptDialog::set_hide_on_ok);
	ObjectTypeDB::bind_method(_MD("get_hide_on_ok"),&AcceptDialog::get_hide_on_ok);
	ObjectTypeDB::bind_method(_MD("add_button:Button","text","right","action"),&AcceptDialog::add_button,DEFVAL(false),DEFVAL(""));
	ObjectTypeDB::bind_method(_MD("add_cancel:Button","name"),&AcceptDialog::add_cancel);
	ObjectTypeDB::bind_method(_MD("_builtin_text_entered"),&AcceptDialog::_builtin_text_entered);
	ObjectTypeDB::bind_method(_MD("register_text_enter:LineEdit","line_edit"),&AcceptDialog::register_text_enter);
	ObjectTypeDB::bind_method(_MD("_custom_action"),&AcceptDialog::_custom_action);
	ObjectTypeDB::bind_method(_MD("set_text","text"),&AcceptDialog::set_text);
	ObjectTypeDB::bind_method(_MD("get_text"),&AcceptDialog::get_text);
	ObjectTypeDB::bind_method(_MD("set_child_rect","child:Control"),&AcceptDialog::set_child_rect);

	ADD_SIGNAL( MethodInfo("confirmed") );
	ADD_SIGNAL( MethodInfo("custom_action",PropertyInfo(Variant::STRING,"action")) );

	ADD_PROPERTYNZ( PropertyInfo(Variant::STRING,"dialog/text",PROPERTY_HINT_MULTILINE_TEXT,"",PROPERTY_USAGE_DEFAULT_INTL),_SCS("set_text"),_SCS("get_text"));
	ADD_PROPERTY( PropertyInfo(Variant::BOOL, "dialog/hide_on_ok"),_SCS("set_hide_on_ok"),_SCS("get_hide_on_ok") );

}

bool AcceptDialog::swap_ok_cancel=false;
void AcceptDialog::set_swap_ok_cancel(bool p_swap) {

	swap_ok_cancel=p_swap;
}

AcceptDialog::AcceptDialog() {

	int margin = get_constant("margin","Dialogs");
	int button_margin = get_constant("button_margin","Dialogs");

	label = memnew( Label );
	label->set_anchor(MARGIN_RIGHT,ANCHOR_END);
	label->set_anchor(MARGIN_BOTTOM,ANCHOR_END);
	label->set_begin( Point2( margin, margin) );
	label->set_end( Point2( margin, button_margin+10) );
	//label->set_autowrap(true);
	add_child(label);

	hbc = memnew( HBoxContainer );
	add_child(hbc);

	hbc->add_spacer();
	ok = memnew( Button );
	ok->set_text(RTR("OK"));
	hbc->add_child(ok);
	hbc->add_spacer();

	ok->connect("pressed", this,"_ok");
	set_as_toplevel(true);

	hide_on_ok=true;
	set_title(RTR("Alert!"));

	child=NULL;
}

AcceptDialog::~AcceptDialog()
{
}

void ConfirmationDialog::_bind_methods() {

	ObjectTypeDB::bind_method(_MD("get_cancel:Button"),&ConfirmationDialog::get_cancel);
}

Button *ConfirmationDialog::get_cancel() {

	return cancel;
}

ConfirmationDialog::ConfirmationDialog() {

	set_title(RTR("Please Confirm..."));
	cancel = add_cancel();
}
<commit_msg>Fix Accept/ConfirmationDialog UI broken<commit_after>/*************************************************************************/
/*  dialogs.cpp                                                          */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                    http://www.godotengine.org                         */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur.                 */
/*                                                                       */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the       */
/* "Software"), to deal in the Software without restriction, including   */
/* without limitation the rights to use, copy, modify, merge, publish,   */
/* distribute, sublicense, and/or sell copies of the Software, and to    */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions:                                             */
/*                                                                       */
/* The above copyright notice and this permission notice shall be        */
/* included in all copies or substantial portions of the Software.       */
/*                                                                       */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
/*************************************************************************/
#include "dialogs.h"
#include "print_string.h"
#include "line_edit.h"
#include "translation.h"

void WindowDialog::_post_popup() {

	dragging=false; //just in case
}

bool WindowDialog::has_point(const Point2& p_point) const {

	int extra = get_constant("titlebar_height","WindowDialog");
	Rect2 r( Point2(), get_size() );
	r.pos.y-=extra;
	r.size.y+=extra;
	return r.has_point(p_point);

}

void WindowDialog::_input_event(const InputEvent& p_event) {

	if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==BUTTON_LEFT) {

		if (p_event.mouse_button.pressed && p_event.mouse_button.y < 0)
			dragging=true;
		else if (dragging && !p_event.mouse_button.pressed)
			dragging=false;
	}

	if (p_event.type == InputEvent::MOUSE_MOTION && dragging) {

		Point2 rel( p_event.mouse_motion.relative_x, p_event.mouse_motion.relative_y );
		Point2 pos = get_pos();

		pos+=rel;

		if (pos.y<0)
			pos.y=0;

		set_pos(pos);
	}
}

void WindowDialog::_notification(int p_what) {

	switch(p_what) {

		case NOTIFICATION_DRAW: {

			RID ci = get_canvas_item();
			Size2 s = get_size();
			Ref<StyleBox> st = get_stylebox("panel","WindowDialog");
			st->draw(ci,Rect2(Point2(),s));
			int th = get_constant("title_height","WindowDialog");
			Color tc = get_color("title_color","WindowDialog");
			Ref<Font> font = get_font("title_font","WindowDialog");
			int ofs = (s.width-font->get_string_size(title).width)/2;
			//int ofs = st->get_margin(MARGIN_LEFT);
			draw_string(font,Point2(ofs,-th+font->get_ascent()),title,tc,s.width - st->get_minimum_size().width);

		} break;
		case NOTIFICATION_THEME_CHANGED:
		case NOTIFICATION_ENTER_TREE: {

			close_button->set_normal_texture( get_icon("close","WindowDialog"));
			close_button->set_pressed_texture( get_icon("close","WindowDialog"));
			close_button->set_hover_texture( get_icon("close_hilite","WindowDialog"));
			close_button->set_anchor(MARGIN_LEFT,ANCHOR_END);
			close_button->set_begin( Point2( get_constant("close_h_ofs","WindowDialog"), -get_constant("close_v_ofs","WindowDialog") ));

		} break;
	}

}

void WindowDialog::_closed() {

	_close_pressed();
	hide();
}

void WindowDialog::set_title(const String& p_title) {

	title=XL_MESSAGE(p_title);
	update();
}

Size2 WindowDialog::get_minimum_size() const {

	Ref<Font> font = get_font("title_font","WindowDialog");
	int msx=close_button->get_combined_minimum_size().x;
	msx+=font->get_string_size(title).x;

	return Size2(msx,1);
}

String WindowDialog::get_title() const {

	return title;
}

TextureButton *WindowDialog::get_close_button() {

	return close_button;
}

void WindowDialog::_bind_methods() {

	ObjectTypeDB::bind_method( _MD("_input_event"),&WindowDialog::_input_event);
	ObjectTypeDB::bind_method( _MD("set_title","title"),&WindowDialog::set_title);
	ObjectTypeDB::bind_method( _MD("get_title"),&WindowDialog::get_title);
	ObjectTypeDB::bind_method( _MD("_closed"),&WindowDialog::_closed);
	ObjectTypeDB::bind_method( _MD("get_close_button:TextureButton"),&WindowDialog::get_close_button);

	ADD_PROPERTY( PropertyInfo(Variant::STRING,"window/title",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_DEFAULT_INTL),_SCS("set_title"),_SCS("get_title"));
}

WindowDialog::WindowDialog() {

	//title="Hello!";
	dragging=false;
	close_button = memnew( TextureButton );
	add_child(close_button);
	close_button->connect("pressed",this,"_closed");

}

WindowDialog::~WindowDialog(){

}

void PopupDialog::_notification(int p_what) {

	if (p_what==NOTIFICATION_DRAW) {

		RID ci = get_canvas_item();
		get_stylebox("panel","PopupMenu")->draw(ci,Rect2(Point2(),get_size()));
	}
}

PopupDialog::PopupDialog() {

}

PopupDialog::~PopupDialog() {

}

//

void AcceptDialog::_post_popup() {

	WindowDialog::_post_popup();
	get_ok()->grab_focus();

}

void AcceptDialog::_notification(int p_what) {

	if (p_what==NOTIFICATION_MODAL_CLOSE) {

		cancel_pressed();
	} if (p_what==NOTIFICATION_RESIZED) {

		_update_child_rect();
	}
}

void AcceptDialog::_builtin_text_entered(const String& p_text) {

	_ok_pressed();
}

void AcceptDialog::_ok_pressed() {

	if (hide_on_ok)
		hide();
	ok_pressed();
	emit_signal("confirmed");

}
void AcceptDialog::_close_pressed() {

	cancel_pressed();
}

String AcceptDialog::get_text() const {

	return label->get_text();
}
void AcceptDialog::set_text(String p_text) {

	label->set_text(p_text);
	minimum_size_changed();
	_update_child_rect();
}

void AcceptDialog::set_hide_on_ok(bool p_hide) {

	hide_on_ok=p_hide;
}

bool AcceptDialog::get_hide_on_ok() const {

	return hide_on_ok;
}

void AcceptDialog::register_text_enter(Node *p_line_edit) {

	ERR_FAIL_NULL(p_line_edit);
	p_line_edit->connect("text_entered", this,"_builtin_text_entered");
}

void AcceptDialog::_update_child_rect() {
	Size2 label_size=label->get_minimum_size();
	if (label->get_text().empty()) {
		label_size.height = 0;
	}
	int margin = get_constant("margin","Dialogs");
	Size2 size = get_size();
	Size2 hminsize = hbc->get_combined_minimum_size();

	Vector2 cpos(margin,margin+label_size.height);
	Vector2 csize(size.x-margin*2,size.y-margin*3-hminsize.y-label_size.height);

	if (child) {

		child->set_pos(cpos);
		child->set_size(csize);
	}

	cpos.y+=csize.y+margin;
	csize.y=hminsize.y;

	hbc->set_pos(cpos);
	hbc->set_size(csize);

}

Size2 AcceptDialog::get_minimum_size() const {

	int margin = get_constant("margin","Dialogs");
	Size2 minsize = label->get_combined_minimum_size();
	if (child) {

		Size2 cminsize = child->get_combined_minimum_size();
		minsize.x=MAX(cminsize.x,minsize.x);
		minsize.y=MAX(cminsize.y,minsize.y);
	}

	Size2 hminsize = hbc->get_combined_minimum_size();
	minsize.x = MAX(hminsize.x,minsize.x);
	minsize.y+=hminsize.y;
	minsize.x+=margin*2;
	minsize.y+=margin*3; //one as separation between hbc and child

	Size2 wmsize = WindowDialog::get_minimum_size();
	minsize.x=MAX(wmsize.x,minsize.x);
	return minsize;
}

void AcceptDialog::set_child_rect(Control *p_child) {

	ERR_FAIL_COND(p_child->get_parent()!=this);

	//p_child->set_area_as_parent_rect(get_constant("margin","Dialogs"));
	child=p_child;
	minimum_size_changed();
	_update_child_rect();
}

void AcceptDialog::remove_child_notify(Node *p_child) {

	if (p_child==child) {
		child=NULL;
	}
}

void AcceptDialog::_custom_action(const String& p_action) {

	emit_signal("custom_action",p_action);
	custom_action(p_action);
}

Button* AcceptDialog::add_button(const String& p_text,bool p_right,const String& p_action) {

	Button *button = memnew( Button );
	button->set_text(p_text);
	if (p_right) {
		hbc->add_child(button);
		hbc->add_spacer();
	} else {

		hbc->add_child(button);
		hbc->move_child(button,0);
		hbc->add_spacer(true);
	}

	if (p_action!="") {
		button->connect("pressed",this,"_custom_action",varray(p_action));
	}

	return button;
}

Button* AcceptDialog::add_cancel(const String &p_cancel) {

	String c = p_cancel;
	if (p_cancel=="")
		c=RTR("Cancel");
	Button *b = swap_ok_cancel ? add_button(c,true) : add_button(c);
	b->connect("pressed",this,"_closed");
	return b;
}

void AcceptDialog::_bind_methods() {

	ObjectTypeDB::bind_method(_MD("_ok"),&AcceptDialog::_ok_pressed);
	ObjectTypeDB::bind_method(_MD("get_ok"),&AcceptDialog::get_ok);
	ObjectTypeDB::bind_method(_MD("get_label"),&AcceptDialog::get_label);
	ObjectTypeDB::bind_method(_MD("set_hide_on_ok","enabled"),&AcceptDialog::set_hide_on_ok);
	ObjectTypeDB::bind_method(_MD("get_hide_on_ok"),&AcceptDialog::get_hide_on_ok);
	ObjectTypeDB::bind_method(_MD("add_button:Button","text","right","action"),&AcceptDialog::add_button,DEFVAL(false),DEFVAL(""));
	ObjectTypeDB::bind_method(_MD("add_cancel:Button","name"),&AcceptDialog::add_cancel);
	ObjectTypeDB::bind_method(_MD("_builtin_text_entered"),&AcceptDialog::_builtin_text_entered);
	ObjectTypeDB::bind_method(_MD("register_text_enter:LineEdit","line_edit"),&AcceptDialog::register_text_enter);
	ObjectTypeDB::bind_method(_MD("_custom_action"),&AcceptDialog::_custom_action);
	ObjectTypeDB::bind_method(_MD("set_text","text"),&AcceptDialog::set_text);
	ObjectTypeDB::bind_method(_MD("get_text"),&AcceptDialog::get_text);
	ObjectTypeDB::bind_method(_MD("set_child_rect","child:Control"),&AcceptDialog::set_child_rect);

	ADD_SIGNAL( MethodInfo("confirmed") );
	ADD_SIGNAL( MethodInfo("custom_action",PropertyInfo(Variant::STRING,"action")) );

	ADD_PROPERTYNZ( PropertyInfo(Variant::STRING,"dialog/text",PROPERTY_HINT_MULTILINE_TEXT,"",PROPERTY_USAGE_DEFAULT_INTL),_SCS("set_text"),_SCS("get_text"));
	ADD_PROPERTY( PropertyInfo(Variant::BOOL, "dialog/hide_on_ok"),_SCS("set_hide_on_ok"),_SCS("get_hide_on_ok") );

}

bool AcceptDialog::swap_ok_cancel=false;
void AcceptDialog::set_swap_ok_cancel(bool p_swap) {

	swap_ok_cancel=p_swap;
}

AcceptDialog::AcceptDialog() {

	int margin = get_constant("margin","Dialogs");
	int button_margin = get_constant("button_margin","Dialogs");

	label = memnew( Label );
	label->set_anchor(MARGIN_RIGHT,ANCHOR_END);
	label->set_anchor(MARGIN_BOTTOM,ANCHOR_END);
	label->set_begin( Point2( margin, margin) );
	label->set_end( Point2( margin, button_margin+10) );
	//label->set_autowrap(true);
	add_child(label);

	hbc = memnew( HBoxContainer );
	add_child(hbc);

	hbc->add_spacer();
	ok = memnew( Button );
	ok->set_text(RTR("OK"));
	hbc->add_child(ok);
	hbc->add_spacer();

	ok->connect("pressed", this,"_ok");
	set_as_toplevel(true);

	hide_on_ok=true;
	set_title(RTR("Alert!"));

	child=NULL;
}

AcceptDialog::~AcceptDialog()
{
}

void ConfirmationDialog::_bind_methods() {

	ObjectTypeDB::bind_method(_MD("get_cancel:Button"),&ConfirmationDialog::get_cancel);
}

Button *ConfirmationDialog::get_cancel() {

	return cancel;
}

ConfirmationDialog::ConfirmationDialog() {

	set_title(RTR("Please Confirm..."));
	cancel = add_cancel();
}
<|endoftext|>


<commit_before>/*********************************************************************
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2015, University of Colorado, Boulder
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of the Univ of CO, Boulder nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *********************************************************************/

/* Author: Dave Coleman <dave@dav.ee>
n   Desc:   Generate a random trajectory to test the ros_control controller
*/

// ROS
#include <ros/ros.h>
#include <control_msgs/FollowJointTrajectoryAction.h>
#include <trajectory_msgs/JointTrajectory.h>
#include <actionlib/client/simple_action_client.h>
#include <actionlib/client/terminal_state.h>

namespace ros_control_boilerplate
{
static const double SEC_PER_TRAJ_POINT = 5.0;  // time between points
static const std::size_t TRAJ_POINTS = 10;     // number of points to generate

class TestTrajectory
{
public:
  /**
   * \brief Constructor
   */
  TestTrajectory()
    : nh_private_("~")
  {
    std::string action_topic;
    nh_private_.getParam("action_topic", action_topic);
    if (action_topic.empty())
    {
      ROS_FATAL_STREAM_NAMED(
          "test_trajectory",
          "Not follow joint trajectory action topic found on the parameter server");
      exit(-1);
    }
    ROS_INFO_STREAM_NAMED("test_trajectory", "Connecting to action " << action_topic);

    // create the action client
    // true causes the client to spin its own thread
    actionlib::SimpleActionClient<control_msgs::FollowJointTrajectoryAction> action_client(
        action_topic, true);

    ROS_INFO_NAMED("test_trajetory", "Waiting for action server to start.");
    // wait for the action server to start
    action_client.waitForServer();  // will wait for infinite time

    ROS_INFO_NAMED("test_trajetory", "Action server started, sending goal.");

    // send a goal to the action
    control_msgs::FollowJointTrajectoryGoal goal;
    goal.trajectory = createTrajectory();
    std::cout << "Trajectry:\n" << goal.trajectory << std::endl;
    action_client.sendGoal(goal);

    // Wait for the action to return
    double wait_extra_padding = 2;  // time to wait longer than trajectory itself
    bool finished_before_timeout = action_client.waitForResult(
        ros::Duration(goal.trajectory.points.back().time_from_start.toSec() + wait_extra_padding));

    if (finished_before_timeout)
    {
      actionlib::SimpleClientGoalState state = action_client.getState();
      ROS_INFO_NAMED("test_trajetory", "Action finished: %s", state.toString().c_str());
    }
    else
      ROS_INFO_NAMED("test_trajetory", "Action did not finish before the time out.");

    ROS_INFO_STREAM_NAMED("test_trajectory", "TestTrajectory Finished");
  }

  /**
   * \brief Create random trajectory
   */
  trajectory_msgs::JointTrajectory createTrajectory()
  {
    std::vector<std::string> joint_names;
    double min_joint_value = -3.14;
    double max_joint_value = 3.14;

    // Get joint names
    nh_private_.getParam("hardware_interface/joints", joint_names);
    if (joint_names.size() == 0)
    {
      ROS_FATAL_STREAM_NAMED(
          "init",
          "Not joints found on parameter server for controller, did you load the proper yaml file?"
              << " Namespace: " << nh_private_.getNamespace() << "/hardware_interface/joints");
      exit(-1);
    }

    nh_private_.getParam("min_joint_value", min_joint_value);
    nh_private_.getParam("max_joint_value", max_joint_value);
    ROS_DEBUG_STREAM_NAMED("test_trajectory", "Creating trajectory with joint values from "
                                                  << min_joint_value << " to " << max_joint_value);

    // Create header
    trajectory_msgs::JointTrajectory trajectory;
    trajectory.header.stamp = ros::Time::now();
    trajectory.joint_names = joint_names;

    // Create trajectory with x points
    trajectory.points.resize(TRAJ_POINTS);
    for (std::size_t i = 0; i < TRAJ_POINTS; ++i)
    {
      trajectory.points[i].positions.resize(joint_names.size());
      // for each joint
      for (std::size_t j = 0; j < joint_names.size(); ++j)
      {
        trajectory.points[i].positions[j] = dRand(min_joint_value, max_joint_value);
        trajectory.points[i].time_from_start = ros::Duration(i * SEC_PER_TRAJ_POINT);
      }
    }

    return trajectory;
  }

  /** \brief Get random number */
  double dRand(double dMin, double dMax)
  {
    double d = (double)rand() / RAND_MAX;
    return dMin + d * (dMax - dMin);
  }

private:
  // A shared node handle
  ros::NodeHandle nh_private_;

};  // end class

// Create boost pointers for this class
typedef boost::shared_ptr<TestTrajectory> TestTrajectoryPtr;
typedef boost::shared_ptr<const TestTrajectory> TestTrajectoryConstPtr;

}  // end namespace

int main(int argc, char** argv)
{
  ros::init(argc, argv, "test_trajectory");
  ROS_INFO_STREAM_NAMED("test_trajectory", "Starting TestTrajectory...");

  // Allow the action server to recieve and send ros messages
  ros::AsyncSpinner spinner(2);
  spinner.start();

  ros_control_boilerplate::TestTrajectory server;

  ROS_INFO_STREAM_NAMED("test_trajectory", "Shutting down.");
  ros::shutdown();

  return 0;
}
<commit_msg>Minor fix<commit_after>/*********************************************************************
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2015, University of Colorado, Boulder
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of the Univ of CO, Boulder nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *********************************************************************/

/* Author: Dave Coleman <dave@dav.ee>
   Desc:   Generate a random trajectory to test the ros_control controller
*/

// ROS
#include <ros/ros.h>
#include <control_msgs/FollowJointTrajectoryAction.h>
#include <trajectory_msgs/JointTrajectory.h>
#include <actionlib/client/simple_action_client.h>
#include <actionlib/client/terminal_state.h>

namespace ros_control_boilerplate
{
static const double SEC_PER_TRAJ_POINT = 5.0;  // time between points
static const std::size_t TRAJ_POINTS = 10;     // number of points to generate

class TestTrajectory
{
public:
  /**
   * \brief Constructor
   */
  TestTrajectory()
    : nh_private_("~")
  {
    std::string action_topic;
    nh_private_.getParam("action_topic", action_topic);
    if (action_topic.empty())
    {
      ROS_FATAL_STREAM_NAMED(
          "test_trajectory",
          "Not follow joint trajectory action topic found on the parameter server");
      exit(-1);
    }
    ROS_INFO_STREAM_NAMED("test_trajectory", "Connecting to action " << action_topic);

    // create the action client
    // true causes the client to spin its own thread
    actionlib::SimpleActionClient<control_msgs::FollowJointTrajectoryAction> action_client(
        action_topic, true);

    ROS_INFO_NAMED("test_trajetory", "Waiting for action server to start.");
    // wait for the action server to start
    action_client.waitForServer();  // will wait for infinite time

    ROS_INFO_NAMED("test_trajetory", "Action server started, sending goal.");

    // send a goal to the action
    control_msgs::FollowJointTrajectoryGoal goal;
    goal.trajectory = createTrajectory();
    std::cout << "Trajectry:\n" << goal.trajectory << std::endl;
    action_client.sendGoal(goal);

    // Wait for the action to return
    double wait_extra_padding = 2;  // time to wait longer than trajectory itself
    bool finished_before_timeout = action_client.waitForResult(
        ros::Duration(goal.trajectory.points.back().time_from_start.toSec() + wait_extra_padding));

    if (finished_before_timeout)
    {
      actionlib::SimpleClientGoalState state = action_client.getState();
      ROS_INFO_NAMED("test_trajetory", "Action finished: %s", state.toString().c_str());
    }
    else
      ROS_INFO_NAMED("test_trajetory", "Action did not finish before the time out.");

    ROS_INFO_STREAM_NAMED("test_trajectory", "TestTrajectory Finished");
  }

  /**
   * \brief Create random trajectory
   */
  trajectory_msgs::JointTrajectory createTrajectory()
  {
    std::vector<std::string> joint_names;
    double min_joint_value = -3.14;
    double max_joint_value = 3.14;

    // Get joint names
    nh_private_.getParam("hardware_interface/joints", joint_names);
    if (joint_names.size() == 0)
    {
      ROS_FATAL_STREAM_NAMED(
          "init",
          "Not joints found on parameter server for controller, did you load the proper yaml file?"
              << " Namespace: " << nh_private_.getNamespace() << "/hardware_interface/joints");
      exit(-1);
    }

    nh_private_.getParam("min_joint_value", min_joint_value);
    nh_private_.getParam("max_joint_value", max_joint_value);
    ROS_DEBUG_STREAM_NAMED("test_trajectory", "Creating trajectory with joint values from "
                                                  << min_joint_value << " to " << max_joint_value);

    // Create header
    trajectory_msgs::JointTrajectory trajectory;
    trajectory.header.stamp = ros::Time::now();
    trajectory.joint_names = joint_names;

    // Create trajectory with x points
    trajectory.points.resize(TRAJ_POINTS);
    for (std::size_t i = 0; i < TRAJ_POINTS; ++i)
    {
      trajectory.points[i].positions.resize(joint_names.size());
      // for each joint
      for (std::size_t j = 0; j < joint_names.size(); ++j)
      {
        trajectory.points[i].positions[j] = dRand(min_joint_value, max_joint_value);
        trajectory.points[i].time_from_start = ros::Duration(i * SEC_PER_TRAJ_POINT);
      }
    }

    return trajectory;
  }

  /** \brief Get random number */
  double dRand(double dMin, double dMax)
  {
    double d = (double)rand() / RAND_MAX;
    return dMin + d * (dMax - dMin);
  }

private:
  // A shared node handle
  ros::NodeHandle nh_private_;

};  // end class

// Create boost pointers for this class
typedef boost::shared_ptr<TestTrajectory> TestTrajectoryPtr;
typedef boost::shared_ptr<const TestTrajectory> TestTrajectoryConstPtr;

}  // end namespace

int main(int argc, char** argv)
{
  ros::init(argc, argv, "test_trajectory");
  ROS_INFO_STREAM_NAMED("test_trajectory", "Starting TestTrajectory...");

  // Allow the action server to recieve and send ros messages
  ros::AsyncSpinner spinner(2);
  spinner.start();

  ros_control_boilerplate::TestTrajectory server;

  ROS_INFO_STREAM_NAMED("test_trajectory", "Shutting down.");
  ros::shutdown();

  return 0;
}
<|endoftext|>


<commit_before>/**
 * This file is part of the "libfnord" project
 *   Copyright (c) 2015 Paul Asmuth
 *
 * FnordMetric is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License v3.0. You should have received a
 * copy of the GNU General Public License along with this program. If not, see
 * <http://www.gnu.org/licenses/>.
 */
#include <tsdb/ReplicationScheme.h>
#include <stx/fnv.h>

using namespace stx;

namespace tsdb {

ReplicaRef::ReplicaRef(
    SHA1Hash _unique_id,
    InetAddr _addr) :
    unique_id(_unique_id),
    addr(_addr) {}

Vector<ReplicaRef> StandaloneReplicationScheme::replicasFor(
    const SHA1Hash& key) {
  return Vector<ReplicaRef>{};
}

bool StandaloneReplicationScheme::hasLocalReplica(const SHA1Hash& key) {
  return true;
}

FixedReplicationScheme::FixedReplicationScheme(
    Vector<ReplicaRef> replicas) :
    replicas_(replicas) {}

Vector<ReplicaRef> FixedReplicationScheme::replicasFor(const SHA1Hash& key) {
  return replicas_;
}

bool FixedReplicationScheme::hasLocalReplica(const SHA1Hash& key) {
  return true;
}

FrontendReplicationScheme::FrontendReplicationScheme(
    Vector<ReplicaRef> replicas) :
    replicas_(replicas) {}

Vector<ReplicaRef> FrontendReplicationScheme::replicasFor(const SHA1Hash& key) {
  return replicas_;
}

bool FrontendReplicationScheme::hasLocalReplica(const SHA1Hash& key) {
  return false;
}

} // namespace tsdb
<commit_msg> ReplicationScheme::replicaAddrsFor<commit_after>/**
 * This file is part of the "libfnord" project
 *   Copyright (c) 2015 Paul Asmuth
 *
 * FnordMetric is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License v3.0. You should have received a
 * copy of the GNU General Public License along with this program. If not, see
 * <http://www.gnu.org/licenses/>.
 */
#include <tsdb/ReplicationScheme.h>
#include <stx/fnv.h>

using namespace stx;

namespace tsdb {

ReplicaRef::ReplicaRef(
    SHA1Hash _unique_id,
    InetAddr _addr) :
    unique_id(_unique_id),
    addr(_addr) {}

Vector<InetAddr> ReplicationScheme::replicaAddrsFor(const SHA1Hash& key) {
  Vector<InetAddr> addrs;

  for (const auto& r : replicasFor(key)) {
    addrs.emplace_back(r.addr);
  }

  return addrs;
}

Vector<ReplicaRef> StandaloneReplicationScheme::replicasFor(
    const SHA1Hash& key) {
  return Vector<ReplicaRef>{};
}

bool StandaloneReplicationScheme::hasLocalReplica(const SHA1Hash& key) {
  return true;
}

FixedReplicationScheme::FixedReplicationScheme(
    Vector<ReplicaRef> replicas) :
    replicas_(replicas) {}

Vector<ReplicaRef> FixedReplicationScheme::replicasFor(const SHA1Hash& key) {
  return replicas_;
}

bool FixedReplicationScheme::hasLocalReplica(const SHA1Hash& key) {
  return true;
}

FrontendReplicationScheme::FrontendReplicationScheme(
    Vector<ReplicaRef> replicas) :
    replicas_(replicas) {}

Vector<ReplicaRef> FrontendReplicationScheme::replicasFor(const SHA1Hash& key) {
  return replicas_;
}

bool FrontendReplicationScheme::hasLocalReplica(const SHA1Hash& key) {
  return false;
}

} // namespace tsdb
<|endoftext|>


<commit_before>#include <stan/math/rev/mat.hpp>
#include <gtest/gtest.h>
#include <stan/math/prim/scal/fun/value_of.hpp>
#include <chrono>

using stan::math::var;
using Eigen::Dynamic;
using Eigen::Matrix;

typedef std::chrono::high_resolution_clock::time_point TimeVar;
#define duration(a) std::chrono::duration_cast<std::chrono::microseconds>(a).count()
#define timeNow() std::chrono::high_resolution_clock::now()

//  We check that the values of the new regression match those of one built
//  from existing primitives.
TEST(ProbDistributionsPoissonLogGLM, glm_matches_poisson_log_doubles)
{
  Matrix<int, Dynamic, 1> n(3, 1);
  n << 15, 3, 5;
  Matrix<double, Dynamic, Dynamic> x(3, 2);
  x << -12, 46, -42,
      24, 25, 27;
  Matrix<double, Dynamic, 1> beta(2, 1);
  beta << 0.3, 2;
  double alpha = 0.3;
  Matrix<double, Dynamic,1> alphavec = alpha * Matrix<double, 3, 1>::Ones();
  Matrix<double, Dynamic, 1> theta(3, 1);
  theta = x * beta + alphavec;

  EXPECT_FLOAT_EQ((stan::math::poisson_log_lpmf(n, theta)),
                  (stan::math::poisson_log_glm_lpmf(n, x, beta, alpha)));
  EXPECT_FLOAT_EQ((stan::math::poisson_log_lpmf<true>(n, theta)),
                  (stan::math::poisson_log_glm_lpmf<true>(n, x, beta, alpha)));
  EXPECT_FLOAT_EQ((stan::math::poisson_log_lpmf<false>(n, theta)),
                  (stan::math::poisson_log_glm_lpmf<false>(n, x, beta, alpha)));
  EXPECT_FLOAT_EQ((stan::math::poisson_log_lpmf<true, Matrix<int, Dynamic, 1>>(n, theta)),
                  (stan::math::poisson_log_glm_lpmf<true, Matrix<int, Dynamic, 1>>(n, x, beta, alpha)));
  EXPECT_FLOAT_EQ((stan::math::poisson_log_lpmf<false, Matrix<int, Dynamic, 1>>(n, theta)),
                  (stan::math::poisson_log_glm_lpmf<false, Matrix<int, Dynamic, 1>>(n, x, beta, alpha)));
  EXPECT_FLOAT_EQ((stan::math::poisson_log_lpmf<Matrix<int, Dynamic, 1>>(n, theta)),
                  (stan::math::poisson_log_glm_lpmf<Matrix<int, Dynamic, 1>>(n, x, beta, alpha)));
}

//  We check that the gradients of the new regression match those of one built
//  from existing primitives.

TEST(ProbDistributionsPoissonLogGLM, glm_matches_poisson_log_vars)
{

  Matrix<int, Dynamic, 1> n(3, 1);
  n << 14, 2, 5;
  Matrix<var, Dynamic, Dynamic> x(3, 2);
  x << -12, 46, -42,
      24, 25, 27;
  Matrix<var, Dynamic, 1> beta(2, 1);
  beta << 0.3, 2;
  var alpha = 0.3;
  Matrix<var, Dynamic,1> alphavec = alpha * Matrix<double, 3, 1>::Ones();
  Matrix<var, Dynamic, 1> theta(3, 1);
  theta = x * beta + alphavec;

  var lp = stan::math::poisson_log_lpmf(n, theta);
  lp.grad();

  stan::math::recover_memory();

  Matrix<int, Dynamic, 1> n2(3, 1);
  n2 << 14, 2, 5;
  Matrix<var, Dynamic, Dynamic> x2(3, 2);
  x2 << -12, 46, -42,
      24, 25, 27;
  Matrix<var, Dynamic, 1> beta2(2, 1);
  beta2 << 0.3, 2;
  var alpha2 = 0.3;

  var lp2 = stan::math::poisson_log_glm_lpmf(n2, x2, beta2, alpha2);
  lp2.grad();

  EXPECT_FLOAT_EQ(lp.val(),
                  lp2.val());
  for (size_t i = 0; i < 2; i++)
  {
    EXPECT_FLOAT_EQ(beta[i].adj(), beta2[i].adj());
  }
  EXPECT_FLOAT_EQ(alpha.adj(), alpha2.adj());
  for (size_t j = 0; j < 3; j++)
  {
    for (size_t i = 0; i < 2; i++)
    {
      EXPECT_FLOAT_EQ(x(j, i).adj(), x2(j, i).adj());
    }
  }
}

//  Here, we compare the speed of the new regression to that of one built from
//  existing primitives.
TEST(ProbDistributionsPoissonLogGLM, glm_matches_poisson_log_speed) {
  const int R = 30000;
  const int C = 1000;

  Matrix<int,Dynamic,1> n(R, 1);
  for (size_t i = 0; i < R; i++) {
    n[i] = rand()%200;
  }

  int T1 = 0;
  int T2 = 0;

  for (size_t testnumber = 0; testnumber < 30; testnumber++){
    Matrix<double, Dynamic, Dynamic> xreal = Matrix<double, Dynamic, Dynamic>::Random(R, C);
    Matrix<double, Dynamic, 1> betareal = Matrix<double, Dynamic, Dynamic>::Random(C, 1);
    Matrix<double, 1, 1> alphareal = Matrix<double, 1, 1>::Random(1, 1);
    Matrix<double, Dynamic, 1> alpharealvec = Matrix<double, R, 1>::Ones() * alphareal;

    Matrix<var, Dynamic, 1> beta = betareal;
    Matrix<var, Dynamic, 1> theta(R, 1);

    TimeVar t1 = timeNow();
    theta = (xreal * beta) + alpharealvec;
    var lp = stan::math::poisson_log_lpmf(n, theta);

    lp.grad();
    TimeVar t2 = timeNow();

    stan::math::recover_memory();

    Matrix<var, Dynamic, 1> beta2 = betareal;

    TimeVar t3 = timeNow();
    var lp2 = stan::math::poisson_log_glm_lpmf(n, xreal, beta2, alphareal[0]);
    lp2.grad();
    TimeVar t4 = timeNow();
    stan::math::recover_memory();
    T1 += duration(t2 - t1);
    T2 += duration(t4 - t3);

  }

  std::cout << "Existing Primitives:" << std::endl << T1 << std::endl  << "New Primitives:" << std::endl << T2 << std::endl;
}

<commit_msg>commented out performance test<commit_after>#include <stan/math/rev/mat.hpp>
#include <gtest/gtest.h>
#include <stan/math/prim/scal/fun/value_of.hpp>
#include <chrono>

using stan::math::var;
using Eigen::Dynamic;
using Eigen::Matrix;

typedef std::chrono::high_resolution_clock::time_point TimeVar;
#define duration(a) std::chrono::duration_cast<std::chrono::microseconds>(a).count()
#define timeNow() std::chrono::high_resolution_clock::now()

//  We check that the values of the new regression match those of one built
//  from existing primitives.
TEST(ProbDistributionsPoissonLogGLM, glm_matches_poisson_log_doubles)
{
  Matrix<int, Dynamic, 1> n(3, 1);
  n << 15, 3, 5;
  Matrix<double, Dynamic, Dynamic> x(3, 2);
  x << -12, 46, -42,
      24, 25, 27;
  Matrix<double, Dynamic, 1> beta(2, 1);
  beta << 0.3, 2;
  double alpha = 0.3;
  Matrix<double, Dynamic,1> alphavec = alpha * Matrix<double, 3, 1>::Ones();
  Matrix<double, Dynamic, 1> theta(3, 1);
  theta = x * beta + alphavec;

  EXPECT_FLOAT_EQ((stan::math::poisson_log_lpmf(n, theta)),
                  (stan::math::poisson_log_glm_lpmf(n, x, beta, alpha)));
  EXPECT_FLOAT_EQ((stan::math::poisson_log_lpmf<true>(n, theta)),
                  (stan::math::poisson_log_glm_lpmf<true>(n, x, beta, alpha)));
  EXPECT_FLOAT_EQ((stan::math::poisson_log_lpmf<false>(n, theta)),
                  (stan::math::poisson_log_glm_lpmf<false>(n, x, beta, alpha)));
  EXPECT_FLOAT_EQ((stan::math::poisson_log_lpmf<true, Matrix<int, Dynamic, 1>>(n, theta)),
                  (stan::math::poisson_log_glm_lpmf<true, Matrix<int, Dynamic, 1>>(n, x, beta, alpha)));
  EXPECT_FLOAT_EQ((stan::math::poisson_log_lpmf<false, Matrix<int, Dynamic, 1>>(n, theta)),
                  (stan::math::poisson_log_glm_lpmf<false, Matrix<int, Dynamic, 1>>(n, x, beta, alpha)));
  EXPECT_FLOAT_EQ((stan::math::poisson_log_lpmf<Matrix<int, Dynamic, 1>>(n, theta)),
                  (stan::math::poisson_log_glm_lpmf<Matrix<int, Dynamic, 1>>(n, x, beta, alpha)));
}

//  We check that the gradients of the new regression match those of one built
//  from existing primitives.

TEST(ProbDistributionsPoissonLogGLM, glm_matches_poisson_log_vars)
{

  Matrix<int, Dynamic, 1> n(3, 1);
  n << 14, 2, 5;
  Matrix<var, Dynamic, Dynamic> x(3, 2);
  x << -12, 46, -42,
      24, 25, 27;
  Matrix<var, Dynamic, 1> beta(2, 1);
  beta << 0.3, 2;
  var alpha = 0.3;
  Matrix<var, Dynamic,1> alphavec = alpha * Matrix<double, 3, 1>::Ones();
  Matrix<var, Dynamic, 1> theta(3, 1);
  theta = x * beta + alphavec;

  var lp = stan::math::poisson_log_lpmf(n, theta);
  lp.grad();

  stan::math::recover_memory();

  Matrix<int, Dynamic, 1> n2(3, 1);
  n2 << 14, 2, 5;
  Matrix<var, Dynamic, Dynamic> x2(3, 2);
  x2 << -12, 46, -42,
      24, 25, 27;
  Matrix<var, Dynamic, 1> beta2(2, 1);
  beta2 << 0.3, 2;
  var alpha2 = 0.3;

  var lp2 = stan::math::poisson_log_glm_lpmf(n2, x2, beta2, alpha2);
  lp2.grad();

  EXPECT_FLOAT_EQ(lp.val(),
                  lp2.val());
  for (size_t i = 0; i < 2; i++)
  {
    EXPECT_FLOAT_EQ(beta[i].adj(), beta2[i].adj());
  }
  EXPECT_FLOAT_EQ(alpha.adj(), alpha2.adj());
  for (size_t j = 0; j < 3; j++)
  {
    for (size_t i = 0; i < 2; i++)
    {
      EXPECT_FLOAT_EQ(x(j, i).adj(), x2(j, i).adj());
    }
  }
}

//  Here, we compare the speed of the new regression to that of one built from
//  existing primitives.
/*
TEST(ProbDistributionsPoissonLogGLM, glm_matches_poisson_log_speed) {
  const int R = 30000;
  const int C = 1000;

  Matrix<int,Dynamic,1> n(R, 1);
  for (size_t i = 0; i < R; i++) {
    n[i] = rand()%200;
  }

  int T1 = 0;
  int T2 = 0;

  for (size_t testnumber = 0; testnumber < 30; testnumber++){
    Matrix<double, Dynamic, Dynamic> xreal = Matrix<double, Dynamic, Dynamic>::Random(R, C);
    Matrix<double, Dynamic, 1> betareal = Matrix<double, Dynamic, Dynamic>::Random(C, 1);
    Matrix<double, 1, 1> alphareal = Matrix<double, 1, 1>::Random(1, 1);
    Matrix<double, Dynamic, 1> alpharealvec = Matrix<double, R, 1>::Ones() * alphareal;

    Matrix<var, Dynamic, 1> beta = betareal;
    Matrix<var, Dynamic, 1> theta(R, 1);

    TimeVar t1 = timeNow();
    theta = (xreal * beta) + alpharealvec;
    var lp = stan::math::poisson_log_lpmf(n, theta);

    lp.grad();
    TimeVar t2 = timeNow();

    stan::math::recover_memory();

    Matrix<var, Dynamic, 1> beta2 = betareal;

    TimeVar t3 = timeNow();
    var lp2 = stan::math::poisson_log_glm_lpmf(n, xreal, beta2, alphareal[0]);
    lp2.grad();
    TimeVar t4 = timeNow();
    stan::math::recover_memory();
    T1 += duration(t2 - t1);
    T2 += duration(t4 - t3);

  }

  std::cout << "Existing Primitives:" << std::endl << T1 << std::endl  << "New Primitives:" << std::endl << T2 << std::endl;
}
*/
<|endoftext|>


<commit_before>#include "processhelper.h"
#include <QtTest>

const char ProcessHelper::Stamp = '%';
bool ProcessHelper::allGreen = true;

QString ProcessHelper::binPath()
{
#if defined(Q_OS_WIN)
	return QStringLiteral(OUTDIR) + QStringLiteral("../../../../examples/backgroundprocess/DemoApp/") + QStringLiteral(RMODE) + QStringLiteral("/DemoApp");
#elif defined(Q_OS_MAC)
	return QStringLiteral(OUTDIR) + QStringLiteral("../../../../examples/backgroundprocess/DemoApp/DemoApp.app/Contents/MacOS/DemoApp");
#else
	return QStringLiteral(OUTDIR) + QStringLiteral("../../../../examples/backgroundprocess/DemoApp/DemoApp");
#endif
}

ProcessHelper::ProcessHelper(QObject *parent) :
	QObject(parent),
	process(new QProcess(this)),
	exitCode(EXIT_SUCCESS)
{
	process->setProgram(binPath());

	connect(process, &QProcess::errorOccurred,
			this, &ProcessHelper::errorOccurred);
	connect(process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
			this, &ProcessHelper::finished);
}

void ProcessHelper::setExitCode(int code)
{
	exitCode = code;
}

void ProcessHelper::start(const QByteArrayList &commands, bool logpath, int timeout)
{
	QStringList s;
	foreach(auto c, commands)
		s.append(QString::fromUtf8(c));
	if(logpath) {
		s.append({QStringLiteral("--logpath"), logPath()});
		s.append({QStringLiteral("--loglevel"), QStringLiteral("4")});
	}
	process->setArguments(s);
	process->start();
	QVERIFY2(process->waitForStarted(5000), qUtf8Printable(process->errorString()));
	QThread::msleep(timeout);
}

void ProcessHelper::waitForFinished()
{
	if(!process->waitForFinished(5000)) {
		process->terminate();
		QFAIL("Process did not stop by itself");
	}
}

void ProcessHelper::verifyLog(const QByteArrayList &log, bool isError)
{
	allGreen = false;

	if(isError) {
		auto err = process->readAllStandardError();
		QBuffer buffer(&err);
		buffer.open(QIODevice::ReadOnly | QIODevice::Text);
		testLog(log, &buffer);
		buffer.close();
	} else
		testLog(log, process);

	if(!allGreen)
		qDebug() << "on arguments:" << process->arguments();
}

void ProcessHelper::verifyLogEmpty(bool isError)
{
	verifyLog(QByteArrayList(), isError);
}

void ProcessHelper::waitForFinished(const QList<ProcessHelper *> &helpers)
{
	foreach (auto h, helpers)
		h->waitForFinished();
}

void ProcessHelper::clearLog()
{
	auto logFile = logPath();
	if(QFile::exists(logFile))
		QVERIFY(QFile::remove(logFile));
}

void ProcessHelper::verifyMasterLog(const QByteArrayList &log)
{
	auto logFile = logPath();
	QFile file(logFile);
	QVERIFY(file.exists());
	QVERIFY2(file.open(QIODevice::ReadOnly | QIODevice::Text), qUtf8Printable(file.errorString()));

	allGreen = false;
	testLog(log, &file);
	if(!allGreen)
		qDebug() << "on master log";

	file.close();
	QVERIFY(file.remove());

}

void ProcessHelper::errorOccurred(QProcess::ProcessError error)
{
	Q_UNUSED(error)
	QFAIL(qUtf8Printable(process->errorString()));
}

void ProcessHelper::finished(int exitCode, QProcess::ExitStatus exitStatus)
{
	QCOMPARE(exitStatus, QProcess::NormalExit);
	QCOMPARE(exitCode, this->exitCode);
}

QString ProcessHelper::logPath()
{
	return QDir::temp().absoluteFilePath(QStringLiteral("MasterTest.log"));
}

void ProcessHelper::testLog(const QByteArrayList &log, QIODevice *device)
{
	auto index = 0;
	while(!device->atEnd()) {
		auto logStr = device->readLine().trimmed();
		if(logStr.isEmpty())
			continue;

		QVERIFY2(index < log.size(), logStr.constData());
		auto testStr = log[index++];

		auto testSplit = testStr.split(Stamp);
		if(testSplit.size() == 2) {
			QVERIFY2(logStr.startsWith(testSplit[0]), logStr.constData());
			QVERIFY2(logStr.endsWith(testSplit[1]), logStr.constData());
		} else
			QCOMPARE(logStr, testStr);
	}
	QCOMPARE(index, log.size());
	allGreen = true;
}
<commit_msg>win debug<commit_after>#include "processhelper.h"
#include <QtTest>

const char ProcessHelper::Stamp = '%';
bool ProcessHelper::allGreen = true;

QString ProcessHelper::binPath()
{
#if defined(Q_OS_WIN)
	return QStringLiteral(OUTDIR) + QStringLiteral("../../../../examples/backgroundprocess/DemoApp/") + QStringLiteral(RMODE) + QStringLiteral("/DemoApp");
#elif defined(Q_OS_MAC)
	return QStringLiteral(OUTDIR) + QStringLiteral("../../../../examples/backgroundprocess/DemoApp/DemoApp.app/Contents/MacOS/DemoApp");
#else
	return QStringLiteral(OUTDIR) + QStringLiteral("../../../../examples/backgroundprocess/DemoApp/DemoApp");
#endif
}

ProcessHelper::ProcessHelper(QObject *parent) :
	QObject(parent),
	process(new QProcess(this)),
	exitCode(EXIT_SUCCESS)
{
	process->setProgram(binPath());

	connect(process, &QProcess::errorOccurred,
			this, &ProcessHelper::errorOccurred);
	connect(process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
			this, &ProcessHelper::finished);
}

void ProcessHelper::setExitCode(int code)
{
	exitCode = code;
}

void ProcessHelper::start(const QByteArrayList &commands, bool logpath, int timeout)
{
	QStringList s;
	foreach(auto c, commands)
		s.append(QString::fromUtf8(c));
	if(logpath) {
		s.append({QStringLiteral("--logpath"), logPath()});
		s.append({QStringLiteral("--loglevel"), QStringLiteral("4")});
	}
	process->setArguments(s);
	process->start();
	QVERIFY2(process->waitForStarted(5000), qUtf8Printable(process->errorString()));
	QThread::msleep(timeout);
}

void ProcessHelper::waitForFinished()
{
	if(!process->waitForFinished(5000)) {
		process->terminate();
		QFAIL("Process did not stop by itself");
	}
}

void ProcessHelper::verifyLog(const QByteArrayList &log, bool isError)
{
	allGreen = false;

	if(isError) {
		auto err = process->readAllStandardError();
		QBuffer buffer(&err);
		buffer.open(QIODevice::ReadOnly | QIODevice::Text);
		testLog(log, &buffer);
		buffer.close();
	} else
		testLog(log, process);

	if(!allGreen)
		qDebug() << "on arguments:" << process->arguments();
}

void ProcessHelper::verifyLogEmpty(bool isError)
{
	verifyLog(QByteArrayList(), isError);
}

void ProcessHelper::waitForFinished(const QList<ProcessHelper *> &helpers)
{
	foreach (auto h, helpers)
		h->waitForFinished();
}

void ProcessHelper::clearLog()
{
	auto logFile = logPath();
	if(QFile::exists(logFile))
		QVERIFY(QFile::remove(logFile));
}

void ProcessHelper::verifyMasterLog(const QByteArrayList &log)
{
	auto logFile = logPath();
	QFile file(logFile);
	QVERIFY(file.exists());
	QVERIFY2(file.open(QIODevice::ReadOnly | QIODevice::Text), qUtf8Printable(file.errorString()));

	allGreen = false;
	testLog(log, &file);
	if(!allGreen)
		qDebug() << "on master log";

	file.close();
	QVERIFY(file.remove());

}

void ProcessHelper::errorOccurred(QProcess::ProcessError error)
{
	Q_UNUSED(error)
	QFAIL(qUtf8Printable(process->errorString()));
}

void ProcessHelper::finished(int exitCode, QProcess::ExitStatus exitStatus)
{
	QCOMPARE(exitStatus, QProcess::NormalExit);
	QCOMPARE(exitCode, this->exitCode);
}

QString ProcessHelper::logPath()
{
	return QDir::temp().absoluteFilePath(QStringLiteral("MasterTest.log"));
}

void ProcessHelper::testLog(const QByteArrayList &log, QIODevice *device)
{
	auto index = 0;
	while(!device->atEnd()) {
		auto logStr = device->readLine().trimmed();
		if(logStr.isEmpty())
			continue;
		//TODO win debug
		if(logStr.contains("QCtrlSignals"))
			continue;

		QVERIFY2(index < log.size(), logStr.constData());
		auto testStr = log[index++];

		auto testSplit = testStr.split(Stamp);
		if(testSplit.size() == 2) {
			QVERIFY2(logStr.startsWith(testSplit[0]), logStr.constData());
			QVERIFY2(logStr.endsWith(testSplit[1]), logStr.constData());
		} else
			QCOMPARE(logStr, testStr);
	}
	QCOMPARE(index, log.size());
	allGreen = true;
}
<|endoftext|>


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

Program:   Medical Imaging & Interaction Toolkit
Language:  C++
Date:      $Date: 2009-06-17 14:15:34 +0200 (Mi, 17. Jun 2009) $
Version:   $Revision: 17745 $

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

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

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

#include "mitkPlanarFigureReader.h"

#include "mitkPlanarAngle.h"
#include "mitkPlanarCircle.h"
#include "mitkPlanarCross.h"
#include "mitkPlanarFourPointAngle.h"
#include "mitkPlanarLine.h"
#include "mitkPlanarPolygon.h"
#include "mitkPlanarRectangle.h"
#include "mitkPlaneGeometry.h"

#include "mitkBasePropertyDeserializer.h"

#include <tinyxml.h>
#include <itksys/SystemTools.hxx>

mitk::PlanarFigureReader::PlanarFigureReader() : PlanarFigureSource(), FileReader(),
m_FileName(""), m_FilePrefix(""), m_FilePattern(""), m_Success(false)
{
  this->SetNumberOfRequiredOutputs(1);
  this->SetNumberOfOutputs(1);
  this->SetNthOutput(0, this->MakeOutput(0));

  //this->Modified();
  //this->GetOutput()->Modified();
  //this->GetOutput()->ReleaseData();
}

mitk::PlanarFigureReader::~PlanarFigureReader()
{}

mitk::PlanarFigureSource::DataObjectPointer mitk::PlanarFigureReader::MakeOutput ( unsigned int )
{
  return static_cast<itk::DataObject*>(PlanarCircle::New().GetPointer()); // just as a stand in for the pipeline update mechanism. This will be overwritten in GenerateData()
}

void mitk::PlanarFigureReader::GenerateData()
{
  m_Success = false;
  if (m_FileName.empty())
  {
    itkWarningMacro( << "Sorry, filename has not been set!" );
    return;
  }
  if (this->CanReadFile( m_FileName.c_str()) == false)
  {
    itkWarningMacro( << "Sorry, can't read file " << m_FileName << "!" );
    return;
  }

  TiXmlDocument document( m_FileName);
  if (!document.LoadFile())
  {
    MITK_ERROR << "Could not open/read/parse " << m_FileName << ". TinyXML reports: '" << document.ErrorDesc() << "'. "
              << "The error occurred in row " << document.ErrorRow() << ", column " << document.ErrorCol() << ".";
    return;
  }
  int fileVersion = 1;
  TiXmlElement* versionObject = document.FirstChildElement("Version");
  if (versionObject != NULL)
  {
    if ( versionObject->QueryIntAttribute( "FileVersion", &fileVersion ) != TIXML_SUCCESS )
    {
      MITK_WARN << m_FileName << " does not contain version information! Trying version 1 format." << std::endl;
    }
  }
  else
  {
    MITK_WARN << m_FileName << " does not contain version information! Trying version 1 format." << std::endl;
  }
  if (fileVersion != 1)  // add file version selection and version specific file parsing here, if newer file versions are created
  {
    MITK_WARN << "File version > 1 is not supported by this reader.";
      return;
  }

  this->SetNumberOfOutputs(0); // reset all outputs, we add new ones depending on the file content
  /* file version 1 reader code */
  for( TiXmlElement* pfElement = document.FirstChildElement("PlanarFigure");
       pfElement != NULL;
       pfElement = pfElement->NextSiblingElement("PlanarFigure") )
  {
    if (pfElement == NULL)
      continue;

    std::string type = pfElement->Attribute("type");

    mitk::PlanarFigure::Pointer planarFigure = NULL;
    if (type == "PlanarAngle")
    {
      planarFigure = mitk::PlanarAngle::New();
    }
    else if (type == "PlanarCircle")
    {
      planarFigure = mitk::PlanarCircle::New();
    }
    else if (type == "PlanarCross")
    {
      planarFigure = mitk::PlanarCross::New();
    }
    else if (type == "PlanarFourPointAngle")
    {
      planarFigure = mitk::PlanarFourPointAngle::New();
    }
    else if (type == "PlanarLine")
    {
      planarFigure = mitk::PlanarLine::New();
    }
    else if (type == "PlanarPolygon")
    {
      planarFigure = mitk::PlanarPolygon::New();
    }
    else if (type == "PlanarRectangle")
    {
      planarFigure = mitk::PlanarRectangle::New();
    }
    else
    {
      // unknown type
      MITK_WARN << "encountered unknown planar figure type '" << type << "'. Skipping this element.";
      continue;
    }

    // Read properties of the planar figure
    for( TiXmlElement* propertyElement = pfElement->FirstChildElement("property");
         propertyElement != NULL;
         propertyElement = propertyElement->NextSiblingElement("property") )
    {
      const char* keya = propertyElement->Attribute("key");
      std::string key( keya ? keya : "");

      const char* typea = propertyElement->Attribute("type");
      std::string type( typea ? typea : "");

      // hand propertyElement to specific reader
      std::stringstream propertyDeserializerClassName;
      propertyDeserializerClassName << type << "Deserializer";

      std::list<itk::LightObject::Pointer> readers =
        itk::ObjectFactoryBase::CreateAllInstance(propertyDeserializerClassName.str().c_str());
      if (readers.size() < 1)
      {
        MITK_ERROR << "No property reader found for " << type;
      }
      if (readers.size() > 1)
      {
        MITK_WARN << "Multiple property readers found for " << type << ". Using arbitrary first one.";
      }

      for ( std::list<itk::LightObject::Pointer>::iterator iter = readers.begin();
        iter != readers.end();
        ++iter )
      {
        if (BasePropertyDeserializer* reader = dynamic_cast<BasePropertyDeserializer*>( iter->GetPointer() ) )
        {
          BaseProperty::Pointer property = reader->Deserialize( propertyElement->FirstChildElement() );
          if (property.IsNotNull())
          {
            planarFigure->GetPropertyList()->ReplaceProperty(key, property);
          }
          else
          {
            MITK_ERROR << "There were errors while loading property '" << key << "' of type " << type << ". Your data may be corrupted";
          }
          break;
        }
      }
    }

    // Read geometry of containing plane
    TiXmlElement* geoElement = pfElement->FirstChildElement("Geometry");
    if (geoElement != NULL)
    {
      try
      {
        // Create plane geometry
        mitk::PlaneGeometry::Pointer planeGeo = mitk::PlaneGeometry::New();

        // Extract and set plane transform parameters
        DoubleList transformList = this->GetDoubleAttributeListFromXMLNode( geoElement->FirstChildElement( "transformParam" ), "param", 12 );

        typedef mitk::AffineGeometryFrame3D::TransformType TransformType;
        TransformType::ParametersType parameters;
        parameters.SetSize( 12 );

        unsigned int i;
        DoubleList::iterator it;
        for ( it = transformList.begin(), i = 0;
              it != transformList.end();
              ++it, ++i )
        {
          parameters.SetElement( i, *it );
        }

        typedef mitk::AffineGeometryFrame3D::TransformType TransformType;
        TransformType::Pointer affineGeometry = TransformType::New();
        affineGeometry->SetParameters( parameters );
        planeGeo->SetIndexToWorldTransform( affineGeometry );

        // Extract and set plane bounds
        DoubleList boundsList = this->GetDoubleAttributeListFromXMLNode( geoElement->FirstChildElement( "boundsParam" ), "bound", 6 );

        typedef mitk::Geometry3D::BoundsArrayType BoundsArrayType;

        BoundsArrayType bounds;
        for ( it = boundsList.begin(), i = 0;
              it != boundsList.end();
              ++it, ++i )
        {
          bounds[i] = *it;
        }

        planeGeo->SetBounds( bounds );

        // Extract and set spacing and origin
        //Vector3D spacing = this->GetVectorFromXMLNode(geoElement->FirstChildElement("Spacing"));
        Point3D origin = this->GetPointFromXMLNode(geoElement->FirstChildElement("Origin"));
        planeGeo->SetOrigin( origin );
        planarFigure->SetGeometry2D(planeGeo);
      }
      catch (...)
      {
      }
    }
    TiXmlElement* cpElement = pfElement->FirstChildElement("ControlPoints");
    bool first = true;
    if (cpElement != NULL)
      for( TiXmlElement* vertElement = cpElement->FirstChildElement("Vertex"); vertElement != NULL; vertElement = vertElement->NextSiblingElement("Vertex"))
      {
        if (vertElement == NULL)
          continue;
        int id = 0;
        mitk::Point2D::ValueType x = 0.0;
        mitk::Point2D::ValueType y = 0.0;
        if (vertElement->QueryIntAttribute("id", &id) == TIXML_WRONG_TYPE)
          return; // TODO: can we do a better error handling?
        if (vertElement->QueryFloatAttribute("x", &x) == TIXML_WRONG_TYPE)
          return; // TODO: can we do a better error handling?
        if (vertElement->QueryFloatAttribute("y", &y) == TIXML_WRONG_TYPE)
          return; // TODO: can we do a better error handling?
        Point2D p;
        p.SetElement(0, x);
        p.SetElement(1, y);
        if (first == true)  // needed to set m_FigurePlaced to true
        {
          planarFigure->PlaceFigure(p);
          first = false;
        }
        planarFigure->SetControlPoint(id, p, true);
      }

    // Calculate feature quantities of this PlanarFigure
    planarFigure->EvaluateFeatures();

    // Make sure that no control point is currently selected
    planarFigure->DeselectControlPoint();

    // \TODO: what about m_FigurePlaced and m_SelectedControlPoint ??
    this->SetNthOutput( this->GetNumberOfOutputs(), planarFigure );  // add planarFigure as new output of this filter
  }
  m_Success = true;
}

mitk::Point3D mitk::PlanarFigureReader::GetPointFromXMLNode(TiXmlElement* e)
{
  if (e == NULL)
    throw std::invalid_argument("node invalid"); // TODO: can we do a better error handling?
  mitk::Point3D point;
  mitk::ScalarType p(-1.0);
  if (e->QueryFloatAttribute("x", &p) == TIXML_WRONG_TYPE)
    throw std::invalid_argument("node malformatted"); // TODO: can we do a better error handling?
  point.SetElement(0, p);
  if (e->QueryFloatAttribute("y", &p) == TIXML_WRONG_TYPE)
    throw std::invalid_argument("node malformatted"); // TODO: can we do a better error handling?
  point.SetElement(1, p);
  if (e->QueryFloatAttribute("z", &p) == TIXML_WRONG_TYPE)
    throw std::invalid_argument("node malformatted"); // TODO: can we do a better error handling?
  point.SetElement(2, p);
  return point;
}

mitk::Vector3D mitk::PlanarFigureReader::GetVectorFromXMLNode(TiXmlElement* e)
{
  if (e == NULL)
    throw std::invalid_argument("node invalid"); // TODO: can we do a better error handling?
  mitk::Vector3D vector;
  mitk::ScalarType p(-1.0);
  if (e->QueryFloatAttribute("x", &p) == TIXML_WRONG_TYPE)
    throw std::invalid_argument("node malformatted"); // TODO: can we do a better error handling?
  vector.SetElement(0, p);
  if (e->QueryFloatAttribute("y", &p) == TIXML_WRONG_TYPE)
    throw std::invalid_argument("node malformatted"); // TODO: can we do a better error handling?
  vector.SetElement(1, p);
  if (e->QueryFloatAttribute("z", &p) == TIXML_WRONG_TYPE)
    throw std::invalid_argument("node malformatted"); // TODO: can we do a better error handling?
  vector.SetElement(2, p);
  return vector;
}

mitk::PlanarFigureReader::DoubleList
mitk::PlanarFigureReader::GetDoubleAttributeListFromXMLNode(TiXmlElement* e, const char *attributeNameBase, unsigned int count)
{
  DoubleList list;

  if (e == NULL)
    throw std::invalid_argument("node invalid"); // TODO: can we do a better error handling?

  for ( unsigned int i = 0; i < count; ++i )
  {
    mitk::ScalarType p(-1.0);
    std::stringstream attributeName;
    attributeName << attributeNameBase << i;

    if (e->QueryFloatAttribute( attributeName.str().c_str(), &p ) == TIXML_WRONG_TYPE)
      throw std::invalid_argument("node malformatted"); // TODO: can we do a better error handling?
    list.push_back( p );
  }

  return list;
}

void mitk::PlanarFigureReader::GenerateOutputInformation()
{
}

int mitk::PlanarFigureReader::CanReadFile ( const char *name )
{
  if (std::string(name).empty())
    return false;

  return (itksys::SystemTools::LowerCase(itksys::SystemTools::GetFilenameLastExtension(name)) == ".pf");  //assume, we can read all .pf files

  //TiXmlDocument document(name);
  //if (document.LoadFile() == false)
  //  return false;
  //return (document.FirstChildElement("PlanarFigure") != NULL);
}

bool mitk::PlanarFigureReader::CanReadFile(const std::string filename, const std::string, const std::string)
{
  if (filename.empty())
    return false;

  return (itksys::SystemTools::LowerCase(itksys::SystemTools::GetFilenameLastExtension(filename)) == ".pf");  //assume, we can read all .pf files

  //TiXmlDocument document(filename);
  //if (document.LoadFile() == false)
  //  return false;
  //return (document.FirstChildElement("PlanarFigure") != NULL);
}

void mitk::PlanarFigureReader::ResizeOutputs( const unsigned int& num )
{
  unsigned int prevNum = this->GetNumberOfOutputs();
  this->SetNumberOfOutputs( num );
  for ( unsigned int i = prevNum; i < num; ++i )
  {
    this->SetNthOutput( i, this->MakeOutput( i ).GetPointer() );
  }
}
<commit_msg>FIX (#4003): Deserialize PlanarFigure spacing<commit_after>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Language:  C++
Date:      $Date: 2009-06-17 14:15:34 +0200 (Mi, 17. Jun 2009) $
Version:   $Revision: 17745 $

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

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

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

#include "mitkPlanarFigureReader.h"

#include "mitkPlanarAngle.h"
#include "mitkPlanarCircle.h"
#include "mitkPlanarCross.h"
#include "mitkPlanarFourPointAngle.h"
#include "mitkPlanarLine.h"
#include "mitkPlanarPolygon.h"
#include "mitkPlanarRectangle.h"
#include "mitkPlaneGeometry.h"

#include "mitkBasePropertyDeserializer.h"

#include <tinyxml.h>
#include <itksys/SystemTools.hxx>

mitk::PlanarFigureReader::PlanarFigureReader() : PlanarFigureSource(), FileReader(),
m_FileName(""), m_FilePrefix(""), m_FilePattern(""), m_Success(false)
{
  this->SetNumberOfRequiredOutputs(1);
  this->SetNumberOfOutputs(1);
  this->SetNthOutput(0, this->MakeOutput(0));

  //this->Modified();
  //this->GetOutput()->Modified();
  //this->GetOutput()->ReleaseData();
}

mitk::PlanarFigureReader::~PlanarFigureReader()
{}

mitk::PlanarFigureSource::DataObjectPointer mitk::PlanarFigureReader::MakeOutput ( unsigned int )
{
  return static_cast<itk::DataObject*>(PlanarCircle::New().GetPointer()); // just as a stand in for the pipeline update mechanism. This will be overwritten in GenerateData()
}

void mitk::PlanarFigureReader::GenerateData()
{
  m_Success = false;
  if (m_FileName.empty())
  {
    itkWarningMacro( << "Sorry, filename has not been set!" );
    return;
  }
  if (this->CanReadFile( m_FileName.c_str()) == false)
  {
    itkWarningMacro( << "Sorry, can't read file " << m_FileName << "!" );
    return;
  }

  TiXmlDocument document( m_FileName);
  if (!document.LoadFile())
  {
    MITK_ERROR << "Could not open/read/parse " << m_FileName << ". TinyXML reports: '" << document.ErrorDesc() << "'. "
              << "The error occurred in row " << document.ErrorRow() << ", column " << document.ErrorCol() << ".";
    return;
  }
  int fileVersion = 1;
  TiXmlElement* versionObject = document.FirstChildElement("Version");
  if (versionObject != NULL)
  {
    if ( versionObject->QueryIntAttribute( "FileVersion", &fileVersion ) != TIXML_SUCCESS )
    {
      MITK_WARN << m_FileName << " does not contain version information! Trying version 1 format." << std::endl;
    }
  }
  else
  {
    MITK_WARN << m_FileName << " does not contain version information! Trying version 1 format." << std::endl;
  }
  if (fileVersion != 1)  // add file version selection and version specific file parsing here, if newer file versions are created
  {
    MITK_WARN << "File version > 1 is not supported by this reader.";
      return;
  }

  this->SetNumberOfOutputs(0); // reset all outputs, we add new ones depending on the file content
  /* file version 1 reader code */
  for( TiXmlElement* pfElement = document.FirstChildElement("PlanarFigure");
       pfElement != NULL;
       pfElement = pfElement->NextSiblingElement("PlanarFigure") )
  {
    if (pfElement == NULL)
      continue;

    std::string type = pfElement->Attribute("type");

    mitk::PlanarFigure::Pointer planarFigure = NULL;
    if (type == "PlanarAngle")
    {
      planarFigure = mitk::PlanarAngle::New();
    }
    else if (type == "PlanarCircle")
    {
      planarFigure = mitk::PlanarCircle::New();
    }
    else if (type == "PlanarCross")
    {
      planarFigure = mitk::PlanarCross::New();
    }
    else if (type == "PlanarFourPointAngle")
    {
      planarFigure = mitk::PlanarFourPointAngle::New();
    }
    else if (type == "PlanarLine")
    {
      planarFigure = mitk::PlanarLine::New();
    }
    else if (type == "PlanarPolygon")
    {
      planarFigure = mitk::PlanarPolygon::New();
    }
    else if (type == "PlanarRectangle")
    {
      planarFigure = mitk::PlanarRectangle::New();
    }
    else
    {
      // unknown type
      MITK_WARN << "encountered unknown planar figure type '" << type << "'. Skipping this element.";
      continue;
    }

    // Read properties of the planar figure
    for( TiXmlElement* propertyElement = pfElement->FirstChildElement("property");
         propertyElement != NULL;
         propertyElement = propertyElement->NextSiblingElement("property") )
    {
      const char* keya = propertyElement->Attribute("key");
      std::string key( keya ? keya : "");

      const char* typea = propertyElement->Attribute("type");
      std::string type( typea ? typea : "");

      // hand propertyElement to specific reader
      std::stringstream propertyDeserializerClassName;
      propertyDeserializerClassName << type << "Deserializer";

      std::list<itk::LightObject::Pointer> readers =
        itk::ObjectFactoryBase::CreateAllInstance(propertyDeserializerClassName.str().c_str());
      if (readers.size() < 1)
      {
        MITK_ERROR << "No property reader found for " << type;
      }
      if (readers.size() > 1)
      {
        MITK_WARN << "Multiple property readers found for " << type << ". Using arbitrary first one.";
      }

      for ( std::list<itk::LightObject::Pointer>::iterator iter = readers.begin();
        iter != readers.end();
        ++iter )
      {
        if (BasePropertyDeserializer* reader = dynamic_cast<BasePropertyDeserializer*>( iter->GetPointer() ) )
        {
          BaseProperty::Pointer property = reader->Deserialize( propertyElement->FirstChildElement() );
          if (property.IsNotNull())
          {
            planarFigure->GetPropertyList()->ReplaceProperty(key, property);
          }
          else
          {
            MITK_ERROR << "There were errors while loading property '" << key << "' of type " << type << ". Your data may be corrupted";
          }
          break;
        }
      }
    }

    // Read geometry of containing plane
    TiXmlElement* geoElement = pfElement->FirstChildElement("Geometry");
    if (geoElement != NULL)
    {
      try
      {
        // Create plane geometry
        mitk::PlaneGeometry::Pointer planeGeo = mitk::PlaneGeometry::New();

        // Extract and set plane transform parameters
        DoubleList transformList = this->GetDoubleAttributeListFromXMLNode( geoElement->FirstChildElement( "transformParam" ), "param", 12 );

        typedef mitk::AffineGeometryFrame3D::TransformType TransformType;
        TransformType::ParametersType parameters;
        parameters.SetSize( 12 );

        unsigned int i;
        DoubleList::iterator it;
        for ( it = transformList.begin(), i = 0;
              it != transformList.end();
              ++it, ++i )
        {
          parameters.SetElement( i, *it );
        }

        typedef mitk::AffineGeometryFrame3D::TransformType TransformType;
        TransformType::Pointer affineGeometry = TransformType::New();
        affineGeometry->SetParameters( parameters );
        planeGeo->SetIndexToWorldTransform( affineGeometry );

        // Extract and set plane bounds
        DoubleList boundsList = this->GetDoubleAttributeListFromXMLNode( geoElement->FirstChildElement( "boundsParam" ), "bound", 6 );

        typedef mitk::Geometry3D::BoundsArrayType BoundsArrayType;

        BoundsArrayType bounds;
        for ( it = boundsList.begin(), i = 0;
              it != boundsList.end();
              ++it, ++i )
        {
          bounds[i] = *it;
        }

        planeGeo->SetBounds( bounds );

        // Extract and set spacing and origin
        Vector3D spacing = this->GetVectorFromXMLNode(geoElement->FirstChildElement("Spacing"));
        planeGeo->SetSpacing( spacing );

        Point3D origin = this->GetPointFromXMLNode(geoElement->FirstChildElement("Origin"));
        planeGeo->SetOrigin( origin );
        planarFigure->SetGeometry2D(planeGeo);
      }
      catch (...)
      {
      }
    }
    TiXmlElement* cpElement = pfElement->FirstChildElement("ControlPoints");
    bool first = true;
    if (cpElement != NULL)
      for( TiXmlElement* vertElement = cpElement->FirstChildElement("Vertex"); vertElement != NULL; vertElement = vertElement->NextSiblingElement("Vertex"))
      {
        if (vertElement == NULL)
          continue;
        int id = 0;
        mitk::Point2D::ValueType x = 0.0;
        mitk::Point2D::ValueType y = 0.0;
        if (vertElement->QueryIntAttribute("id", &id) == TIXML_WRONG_TYPE)
          return; // TODO: can we do a better error handling?
        if (vertElement->QueryFloatAttribute("x", &x) == TIXML_WRONG_TYPE)
          return; // TODO: can we do a better error handling?
        if (vertElement->QueryFloatAttribute("y", &y) == TIXML_WRONG_TYPE)
          return; // TODO: can we do a better error handling?
        Point2D p;
        p.SetElement(0, x);
        p.SetElement(1, y);
        if (first == true)  // needed to set m_FigurePlaced to true
        {
          planarFigure->PlaceFigure(p);
          first = false;
        }
        planarFigure->SetControlPoint(id, p, true);
      }

    // Calculate feature quantities of this PlanarFigure
    planarFigure->EvaluateFeatures();

    // Make sure that no control point is currently selected
    planarFigure->DeselectControlPoint();

    // \TODO: what about m_FigurePlaced and m_SelectedControlPoint ??
    this->SetNthOutput( this->GetNumberOfOutputs(), planarFigure );  // add planarFigure as new output of this filter
  }
  m_Success = true;
}

mitk::Point3D mitk::PlanarFigureReader::GetPointFromXMLNode(TiXmlElement* e)
{
  if (e == NULL)
    throw std::invalid_argument("node invalid"); // TODO: can we do a better error handling?
  mitk::Point3D point;
  mitk::ScalarType p(-1.0);
  if (e->QueryFloatAttribute("x", &p) == TIXML_WRONG_TYPE)
    throw std::invalid_argument("node malformatted"); // TODO: can we do a better error handling?
  point.SetElement(0, p);
  if (e->QueryFloatAttribute("y", &p) == TIXML_WRONG_TYPE)
    throw std::invalid_argument("node malformatted"); // TODO: can we do a better error handling?
  point.SetElement(1, p);
  if (e->QueryFloatAttribute("z", &p) == TIXML_WRONG_TYPE)
    throw std::invalid_argument("node malformatted"); // TODO: can we do a better error handling?
  point.SetElement(2, p);
  return point;
}

mitk::Vector3D mitk::PlanarFigureReader::GetVectorFromXMLNode(TiXmlElement* e)
{
  if (e == NULL)
    throw std::invalid_argument("node invalid"); // TODO: can we do a better error handling?
  mitk::Vector3D vector;
  mitk::ScalarType p(-1.0);
  if (e->QueryFloatAttribute("x", &p) == TIXML_WRONG_TYPE)
    throw std::invalid_argument("node malformatted"); // TODO: can we do a better error handling?
  vector.SetElement(0, p);
  if (e->QueryFloatAttribute("y", &p) == TIXML_WRONG_TYPE)
    throw std::invalid_argument("node malformatted"); // TODO: can we do a better error handling?
  vector.SetElement(1, p);
  if (e->QueryFloatAttribute("z", &p) == TIXML_WRONG_TYPE)
    throw std::invalid_argument("node malformatted"); // TODO: can we do a better error handling?
  vector.SetElement(2, p);
  return vector;
}

mitk::PlanarFigureReader::DoubleList
mitk::PlanarFigureReader::GetDoubleAttributeListFromXMLNode(TiXmlElement* e, const char *attributeNameBase, unsigned int count)
{
  DoubleList list;

  if (e == NULL)
    throw std::invalid_argument("node invalid"); // TODO: can we do a better error handling?

  for ( unsigned int i = 0; i < count; ++i )
  {
    mitk::ScalarType p(-1.0);
    std::stringstream attributeName;
    attributeName << attributeNameBase << i;

    if (e->QueryFloatAttribute( attributeName.str().c_str(), &p ) == TIXML_WRONG_TYPE)
      throw std::invalid_argument("node malformatted"); // TODO: can we do a better error handling?
    list.push_back( p );
  }

  return list;
}

void mitk::PlanarFigureReader::GenerateOutputInformation()
{
}

int mitk::PlanarFigureReader::CanReadFile ( const char *name )
{
  if (std::string(name).empty())
    return false;

  return (itksys::SystemTools::LowerCase(itksys::SystemTools::GetFilenameLastExtension(name)) == ".pf");  //assume, we can read all .pf files

  //TiXmlDocument document(name);
  //if (document.LoadFile() == false)
  //  return false;
  //return (document.FirstChildElement("PlanarFigure") != NULL);
}

bool mitk::PlanarFigureReader::CanReadFile(const std::string filename, const std::string, const std::string)
{
  if (filename.empty())
    return false;

  return (itksys::SystemTools::LowerCase(itksys::SystemTools::GetFilenameLastExtension(filename)) == ".pf");  //assume, we can read all .pf files

  //TiXmlDocument document(filename);
  //if (document.LoadFile() == false)
  //  return false;
  //return (document.FirstChildElement("PlanarFigure") != NULL);
}

void mitk::PlanarFigureReader::ResizeOutputs( const unsigned int& num )
{
  unsigned int prevNum = this->GetNumberOfOutputs();
  this->SetNumberOfOutputs( num );
  for ( unsigned int i = prevNum; i < num; ++i )
  {
    this->SetNthOutput( i, this->MakeOutput( i ).GetPointer() );
  }
}
<|endoftext|>