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

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_shell.hxx"

#ifdef _MSC_VER
#pragma warning (disable : 4786 4503)
#endif

#ifndef DOCUMENT_STATISTIC_HXX_INCLUDED
#include "document_statistic.hxx"
#endif

#ifndef UTILITIES_HXX_INCLUDED
#include "internal/utilities.hxx"
#endif

#ifndef METAINFOREADER_HXX_INCLUDED
#include "internal/metainforeader.hxx"
#endif

#ifndef RESOURCE_H_INCLUDED
#include "internal/resource.h"
#endif

#ifndef FILEEXTENSIONS_HXX_INCLUDED
#include "internal/fileextensions.hxx"
#endif

#ifndef CONFIG_HXX_INCLUDED
#include "internal/config.hxx"
#endif

#ifndef ISO8601_CONVERTER_HXX_INCLUDED
#include "internal/iso8601_converter.hxx"
#endif

//#####################################
const bool READONLY  = false;
const bool WRITEABLE = true;

//#####################################
document_statistic_reader_ptr create_document_statistic_reader(const std::string& document_name, CMetaInfoReader* meta_info_accessor)
{
    File_Type_t file_type = get_file_type(document_name);

    if (WRITER == file_type)
        return document_statistic_reader_ptr(new writer_document_statistic_reader(document_name, meta_info_accessor));
    else if (CALC == file_type)
        return document_statistic_reader_ptr(new calc_document_statistic_reader(document_name, meta_info_accessor));
    else
        return document_statistic_reader_ptr(new draw_impress_math_document_statistic_reader(document_name, meta_info_accessor));
}

//#####################################
document_statistic_reader::document_statistic_reader(const std::string& document_name, CMetaInfoReader* meta_info_accessor) :
    document_name_(document_name),
    meta_info_accessor_(meta_info_accessor)
{}

//#####################################
document_statistic_reader::~document_statistic_reader()
{}

//#####################################
void document_statistic_reader::read(statistic_group_list_t* group_list)
{
    group_list->clear();
    fill_description_section(meta_info_accessor_, group_list);
    fill_origin_section(meta_info_accessor_, group_list);
}

//#####################################
std::string document_statistic_reader::get_document_name() const
{
    return document_name_;
}

//#####################################
void document_statistic_reader::fill_origin_section(CMetaInfoReader *meta_info_accessor, statistic_group_list_t* group_list)
{
    statistic_item_list_t il;

    il.push_back(statistic_item(GetResString(IDS_AUTHOR), meta_info_accessor->getTagData( META_INFO_AUTHOR ), READONLY));

    il.push_back(statistic_item(GetResString(IDS_MODIFIED),
        iso8601_date_to_local_date(meta_info_accessor->getTagData(META_INFO_MODIFIED )), READONLY));

    il.push_back(statistic_item(GetResString(IDS_DOCUMENT_NUMBER), meta_info_accessor->getTagData( META_INFO_DOCUMENT_NUMBER ), READONLY));

    il.push_back(statistic_item(GetResString(IDS_EDITING_TIME),
        iso8601_duration_to_local_duration(meta_info_accessor->getTagData( META_INFO_EDITING_TIME )), READONLY));

    group_list->push_back(statistic_group_t(GetResString(IDS_ORIGIN), il));
}

//#####################################
writer_document_statistic_reader::writer_document_statistic_reader(const std::string& document_name, CMetaInfoReader* meta_info_accessor) :
    document_statistic_reader(document_name, meta_info_accessor)
{}

//#####################################
void writer_document_statistic_reader::fill_description_section(CMetaInfoReader *meta_info_accessor, statistic_group_list_t* group_list)
{
    statistic_item_list_t il;

    il.push_back(statistic_item(GetResString(IDS_TITLE),    meta_info_accessor->getTagData( META_INFO_TITLE ),       READONLY));
    il.push_back(statistic_item(GetResString(IDS_COMMENTS), meta_info_accessor->getTagData( META_INFO_DESCRIPTION ), READONLY));
    il.push_back(statistic_item(GetResString(IDS_SUBJECT),  meta_info_accessor->getTagData( META_INFO_SUBJECT ),     READONLY));
    il.push_back(statistic_item(GetResString(IDS_KEYWORDS), meta_info_accessor->getTagData(META_INFO_KEYWORDS ),    READONLY));
    il.push_back(statistic_item(GetResString(IDS_PAGES),    meta_info_accessor->getTagAttribute( META_INFO_DOCUMENT_STATISTIC,META_INFO_PAGES) , READONLY));
    il.push_back(statistic_item(GetResString(IDS_TABLES), meta_info_accessor->getTagAttribute( META_INFO_DOCUMENT_STATISTIC,META_INFO_TABLES) , READONLY));
    il.push_back(statistic_item(GetResString(IDS_GRAPHICS), meta_info_accessor->getTagAttribute( META_INFO_DOCUMENT_STATISTIC,META_INFO_DRAWS) , READONLY));
    il.push_back(statistic_item(GetResString(IDS_OLE_OBJECTS), meta_info_accessor->getTagAttribute( META_INFO_DOCUMENT_STATISTIC,META_INFO_OBJECTS) ,    READONLY));
    il.push_back(statistic_item(GetResString(IDS_PARAGRAPHS), meta_info_accessor->getTagAttribute( META_INFO_DOCUMENT_STATISTIC,META_INFO_PARAGRAPHS) , READONLY));
    il.push_back(statistic_item(GetResString(IDS_WORDS), meta_info_accessor->getTagAttribute( META_INFO_DOCUMENT_STATISTIC,META_INFO_WORDS) , READONLY));
    il.push_back(statistic_item(GetResString(IDS_CHARACTERS), meta_info_accessor->getTagAttribute( META_INFO_DOCUMENT_STATISTIC,META_INFO_CHARACTERS) , READONLY));

    group_list->push_back(statistic_group_t(GetResString(IDS_DESCRIPTION), il));
}

//#######################################
calc_document_statistic_reader::calc_document_statistic_reader(
    const std::string& document_name, CMetaInfoReader* meta_info_accessor) :
    document_statistic_reader(document_name, meta_info_accessor)
{}

//#######################################
void calc_document_statistic_reader::fill_description_section(
    CMetaInfoReader *meta_info_accessor,statistic_group_list_t* group_list)
{
    statistic_item_list_t il;

    il.push_back(statistic_item(GetResString(IDS_TITLE),       meta_info_accessor->getTagData( META_INFO_TITLE ),       READONLY));
    il.push_back(statistic_item(GetResString(IDS_COMMENTS),    meta_info_accessor->getTagData( META_INFO_DESCRIPTION ), READONLY));
    il.push_back(statistic_item(GetResString(IDS_SUBJECT),     meta_info_accessor->getTagData( META_INFO_SUBJECT ),     READONLY));
    il.push_back(statistic_item(GetResString(IDS_KEYWORDS),    meta_info_accessor->getTagData(META_INFO_KEYWORDS ),    READONLY));
    il.push_back(statistic_item(GetResString(IDS_TABLES),      meta_info_accessor->getTagAttribute( META_INFO_DOCUMENT_STATISTIC,META_INFO_TABLES) ,  READONLY));
    il.push_back(statistic_item(GetResString(IDS_CELLS),       meta_info_accessor->getTagAttribute( META_INFO_DOCUMENT_STATISTIC,META_INFO_CELLS) ,   READONLY));
    il.push_back(statistic_item(GetResString(IDS_OLE_OBJECTS), meta_info_accessor->getTagAttribute( META_INFO_DOCUMENT_STATISTIC,META_INFO_OBJECTS) , READONLY));

    group_list->push_back(statistic_group_t(GetResString(IDS_DESCRIPTION), il));
}

//#######################################
draw_impress_math_document_statistic_reader::draw_impress_math_document_statistic_reader(
    const std::string& document_name, CMetaInfoReader* meta_info_accessor) :
    document_statistic_reader(document_name, meta_info_accessor)
{}

//#######################################
void draw_impress_math_document_statistic_reader::fill_description_section(
    CMetaInfoReader *meta_info_accessor, statistic_group_list_t* group_list)
{
    statistic_item_list_t il;

    il.push_back(statistic_item(GetResString(IDS_TITLE),       meta_info_accessor->getTagData( META_INFO_TITLE ),       READONLY));
    il.push_back(statistic_item(GetResString(IDS_COMMENTS),    meta_info_accessor->getTagData( META_INFO_DESCRIPTION ), READONLY));
    il.push_back(statistic_item(GetResString(IDS_SUBJECT),     meta_info_accessor->getTagData( META_INFO_SUBJECT ),     READONLY));
    il.push_back(statistic_item(GetResString(IDS_KEYWORDS),    meta_info_accessor->getTagData(META_INFO_KEYWORDS ),    READONLY));
    il.push_back(statistic_item(GetResString(IDS_PAGES),       meta_info_accessor->getTagAttribute( META_INFO_DOCUMENT_STATISTIC,META_INFO_PAGES) ,   READONLY));
    il.push_back(statistic_item(GetResString(IDS_OLE_OBJECTS), meta_info_accessor->getTagAttribute( META_INFO_DOCUMENT_STATISTIC,META_INFO_OBJECTS) , READONLY));

    group_list->push_back(statistic_group_t(GetResString(IDS_DESCRIPTION), il));
}
<commit_msg>INTEGRATION: CWS changefileheader (1.6.44); FILE MERGED 2008/04/01 12:41:15 thb 1.6.44.2: #i85898# Stripping all external header guards 2008/03/31 13:17:13 rt 1.6.44.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: document_statistic.cxx,v $
 * $Revision: 1.7 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_shell.hxx"

#ifdef _MSC_VER
#pragma warning (disable : 4786 4503)
#endif
#include "document_statistic.hxx"
#include "internal/utilities.hxx"
#include "internal/metainforeader.hxx"
#include "internal/resource.h"
#include "internal/fileextensions.hxx"
#include "internal/config.hxx"
#include "internal/iso8601_converter.hxx"

//#####################################
const bool READONLY  = false;
const bool WRITEABLE = true;

//#####################################
document_statistic_reader_ptr create_document_statistic_reader(const std::string& document_name, CMetaInfoReader* meta_info_accessor)
{
    File_Type_t file_type = get_file_type(document_name);

    if (WRITER == file_type)
        return document_statistic_reader_ptr(new writer_document_statistic_reader(document_name, meta_info_accessor));
    else if (CALC == file_type)
        return document_statistic_reader_ptr(new calc_document_statistic_reader(document_name, meta_info_accessor));
    else
        return document_statistic_reader_ptr(new draw_impress_math_document_statistic_reader(document_name, meta_info_accessor));
}

//#####################################
document_statistic_reader::document_statistic_reader(const std::string& document_name, CMetaInfoReader* meta_info_accessor) :
    document_name_(document_name),
    meta_info_accessor_(meta_info_accessor)
{}

//#####################################
document_statistic_reader::~document_statistic_reader()
{}

//#####################################
void document_statistic_reader::read(statistic_group_list_t* group_list)
{
    group_list->clear();
    fill_description_section(meta_info_accessor_, group_list);
    fill_origin_section(meta_info_accessor_, group_list);
}

//#####################################
std::string document_statistic_reader::get_document_name() const
{
    return document_name_;
}

//#####################################
void document_statistic_reader::fill_origin_section(CMetaInfoReader *meta_info_accessor, statistic_group_list_t* group_list)
{
    statistic_item_list_t il;

    il.push_back(statistic_item(GetResString(IDS_AUTHOR), meta_info_accessor->getTagData( META_INFO_AUTHOR ), READONLY));

    il.push_back(statistic_item(GetResString(IDS_MODIFIED),
        iso8601_date_to_local_date(meta_info_accessor->getTagData(META_INFO_MODIFIED )), READONLY));

    il.push_back(statistic_item(GetResString(IDS_DOCUMENT_NUMBER), meta_info_accessor->getTagData( META_INFO_DOCUMENT_NUMBER ), READONLY));

    il.push_back(statistic_item(GetResString(IDS_EDITING_TIME),
        iso8601_duration_to_local_duration(meta_info_accessor->getTagData( META_INFO_EDITING_TIME )), READONLY));

    group_list->push_back(statistic_group_t(GetResString(IDS_ORIGIN), il));
}

//#####################################
writer_document_statistic_reader::writer_document_statistic_reader(const std::string& document_name, CMetaInfoReader* meta_info_accessor) :
    document_statistic_reader(document_name, meta_info_accessor)
{}

//#####################################
void writer_document_statistic_reader::fill_description_section(CMetaInfoReader *meta_info_accessor, statistic_group_list_t* group_list)
{
    statistic_item_list_t il;

    il.push_back(statistic_item(GetResString(IDS_TITLE),    meta_info_accessor->getTagData( META_INFO_TITLE ),       READONLY));
    il.push_back(statistic_item(GetResString(IDS_COMMENTS), meta_info_accessor->getTagData( META_INFO_DESCRIPTION ), READONLY));
    il.push_back(statistic_item(GetResString(IDS_SUBJECT),  meta_info_accessor->getTagData( META_INFO_SUBJECT ),     READONLY));
    il.push_back(statistic_item(GetResString(IDS_KEYWORDS), meta_info_accessor->getTagData(META_INFO_KEYWORDS ),    READONLY));
    il.push_back(statistic_item(GetResString(IDS_PAGES),    meta_info_accessor->getTagAttribute( META_INFO_DOCUMENT_STATISTIC,META_INFO_PAGES) , READONLY));
    il.push_back(statistic_item(GetResString(IDS_TABLES), meta_info_accessor->getTagAttribute( META_INFO_DOCUMENT_STATISTIC,META_INFO_TABLES) , READONLY));
    il.push_back(statistic_item(GetResString(IDS_GRAPHICS), meta_info_accessor->getTagAttribute( META_INFO_DOCUMENT_STATISTIC,META_INFO_DRAWS) , READONLY));
    il.push_back(statistic_item(GetResString(IDS_OLE_OBJECTS), meta_info_accessor->getTagAttribute( META_INFO_DOCUMENT_STATISTIC,META_INFO_OBJECTS) ,    READONLY));
    il.push_back(statistic_item(GetResString(IDS_PARAGRAPHS), meta_info_accessor->getTagAttribute( META_INFO_DOCUMENT_STATISTIC,META_INFO_PARAGRAPHS) , READONLY));
    il.push_back(statistic_item(GetResString(IDS_WORDS), meta_info_accessor->getTagAttribute( META_INFO_DOCUMENT_STATISTIC,META_INFO_WORDS) , READONLY));
    il.push_back(statistic_item(GetResString(IDS_CHARACTERS), meta_info_accessor->getTagAttribute( META_INFO_DOCUMENT_STATISTIC,META_INFO_CHARACTERS) , READONLY));

    group_list->push_back(statistic_group_t(GetResString(IDS_DESCRIPTION), il));
}

//#######################################
calc_document_statistic_reader::calc_document_statistic_reader(
    const std::string& document_name, CMetaInfoReader* meta_info_accessor) :
    document_statistic_reader(document_name, meta_info_accessor)
{}

//#######################################
void calc_document_statistic_reader::fill_description_section(
    CMetaInfoReader *meta_info_accessor,statistic_group_list_t* group_list)
{
    statistic_item_list_t il;

    il.push_back(statistic_item(GetResString(IDS_TITLE),       meta_info_accessor->getTagData( META_INFO_TITLE ),       READONLY));
    il.push_back(statistic_item(GetResString(IDS_COMMENTS),    meta_info_accessor->getTagData( META_INFO_DESCRIPTION ), READONLY));
    il.push_back(statistic_item(GetResString(IDS_SUBJECT),     meta_info_accessor->getTagData( META_INFO_SUBJECT ),     READONLY));
    il.push_back(statistic_item(GetResString(IDS_KEYWORDS),    meta_info_accessor->getTagData(META_INFO_KEYWORDS ),    READONLY));
    il.push_back(statistic_item(GetResString(IDS_TABLES),      meta_info_accessor->getTagAttribute( META_INFO_DOCUMENT_STATISTIC,META_INFO_TABLES) ,  READONLY));
    il.push_back(statistic_item(GetResString(IDS_CELLS),       meta_info_accessor->getTagAttribute( META_INFO_DOCUMENT_STATISTIC,META_INFO_CELLS) ,   READONLY));
    il.push_back(statistic_item(GetResString(IDS_OLE_OBJECTS), meta_info_accessor->getTagAttribute( META_INFO_DOCUMENT_STATISTIC,META_INFO_OBJECTS) , READONLY));

    group_list->push_back(statistic_group_t(GetResString(IDS_DESCRIPTION), il));
}

//#######################################
draw_impress_math_document_statistic_reader::draw_impress_math_document_statistic_reader(
    const std::string& document_name, CMetaInfoReader* meta_info_accessor) :
    document_statistic_reader(document_name, meta_info_accessor)
{}

//#######################################
void draw_impress_math_document_statistic_reader::fill_description_section(
    CMetaInfoReader *meta_info_accessor, statistic_group_list_t* group_list)
{
    statistic_item_list_t il;

    il.push_back(statistic_item(GetResString(IDS_TITLE),       meta_info_accessor->getTagData( META_INFO_TITLE ),       READONLY));
    il.push_back(statistic_item(GetResString(IDS_COMMENTS),    meta_info_accessor->getTagData( META_INFO_DESCRIPTION ), READONLY));
    il.push_back(statistic_item(GetResString(IDS_SUBJECT),     meta_info_accessor->getTagData( META_INFO_SUBJECT ),     READONLY));
    il.push_back(statistic_item(GetResString(IDS_KEYWORDS),    meta_info_accessor->getTagData(META_INFO_KEYWORDS ),    READONLY));
    il.push_back(statistic_item(GetResString(IDS_PAGES),       meta_info_accessor->getTagAttribute( META_INFO_DOCUMENT_STATISTIC,META_INFO_PAGES) ,   READONLY));
    il.push_back(statistic_item(GetResString(IDS_OLE_OBJECTS), meta_info_accessor->getTagAttribute( META_INFO_DOCUMENT_STATISTIC,META_INFO_OBJECTS) , READONLY));

    group_list->push_back(statistic_group_t(GetResString(IDS_DESCRIPTION), il));
}
<|endoftext|>


<commit_before>#include <stdio.h>
#include <math.h>

#include <lcm/lcm-cpp.hpp>
#include "lcmtypes/drc_lcmtypes.hpp"

inline void
bot_quat_mult (double c[4], const double a[4], const double b[4])
{
    c[0] = a[0]*b[0] - a[1]*b[1] - a[2]*b[2] - a[3]*b[3];
    c[1] = a[0]*b[1] + a[1]*b[0] + a[2]*b[3] - a[3]*b[2];
    c[2] = a[0]*b[2] - a[1]*b[3] + a[2]*b[0] + a[3]*b[1];
    c[3] = a[0]*b[3] + a[1]*b[2] - a[2]*b[1] + a[3]*b[0];
}

void
bot_quat_rotate_rev (const double rot[4], double v[3])
{
    double a[4], b[4], c[4];

    b[0] = 0;
    memcpy (b+1, v, 3 * sizeof (double));

    bot_quat_mult (a, b, rot);
    b[0] = rot[0];
    b[1] = -rot[1];
    b[2] = -rot[2];
    b[3] = -rot[3];
    bot_quat_mult (c, b, a);

    memcpy (v, c+1, 3 * sizeof (double));
}

static inline int
feq (double a, double b) {
    return fabs (a - b) < 1e-9;
}

void
bot_quat_to_angle_axis (const double q[4], double *theta, double axis[3])
{
    double halftheta = acos (q[0]);
    *theta = halftheta * 2;
    double sinhalftheta = sin (halftheta);
    if (feq (halftheta, 0)) {
        axis[0] = 0;
        axis[1] = 0;
        axis[2] = 1;
        *theta = 0;
    } else {
        axis[0] = q[1] / sinhalftheta;
        axis[1] = q[2] / sinhalftheta;
        axis[2] = q[3] / sinhalftheta;
    }
}

class Handler
{
	drc::vector_3d_t translation;
	drc::quaternion_t rotation;
	public:
		lcm::LCM lcm;
		~Handler() {}

 		void handleStateMessage(const lcm::ReceiveBuffer* rbuf, const std::string& channel, const drc::robot_state_t* msg) {
			// printf("received message on channel \"%s\":\n", channel.c_str());
			// printf("timestamp = %11d\n", (long long)msg->utime);
			translation = msg->origin_position.translation;
			rotation = msg->origin_position.rotation;

		};

		void handleGoalMessage(const lcm::ReceiveBuffer* rbuf, const std::string& channel, const drc::nav_goal_timed_t* msg) {
			printf("start = %f, %f, %f\n", translation.x, translation.y, translation.z);
			printf("goal = %f, %f, %f\n", msg->goal_pos.translation.x, msg->goal_pos.translation.y, msg->goal_pos.translation.z);
			double translation_to_goal[3] = {msg->goal_pos.translation.x - translation.x, msg->goal_pos.translation.y - translation.y, msg->goal_pos.translation.z - translation.z};
			// translation_to_goal[0] = msg->goal_pos.translation.x - translation.x;
			// translation_to_goal[1] = msg->goal_pos.translation.y - translation.y;
			// translation_to_goal[2] = msg->goal_pos.translation.z - translation.z};

			// printf("x vec: %f - %f = %f, %f\n", msg->goal_pos.translation.x, translation.x,msg->goal_pos.translation.x - translation.x, translation_to_goal[0]);
			printf("vec to goal: %f, %f, %f\n", translation_to_goal[0], translation_to_goal[1], translation_to_goal[2]);

			// double robot_rotation[4] = {rotation.x, rotation.y, rotation.z, rotation.w};
			// printf("quaternion: %f, %f, %f, %f\n", rotation.x, rotation.y, rotation.z, rotation.w);
			// double rot_axis[3];
			// double rot_theta;
			// bot_quat_to_angle_axis(robot_rotation, &rot_theta, rot_axis);
			// printf("axis: %f, %f, %f\n", rot_axis[0], rot_axis[1], rot_axis[2]);
			// printf("angle: %f\n", rot_theta);
			// bot_quat_rotate_rev(robot_rotation, translation_to_goal);
			printf("vec to goal in robot frame: %f, %f, %f\n", translation_to_goal[0], translation_to_goal[1], translation_to_goal[2]);
			// double x_dist = msg->goal_pos.translation.x - translation.x;
			// double y_dist = msg->goal_pos.translation.y - translation.y;
			double total_dist = sqrt(pow(translation_to_goal[0], 2) + pow(translation_to_goal[1], 2));
			// TODO: Handle case when y_dist == total_dist
			double theta = 2 * acos(translation_to_goal[0] / total_dist);
			double R = translation_to_goal[0] / sin(theta);
			printf("plan: R = %f, theta = %f\n", R, theta);

			if (translation_to_goal[1] < 0) {
				R = -R;
				theta = -theta;
			}
			double path_center[2];
			path_center[0] = translation.x;
			path_center[1] = translation.y + R;
			printf("path center = %f, %f\n", path_center[0], path_center[1]);

			double step_size_m = 0.5;
			double step_width_m = 0.30;
			double step_dt_s = 1;

			double arc_dist_to_goal_m = theta * R;
			int num_steps = floor(arc_dist_to_goal_m / step_size_m);
			double step_arc_size_rad = theta / num_steps;

			drc::ee_goal_sequence_t right_foot_goals;
			right_foot_goals.utime = msg->utime;
			right_foot_goals.robot_name = msg->robot_name;
			right_foot_goals.num_goals = num_steps;

			drc::ee_goal_sequence_t left_foot_goals;
			left_foot_goals.utime = msg->utime;
			left_foot_goals.robot_name = msg->robot_name;
			left_foot_goals.num_goals = num_steps;

			for (int i=0; i < num_steps; i++) {
				double right_foot_angle = step_arc_size_rad * (i + 0.5);
				double left_foot_angle = step_arc_size_rad * (i + 1);
				double left_foot_radius;
				double right_foot_radius;
				if (R > 0) {
					right_foot_radius = R - step_width_m / 2;
					left_foot_radius = R + step_width_m / 2;
				} else {
					right_foot_radius = R + step_width_m / 2;
					left_foot_radius = R - step_width_m / 2;
				}
				drc::ee_goal_t ee_goal;
				ee_goal.utime = msg->utime + i * step_dt_s;
				ee_goal.robot_name = msg->robot_name;
				ee_goal.ee_name = "RbackWheel";
				ee_goal.num_chain_joints = 0;
				drc::position_3d_t step_pos;
				step_pos.rotation = rotation;
				step_pos.translation.x = translation.x + right_foot_radius * sin(right_foot_angle);
				step_pos.translation.y = translation.y + right_foot_radius * (1 - cos(right_foot_angle));
				step_pos.translation.z = 0;
				ee_goal.ee_goal_pos = step_pos;
				right_foot_goals.goals.push_back(ee_goal);

				step_pos.rotation = rotation;
				step_pos.translation.x = translation.x + left_foot_radius * sin(left_foot_angle);
				step_pos.translation.y = translation.y + left_foot_radius * (1 - cos(left_foot_angle));
				step_pos.translation.z = 0;
				ee_goal.ee_goal_pos = step_pos;
				ee_goal.ee_name = "LbackWheel";
				left_foot_goals.goals.push_back(ee_goal);
			}

			lcm.publish("RIGHT_FOOT_STEPS", &right_foot_goals);
			lcm.publish("LEFT_FOOT_STEPS", &left_foot_goals);
		};
};

int main(int argc, char **argv)
{
	lcm::LCM lcm;
	if (!lcm.good())
		return 1;

	Handler handlerObject;
	handlerObject.lcm = lcm;
	lcm.subscribe("EST_ROBOT_STATE", &Handler::handleStateMessage, &handlerObject);
	lcm.subscribe("NAV_GOAL_TIMED", &Handler::handleGoalMessage, &handlerObject);
	while (0 == lcm.handle());

	return 0;
}
<commit_msg>Fixed foot width bug<commit_after>#include <stdio.h>
#include <math.h>

#include <lcm/lcm-cpp.hpp>
#include "lcmtypes/drc_lcmtypes.hpp"

inline void
bot_quat_mult (double c[4], const double a[4], const double b[4])
{
    c[0] = a[0]*b[0] - a[1]*b[1] - a[2]*b[2] - a[3]*b[3];
    c[1] = a[0]*b[1] + a[1]*b[0] + a[2]*b[3] - a[3]*b[2];
    c[2] = a[0]*b[2] - a[1]*b[3] + a[2]*b[0] + a[3]*b[1];
    c[3] = a[0]*b[3] + a[1]*b[2] - a[2]*b[1] + a[3]*b[0];
}

void
bot_quat_rotate_rev (const double rot[4], double v[3])
{
    double a[4], b[4], c[4];

    b[0] = 0;
    memcpy (b+1, v, 3 * sizeof (double));

    bot_quat_mult (a, b, rot);
    b[0] = rot[0];
    b[1] = -rot[1];
    b[2] = -rot[2];
    b[3] = -rot[3];
    bot_quat_mult (c, b, a);

    memcpy (v, c+1, 3 * sizeof (double));
}

static inline int
feq (double a, double b) {
    return fabs (a - b) < 1e-9;
}

void
bot_quat_to_angle_axis (const double q[4], double *theta, double axis[3])
{
    double halftheta = acos (q[0]);
    *theta = halftheta * 2;
    double sinhalftheta = sin (halftheta);
    if (feq (halftheta, 0)) {
        axis[0] = 0;
        axis[1] = 0;
        axis[2] = 1;
        *theta = 0;
    } else {
        axis[0] = q[1] / sinhalftheta;
        axis[1] = q[2] / sinhalftheta;
        axis[2] = q[3] / sinhalftheta;
    }
}

class Handler
{
	drc::vector_3d_t translation;
	drc::quaternion_t rotation;
	public:
		lcm::LCM lcm;
		~Handler() {}

 		void handleStateMessage(const lcm::ReceiveBuffer* rbuf, const std::string& channel, const drc::robot_state_t* msg) {
			// printf("received message on channel \"%s\":\n", channel.c_str());
			// printf("timestamp = %11d\n", (long long)msg->utime);
			translation = msg->origin_position.translation;
			rotation = msg->origin_position.rotation;

		};

		void handleGoalMessage(const lcm::ReceiveBuffer* rbuf, const std::string& channel, const drc::nav_goal_timed_t* msg) {
			printf("start = %f, %f, %f\n", translation.x, translation.y, translation.z);
			printf("goal = %f, %f, %f\n", msg->goal_pos.translation.x, msg->goal_pos.translation.y, msg->goal_pos.translation.z);
			double translation_to_goal[3] = {msg->goal_pos.translation.x - translation.x, msg->goal_pos.translation.y - translation.y, msg->goal_pos.translation.z - translation.z};
			// translation_to_goal[0] = msg->goal_pos.translation.x - translation.x;
			// translation_to_goal[1] = msg->goal_pos.translation.y - translation.y;
			// translation_to_goal[2] = msg->goal_pos.translation.z - translation.z};

			// printf("x vec: %f - %f = %f, %f\n", msg->goal_pos.translation.x, translation.x,msg->goal_pos.translation.x - translation.x, translation_to_goal[0]);
			printf("vec to goal: %f, %f, %f\n", translation_to_goal[0], translation_to_goal[1], translation_to_goal[2]);

			// double robot_rotation[4] = {rotation.x, rotation.y, rotation.z, rotation.w};
			// printf("quaternion: %f, %f, %f, %f\n", rotation.x, rotation.y, rotation.z, rotation.w);
			// double rot_axis[3];
			// double rot_theta;
			// bot_quat_to_angle_axis(robot_rotation, &rot_theta, rot_axis);
			// printf("axis: %f, %f, %f\n", rot_axis[0], rot_axis[1], rot_axis[2]);
			// printf("angle: %f\n", rot_theta);
			// bot_quat_rotate_rev(robot_rotation, translation_to_goal);
			printf("vec to goal in robot frame: %f, %f, %f\n", translation_to_goal[0], translation_to_goal[1], translation_to_goal[2]);
			// double x_dist = msg->goal_pos.translation.x - translation.x;
			// double y_dist = msg->goal_pos.translation.y - translation.y;
			double total_dist = sqrt(pow(translation_to_goal[0], 2) + pow(translation_to_goal[1], 2));
			// TODO: Handle case when y_dist == total_dist
			double theta = 2 * acos(translation_to_goal[0] / total_dist);
			double R = translation_to_goal[0] / sin(theta);
			printf("plan: R = %f, theta = %f\n", R, theta);

			if (translation_to_goal[1] < 0) {
				R = -R;
				theta = -theta;
			}
			double path_center[2];
			path_center[0] = translation.x;
			path_center[1] = translation.y + R;
			printf("path center = %f, %f\n", path_center[0], path_center[1]);

			double step_size_m = 0.5;
			double step_width_m = 0.30;
			double step_dt_s = 1;

			double arc_dist_to_goal_m = theta * R;
			int num_steps = floor(arc_dist_to_goal_m / step_size_m);
			double step_arc_size_rad = theta / num_steps;

			drc::ee_goal_sequence_t right_foot_goals;
			right_foot_goals.utime = msg->utime;
			right_foot_goals.robot_name = msg->robot_name;
			right_foot_goals.num_goals = num_steps;

			drc::ee_goal_sequence_t left_foot_goals;
			left_foot_goals.utime = msg->utime;
			left_foot_goals.robot_name = msg->robot_name;
			left_foot_goals.num_goals = num_steps;
			double left_foot_radius;
			double right_foot_radius;
			if (R > 0) {
				right_foot_radius = R - step_width_m / 2;
				left_foot_radius = R + step_width_m / 2;
			} else {
				right_foot_radius = R + step_width_m / 2;
				left_foot_radius = R - step_width_m / 2;
			}
			printf("right foot rad = %f, left foot rad = %f\n", right_foot_radius, left_foot_radius);

			for (int i=0; i < num_steps; i++) {
				double right_foot_angle = step_arc_size_rad * (i + 0.5);
				double left_foot_angle = step_arc_size_rad * (i + 1);
				drc::ee_goal_t ee_goal;
				ee_goal.utime = msg->utime + i * step_dt_s;
				ee_goal.robot_name = msg->robot_name;
				ee_goal.ee_name = "RbackWheel";
				ee_goal.num_chain_joints = 0;
				drc::position_3d_t step_pos;
				step_pos.rotation = rotation;
				step_pos.translation.x = translation.x + right_foot_radius * sin(right_foot_angle);
				// printf("right trans x = %f\n", step_pos.translation.x);
				step_pos.translation.y = translation.y + R  - right_foot_radius * cos(right_foot_angle);
				step_pos.translation.z = 0;
				ee_goal.ee_goal_pos = step_pos;
				right_foot_goals.goals.push_back(ee_goal);

				step_pos.rotation = rotation;
				step_pos.translation.x = translation.x + left_foot_radius * sin(left_foot_angle);
				// printf("left trans x = %f\n", step_pos.translation.x);
				step_pos.translation.y = translation.y + R - left_foot_radius * cos(left_foot_angle);
				step_pos.translation.z = 0;
				ee_goal.ee_goal_pos = step_pos;
				ee_goal.ee_name = "LbackWheel";
				left_foot_goals.goals.push_back(ee_goal);
			}

			lcm.publish("RIGHT_FOOT_STEPS", &right_foot_goals);
			lcm.publish("LEFT_FOOT_STEPS", &left_foot_goals);
		};
};

int main(int argc, char **argv)
{
	lcm::LCM lcm;
	if (!lcm.good())
		return 1;

	Handler handlerObject;
	handlerObject.lcm = lcm;
	lcm.subscribe("EST_ROBOT_STATE", &Handler::handleStateMessage, &handlerObject);
	lcm.subscribe("NAV_GOAL_TIMED", &Handler::handleGoalMessage, &handlerObject);
	while (0 == lcm.handle());

	return 0;
}
<|endoftext|>


<commit_before>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2020 Scientific Computing and Imaging Institute,
   University of Utah.

   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 <gtest/gtest.h>
#include <Core/Algorithms/Base/Option.h>
#include <Core/Datatypes/DatatypeFwd.h>
#include <Core/Datatypes/Legacy/Field/CastFData.h>
#include <Core/Datatypes/Legacy/Field/FieldInformation.h>
#include <Core/Datatypes/Legacy/Field/Mesh.h>
#include <Core/Datatypes/Legacy/Field/VField.h>
#include <Core/GeometryPrimitives/Tensor.h>
#include <Core/GeometryPrimitives/Point.h>
#include <Core/GeometryPrimitives/Vector.h>
#include <Core/Datatypes/Dyadic3DTensor.h>
#include <Core/Algorithms/Base/AlgorithmData.h>
#include <Core/Algorithms/Math/ComputeTensorUncertaintyAlgorithm.h>
#include <boost/smart_ptr/make_shared_object.hpp>
#include "Core/Datatypes/MatrixFwd.h"

using namespace SCIRun;
using namespace SCIRun::Core::Datatypes;
using namespace SCIRun::Core::Geometry;
using namespace SCIRun::Core::Algorithms;
using namespace SCIRun::Core::Algorithms::Math;

const auto DIM = 3;
const auto epsilon = 1.0e-12;
const std::set<std::string> options = {"Linear Invariant","Log-Euclidean","Matrix Average"};
const auto MATRIX_AVERAGE = AlgoOption("Matrix Average", options);
const auto LOG_EUCLIDEAN = AlgoOption("Log-Euclidean", options);
const auto LINEAR_INVARIANT = AlgoOption("Linear Invariant", options);

// Used test from ReportFieldInfoTests as template for setting tensor data
TEST(ComputeTensorUncertaintTest, SetFieldData)
{
  const double unitHalf = 0.5 * std::sqrt(2);
  Tensor t1(5*Vector(1,0,0), 3*Vector(0,1,0), Vector(0,0,1));
  Tensor t2(7*Vector(unitHalf,unitHalf,0), 2*Vector(unitHalf,-unitHalf,0), Vector(0,0,1));
  Tensor t_expected(4.75, 1.25, 0, 3.75, 0, 1);
  FieldInformation lfi("LatVolMesh", 1, "Tensor");

  MeshHandle mesh1 = CreateMesh(lfi);
  MeshHandle mesh2 = CreateMesh(lfi);
  FieldHandle fh1 = CreateField(lfi, mesh1);
  FieldHandle fh2 = CreateField(lfi, mesh2);
  fh1->vfield()->set_all_values(t1);
  fh2->vfield()->set_all_values(t2);

  Tensor t;
  fh1->vfield()->get_value(t, 0);
  std::cout << "t1 from field: " << t << std::endl;
  fh2->vfield()->get_value(t, 0);
  std::cout << "t2 from field: " << t << std::endl;

  FieldList fields = {fh1, fh2};
  ComputeTensorUncertaintyAlgorithm algo;
  boost::tuple<FieldHandle, MatrixHandle> output = algo.runImpl(fields, MATRIX_AVERAGE, MATRIX_AVERAGE);
  output.get<0>()->vfield()->get_value(t,0);
  std::cout << "t average: " << t << std::endl;
  for (int i = 0; i < DIM; ++i)
    for (int j = 0; j < DIM; ++j)
      ASSERT_NEAR(t.val(i, j), t_expected.val(i, j), epsilon);
}
<commit_msg>Added tests for log euclidean and linear invariant<commit_after>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2020 Scientific Computing and Imaging Institute,
   University of Utah.

   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 <gtest/gtest.h>
#include <Core/Algorithms/Base/Option.h>
#include <Core/Datatypes/DatatypeFwd.h>
#include <Core/Datatypes/Legacy/Field/CastFData.h>
#include <Core/Datatypes/Legacy/Field/FieldInformation.h>
#include <Core/Datatypes/Legacy/Field/Mesh.h>
#include <Core/Datatypes/Legacy/Field/VField.h>
#include <Core/GeometryPrimitives/Tensor.h>
#include <Core/GeometryPrimitives/Point.h>
#include <Core/GeometryPrimitives/Vector.h>
#include <Core/Datatypes/Dyadic3DTensor.h>
#include <Core/Algorithms/Base/AlgorithmData.h>
#include <Core/Algorithms/Math/ComputeTensorUncertaintyAlgorithm.h>
#include <boost/smart_ptr/make_shared_object.hpp>
#include "Core/Datatypes/MatrixFwd.h"

using namespace SCIRun;
using namespace SCIRun::Core::Datatypes;
using namespace SCIRun::Core::Geometry;
using namespace SCIRun::Core::Algorithms;
using namespace SCIRun::Core::Algorithms::Math;

const auto DIM = 3;
const std::set<std::string> options = {"Linear Invariant","Log-Euclidean","Matrix Average"};
const auto MATRIX_AVERAGE = AlgoOption("Matrix Average", options);
const auto LOG_EUCLIDEAN = AlgoOption("Log-Euclidean", options);
const auto LINEAR_INVARIANT = AlgoOption("Linear Invariant", options);

FieldHandle tensorToField(Tensor t)
{
  FieldInformation lfi("LatVolMesh", 1, "Tensor");
  MeshHandle mesh = CreateMesh(lfi);
  FieldHandle fh = CreateField(lfi, mesh);
  fh->vfield()->set_all_values(t);
  return fh;
}

void assertTensorsNear(const Tensor& t, const Tensor& expected, double epsilon)
{
  for (int i = 0; i < DIM; ++i)
    for (int j = 0; j < DIM; ++j)
      ASSERT_NEAR(t.val(i, j), expected.val(i, j), epsilon);
}

TEST(ComputeTensorUncertaintyTest, MatrixAverage)
{
  const double unitHalf = 0.5 * std::sqrt(2);
  auto fh1 = tensorToField(Tensor(5*Vector(1,0,0), 3*Vector(0,1,0), Vector(0,0,1)));
  auto fh2 = tensorToField(Tensor(7*Vector(unitHalf,unitHalf,0), 2*Vector(unitHalf,-unitHalf,0), Vector(0,0,1)));
  Tensor t_expected(4.75, 1.25, 0, 3.75, 0, 1);
  const auto epsilon = 1.0e-12;

  FieldList fields = {fh1, fh2};
  ComputeTensorUncertaintyAlgorithm algo;
  boost::tuple<FieldHandle, MatrixHandle> output = algo.runImpl(fields, MATRIX_AVERAGE, MATRIX_AVERAGE);

  Tensor t;
  output.get<0>()->vfield()->get_value(t,0);
  assertTensorsNear(t, t_expected, epsilon);
}

// I hand calculated the Log-Euclidean calcuation except the last step of matrix exponential, hence the large epsilon
TEST(ComputeTensorUncertaintyTest, LogEuclidean)
{
  const double unitHalf = 0.5 * std::sqrt(2);
  auto fh1 = tensorToField(Tensor(5*Vector(1,0,0), 3*Vector(0,1,0), Vector(0,0,1)));
  auto fh2 = tensorToField(Tensor(7*Vector(unitHalf,unitHalf,0), 2*Vector(unitHalf,-unitHalf,0), Vector(0,0,1)));
  Tensor t_expected(4.522, 1.215, 0, 3.531, 0, 1);
  const auto epsilon = 0.001;

  FieldList fields = {fh1, fh2};
  ComputeTensorUncertaintyAlgorithm algo;
  boost::tuple<FieldHandle, MatrixHandle> output = algo.runImpl(fields, LOG_EUCLIDEAN, LOG_EUCLIDEAN);

  Tensor t;
  output.get<0>()->vfield()->get_value(t,0);
  assertTensorsNear(t, t_expected, epsilon);
}

// Since this only tests the invariant calculation, we only need to check the eigenvalues
TEST(ComputeTensorUncertaintyTest, LinearInvariant)
{
  const double unitHalf = 0.5 * std::sqrt(2);
  auto fh1 = tensorToField(Tensor(5*Vector(1,0,0), 3*Vector(0,1,0), Vector(0,0,1)));
  auto fh2 = tensorToField(Tensor(7*Vector(unitHalf,unitHalf,0), 2*Vector(unitHalf,-unitHalf,0), Vector(0,0,1)));
  std::vector<double> eigs_expected = {5.9075, 2.715, 0.877};
  const auto epsilon = 0.003;

  FieldList fields = {fh1, fh2};
  ComputeTensorUncertaintyAlgorithm algo;
  boost::tuple<FieldHandle, MatrixHandle> output = algo.runImpl(fields, LINEAR_INVARIANT, MATRIX_AVERAGE);

  Tensor t;
  output.get<0>()->vfield()->get_value(t,0);
  std::vector<double> eigs(3);
  t.get_eigenvalues(eigs[0], eigs[1], eigs[2]);

  for (auto i = 0; i < DIM; ++i)
    ASSERT_NEAR(eigs[i], eigs_expected[i], epsilon);
}
<|endoftext|>


<commit_before>#include "DlgAddWatchEntry.h"

#include <QDialogButtonBox>
#include <QHBoxLayout>
#include <QMessageBox>
#include <QVBoxLayout>
#include <sstream>

#include "../../DolphinProcess/DolphinAccessor.h"
#include "../GUICommon.h"

DlgAddWatchEntry::DlgAddWatchEntry(MemWatchEntry* entry) : m_entry(entry)
{
  m_chkBoundToPointer = new QCheckBox("This is a pointer", this);
  connect(m_chkBoundToPointer, static_cast<void (QCheckBox::*)(int)>(&QCheckBox::stateChanged),
          this, &DlgAddWatchEntry::onIsPointerChanged);

  QLabel* lblPreview = new QLabel("Value preview: ");
  m_lblValuePreview = new QLabel("", this);
  QHBoxLayout* preview_layout = new QHBoxLayout;
  preview_layout->addWidget(lblPreview);
  preview_layout->addWidget(m_lblValuePreview);
  QWidget* preview_widget = new QWidget();
  preview_widget->setLayout(preview_layout);

  QLabel* lblAddress = new QLabel("Address: ", this);
  m_txbAddress = new QLineEdit(this);
  QHBoxLayout* layout_addressAndPreview = new QHBoxLayout;
  layout_addressAndPreview->addWidget(lblAddress);
  layout_addressAndPreview->addWidget(m_txbAddress);
  QWidget* addressWidget = new QWidget(this);
  addressWidget->setLayout(layout_addressAndPreview);
  connect(m_txbAddress, static_cast<void (QLineEdit::*)(const QString&)>(&QLineEdit::textEdited),
          this, &DlgAddWatchEntry::onAddressChanged);

  m_offsetsLayout = new QFormLayout;
  m_offsetsWidgets = QVector<QLineEdit*>();
  QWidget* offsetsWidget = new QWidget();
  offsetsWidget->setLayout(m_offsetsLayout);

  QLabel* lblOffset = new QLabel("Offsets (in hex): ", this);

  m_btnAddOffset = new QPushButton("Add offset");
  m_btnRemoveOffset = new QPushButton("Remove offset");
  QHBoxLayout* pointerButtons_layout = new QHBoxLayout;
  pointerButtons_layout->addWidget(m_btnAddOffset);
  pointerButtons_layout->addWidget(m_btnRemoveOffset);
  QWidget* pointerButtons_widget = new QWidget();
  pointerButtons_widget->setLayout(pointerButtons_layout);
  connect(m_btnAddOffset, static_cast<void (QPushButton::*)(bool)>(&QPushButton::clicked), this,
          &DlgAddWatchEntry::addPointerOffset);
  connect(m_btnRemoveOffset, static_cast<void (QPushButton::*)(bool)>(&QPushButton::clicked), this,
          &DlgAddWatchEntry::removePointerOffset);

  QVBoxLayout* pointerOffset_layout = new QVBoxLayout;
  pointerOffset_layout->addWidget(lblOffset);
  pointerOffset_layout->addWidget(offsetsWidget);
  pointerOffset_layout->addWidget(pointerButtons_widget);
  m_pointerWidget = new QWidget(this);
  m_pointerWidget->setLayout(pointerOffset_layout);

  QLabel* lblLabel = new QLabel("Label: ", this);
  m_txbLabel = new QLineEdit(this);
  QHBoxLayout* layout_label = new QHBoxLayout;
  layout_label->addWidget(lblLabel);
  layout_label->addWidget(m_txbLabel);
  QWidget* labelWidget = new QWidget(this);
  labelWidget->setLayout(layout_label);

  QLabel* lblType = new QLabel("Type: ", this);
  m_cmbTypes = new QComboBox(this);
  m_cmbTypes->addItems(GUICommon::g_memTypeNames);
  connect(m_cmbTypes, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
          &DlgAddWatchEntry::onTypeChange);
  QHBoxLayout* layout_type = new QHBoxLayout;
  layout_type->addWidget(lblType);
  layout_type->addWidget(m_cmbTypes);
  QWidget* typeWidget = new QWidget(this);
  typeWidget->setLayout(layout_type);

  QLabel* lblLength = new QLabel(QString("Length: "), this);
  m_spnLength = new QSpinBox(this);
  m_spnLength->setMinimum(1);
  QHBoxLayout* layout_length = new QHBoxLayout;
  layout_length->addWidget(lblLength);
  layout_length->addWidget(m_spnLength);
  m_lengtWidget = new QWidget;
  m_lengtWidget->setLayout(layout_length);
  connect(m_spnLength, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this,
          &DlgAddWatchEntry::onLengthChanged);

  QDialogButtonBox* buttonBox =
      new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);

  QVBoxLayout* main_layout = new QVBoxLayout;
  main_layout->addWidget(preview_widget);
  main_layout->addWidget(m_chkBoundToPointer);
  main_layout->addWidget(addressWidget);
  main_layout->addWidget(m_pointerWidget);
  main_layout->addWidget(labelWidget);
  main_layout->addWidget(typeWidget);
  main_layout->addWidget(m_lengtWidget);
  main_layout->addWidget(buttonBox);
  setLayout(main_layout);

  connect(buttonBox, &QDialogButtonBox::accepted, this, &DlgAddWatchEntry::accept);
  connect(buttonBox, &QDialogButtonBox::rejected, this, &DlgAddWatchEntry::reject);

  if (entry == nullptr)
  {
    m_entry = new MemWatchEntry();
    m_entry->setLength(1);

    m_cmbTypes->setCurrentIndex(0);
    m_spnLength->setValue(1);
    m_lengtWidget->hide();
    m_lblValuePreview->setText("???");
    m_chkBoundToPointer->setChecked(false);
    m_pointerWidget->hide();

    addPointerOffset();
  }
  else
  {
    m_cmbTypes->setCurrentIndex(static_cast<int>(m_entry->getType()));
    m_spnLength->setValue(static_cast<int>(m_entry->getLength()));
    if (m_entry->getType() == Common::MemType::type_string ||
        m_entry->getType() == Common::MemType::type_byteArray)
      m_lengtWidget->show();
    else
      m_lengtWidget->hide();
    m_txbLabel->setText(QString::fromStdString(m_entry->getLabel()));
    std::stringstream ssAddress;
    ssAddress << std::hex << std::uppercase << m_entry->getConsoleAddress();
    m_txbAddress->setText(QString::fromStdString(ssAddress.str()));
    m_chkBoundToPointer->setChecked(m_entry->isBoundToPointer());
    if (entry->isBoundToPointer())
    {
      m_pointerWidget->show();
      for (int i = 0; i < m_entry->getPointerLevel(); ++i)
      {
        std::stringstream ssOffset;
        ssOffset << std::hex << std::uppercase << m_entry->getPointerOffset(i);
        QLineEdit* lineEdit = new QLineEdit();
        lineEdit->setText(QString::fromStdString(ssOffset.str()));
        m_offsetsWidgets.append(lineEdit);
        QLabel* label = new QLabel(QString::fromStdString("Level " + std::to_string(i + 1) + ":"));
        m_offsetsLayout->addRow(label, lineEdit);
      }
    }
    else
    {
      m_pointerWidget->hide();
      addPointerOffset();
    }
    updateValuePreview();
  }
}

void DlgAddWatchEntry::addPointerOffset()
{
  QLineEdit* lineEdit = new QLineEdit();
  lineEdit->setText(0);
  m_offsetsWidgets.append(lineEdit);
  int level = m_offsetsLayout->rowCount();
  QLabel* label = new QLabel(QString::fromStdString("Level " + std::to_string(level + 1) + ":"));
  m_offsetsLayout->addRow(label, lineEdit);
  m_entry->addOffset(0);
  connect(lineEdit, static_cast<void (QLineEdit::*)(const QString&)>(&QLineEdit::textEdited), this,
          &DlgAddWatchEntry::onOffsetChanged);
  if (m_offsetsLayout->rowCount() > 1)
    m_btnRemoveOffset->setEnabled(true);
  else
    m_btnRemoveOffset->setDisabled(true);
}

void DlgAddWatchEntry::removePointerOffset()
{
  m_offsetsLayout->removeRow(m_offsetsLayout->rowCount() - 1);
  m_offsetsWidgets.removeLast();
  m_entry->removeOffset();
  updateValuePreview();
  if (m_offsetsLayout->rowCount() == 1)
    m_btnRemoveOffset->setDisabled(true);
}

void DlgAddWatchEntry::onOffsetChanged()
{
  QLineEdit* theLineEdit = static_cast<QLineEdit*>(sender());
  int index = 0;
  QFormLayout::ItemRole itemRole;
  m_offsetsLayout->getWidgetPosition(theLineEdit, &index, &itemRole);
  if (validateAndSetOffset(index))
  {
    updateValuePreview();
  }
}

void DlgAddWatchEntry::onTypeChange(int index)
{
  Common::MemType theType = static_cast<Common::MemType>(index);
  if (theType == Common::MemType::type_string || theType == Common::MemType::type_byteArray)
    m_lengtWidget->show();
  else
    m_lengtWidget->hide();
  m_entry->setType(theType);
  if (validateAndSetAddress())
    updateValuePreview();
}

void DlgAddWatchEntry::accept()
{
  if (!validateAndSetAddress())
  {
    QString errorMsg = QString(
        "The address you entered is invalid, make sure it is an "
        "hexadecimal number between 0x80000000 and 0x817FFFFF");
    if (DolphinComm::DolphinAccessor::isMem2Enabled())
    {
      errorMsg.append(" or between 0x90000000 and 0x93FFFFFF");
    }
    QMessageBox* errorBox = new QMessageBox(QMessageBox::Critical, QString("Invalid address"),
                                            errorMsg, QMessageBox::Ok, this);
    errorBox->exec();
  }
  else
  {
    if (m_chkBoundToPointer->isChecked())
    {
      bool allOffsetsValid = true;
      int i = 0;
      for (i; i < m_offsetsWidgets.count(); ++i)
      {
        allOffsetsValid = validateAndSetOffset(i);
        if (!allOffsetsValid)
          break;
      }
      if (!allOffsetsValid)
      {
        QMessageBox* errorBox = new QMessageBox(
            QMessageBox::Critical, "Invalid offset",
            QString::fromStdString("The offset you entered for the level " + std::to_string(i + 1) +
                                   " is invalid, make sure it is an "
                                   "hexadecimal number"),
            QMessageBox::Ok, this);
        errorBox->exec();
        return;
      }
    }
    if (m_txbLabel->text() == "")
      m_entry->setLabel("No label");
    else
      m_entry->setLabel(m_txbLabel->text().toStdString());

    setResult(QDialog::Accepted);
    hide();
  }
}

bool DlgAddWatchEntry::validateAndSetAddress()
{
  std::string addressStr = m_txbAddress->text().toStdString();
  std::stringstream ss(addressStr);
  ss >> std::hex;
  u32 address = 0;
  ss >> address;
  if (!ss.fail())
  {
    if (DolphinComm::DolphinAccessor::isValidConsoleAddress(address))
    {
      m_entry->setConsoleAddress(address);
      return true;
    }
  }
  return false;
}

bool DlgAddWatchEntry::validateAndSetOffset(int index)
{
  std::string offsetStr = m_offsetsWidgets[index]->text().toStdString();
  std::stringstream ss(offsetStr);
  ss >> std::hex;
  int offset = 0;
  ss >> offset;
  if (!ss.fail())
  {
    m_entry->setPointerOffset(offset, index);
    return true;
  }
  return false;
}

void DlgAddWatchEntry::onAddressChanged()
{
  if (validateAndSetAddress())
  {
    updateValuePreview();
  }
  else
  {
    m_lblValuePreview->setText("???");
  }
}

void DlgAddWatchEntry::updateValuePreview()
{
  m_entry->readMemoryFromRAM();
  m_lblValuePreview->setText(QString::fromStdString(m_entry->getStringFromMemory()));
}

void DlgAddWatchEntry::onLengthChanged()
{
  m_entry->setLength(m_spnLength->value());
  if (validateAndSetAddress())
    updateValuePreview();
}

void DlgAddWatchEntry::onIsPointerChanged()
{
  if (m_chkBoundToPointer->isChecked())
    m_pointerWidget->show();
  else
    m_pointerWidget->hide();
  m_entry->setBoundToPointer(m_chkBoundToPointer->isChecked());
  updateValuePreview();
}

MemWatchEntry* DlgAddWatchEntry::getEntry() const
{
  return m_entry;
}<commit_msg>Initializes the base and the sign property when adding an entry<commit_after>#include "DlgAddWatchEntry.h"

#include <QDialogButtonBox>
#include <QHBoxLayout>
#include <QMessageBox>
#include <QVBoxLayout>
#include <sstream>

#include "../../DolphinProcess/DolphinAccessor.h"
#include "../GUICommon.h"

DlgAddWatchEntry::DlgAddWatchEntry(MemWatchEntry* entry) : m_entry(entry)
{
  m_chkBoundToPointer = new QCheckBox("This is a pointer", this);
  connect(m_chkBoundToPointer, static_cast<void (QCheckBox::*)(int)>(&QCheckBox::stateChanged),
          this, &DlgAddWatchEntry::onIsPointerChanged);

  QLabel* lblPreview = new QLabel("Value preview: ");
  m_lblValuePreview = new QLabel("", this);
  QHBoxLayout* preview_layout = new QHBoxLayout;
  preview_layout->addWidget(lblPreview);
  preview_layout->addWidget(m_lblValuePreview);
  QWidget* preview_widget = new QWidget();
  preview_widget->setLayout(preview_layout);

  QLabel* lblAddress = new QLabel("Address: ", this);
  m_txbAddress = new QLineEdit(this);
  QHBoxLayout* layout_addressAndPreview = new QHBoxLayout;
  layout_addressAndPreview->addWidget(lblAddress);
  layout_addressAndPreview->addWidget(m_txbAddress);
  QWidget* addressWidget = new QWidget(this);
  addressWidget->setLayout(layout_addressAndPreview);
  connect(m_txbAddress, static_cast<void (QLineEdit::*)(const QString&)>(&QLineEdit::textEdited),
          this, &DlgAddWatchEntry::onAddressChanged);

  m_offsetsLayout = new QFormLayout;
  m_offsetsWidgets = QVector<QLineEdit*>();
  QWidget* offsetsWidget = new QWidget();
  offsetsWidget->setLayout(m_offsetsLayout);

  QLabel* lblOffset = new QLabel("Offsets (in hex): ", this);

  m_btnAddOffset = new QPushButton("Add offset");
  m_btnRemoveOffset = new QPushButton("Remove offset");
  QHBoxLayout* pointerButtons_layout = new QHBoxLayout;
  pointerButtons_layout->addWidget(m_btnAddOffset);
  pointerButtons_layout->addWidget(m_btnRemoveOffset);
  QWidget* pointerButtons_widget = new QWidget();
  pointerButtons_widget->setLayout(pointerButtons_layout);
  connect(m_btnAddOffset, static_cast<void (QPushButton::*)(bool)>(&QPushButton::clicked), this,
          &DlgAddWatchEntry::addPointerOffset);
  connect(m_btnRemoveOffset, static_cast<void (QPushButton::*)(bool)>(&QPushButton::clicked), this,
          &DlgAddWatchEntry::removePointerOffset);

  QVBoxLayout* pointerOffset_layout = new QVBoxLayout;
  pointerOffset_layout->addWidget(lblOffset);
  pointerOffset_layout->addWidget(offsetsWidget);
  pointerOffset_layout->addWidget(pointerButtons_widget);
  m_pointerWidget = new QWidget(this);
  m_pointerWidget->setLayout(pointerOffset_layout);

  QLabel* lblLabel = new QLabel("Label: ", this);
  m_txbLabel = new QLineEdit(this);
  QHBoxLayout* layout_label = new QHBoxLayout;
  layout_label->addWidget(lblLabel);
  layout_label->addWidget(m_txbLabel);
  QWidget* labelWidget = new QWidget(this);
  labelWidget->setLayout(layout_label);

  QLabel* lblType = new QLabel("Type: ", this);
  m_cmbTypes = new QComboBox(this);
  m_cmbTypes->addItems(GUICommon::g_memTypeNames);
  connect(m_cmbTypes, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
          &DlgAddWatchEntry::onTypeChange);
  QHBoxLayout* layout_type = new QHBoxLayout;
  layout_type->addWidget(lblType);
  layout_type->addWidget(m_cmbTypes);
  QWidget* typeWidget = new QWidget(this);
  typeWidget->setLayout(layout_type);

  QLabel* lblLength = new QLabel(QString("Length: "), this);
  m_spnLength = new QSpinBox(this);
  m_spnLength->setMinimum(1);
  QHBoxLayout* layout_length = new QHBoxLayout;
  layout_length->addWidget(lblLength);
  layout_length->addWidget(m_spnLength);
  m_lengtWidget = new QWidget;
  m_lengtWidget->setLayout(layout_length);
  connect(m_spnLength, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this,
          &DlgAddWatchEntry::onLengthChanged);

  QDialogButtonBox* buttonBox =
      new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);

  QVBoxLayout* main_layout = new QVBoxLayout;
  main_layout->addWidget(preview_widget);
  main_layout->addWidget(m_chkBoundToPointer);
  main_layout->addWidget(addressWidget);
  main_layout->addWidget(m_pointerWidget);
  main_layout->addWidget(labelWidget);
  main_layout->addWidget(typeWidget);
  main_layout->addWidget(m_lengtWidget);
  main_layout->addWidget(buttonBox);
  setLayout(main_layout);

  connect(buttonBox, &QDialogButtonBox::accepted, this, &DlgAddWatchEntry::accept);
  connect(buttonBox, &QDialogButtonBox::rejected, this, &DlgAddWatchEntry::reject);

  if (entry == nullptr)
  {
    m_entry = new MemWatchEntry();
    m_entry->setLength(1);

    m_cmbTypes->setCurrentIndex(0);
    m_spnLength->setValue(1);
    m_lengtWidget->hide();
    m_lblValuePreview->setText("???");
    m_chkBoundToPointer->setChecked(false);
    m_pointerWidget->hide();

    addPointerOffset();
  }
  else
  {
    m_cmbTypes->setCurrentIndex(static_cast<int>(m_entry->getType()));
    m_spnLength->setValue(static_cast<int>(m_entry->getLength()));
    if (m_entry->getType() == Common::MemType::type_string ||
        m_entry->getType() == Common::MemType::type_byteArray)
      m_lengtWidget->show();
    else
      m_lengtWidget->hide();
    m_txbLabel->setText(QString::fromStdString(m_entry->getLabel()));
    std::stringstream ssAddress;
    ssAddress << std::hex << std::uppercase << m_entry->getConsoleAddress();
    m_txbAddress->setText(QString::fromStdString(ssAddress.str()));
    m_chkBoundToPointer->setChecked(m_entry->isBoundToPointer());
    if (entry->isBoundToPointer())
    {
      m_pointerWidget->show();
      for (int i = 0; i < m_entry->getPointerLevel(); ++i)
      {
        std::stringstream ssOffset;
        ssOffset << std::hex << std::uppercase << m_entry->getPointerOffset(i);
        QLineEdit* lineEdit = new QLineEdit();
        lineEdit->setText(QString::fromStdString(ssOffset.str()));
        m_offsetsWidgets.append(lineEdit);
        QLabel* label = new QLabel(QString::fromStdString("Level " + std::to_string(i + 1) + ":"));
        m_offsetsLayout->addRow(label, lineEdit);
      }
    }
    else
    {
      m_pointerWidget->hide();
      addPointerOffset();
    }
    updateValuePreview();
  }
}

void DlgAddWatchEntry::addPointerOffset()
{
  QLineEdit* lineEdit = new QLineEdit();
  lineEdit->setText(0);
  m_offsetsWidgets.append(lineEdit);
  int level = m_offsetsLayout->rowCount();
  QLabel* label = new QLabel(QString::fromStdString("Level " + std::to_string(level + 1) + ":"));
  m_offsetsLayout->addRow(label, lineEdit);
  m_entry->addOffset(0);
  connect(lineEdit, static_cast<void (QLineEdit::*)(const QString&)>(&QLineEdit::textEdited), this,
          &DlgAddWatchEntry::onOffsetChanged);
  if (m_offsetsLayout->rowCount() > 1)
    m_btnRemoveOffset->setEnabled(true);
  else
    m_btnRemoveOffset->setDisabled(true);
}

void DlgAddWatchEntry::removePointerOffset()
{
  m_offsetsLayout->removeRow(m_offsetsLayout->rowCount() - 1);
  m_offsetsWidgets.removeLast();
  m_entry->removeOffset();
  updateValuePreview();
  if (m_offsetsLayout->rowCount() == 1)
    m_btnRemoveOffset->setDisabled(true);
}

void DlgAddWatchEntry::onOffsetChanged()
{
  QLineEdit* theLineEdit = static_cast<QLineEdit*>(sender());
  int index = 0;
  QFormLayout::ItemRole itemRole;
  m_offsetsLayout->getWidgetPosition(theLineEdit, &index, &itemRole);
  if (validateAndSetOffset(index))
  {
    updateValuePreview();
  }
}

void DlgAddWatchEntry::onTypeChange(int index)
{
  Common::MemType theType = static_cast<Common::MemType>(index);
  if (theType == Common::MemType::type_string || theType == Common::MemType::type_byteArray)
    m_lengtWidget->show();
  else
    m_lengtWidget->hide();
  m_entry->setType(theType);
  if (validateAndSetAddress())
    updateValuePreview();
}

void DlgAddWatchEntry::accept()
{
  if (!validateAndSetAddress())
  {
    QString errorMsg = QString(
        "The address you entered is invalid, make sure it is an "
        "hexadecimal number between 0x80000000 and 0x817FFFFF");
    if (DolphinComm::DolphinAccessor::isMem2Enabled())
    {
      errorMsg.append(" or between 0x90000000 and 0x93FFFFFF");
    }
    QMessageBox* errorBox = new QMessageBox(QMessageBox::Critical, QString("Invalid address"),
                                            errorMsg, QMessageBox::Ok, this);
    errorBox->exec();
  }
  else
  {
    if (m_chkBoundToPointer->isChecked())
    {
      bool allOffsetsValid = true;
      int i = 0;
      for (i; i < m_offsetsWidgets.count(); ++i)
      {
        allOffsetsValid = validateAndSetOffset(i);
        if (!allOffsetsValid)
          break;
      }
      if (!allOffsetsValid)
      {
        QMessageBox* errorBox = new QMessageBox(
            QMessageBox::Critical, "Invalid offset",
            QString::fromStdString("The offset you entered for the level " + std::to_string(i + 1) +
                                   " is invalid, make sure it is an "
                                   "hexadecimal number"),
            QMessageBox::Ok, this);
        errorBox->exec();
        return;
      }
    }
    if (m_txbLabel->text() == "")
      m_entry->setLabel("No label");
    else
      m_entry->setLabel(m_txbLabel->text().toStdString());
    m_entry->setBase(Common::MemBase::base_decimal);
    m_entry->setSignedUnsigned(false);
    setResult(QDialog::Accepted);
    hide();
  }
}

bool DlgAddWatchEntry::validateAndSetAddress()
{
  std::string addressStr = m_txbAddress->text().toStdString();
  std::stringstream ss(addressStr);
  ss >> std::hex;
  u32 address = 0;
  ss >> address;
  if (!ss.fail())
  {
    if (DolphinComm::DolphinAccessor::isValidConsoleAddress(address))
    {
      m_entry->setConsoleAddress(address);
      return true;
    }
  }
  return false;
}

bool DlgAddWatchEntry::validateAndSetOffset(int index)
{
  std::string offsetStr = m_offsetsWidgets[index]->text().toStdString();
  std::stringstream ss(offsetStr);
  ss >> std::hex;
  int offset = 0;
  ss >> offset;
  if (!ss.fail())
  {
    m_entry->setPointerOffset(offset, index);
    return true;
  }
  return false;
}

void DlgAddWatchEntry::onAddressChanged()
{
  if (validateAndSetAddress())
  {
    updateValuePreview();
  }
  else
  {
    m_lblValuePreview->setText("???");
  }
}

void DlgAddWatchEntry::updateValuePreview()
{
  m_entry->readMemoryFromRAM();
  m_lblValuePreview->setText(QString::fromStdString(m_entry->getStringFromMemory()));
}

void DlgAddWatchEntry::onLengthChanged()
{
  m_entry->setLength(m_spnLength->value());
  if (validateAndSetAddress())
    updateValuePreview();
}

void DlgAddWatchEntry::onIsPointerChanged()
{
  if (m_chkBoundToPointer->isChecked())
    m_pointerWidget->show();
  else
    m_pointerWidget->hide();
  m_entry->setBoundToPointer(m_chkBoundToPointer->isChecked());
  updateValuePreview();
}

MemWatchEntry* DlgAddWatchEntry::getEntry() const
{
  return m_entry;
}<|endoftext|>


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

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

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

#include "mitkFileReaderWriterBase.h"

#include "mitkCoreServices.h"
#include "mitkIMimeTypeProvider.h"
#include "mitkIOMimeTypes.h"
#include "mitkLogMacros.h"

#include <usGetModuleContext.h>
#include <usLDAPProp.h>

namespace mitk
{
  FileReaderWriterBase::FileReaderWriterBase() : m_Ranking(0), m_MimeTypePrefix(IOMimeTypes::DEFAULT_BASE_NAME() + ".")
  {
  }

  FileReaderWriterBase::~FileReaderWriterBase() { this->UnregisterMimeType(); }
  FileReaderWriterBase::FileReaderWriterBase(const FileReaderWriterBase &other)
    : m_Description(other.m_Description),
      m_Ranking(other.m_Ranking),
      m_MimeTypePrefix(other.m_MimeTypePrefix),
      m_Options(other.m_Options),
      m_DefaultOptions(other.m_DefaultOptions),
      m_CustomMimeType(other.m_CustomMimeType->Clone())
  {
  }

  FileReaderWriterBase::Options FileReaderWriterBase::GetOptions() const
  {
    Options options = m_Options;
    options.insert(m_DefaultOptions.begin(), m_DefaultOptions.end());
    return options;
  }

  us::Any FileReaderWriterBase::GetOption(const std::string &name) const
  {
    auto iter = m_Options.find(name);
    if (iter != m_Options.end())
    {
      return iter->second;
    }
    iter = m_DefaultOptions.find(name);
    if (iter != m_DefaultOptions.end())
    {
      return iter->second;
    }
    return us::Any();
  }

  void FileReaderWriterBase::SetOptions(const FileReaderWriterBase::Options &options)
  {
    for (const auto &option : options)
    {
      this->SetOption(option.first, option.second);
    }
  }

  void FileReaderWriterBase::SetOption(const std::string &name, const us::Any &value)
  {
    if (m_DefaultOptions.find(name) == m_DefaultOptions.end())
    {
      MITK_WARN << "Ignoring unknown IFileReader option '" << name << "'";
    }
    else
    {
      if (value.Empty())
      {
        // an empty Any signals 'reset to default value'
        m_Options.erase(name);
      }
      else
      {
        m_Options[name] = value;
      }
    }
  }

  void FileReaderWriterBase::SetDefaultOptions(const FileReaderWriterBase::Options &defaultOptions)
  {
    m_DefaultOptions = defaultOptions;
  }

  FileReaderWriterBase::Options FileReaderWriterBase::GetDefaultOptions() const { return m_DefaultOptions; }
  void FileReaderWriterBase::SetRanking(int ranking) { m_Ranking = ranking; }
  int FileReaderWriterBase::GetRanking() const { return m_Ranking; }
  void FileReaderWriterBase::SetMimeType(const CustomMimeType &mimeType) { m_CustomMimeType.reset(mimeType.Clone()); }
  const CustomMimeType *FileReaderWriterBase::GetMimeType() const { return m_CustomMimeType.get(); }
  CustomMimeType *FileReaderWriterBase::GetMimeType() { return m_CustomMimeType.get(); }
  MimeType FileReaderWriterBase::GetRegisteredMimeType() const
  {
    MimeType result;
    if (!m_MimeTypeReg)
    {
      if (!m_CustomMimeType->GetName().empty())
      {
        CoreServicePointer<IMimeTypeProvider> mimeTypeProvider(
          CoreServices::GetMimeTypeProvider(us::GetModuleContext()));
        return mimeTypeProvider->GetMimeTypeForName(m_CustomMimeType->GetName());
      }
      return result;
    }

    us::ServiceReferenceU reference = m_MimeTypeReg.GetReference();
    try
    {
      int rank = 0;
      us::Any rankProp = reference.GetProperty(us::ServiceConstants::SERVICE_RANKING());
      if (!rankProp.Empty())
      {
        rank = us::any_cast<int>(rankProp);
      }
      auto id = us::any_cast<long>(reference.GetProperty(us::ServiceConstants::SERVICE_ID()));
      result = MimeType(*m_CustomMimeType, rank, id);
    }
    catch (const us::BadAnyCastException &e)
    {
      MITK_WARN << "Unexpected exception: " << e.what();
    }
    return result;
  }

  void FileReaderWriterBase::SetMimeTypePrefix(const std::string &prefix) { m_MimeTypePrefix = prefix; }
  std::string FileReaderWriterBase::GetMimeTypePrefix() const { return m_MimeTypePrefix; }
  void FileReaderWriterBase::SetDescription(const std::string &description) { m_Description = description; }
  std::string FileReaderWriterBase::GetDescription() const { return m_Description; }
  void FileReaderWriterBase::AddProgressCallback(const FileReaderWriterBase::ProgressCallback &callback)
  {
    m_ProgressMessage += callback;
  }

  void FileReaderWriterBase::RemoveProgressCallback(const FileReaderWriterBase::ProgressCallback &callback)
  {
    m_ProgressMessage -= callback;
  }

  us::ServiceRegistration<CustomMimeType> FileReaderWriterBase::RegisterMimeType(us::ModuleContext *context)
  {
    if (context == nullptr)
      throw std::invalid_argument("The context argument must not be nullptr.");

    CoreServicePointer<IMimeTypeProvider> mimeTypeProvider(CoreServices::GetMimeTypeProvider(context));

    const std::vector<std::string> extensions = m_CustomMimeType->GetExtensions();

    // If the mime type name is set and the list of extensions is empty,
    // look up the mime type in the registry and print a warning if
    // there is none
    if (!m_CustomMimeType->GetName().empty() && extensions.empty())
    {
      if (!mimeTypeProvider->GetMimeTypeForName(m_CustomMimeType->GetName()).IsValid())
      {
        MITK_WARN << "Registering a MITK reader or writer with an unknown MIME type " << m_CustomMimeType->GetName();
      }
      return m_MimeTypeReg;
    }

    // If the mime type name and extensions list is empty, print a warning
    if (m_CustomMimeType->GetName().empty() && extensions.empty())
    {
      MITK_WARN << "Trying to register a MITK reader or writer with an empty mime type name and empty extension list.";
      return m_MimeTypeReg;
    }

    // extensions is not empty

    if (m_CustomMimeType->GetName().empty())
    {
      // Create a synthetic mime type name from the
      // first extension in the list
      m_CustomMimeType->SetName(m_MimeTypePrefix + extensions.front());
    }

    // Register a new mime type
    // us::ServiceProperties props;
    // props["name"] = m_CustomMimeType.GetName();
    // props["extensions"] = m_CustomMimeType.GetExtensions();
    m_MimeTypeReg = context->RegisterService<CustomMimeType>(m_CustomMimeType.get());

    return m_MimeTypeReg;
  }

  void FileReaderWriterBase::UnregisterMimeType()
  {
    if (m_MimeTypeReg)
    {
      try
      {
        m_MimeTypeReg.Unregister();
      }
      catch (const std::logic_error &)
      {
        // service already unregistered
      }
    }
  }
}
<commit_msg>Add possibility to fix up mime type names<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

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

#include "mitkFileReaderWriterBase.h"

#include "mitkCoreServices.h"
#include "mitkIMimeTypeProvider.h"
#include "mitkIOMimeTypes.h"
#include "mitkLogMacros.h"

#include <usGetModuleContext.h>
#include <usLDAPProp.h>

namespace mitk
{
  FileReaderWriterBase::FileReaderWriterBase() : m_Ranking(0), m_MimeTypePrefix(IOMimeTypes::DEFAULT_BASE_NAME() + ".")
  {
  }

  FileReaderWriterBase::~FileReaderWriterBase() { this->UnregisterMimeType(); }
  FileReaderWriterBase::FileReaderWriterBase(const FileReaderWriterBase &other)
    : m_Description(other.m_Description),
      m_Ranking(other.m_Ranking),
      m_MimeTypePrefix(other.m_MimeTypePrefix),
      m_Options(other.m_Options),
      m_DefaultOptions(other.m_DefaultOptions),
      m_CustomMimeType(other.m_CustomMimeType->Clone())
  {
  }

  FileReaderWriterBase::Options FileReaderWriterBase::GetOptions() const
  {
    Options options = m_Options;
    options.insert(m_DefaultOptions.begin(), m_DefaultOptions.end());
    return options;
  }

  us::Any FileReaderWriterBase::GetOption(const std::string &name) const
  {
    auto iter = m_Options.find(name);
    if (iter != m_Options.end())
    {
      return iter->second;
    }
    iter = m_DefaultOptions.find(name);
    if (iter != m_DefaultOptions.end())
    {
      return iter->second;
    }
    return us::Any();
  }

  void FileReaderWriterBase::SetOptions(const FileReaderWriterBase::Options &options)
  {
    for (const auto &option : options)
    {
      this->SetOption(option.first, option.second);
    }
  }

  void FileReaderWriterBase::SetOption(const std::string &name, const us::Any &value)
  {
    if (m_DefaultOptions.find(name) == m_DefaultOptions.end())
    {
      MITK_WARN << "Ignoring unknown IFileReader option '" << name << "'";
    }
    else
    {
      if (value.Empty())
      {
        // an empty Any signals 'reset to default value'
        m_Options.erase(name);
      }
      else
      {
        m_Options[name] = value;
      }
    }
  }

  void FileReaderWriterBase::SetDefaultOptions(const FileReaderWriterBase::Options &defaultOptions)
  {
    m_DefaultOptions = defaultOptions;
  }

  FileReaderWriterBase::Options FileReaderWriterBase::GetDefaultOptions() const { return m_DefaultOptions; }
  void FileReaderWriterBase::SetRanking(int ranking) { m_Ranking = ranking; }
  int FileReaderWriterBase::GetRanking() const { return m_Ranking; }
  void FileReaderWriterBase::SetMimeType(const CustomMimeType &mimeType) { m_CustomMimeType.reset(mimeType.Clone()); }
  const CustomMimeType *FileReaderWriterBase::GetMimeType() const { return m_CustomMimeType.get(); }
  CustomMimeType *FileReaderWriterBase::GetMimeType() { return m_CustomMimeType.get(); }
  MimeType FileReaderWriterBase::GetRegisteredMimeType() const
  {
    MimeType result;
    if (!m_MimeTypeReg)
    {
      if (!m_CustomMimeType->GetName().empty())
      {
        CoreServicePointer<IMimeTypeProvider> mimeTypeProvider(
          CoreServices::GetMimeTypeProvider(us::GetModuleContext()));
        return mimeTypeProvider->GetMimeTypeForName(m_CustomMimeType->GetName());
      }
      return result;
    }

    us::ServiceReferenceU reference = m_MimeTypeReg.GetReference();
    try
    {
      int rank = 0;
      us::Any rankProp = reference.GetProperty(us::ServiceConstants::SERVICE_RANKING());
      if (!rankProp.Empty())
      {
        rank = us::any_cast<int>(rankProp);
      }
      auto id = us::any_cast<long>(reference.GetProperty(us::ServiceConstants::SERVICE_ID()));
      result = MimeType(*m_CustomMimeType, rank, id);
    }
    catch (const us::BadAnyCastException &e)
    {
      MITK_WARN << "Unexpected exception: " << e.what();
    }
    return result;
  }

  void FileReaderWriterBase::SetMimeTypePrefix(const std::string &prefix) { m_MimeTypePrefix = prefix; }
  std::string FileReaderWriterBase::GetMimeTypePrefix() const { return m_MimeTypePrefix; }
  void FileReaderWriterBase::SetDescription(const std::string &description) { m_Description = description; }
  std::string FileReaderWriterBase::GetDescription() const { return m_Description; }
  void FileReaderWriterBase::AddProgressCallback(const FileReaderWriterBase::ProgressCallback &callback)
  {
    m_ProgressMessage += callback;
  }

  void FileReaderWriterBase::RemoveProgressCallback(const FileReaderWriterBase::ProgressCallback &callback)
  {
    m_ProgressMessage -= callback;
  }

  us::ServiceRegistration<CustomMimeType> FileReaderWriterBase::RegisterMimeType(us::ModuleContext *context)
  {
    if (context == nullptr)
      throw std::invalid_argument("The context argument must not be nullptr.");

    CoreServicePointer<IMimeTypeProvider> mimeTypeProvider(CoreServices::GetMimeTypeProvider(context));

    const std::vector<std::string> extensions = m_CustomMimeType->GetExtensions();

    // If the mime type name is set and the list of extensions is empty,
    // look up the mime type in the registry and print a warning if
    // there is none
    /*if (!m_CustomMimeType->GetName().empty() && extensions.empty())
    {
      if (!mimeTypeProvider->GetMimeTypeForName(m_CustomMimeType->GetName()).IsValid())
      {
        MITK_WARN << "Registering a MITK reader or writer with an unknown MIME type " << m_CustomMimeType->GetName();
      }
      return m_MimeTypeReg;
    }*/

    // If the mime type name and extensions list is empty, print a warning
    if (m_CustomMimeType->GetName().empty() && extensions.empty())
    {
      MITK_WARN << "Trying to register a MITK reader or writer with an empty mime type name and empty extension list.";
      return m_MimeTypeReg;
    }

    // extensions is not empty

    if (m_CustomMimeType->GetName().empty())
    {
      // Create a synthetic mime type name from the
      // first extension in the list
      m_CustomMimeType->SetName(m_MimeTypePrefix + extensions.front());
    }

    // Register a new mime type
    // us::ServiceProperties props;
    // props["name"] = m_CustomMimeType.GetName();
    // props["extensions"] = m_CustomMimeType.GetExtensions();
    m_MimeTypeReg = context->RegisterService<CustomMimeType>(m_CustomMimeType.get());

    return m_MimeTypeReg;
  }

  void FileReaderWriterBase::UnregisterMimeType()
  {
    if (m_MimeTypeReg)
    {
      try
      {
        m_MimeTypeReg.Unregister();
      }
      catch (const std::logic_error &)
      {
        // service already unregistered
      }
    }
  }
}
<|endoftext|>