<commit_before>// -*-c++-*- Copyright (C) 2010 osgPango Development Team
// $Id$

#include <osg/Texture2D>
#include <osg/MatrixTransform>
#include <osg/AlphaFunc>
#include <osg/Depth>
#include <osg/ColorMask>
#include <osgGA/StateSetManipulator>
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>
#include <osgPango/Context>

struct GlyphLayerLines: public osgPango::GlyphLayer {
	virtual bool render(
		cairo_t*       c,
		cairo_glyph_t* glyph,
		unsigned int   width,
		unsigned int   height
	) {
		if(cairo_status(c) || !glyph) return false;

		cairo_surface_t* tmp = cairo_image_surface_create(CAIRO_FORMAT_A8, width, height);

		if(cairo_surface_status(tmp)) return false;

		cairo_t* tc = cairo_create(tmp);

		if(cairo_status(tc)) return false;

		// Clear the temporary 'pattern' surface.
		cairo_save(tc);
		cairo_set_operator(tc, CAIRO_OPERATOR_CLEAR);
		cairo_rectangle(tc, 0.0f, 0.0f, width, height);
		cairo_paint(tc);
		cairo_restore(tc);

		// Now, we draw our lines to the temporary surface.
		cairo_set_line_width(tc, 1.0f);

		for(unsigned int w = 0; w < width; w += 3) {
			cairo_move_to(tc, w + 0.5f, 0.0);
			cairo_line_to(tc, w + 0.5f, height);
			cairo_stroke(tc);
		}

		for(unsigned int h = 0; h < height; h += 3) {
			cairo_move_to(tc, 0.0f, h + 0.5f);
			cairo_line_to(tc, width, h + 0.5f);
			cairo_stroke(tc);
		}

		// Use our temporary surface to fill the glyph path.
		cairo_set_source_surface(c, tmp, 0, 0);
		cairo_glyph_path(c, glyph, 1);
		cairo_fill(c);

		cairo_destroy(tc);
		cairo_surface_destroy(tmp);

		return true;
	}
};

struct GlyphRendererComplex: public osgPango::GlyphRenderer {
	GlyphRendererComplex(bool useCustomLayer = false) {
		addLayer(new osgPango::GlyphLayerShadowGaussian(17.0f));
		addLayer(new osgPango::GlyphLayerOutline(2.0f));

		if(useCustomLayer) addLayer(new GlyphLayerLines());

		else addLayer(new osgPango::GlyphLayer());
	}

	virtual unsigned int getNumPasses() const {
		return 3;
	}

	bool updateOrCreateState(int pass, osg::Geode* geode) {
		if(!GlyphRenderer::updateOrCreateState(pass, geode)) return false;

		osg::StateSet* state   = geode->getOrCreateStateSet();
		osg::Program*  program = dynamic_cast<osg::Program*>(state->getAttribute(osg::StateAttribute::PROGRAM));

		if(!program) return false;

		switch(pass) {
			// blur shadow
			case 0: {
				const char* GET_FRAGMENT =
					"#version 120\n"
					"vec4 osgPango_GetFragment(vec4 coord, sampler2D textures[8], vec3 colors[8], float alpha) {"
					"	float tex0   = texture2D(textures[0], coord.st).a;"
					"	vec3 color0  = vec3(0.0, 0.0, 0.0) * tex0;"
					"	float alpha0 = tex0;"
					"	return vec4(color0, alpha0 * alpha);"
					"}"
				;

				osg::Shader* frag = new osg::Shader(osg::Shader::FRAGMENT, GET_FRAGMENT);

				program->addShader(frag);
			}

			break;

			// outline + base
			case 1: {
				const char* GET_FRAGMENT =
					"#version 120\n"
					"vec4 osgPango_GetFragment(vec4 coord, sampler2D textures[8], vec3 colors[8], float alpha) {"
					"	float tex0   = texture2D(textures[1], coord.st).a;"
					"	float tex1   = texture2D(textures[2], coord.st).a;"
					"	vec3 color0  = vec3(1.0, 1.0, 1.0) * tex0;"
					"	vec3 color1  = vec3(0.0, 0.4, 1.0) * tex1 + color0 * (1.0 - tex1);"
					"	float alpha0 = tex0;"
					"	float alpha1 = tex0 + tex1;"
					"	return vec4(color1, alpha1 * alpha);"
					"}"
				;

				osg::Shader* frag = new osg::Shader(osg::Shader::FRAGMENT, GET_FRAGMENT);

				program->addShader(frag);
			}

			break;

			// write to depth only with base
			case 2: {
				const char* GET_FRAGMENT =
					"#version 120\n"
					"vec4 osgPango_GetFragment(vec4 coord, sampler2D textures[8], vec3 colors[8], float alpha) {"
					"	float tex0   = texture2D(textures[2], coord.st).a;"
					"	vec3 color0  = vec3(0.0, 0.0, 0.0) * tex0;"
					"	float alpha0 = tex0;"
					"	return vec4(color0, alpha0 * alpha);"
					"}"
				;

				osg::Shader* frag = new osg::Shader(osg::Shader::FRAGMENT, GET_FRAGMENT);

				program->addShader(frag);

				state->removeAttribute(osg::StateAttribute::DEPTH);
				state->setAttribute(new osg::ColorMask(false, false, false, false));
				state->setMode(GL_BLEND, osg::StateAttribute::OFF);
				state->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);
			}

			break;

		}

		return true;
	}
};

osg::Geometry* createGeometry(osg::Image* image) {
	static osg::Vec3 pos(50.0f, 50.0f, -0.8f);

	osg::Texture2D* texture = new osg::Texture2D();
	osg::Geometry*  geom    = osg::createTexturedQuadGeometry(
		pos,
		osg::Vec3(image->s(), 0.0f, 0.0f),
		osg::Vec3(0.0f, image->t(), 0.0f),
		0.0f,
		0.0f,
		1.0f,
		1.0f
	);

	texture->setImage(image);
	texture->setDataVariance(osg::Object::DYNAMIC);

	osg::StateSet* state = geom->getOrCreateStateSet();

	state->setTextureAttributeAndModes(
		0,
		texture,
		osg::StateAttribute::ON
	);

	state->setMode(GL_BLEND, osg::StateAttribute::ON);
	state->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);

	pos += osg::Vec3(image->s() + 50.0f, 0.0f, 0.1f);

	return geom;
}

osg::Camera* createOrthoCamera(float width, float height) {
	osg::Camera* camera = new osg::Camera();

	camera->getOrCreateStateSet()->setMode(
		GL_LIGHTING,
		osg::StateAttribute::PROTECTED | osg::StateAttribute::OFF
	);

	camera->setProjectionMatrix(osg::Matrix::ortho2D(0.0, width, 0.0f, height));
	camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
	camera->setViewMatrix(osg::Matrix::identity());
	camera->setClearMask(GL_DEPTH_BUFFER_BIT);
	camera->setRenderOrder(osg::Camera::POST_RENDER);

	return camera;
}

const int WINDOW_WIDTH  = 800;
const int WINDOW_HEIGHT = 600;

int main(int argc, char** argv) {
	osgPango::Context& context = osgPango::Context::instance();

	context.init();
	context.addGlyphRenderer("complex", new GlyphRendererComplex());
	context.addGlyphRenderer("complex-lines", new GlyphRendererComplex(true));

	osgPango::TextTransform* t = new osgPango::TextTransform();

	t->addText(
		"This is a cow.",
		0,
		0,
		osgPango::TextOptions("complex")
	);

	t->addText(
		"Yes, a cow.",
		0,
		-60,
		osgPango::TextOptions("complex-lines")
	);

	t->finalize();
	t->setMatrix(osg::Matrixd::translate(osg::Vec3(WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2, 0.0f)));
	t->setPositionAlignment(osgPango::TextTransform::POS_ALIGN_CENTER);
	t->setAxisAlignment(osgPango::TextTransform::AXIS_ALIGN_REVERSED_XY_PLANE);

	osgViewer::Viewer viewer;

	osg::Group*  group  = new osg::Group();
	osg::Camera* camera = createOrthoCamera(WINDOW_WIDTH, WINDOW_HEIGHT);
	osg::Node*   node   = osgDB::readNodeFile("cow.osg");

        viewer.addEventHandler(new osgViewer::StatsHandler());
        viewer.addEventHandler(new osgViewer::WindowSizeHandler());
        viewer.addEventHandler(new osgGA::StateSetManipulator(
                viewer.getCamera()->getOrCreateStateSet()
        ));

	camera->addChild(t);

	group->addChild(node);
	group->addChild(camera);

	viewer.setSceneData(group);
	viewer.getCamera()->setClearColor(osg::Vec4(0.3f, 0.3f, 0.3f, 1.0f));
	viewer.setUpViewInWindow(50, 50, WINDOW_WIDTH, WINDOW_HEIGHT);

	viewer.run();

	osgPango::Context::instance().writeCachesToPNGFiles("osgpangocustomrenderer");

	unsigned long bytes = osgPango::Context::instance().getMemoryUsageInBytes();

	osg::notify(osg::NOTICE)
		<< "Used " << (bytes / 1024.0f) / 1024.0f << "MB of Image data internally."
		<< std::endl
	;

	return 0;
}
<commit_msg>Small fix, forgot testing code.<commit_after>// -*-c++-*- Copyright (C) 2010 osgPango Development Team
// $Id$

#include <osg/Texture2D>
#include <osg/MatrixTransform>
#include <osg/AlphaFunc>
#include <osg/Depth>
#include <osg/ColorMask>
#include <osgGA/StateSetManipulator>
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>
#include <osgPango/Context>

struct GlyphLayerLines: public osgPango::GlyphLayer {
	virtual bool render(
		cairo_t*       c,
		cairo_glyph_t* glyph,
		unsigned int   width,
		unsigned int   height
	) {
		if(cairo_status(c) || !glyph) return false;

		cairo_surface_t* tmp = cairo_image_surface_create(CAIRO_FORMAT_A8, width, height);

		if(cairo_surface_status(tmp)) return false;

		cairo_t* tc = cairo_create(tmp);

		if(cairo_status(tc)) return false;

		// Clear the temporary 'pattern' surface.
		cairo_save(tc);
		cairo_set_operator(tc, CAIRO_OPERATOR_CLEAR);
		cairo_rectangle(tc, 0.0f, 0.0f, width, height);
		cairo_paint(tc);
		cairo_restore(tc);

		// Now, we draw our lines to the temporary surface.
		cairo_set_line_width(tc, 1.0f);

		for(unsigned int w = 0; w < width; w += 3) {
			cairo_move_to(tc, w + 0.5f, 0.0);
			cairo_line_to(tc, w + 0.5f, height);
			cairo_stroke(tc);
		}

		for(unsigned int h = 0; h < height; h += 3) {
			cairo_move_to(tc, 0.0f, h + 0.5f);
			cairo_line_to(tc, width, h + 0.5f);
			cairo_stroke(tc);
		}

		// Use our temporary surface to fill the glyph path.
		cairo_set_source_surface(c, tmp, 0, 0);
		cairo_glyph_path(c, glyph, 1);
		cairo_fill(c);

		cairo_destroy(tc);
		cairo_surface_destroy(tmp);

		return true;
	}
};

struct GlyphRendererComplex: public osgPango::GlyphRenderer {
	GlyphRendererComplex(bool useCustomLayer = false) {
		addLayer(new osgPango::GlyphLayerShadowGaussian(17.0f));
		addLayer(new osgPango::GlyphLayerOutline(2.0f));

		if(useCustomLayer) addLayer(new GlyphLayerLines());

		else addLayer(new osgPango::GlyphLayer());
	}

	virtual unsigned int getNumPasses() const {
		return 3;
	}

	bool updateOrCreateState(int pass, osg::Geode* geode) {
		if(!GlyphRenderer::updateOrCreateState(pass, geode)) return false;

		osg::StateSet* state   = geode->getOrCreateStateSet();
		osg::Program*  program = dynamic_cast<osg::Program*>(state->getAttribute(osg::StateAttribute::PROGRAM));

		if(!program) return false;

		switch(pass) {
			// blur shadow
			case 0: {
				const char* GET_FRAGMENT =
					"#version 120\n"
					"vec4 osgPango_GetFragment(vec4 coord, sampler2D textures[8], vec3 colors[8], float alpha) {"
					"	float tex0   = texture2D(textures[0], coord.st).a;"
					"	vec3 color0  = vec3(0.0, 0.0, 0.0) * tex0;"
					"	float alpha0 = tex0;"
					"	return vec4(color0, alpha0 * alpha);"
					"}"
				;

				osg::Shader* frag = new osg::Shader(osg::Shader::FRAGMENT, GET_FRAGMENT);

				program->addShader(frag);
			}

			break;

			// outline + base
			case 1: {
				const char* GET_FRAGMENT =
					"#version 120\n"
					"vec4 osgPango_GetFragment(vec4 coord, sampler2D textures[8], vec3 colors[8], float alpha) {"
					"	float tex0   = texture2D(textures[1], coord.st).a;"
					"	float tex1   = texture2D(textures[2], coord.st).a;"
					"	vec3 color0  = vec3(1.0, 1.0, 1.0) * tex0;"
					"	vec3 color1  = vec3(0.0, 0.4, 1.0) * tex1 + color0 * (1.0 - tex1);"
					"	float alpha0 = tex0;"
					"	float alpha1 = tex0 + tex1;"
					"	return vec4(color1, alpha1 * alpha);"
					"}"
				;

				osg::Shader* frag = new osg::Shader(osg::Shader::FRAGMENT, GET_FRAGMENT);

				program->addShader(frag);
			}

			break;

			// write to depth only with base
			case 2: {
				const char* GET_FRAGMENT =
					"#version 120\n"
					"vec4 osgPango_GetFragment(vec4 coord, sampler2D textures[8], vec3 colors[8], float alpha) {"
					"	float tex0   = texture2D(textures[2], coord.st).a;"
					"	vec3 color0  = vec3(0.0, 0.0, 0.0) * tex0;"
					"	float alpha0 = tex0;"
					"	return vec4(color0, alpha0 * alpha);"
					"}"
				;

				osg::Shader* frag = new osg::Shader(osg::Shader::FRAGMENT, GET_FRAGMENT);

				program->addShader(frag);

				state->removeAttribute(osg::StateAttribute::DEPTH);
				state->setAttribute(new osg::ColorMask(false, false, false, false));
				state->setMode(GL_BLEND, osg::StateAttribute::OFF);
				state->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);
			}

			break;

		}

		return true;
	}
};

osg::Geometry* createGeometry(osg::Image* image) {
	static osg::Vec3 pos(50.0f, 50.0f, -0.8f);

	osg::Texture2D* texture = new osg::Texture2D();
	osg::Geometry*  geom    = osg::createTexturedQuadGeometry(
		pos,
		osg::Vec3(image->s(), 0.0f, 0.0f),
		osg::Vec3(0.0f, image->t(), 0.0f),
		0.0f,
		0.0f,
		1.0f,
		1.0f
	);

	texture->setImage(image);
	texture->setDataVariance(osg::Object::DYNAMIC);

	osg::StateSet* state = geom->getOrCreateStateSet();

	state->setTextureAttributeAndModes(
		0,
		texture,
		osg::StateAttribute::ON
	);

	state->setMode(GL_BLEND, osg::StateAttribute::ON);
	state->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);

	pos += osg::Vec3(image->s() + 50.0f, 0.0f, 0.1f);

	return geom;
}

osg::Camera* createOrthoCamera(float width, float height) {
	osg::Camera* camera = new osg::Camera();

	camera->getOrCreateStateSet()->setMode(
		GL_LIGHTING,
		osg::StateAttribute::PROTECTED | osg::StateAttribute::OFF
	);

	camera->setProjectionMatrix(osg::Matrix::ortho2D(0.0, width, 0.0f, height));
	camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
	camera->setViewMatrix(osg::Matrix::identity());
	camera->setClearMask(GL_DEPTH_BUFFER_BIT);
	camera->setRenderOrder(osg::Camera::POST_RENDER);

	return camera;
}

const int WINDOW_WIDTH  = 800;
const int WINDOW_HEIGHT = 600;

int main(int argc, char** argv) {
	osgPango::Context& context = osgPango::Context::instance();

	context.init();
	context.addGlyphRenderer("complex", new GlyphRendererComplex());
	context.addGlyphRenderer("complex-lines", new GlyphRendererComplex(true));

	osgPango::TextTransform* t = new osgPango::TextTransform();

	t->addText(
		"This is a cow.",
		0,
		0,
		osgPango::TextOptions("complex")
	);

	t->addText(
		"Yes, a cow.",
		0,
		-60,
		osgPango::TextOptions("complex-lines")
	);

	t->finalize();
	t->setMatrix(osg::Matrixd::translate(osg::Vec3(WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2, 0.0f)));
	t->setPositionAlignment(osgPango::TextTransform::POS_ALIGN_CENTER);

	osgViewer::Viewer viewer;

	osg::Group*  group  = new osg::Group();
	osg::Camera* camera = createOrthoCamera(WINDOW_WIDTH, WINDOW_HEIGHT);
	osg::Node*   node   = osgDB::readNodeFile("cow.osg");

        viewer.addEventHandler(new osgViewer::StatsHandler());
        viewer.addEventHandler(new osgViewer::WindowSizeHandler());
        viewer.addEventHandler(new osgGA::StateSetManipulator(
                viewer.getCamera()->getOrCreateStateSet()
        ));

	camera->addChild(t);

	group->addChild(node);
	group->addChild(camera);

	viewer.setSceneData(group);
	viewer.getCamera()->setClearColor(osg::Vec4(0.3f, 0.3f, 0.3f, 1.0f));
	viewer.setUpViewInWindow(50, 50, WINDOW_WIDTH, WINDOW_HEIGHT);

	viewer.run();

	osgPango::Context::instance().writeCachesToPNGFiles("osgpangocustomrenderer");

	unsigned long bytes = osgPango::Context::instance().getMemoryUsageInBytes();

	osg::notify(osg::NOTICE)
		<< "Used " << (bytes / 1024.0f) / 1024.0f << "MB of Image data internally."
		<< std::endl
	;

	return 0;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <stdexcept>

#include <ccpp_dds_dcps.h>

#include "rosidl_generator_cpp/MessageTypeSupport.h"
#include "ros_middleware_interface/handles.h"
#include "ros_middleware_opensplice_cpp/MessageTypeSupport.h"

namespace ros_middleware_interface
{

const char * _prismtech_opensplice_identifier = "opensplice_static";

ros_middleware_interface::NodeHandle create_node()
{
    std::cout << "create_node()" << std::endl;

    std::cout << "  create_node() get_instance" << std::endl;
    DDS::DomainParticipantFactory_var dpf_ = DDS::DomainParticipantFactory::get_instance();
    if (!dpf_) {
        printf("  create_node() could not get participant factory\n");
        throw std::runtime_error("could not get participant factory");
    };

    DDS::DomainId_t domain = 0;

    std::cout << "  create_node() create_participant in domain " << domain  << std::endl;
    DDS::DomainParticipant * participant = dpf_->create_participant(
        domain, PARTICIPANT_QOS_DEFAULT, NULL,
        DDS::STATUS_MASK_NONE);
    if (!participant) {
        printf("  create_node() could not create participant\n");
        throw std::runtime_error("could not create participant");
    };

    std::cout << "  create_node() pass opaque node handle" << std::endl;

    ros_middleware_interface::NodeHandle node_handle = {
        _prismtech_opensplice_identifier,
        participant
    };
    return node_handle;
}

struct CustomPublisherInfo {
  DDS::DataWriter * topic_writer_;
  ros_middleware_opensplice_cpp::MessageTypeSupportCallbacks * callbacks_;
};

ros_middleware_interface::PublisherHandle create_publisher(const ros_middleware_interface::NodeHandle& node_handle, const rosidl_generator_cpp::MessageTypeSupportHandle & type_support_handle, const char * topic_name)
{
    std::cout << "create_publisher()" << std::endl;

    if (node_handle._implementation_identifier != _prismtech_opensplice_identifier)
    {
        printf("node handle not from this implementation\n");
        printf("but from: %s\n", node_handle._implementation_identifier);
        throw std::runtime_error("node handle not from this implementation");
    }

    std::cout << "create_publisher() " << node_handle._implementation_identifier << std::endl;

    std::cout << "  create_publisher() extract participant from opaque node handle" << std::endl;
    DDS::DomainParticipant * participant = (DDS::DomainParticipant *)node_handle._data;

    ros_middleware_opensplice_cpp::MessageTypeSupportCallbacks * callbacks = (ros_middleware_opensplice_cpp::MessageTypeSupportCallbacks*)type_support_handle._data;
    std::string type_name = std::string(callbacks->_package_name) + "::dds_::" + callbacks->_message_name + "_";

    std::cout << "  create_publisher() invoke register callback" << std::endl;
    callbacks->_register_type(participant, type_name.c_str());

    DDS::PublisherQos publisher_qos;
    DDS::ReturnCode_t status = participant->get_default_publisher_qos(publisher_qos);
    if (status != DDS::RETCODE_OK) {
        printf("get_default_publisher_qos() failed. Status = %d\n", status);
        throw std::runtime_error("get default publisher qos failed");
    };

    std::cout << "  create_publisher() create dds publisher" << std::endl;
    DDS::Publisher * dds_publisher = participant->create_publisher(
        publisher_qos, NULL, DDS::STATUS_MASK_NONE);
    if (!dds_publisher) {
        printf("  create_publisher() could not create publisher\n");
        throw std::runtime_error("could not create publisher");
    };

    DDS::TopicQos default_topic_qos;
    status = participant->get_default_topic_qos(default_topic_qos);
    if (status != DDS::RETCODE_OK) {
        printf("get_default_topic_qos() failed. Status = %d\n", status);
        throw std::runtime_error("get default topic qos failed");
    };

    std::cout << "  create_publisher() create topic" << std::endl;
    DDS::Topic * topic = participant->create_topic(
        topic_name, type_name.c_str(), default_topic_qos, NULL,
        DDS::STATUS_MASK_NONE
    );
    if (!topic) {
        printf("  create_topic() could not create topic\n");
        throw std::runtime_error("could not create topic");
    };

    DDS::DataWriterQos default_datawriter_qos;
    status = dds_publisher->get_default_datawriter_qos(default_datawriter_qos);
    if (status != DDS::RETCODE_OK) {
        printf("get_default_datawriter_qos() failed. Status = %d\n", status);
        throw std::runtime_error("get default datawriter qos failed");
    };

    std::cout << "  create_publisher() create data writer" << std::endl;
    DDS::DataWriter * topic_writer = dds_publisher->create_datawriter(
        topic, default_datawriter_qos,
        NULL, DDS::STATUS_MASK_NONE);

    std::cout << "  create_publisher() build opaque publisher handle" << std::endl;
    CustomPublisherInfo* custom_publisher_info = new CustomPublisherInfo();
    custom_publisher_info->topic_writer_ = topic_writer;
    custom_publisher_info->callbacks_ = callbacks;

    ros_middleware_interface::PublisherHandle publisher_handle = {
        _prismtech_opensplice_identifier,
        custom_publisher_info
    };
    return publisher_handle;
}

void publish(const ros_middleware_interface::PublisherHandle& publisher_handle, const void * ros_message)
{
    //std::cout << "publish()" << std::endl;

    if (publisher_handle._implementation_identifier != _prismtech_opensplice_identifier)
    {
        printf("publisher handle not from this implementation\n");
        printf("but from: %s\n", publisher_handle._implementation_identifier);
        throw std::runtime_error("publisher handle not from this implementation");
    }

    //std::cout << "  publish() extract data writer and type code from opaque publisher handle" << std::endl;
    CustomPublisherInfo * custom_publisher_info = (CustomPublisherInfo*)publisher_handle._data;
    DDS::DataWriter * topic_writer = custom_publisher_info->topic_writer_;
    const ros_middleware_opensplice_cpp::MessageTypeSupportCallbacks * callbacks = custom_publisher_info->callbacks_;

    //std::cout << "  publish() invoke publish callback" << std::endl;
    callbacks->_publish(topic_writer, ros_message);
}

struct CustomSubscriberInfo {
  DDS::DataReader * topic_reader_;
  ros_middleware_opensplice_cpp::MessageTypeSupportCallbacks * callbacks_;
};

ros_middleware_interface::SubscriberHandle create_subscriber(const NodeHandle& node_handle, const rosidl_generator_cpp::MessageTypeSupportHandle & type_support_handle, const char * topic_name)
{
  std::cout << "create_subscriber()" << std::endl;

    if (node_handle._implementation_identifier != _prismtech_opensplice_identifier)
    {
        printf("node handle not from this implementation\n");
        printf("but from: %s\n", node_handle._implementation_identifier);
        throw std::runtime_error("node handle not from this implementation");
    }
    std::cout << "create_subscriber() " << node_handle._implementation_identifier << std::endl;

    std::cout << "  create_subscriber() extract participant from opaque node handle" << std::endl;
    DDS::DomainParticipant * participant = (DDS::DomainParticipant *)node_handle._data;

    ros_middleware_opensplice_cpp::MessageTypeSupportCallbacks * callbacks = (ros_middleware_opensplice_cpp::MessageTypeSupportCallbacks*)type_support_handle._data;
    std::string type_name = std::string(callbacks->_package_name) + "::dds_::" + callbacks->_message_name + "_";

    std::cout << "  create_subscriber() invoke register callback" << std::endl;
    callbacks->_register_type(participant, type_name.c_str());

    DDS::SubscriberQos subscriber_qos;
    DDS::ReturnCode_t status = participant->get_default_subscriber_qos(subscriber_qos);
    if (status != DDS::RETCODE_OK) {
        printf("get_default_subscriber_qos() failed. Status = %d\n", status);
        throw std::runtime_error("get default subscriber qos failed");
    };

    std::cout << "  create_subscriber() create dds subscriber" << std::endl;
    DDS::Subscriber * dds_subscriber = participant->create_subscriber(
        subscriber_qos, NULL, DDS::STATUS_MASK_NONE);
    if (!dds_subscriber) {
        printf("  create_subscriber() could not create subscriber\n");
        throw std::runtime_error("could not create subscriber");
    };

    DDS::TopicQos default_topic_qos;
    status = participant->get_default_topic_qos(default_topic_qos);
    if (status != DDS::RETCODE_OK) {
        printf("get_default_topic_qos() failed. Status = %d\n", status);
        throw std::runtime_error("get default topic qos failed");
    };

    std::cout << "  create_subscriber() create topic" << std::endl;
    DDS::Topic * topic = participant->create_topic(
        topic_name, type_name.c_str(), default_topic_qos, NULL,
        DDS::STATUS_MASK_NONE
    );
    if (!topic) {
        printf("  create_topic() could not create topic\n");
        throw std::runtime_error("could not create topic");
    };

    DDS::DataReaderQos default_datareader_qos;
    status = dds_subscriber->get_default_datareader_qos(default_datareader_qos);
    if (status != DDS::RETCODE_OK) {
        printf("get_default_datareader_qos() failed. Status = %d\n", status);
        throw std::runtime_error("get default datareader qos failed");
    };

    std::cout << "  create_subscriber() create data reader" << std::endl;
    DDS::DataReader * topic_reader = dds_subscriber->create_datareader(
        topic, default_datareader_qos,
        NULL, DDS::STATUS_MASK_NONE);

    std::cout << "  topic reader" << topic_reader << std::endl;

    std::cout << "  create_subscriber() build opaque subscriber handle" << std::endl;
    CustomSubscriberInfo* custom_subscriber_info = new CustomSubscriberInfo();
    custom_subscriber_info->topic_reader_ = topic_reader;
    custom_subscriber_info->callbacks_ = callbacks;

    ros_middleware_interface::SubscriberHandle subscriber_handle = {
        _prismtech_opensplice_identifier,
        custom_subscriber_info
    };
    return subscriber_handle;

}

bool take(const ros_middleware_interface::SubscriberHandle& subscriber_handle, void * ros_message)
{
  if (subscriber_handle.implementation_identifier_ != _prismtech_opensplice_identifier)
  {
    printf("subscriber handle not from this implementation\n");
    printf("but from: %s\n", subscriber_handle.implementation_identifier_);
    throw std::runtime_error("subscriber handle not from this implementation");
  }

  //std::cout << "  take() extract data writer and type code from opaque subscriber handle" << std::endl;
  CustomSubscriberInfo * custom_subscriber_info = (CustomSubscriberInfo*)subscriber_handle.data_;
  DDS::DataReader * topic_reader = custom_subscriber_info->topic_reader_;
  const ros_middleware_opensplice_cpp::MessageTypeSupportCallbacks * callbacks = custom_subscriber_info->callbacks_;

  return callbacks->_take(topic_reader, ros_message);
}

ros_middleware_interface::GuardConditionHandle create_guard_condition()
{
  ros_middleware_interface::GuardConditionHandle guard_condition_handle;
  guard_condition_handle.implementation_identifier_ = _prismtech_opensplice_identifier;
  guard_condition_handle.data_ = new DDS::GuardCondition();
  return guard_condition_handle;
}

void trigger_guard_condition(const ros_middleware_interface::GuardConditionHandle& guard_condition_handle)
{
  if (guard_condition_handle.implementation_identifier_ != _prismtech_opensplice_identifier)
  {
    printf("guard condition handle not from this implementation\n");
    printf("but from: %s\n", guard_condition_handle.implementation_identifier_);
    throw std::runtime_error("guard condition handle not from this implementation");
  }

  DDS::GuardCondition * guard_condition = (DDS::GuardCondition*)guard_condition_handle.data_;
  guard_condition->set_trigger_value(true);
}

void wait(ros_middleware_interface::SubscriberHandles& subscriber_handles, ros_middleware_interface::GuardConditionHandles& guard_condition_handles, bool non_blocking)
{
  DDS::WaitSet waitset;

  // add a condition for each subscriber
  for (unsigned long i = 0; i < subscriber_handles.subscriber_count_; ++i)
  {
    void * data = subscriber_handles.subscribers_[i];
    CustomSubscriberInfo * custom_subscriber_info = (CustomSubscriberInfo*)data;
    DDS::DataReader * topic_reader = custom_subscriber_info->topic_reader_;
    DDS::StatusCondition * condition = topic_reader->get_statuscondition();
    condition->set_enabled_statuses(DDS::DATA_AVAILABLE_STATUS);
    waitset.attach_condition(condition);
  }

  // add a condition for each guard condition
  for (unsigned long i = 0; i < guard_condition_handles.guard_condition_count_; ++i)
  {
    void * data = guard_condition_handles.guard_conditions_[i];
    DDS::GuardCondition * guard_condition = (DDS::GuardCondition*)data;
    waitset.attach_condition(guard_condition);
  }

  // invoke wait until one of the conditions triggers
  DDS::ConditionSeq active_conditions;
  DDS::Duration_t timeout;
  timeout.sec = non_blocking ? 0 : 1;
  DDS::ReturnCode_t status = DDS::RETCODE_TIMEOUT;
  while (DDS::RETCODE_TIMEOUT == status)
  {
    status = waitset.wait(active_conditions, timeout);
    if (DDS::RETCODE_TIMEOUT == status) {
      if (non_blocking)
      {
        break;
      }
      continue;
    };
    if (status != DDS::RETCODE_OK) {
      printf("wait() failed. Status = %d\n", status);
      throw std::runtime_error("wait failed");
    };
  }

  // set subscriber handles to zero for all not triggered conditions
  for (unsigned long i = 0; i < subscriber_handles.subscriber_count_; ++i)
  {
    void * data = subscriber_handles.subscribers_[i];
    CustomSubscriberInfo * custom_subscriber_info = (CustomSubscriberInfo*)data;
    DDS::DataReader* topic_reader = custom_subscriber_info->topic_reader_;
    DDS::StatusCondition * condition = topic_reader->get_statuscondition();

    // search for subscriber condition in active set
    unsigned long j = 0;
    for (; j < active_conditions.length(); ++j)
    {
      if (active_conditions[j] == condition)
      {
        break;
      }
    }
    // if subscriber condition is not found in the active set
    // reset the subscriber handle
    if (!(j < active_conditions.length()))
    {
      subscriber_handles.subscribers_[i] = 0;
    }
  }

  // set subscriber handles to zero for all not triggered conditions
  for (unsigned long i = 0; i < guard_condition_handles.guard_condition_count_; ++i)
  {
    void * data = guard_condition_handles.guard_conditions_[i];
    DDS::Condition * condition = (DDS::Condition*)data;

    // search for guard condition in active set
    unsigned long j = 0;
    for (; j < active_conditions.length(); ++j)
    {
      if (active_conditions[j] == condition)
      {
        break;
      }
    }
    // if guard condition is not found in the active set
    // reset the guard handle
    if (!(j < active_conditions.length()))
    {
      guard_condition_handles.guard_conditions_[i] = 0;
    }
  }
}

}
<commit_msg>display implementation type during node creation<commit_after>#include <iostream>
#include <stdexcept>

#include <ccpp_dds_dcps.h>

#include "rosidl_generator_cpp/MessageTypeSupport.h"
#include "ros_middleware_interface/handles.h"
#include "ros_middleware_opensplice_cpp/MessageTypeSupport.h"

namespace ros_middleware_interface
{

const char * _prismtech_opensplice_identifier = "opensplice_static";

ros_middleware_interface::NodeHandle create_node()
{
    std::cout << "create_node()" << std::endl;

    std::cout << "  create_node() " << _prismtech_opensplice_identifier << std::endl;

    std::cout << "  create_node() get_instance" << std::endl;
    DDS::DomainParticipantFactory_var dpf_ = DDS::DomainParticipantFactory::get_instance();
    if (!dpf_) {
        printf("  create_node() could not get participant factory\n");
        throw std::runtime_error("could not get participant factory");
    };

    DDS::DomainId_t domain = 0;

    std::cout << "  create_node() create_participant in domain " << domain  << std::endl;
    DDS::DomainParticipant * participant = dpf_->create_participant(
        domain, PARTICIPANT_QOS_DEFAULT, NULL,
        DDS::STATUS_MASK_NONE);
    if (!participant) {
        printf("  create_node() could not create participant\n");
        throw std::runtime_error("could not create participant");
    };

    std::cout << "  create_node() pass opaque node handle" << std::endl;

    ros_middleware_interface::NodeHandle node_handle = {
        _prismtech_opensplice_identifier,
        participant
    };
    return node_handle;
}

struct CustomPublisherInfo {
  DDS::DataWriter * topic_writer_;
  ros_middleware_opensplice_cpp::MessageTypeSupportCallbacks * callbacks_;
};

ros_middleware_interface::PublisherHandle create_publisher(const ros_middleware_interface::NodeHandle& node_handle, const rosidl_generator_cpp::MessageTypeSupportHandle & type_support_handle, const char * topic_name)
{
    std::cout << "create_publisher()" << std::endl;

    if (node_handle._implementation_identifier != _prismtech_opensplice_identifier)
    {
        printf("node handle not from this implementation\n");
        printf("but from: %s\n", node_handle._implementation_identifier);
        throw std::runtime_error("node handle not from this implementation");
    }

    std::cout << "create_publisher() " << node_handle._implementation_identifier << std::endl;

    std::cout << "  create_publisher() extract participant from opaque node handle" << std::endl;
    DDS::DomainParticipant * participant = (DDS::DomainParticipant *)node_handle._data;

    ros_middleware_opensplice_cpp::MessageTypeSupportCallbacks * callbacks = (ros_middleware_opensplice_cpp::MessageTypeSupportCallbacks*)type_support_handle._data;
    std::string type_name = std::string(callbacks->_package_name) + "::dds_::" + callbacks->_message_name + "_";

    std::cout << "  create_publisher() invoke register callback" << std::endl;
    callbacks->_register_type(participant, type_name.c_str());

    DDS::PublisherQos publisher_qos;
    DDS::ReturnCode_t status = participant->get_default_publisher_qos(publisher_qos);
    if (status != DDS::RETCODE_OK) {
        printf("get_default_publisher_qos() failed. Status = %d\n", status);
        throw std::runtime_error("get default publisher qos failed");
    };

    std::cout << "  create_publisher() create dds publisher" << std::endl;
    DDS::Publisher * dds_publisher = participant->create_publisher(
        publisher_qos, NULL, DDS::STATUS_MASK_NONE);
    if (!dds_publisher) {
        printf("  create_publisher() could not create publisher\n");
        throw std::runtime_error("could not create publisher");
    };

    DDS::TopicQos default_topic_qos;
    status = participant->get_default_topic_qos(default_topic_qos);
    if (status != DDS::RETCODE_OK) {
        printf("get_default_topic_qos() failed. Status = %d\n", status);
        throw std::runtime_error("get default topic qos failed");
    };

    std::cout << "  create_publisher() create topic" << std::endl;
    DDS::Topic * topic = participant->create_topic(
        topic_name, type_name.c_str(), default_topic_qos, NULL,
        DDS::STATUS_MASK_NONE
    );
    if (!topic) {
        printf("  create_topic() could not create topic\n");
        throw std::runtime_error("could not create topic");
    };

    DDS::DataWriterQos default_datawriter_qos;
    status = dds_publisher->get_default_datawriter_qos(default_datawriter_qos);
    if (status != DDS::RETCODE_OK) {
        printf("get_default_datawriter_qos() failed. Status = %d\n", status);
        throw std::runtime_error("get default datawriter qos failed");
    };

    std::cout << "  create_publisher() create data writer" << std::endl;
    DDS::DataWriter * topic_writer = dds_publisher->create_datawriter(
        topic, default_datawriter_qos,
        NULL, DDS::STATUS_MASK_NONE);

    std::cout << "  create_publisher() build opaque publisher handle" << std::endl;
    CustomPublisherInfo* custom_publisher_info = new CustomPublisherInfo();
    custom_publisher_info->topic_writer_ = topic_writer;
    custom_publisher_info->callbacks_ = callbacks;

    ros_middleware_interface::PublisherHandle publisher_handle = {
        _prismtech_opensplice_identifier,
        custom_publisher_info
    };
    return publisher_handle;
}

void publish(const ros_middleware_interface::PublisherHandle& publisher_handle, const void * ros_message)
{
    //std::cout << "publish()" << std::endl;

    if (publisher_handle._implementation_identifier != _prismtech_opensplice_identifier)
    {
        printf("publisher handle not from this implementation\n");
        printf("but from: %s\n", publisher_handle._implementation_identifier);
        throw std::runtime_error("publisher handle not from this implementation");
    }

    //std::cout << "  publish() extract data writer and type code from opaque publisher handle" << std::endl;
    CustomPublisherInfo * custom_publisher_info = (CustomPublisherInfo*)publisher_handle._data;
    DDS::DataWriter * topic_writer = custom_publisher_info->topic_writer_;
    const ros_middleware_opensplice_cpp::MessageTypeSupportCallbacks * callbacks = custom_publisher_info->callbacks_;

    //std::cout << "  publish() invoke publish callback" << std::endl;
    callbacks->_publish(topic_writer, ros_message);
}

struct CustomSubscriberInfo {
  DDS::DataReader * topic_reader_;
  ros_middleware_opensplice_cpp::MessageTypeSupportCallbacks * callbacks_;
};

ros_middleware_interface::SubscriberHandle create_subscriber(const NodeHandle& node_handle, const rosidl_generator_cpp::MessageTypeSupportHandle & type_support_handle, const char * topic_name)
{
  std::cout << "create_subscriber()" << std::endl;

    if (node_handle._implementation_identifier != _prismtech_opensplice_identifier)
    {
        printf("node handle not from this implementation\n");
        printf("but from: %s\n", node_handle._implementation_identifier);
        throw std::runtime_error("node handle not from this implementation");
    }
    std::cout << "create_subscriber() " << node_handle._implementation_identifier << std::endl;

    std::cout << "  create_subscriber() extract participant from opaque node handle" << std::endl;
    DDS::DomainParticipant * participant = (DDS::DomainParticipant *)node_handle._data;

    ros_middleware_opensplice_cpp::MessageTypeSupportCallbacks * callbacks = (ros_middleware_opensplice_cpp::MessageTypeSupportCallbacks*)type_support_handle._data;
    std::string type_name = std::string(callbacks->_package_name) + "::dds_::" + callbacks->_message_name + "_";

    std::cout << "  create_subscriber() invoke register callback" << std::endl;
    callbacks->_register_type(participant, type_name.c_str());

    DDS::SubscriberQos subscriber_qos;
    DDS::ReturnCode_t status = participant->get_default_subscriber_qos(subscriber_qos);
    if (status != DDS::RETCODE_OK) {
        printf("get_default_subscriber_qos() failed. Status = %d\n", status);
        throw std::runtime_error("get default subscriber qos failed");
    };

    std::cout << "  create_subscriber() create dds subscriber" << std::endl;
    DDS::Subscriber * dds_subscriber = participant->create_subscriber(
        subscriber_qos, NULL, DDS::STATUS_MASK_NONE);
    if (!dds_subscriber) {
        printf("  create_subscriber() could not create subscriber\n");
        throw std::runtime_error("could not create subscriber");
    };

    DDS::TopicQos default_topic_qos;
    status = participant->get_default_topic_qos(default_topic_qos);
    if (status != DDS::RETCODE_OK) {
        printf("get_default_topic_qos() failed. Status = %d\n", status);
        throw std::runtime_error("get default topic qos failed");
    };

    std::cout << "  create_subscriber() create topic" << std::endl;
    DDS::Topic * topic = participant->create_topic(
        topic_name, type_name.c_str(), default_topic_qos, NULL,
        DDS::STATUS_MASK_NONE
    );
    if (!topic) {
        printf("  create_topic() could not create topic\n");
        throw std::runtime_error("could not create topic");
    };

    DDS::DataReaderQos default_datareader_qos;
    status = dds_subscriber->get_default_datareader_qos(default_datareader_qos);
    if (status != DDS::RETCODE_OK) {
        printf("get_default_datareader_qos() failed. Status = %d\n", status);
        throw std::runtime_error("get default datareader qos failed");
    };

    std::cout << "  create_subscriber() create data reader" << std::endl;
    DDS::DataReader * topic_reader = dds_subscriber->create_datareader(
        topic, default_datareader_qos,
        NULL, DDS::STATUS_MASK_NONE);

    std::cout << "  topic reader" << topic_reader << std::endl;

    std::cout << "  create_subscriber() build opaque subscriber handle" << std::endl;
    CustomSubscriberInfo* custom_subscriber_info = new CustomSubscriberInfo();
    custom_subscriber_info->topic_reader_ = topic_reader;
    custom_subscriber_info->callbacks_ = callbacks;

    ros_middleware_interface::SubscriberHandle subscriber_handle = {
        _prismtech_opensplice_identifier,
        custom_subscriber_info
    };
    return subscriber_handle;

}

bool take(const ros_middleware_interface::SubscriberHandle& subscriber_handle, void * ros_message)
{
  if (subscriber_handle.implementation_identifier_ != _prismtech_opensplice_identifier)
  {
    printf("subscriber handle not from this implementation\n");
    printf("but from: %s\n", subscriber_handle.implementation_identifier_);
    throw std::runtime_error("subscriber handle not from this implementation");
  }

  //std::cout << "  take() extract data writer and type code from opaque subscriber handle" << std::endl;
  CustomSubscriberInfo * custom_subscriber_info = (CustomSubscriberInfo*)subscriber_handle.data_;
  DDS::DataReader * topic_reader = custom_subscriber_info->topic_reader_;
  const ros_middleware_opensplice_cpp::MessageTypeSupportCallbacks * callbacks = custom_subscriber_info->callbacks_;

  return callbacks->_take(topic_reader, ros_message);
}

ros_middleware_interface::GuardConditionHandle create_guard_condition()
{
  ros_middleware_interface::GuardConditionHandle guard_condition_handle;
  guard_condition_handle.implementation_identifier_ = _prismtech_opensplice_identifier;
  guard_condition_handle.data_ = new DDS::GuardCondition();
  return guard_condition_handle;
}

void trigger_guard_condition(const ros_middleware_interface::GuardConditionHandle& guard_condition_handle)
{
  if (guard_condition_handle.implementation_identifier_ != _prismtech_opensplice_identifier)
  {
    printf("guard condition handle not from this implementation\n");
    printf("but from: %s\n", guard_condition_handle.implementation_identifier_);
    throw std::runtime_error("guard condition handle not from this implementation");
  }

  DDS::GuardCondition * guard_condition = (DDS::GuardCondition*)guard_condition_handle.data_;
  guard_condition->set_trigger_value(true);
}

void wait(ros_middleware_interface::SubscriberHandles& subscriber_handles, ros_middleware_interface::GuardConditionHandles& guard_condition_handles, bool non_blocking)
{
  DDS::WaitSet waitset;

  // add a condition for each subscriber
  for (unsigned long i = 0; i < subscriber_handles.subscriber_count_; ++i)
  {
    void * data = subscriber_handles.subscribers_[i];
    CustomSubscriberInfo * custom_subscriber_info = (CustomSubscriberInfo*)data;
    DDS::DataReader * topic_reader = custom_subscriber_info->topic_reader_;
    DDS::StatusCondition * condition = topic_reader->get_statuscondition();
    condition->set_enabled_statuses(DDS::DATA_AVAILABLE_STATUS);
    waitset.attach_condition(condition);
  }

  // add a condition for each guard condition
  for (unsigned long i = 0; i < guard_condition_handles.guard_condition_count_; ++i)
  {
    void * data = guard_condition_handles.guard_conditions_[i];
    DDS::GuardCondition * guard_condition = (DDS::GuardCondition*)data;
    waitset.attach_condition(guard_condition);
  }

  // invoke wait until one of the conditions triggers
  DDS::ConditionSeq active_conditions;
  DDS::Duration_t timeout;
  timeout.sec = non_blocking ? 0 : 1;
  DDS::ReturnCode_t status = DDS::RETCODE_TIMEOUT;
  while (DDS::RETCODE_TIMEOUT == status)
  {
    status = waitset.wait(active_conditions, timeout);
    if (DDS::RETCODE_TIMEOUT == status) {
      if (non_blocking)
      {
        break;
      }
      continue;
    };
    if (status != DDS::RETCODE_OK) {
      printf("wait() failed. Status = %d\n", status);
      throw std::runtime_error("wait failed");
    };
  }

  // set subscriber handles to zero for all not triggered conditions
  for (unsigned long i = 0; i < subscriber_handles.subscriber_count_; ++i)
  {
    void * data = subscriber_handles.subscribers_[i];
    CustomSubscriberInfo * custom_subscriber_info = (CustomSubscriberInfo*)data;
    DDS::DataReader* topic_reader = custom_subscriber_info->topic_reader_;
    DDS::StatusCondition * condition = topic_reader->get_statuscondition();

    // search for subscriber condition in active set
    unsigned long j = 0;
    for (; j < active_conditions.length(); ++j)
    {
      if (active_conditions[j] == condition)
      {
        break;
      }
    }
    // if subscriber condition is not found in the active set
    // reset the subscriber handle
    if (!(j < active_conditions.length()))
    {
      subscriber_handles.subscribers_[i] = 0;
    }
  }

  // set subscriber handles to zero for all not triggered conditions
  for (unsigned long i = 0; i < guard_condition_handles.guard_condition_count_; ++i)
  {
    void * data = guard_condition_handles.guard_conditions_[i];
    DDS::Condition * condition = (DDS::Condition*)data;

    // search for guard condition in active set
    unsigned long j = 0;
    for (; j < active_conditions.length(); ++j)
    {
      if (active_conditions[j] == condition)
      {
        break;
      }
    }
    // if guard condition is not found in the active set
    // reset the guard handle
    if (!(j < active_conditions.length()))
    {
      guard_condition_handles.guard_conditions_[i] = 0;
    }
  }
}

}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: directsql.cxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: kz $ $Date: 2007-05-10 10:25:48 $
 *
 *  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_dbaccess.hxx"

#ifndef _DBACCESS_UI_DIRECTSQL_HXX_
#include "directsql.hxx"
#endif
#ifndef _DBACCESS_UI_DIRECTSQL_HRC_
#include "directsql.hrc"
#endif
#ifndef _DBAUI_MODULE_DBU_HXX_
#include "moduledbu.hxx"
#endif
#ifndef _DBU_DLG_HRC_
#include "dbu_dlg.hrc"
#endif
#ifndef _SV_MSGBOX_HXX
#include <vcl/msgbox.hxx>
#endif
#ifndef _COMPHELPER_TYPES_HXX_
#include <comphelper/types.hxx>
#endif
#ifndef _SV_MSGBOX_HXX
#include <vcl/msgbox.hxx>
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif
#ifndef _VOS_MUTEX_HXX_
#include <vos/mutex.hxx>
#endif

//........................................................................
namespace dbaui
{
//........................................................................

    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::sdbc;
    using namespace ::com::sun::star::lang;

    //====================================================================
    //= LargeEntryListBox
    //====================================================================
    class LargeEntryListBox : public ListBox
    {
    public:
        LargeEntryListBox( Window* _pParent, const ResId& _rId );

    protected:
        virtual void    UserDraw( const UserDrawEvent& rUDEvt );
    };

    //--------------------------------------------------------------------
    LargeEntryListBox::LargeEntryListBox( Window* _pParent, const ResId& _rId )
        :ListBox(_pParent, _rId )
    {
        EnableUserDraw(sal_True);
    }

    //--------------------------------------------------------------------
    void LargeEntryListBox::UserDraw( const UserDrawEvent& _rUDEvt )
    {
        if (LISTBOX_ENTRY_NOTFOUND == _rUDEvt.GetItemId())
            ListBox::UserDraw( _rUDEvt );
        else
            _rUDEvt.GetDevice()->DrawText( _rUDEvt.GetRect(), GetEntry( _rUDEvt.GetItemId() ), TEXT_DRAW_LEFT | TEXT_DRAW_VCENTER | TEXT_DRAW_ENDELLIPSIS);
    }

    //====================================================================
    //= DirectSQLDialog
    //====================================================================
DBG_NAME(DirectSQLDialog)
//--------------------------------------------------------------------
    DirectSQLDialog::DirectSQLDialog( Window* _pParent, const Reference< XConnection >& _rxConn )
        :ModalDialog(_pParent, ModuleRes(DLG_DIRECTSQL))
        ,m_aFrame               (this, ModuleRes(FL_SQL))
        ,m_aSQLLabel            (this, ModuleRes(FT_SQL))
        ,m_aSQL                 (this, ModuleRes(ME_SQL))
        ,m_aExecute             (this, ModuleRes(PB_EXECUTE))
        ,m_aHistoryLabel        (this, ModuleRes(FT_HISTORY))
        ,m_pSQLHistory(new LargeEntryListBox(this, ModuleRes(LB_HISTORY)))
        ,m_aStatusFrame         (this, ModuleRes(FL_STATUS))
        ,m_aStatus              (this, ModuleRes(ME_STATUS))
        ,m_aButtonSeparator     (this, ModuleRes(FL_BUTTONS))
        ,m_aHelp                (this, ModuleRes(PB_HELP))
        ,m_aClose               (this, ModuleRes(PB_CLOSE))
        ,m_nHistoryLimit(20)
        ,m_nStatusCount(1)
        ,m_xConnection(_rxConn)
    {
        DBG_CTOR(DirectSQLDialog,NULL);

        FreeResource();

        m_aSQL.GrabFocus();

        m_aExecute.SetClickHdl(LINK(this, DirectSQLDialog, OnExecute));
        m_aClose.SetClickHdl(LINK(this, DirectSQLDialog, OnClose));
        m_pSQLHistory->SetSelectHdl(LINK(this, DirectSQLDialog, OnListEntrySelected));
        m_pSQLHistory->SetDropDownLineCount(10);

        // add a dispose listener to the connection
        Reference< XComponent > xConnComp(m_xConnection, UNO_QUERY);
        OSL_ENSURE(xConnComp.is(), "DirectSQLDialog::DirectSQLDialog: invalid connection!");
        if (xConnComp.is())
            startComponentListening(xConnComp);

        m_aSQL.SetModifyHdl(LINK(this, DirectSQLDialog, OnStatementModified));
        OnStatementModified(&m_aSQL);
    }

    //--------------------------------------------------------------------
    DirectSQLDialog::~DirectSQLDialog()
    {
        {
            ::osl::MutexGuard aGuard(m_aMutex);
            stopAllComponentListening();
        }
        delete m_pSQLHistory;

        DBG_DTOR(DirectSQLDialog,NULL);
    }

    //--------------------------------------------------------------------
    void DirectSQLDialog::_disposing( const EventObject& _rSource )
    {
        ::vos::OGuard aSolarGuard(Application::GetSolarMutex());
        ::osl::MutexGuard aGuard(m_aMutex);

        OSL_ENSURE(Reference< XConnection >(_rSource.Source, UNO_QUERY).get() == m_xConnection.get(),
            "DirectSQLDialog::_disposing: where does this come from?");
        (void)_rSource;

        {
            String sMessage(ModuleRes(STR_DIRECTSQL_CONNECTIONLOST));
            ErrorBox aError(this, WB_OK, sMessage);
            aError.Execute();
        }

        PostUserEvent(LINK(this, DirectSQLDialog, OnClose));
    }

    //--------------------------------------------------------------------
    void DirectSQLDialog::addHistoryEntry(const String& _rStatement)
    {
        CHECK_INVARIANTS("DirectSQLDialog::addHistoryEntry");
        implAddToStatementHistory(_rStatement);
    }

    //--------------------------------------------------------------------
    sal_Int32 DirectSQLDialog::getHistorySize() const
    {
        CHECK_INVARIANTS("DirectSQLDialog::getHistorySize");
        return m_aStatementHistory.size();
    }

    //--------------------------------------------------------------------
    void DirectSQLDialog::implEnsureHistoryLimit()
    {
        CHECK_INVARIANTS("DirectSQLDialog::implEnsureHistoryLimit");

        if (getHistorySize() <= m_nHistoryLimit)
            // nothing to do
            return;

        sal_Int32 nRemoveEntries = getHistorySize() - m_nHistoryLimit;
        while (nRemoveEntries--)
        {
            m_aStatementHistory.pop_front();
            m_aNormalizedHistory.pop_front();
            m_pSQLHistory->RemoveEntry((USHORT)0);
        }
    }

    //--------------------------------------------------------------------
    void DirectSQLDialog::implAddToStatementHistory(const String& _rStatement)
    {
        CHECK_INVARIANTS("DirectSQLDialog::implAddToStatementHistory");

        // add the statement to the history
        m_aStatementHistory.push_back(_rStatement);

        // normalize the statement, and remember the normalized form, too
        String sNormalized(_rStatement);
        sNormalized.SearchAndReplaceAll((sal_Unicode)'\n', ' ');
        m_aNormalizedHistory.push_back(sNormalized);

        // add the normalized version to the list box
        m_pSQLHistory->InsertEntry(sNormalized);

        // ensure that we don't exceed the history limit
        implEnsureHistoryLimit();
    }

#ifdef DBG_UTIL
    //--------------------------------------------------------------------
    const sal_Char* DirectSQLDialog::impl_CheckInvariants() const
    {
        if (m_aStatementHistory.size() != m_aNormalizedHistory.size())
            return "statement history is inconsistent!";

        if (!m_pSQLHistory)
            return "invalid listbox!";

        if (m_aStatementHistory.size() != m_pSQLHistory->GetEntryCount())
            return "invalid listbox entry count!";

        if (!m_xConnection.is())
            return "have no connection!";

        return NULL;
    }
#endif

    //--------------------------------------------------------------------
    void DirectSQLDialog::implExecuteStatement(const String& _rStatement)
    {
        CHECK_INVARIANTS("DirectSQLDialog::implExecuteStatement");

        ::osl::MutexGuard aGuard(m_aMutex);

        String sStatus;
        try
        {
            // create a statement
            Reference< XStatement > xStatement = m_xConnection->createStatement();
            OSL_ENSURE(xStatement.is(), "DirectSQLDialog::implExecuteStatement: no statement returned by the connection!");

            // execute it
            if (xStatement.is())
                xStatement->execute(_rStatement);

            // successfull
            sStatus = String(ModuleRes(STR_COMMAND_EXECUTED_SUCCESSFULLY));

            // dispose the statement
            ::comphelper::disposeComponent(xStatement);
        }
        catch(const SQLException& e)
        {
            sStatus = e.Message;
        }
        catch(const Exception&)
        {
            OSL_ENSURE(sal_False, "DirectSQLDialog::implExecuteStatement: caught an (unknown) exception!");
        }

        // add the status text
        addStatusText(sStatus);
    }

    //--------------------------------------------------------------------
    void DirectSQLDialog::addStatusText(const String& _rMessage)
    {
        String sAppendMessage = String::CreateFromInt32(m_nStatusCount++);
        sAppendMessage += String::CreateFromAscii(": ");
        sAppendMessage += _rMessage;
        sAppendMessage += String::CreateFromAscii("\n\n");

        String sCompleteMessage = m_aStatus.GetText();
        sCompleteMessage += sAppendMessage;
        m_aStatus.SetText(sCompleteMessage);

        m_aStatus.SetSelection(Selection(sCompleteMessage.Len(), sCompleteMessage.Len()));
    }

    //--------------------------------------------------------------------
    void DirectSQLDialog::executeCurrent()
    {
        CHECK_INVARIANTS("DirectSQLDialog::executeCurrent");

        String sStatement = m_aSQL.GetText();

        // execute
        implExecuteStatement(sStatement);

        // add the statement to the history
        implAddToStatementHistory(sStatement);

        m_aSQL.SetSelection(Selection());
        m_aSQL.GrabFocus();
    }

    //--------------------------------------------------------------------
    void DirectSQLDialog::switchToHistory(sal_Int32 _nHistoryPos, sal_Bool _bUpdateListBox)
    {
        CHECK_INVARIANTS("DirectSQLDialog::switchToHistory");

        if ((_nHistoryPos >= 0) && (_nHistoryPos < getHistorySize()))
        {
            // set the text in the statement editor
            String sStatement = m_aStatementHistory[_nHistoryPos];
            m_aSQL.SetText(sStatement);
            OnStatementModified(&m_aSQL);

            if (_bUpdateListBox)
            {
                // selecte the normalized statement in the list box
                m_pSQLHistory->SelectEntryPos((USHORT)_nHistoryPos);
                OSL_ENSURE(m_pSQLHistory->GetSelectEntry() == m_aNormalizedHistory[_nHistoryPos],
                    "DirectSQLDialog::switchToHistory: inconsistent listbox entries!");
            }

            m_aSQL.GrabFocus();
            m_aSQL.SetSelection(Selection(sStatement.Len(), sStatement.Len()));
        }
        else
            OSL_ENSURE(sal_False, "DirectSQLDialog::switchToHistory: invalid position!");
    }

    //--------------------------------------------------------------------
    IMPL_LINK( DirectSQLDialog, OnStatementModified, void*, /*NOTINTERESTEDIN*/ )
    {
        m_aExecute.Enable(0 != m_aSQL.GetText().Len());
        return 0L;
    }

    //--------------------------------------------------------------------
    IMPL_LINK( DirectSQLDialog, OnClose, void*, /*NOTINTERESTEDIN*/ )
    {
        EndDialog( RET_OK );
        return 0L;
    }

    //--------------------------------------------------------------------
    IMPL_LINK( DirectSQLDialog, OnExecute, void*, /*NOTINTERESTEDIN*/ )
    {
        executeCurrent();
        return 0L;
    }

    //--------------------------------------------------------------------
    IMPL_LINK( DirectSQLDialog, OnListEntrySelected, void*, /*NOTINTERESTEDIN*/ )
    {
        if (!m_pSQLHistory->IsTravelSelect())
        {
            const sal_uInt16 nSelected = m_pSQLHistory->GetSelectEntryPos();
            if (LISTBOX_ENTRY_NOTFOUND != nSelected)
                switchToHistory(nSelected, sal_False);
        }
        return 0L;
    }

//........................................................................
}   // namespace dbaui
//........................................................................

<commit_msg>INTEGRATION: CWS oj14 (1.5.4); FILE MERGED 2007/06/04 18:23:02 oj 1.5.4.6: RESYNC: (1.7-1.9); FILE MERGED 2006/11/07 09:22:05 oj 1.5.4.5: RESYNC: (1.6-1.7); FILE MERGED 2006/07/04 07:57:54 oj 1.5.4.4: RESYNC: (1.5-1.6); FILE MERGED 2006/04/25 13:02:56 oj 1.5.4.3: new include 2006/03/20 07:48:28 oj 1.5.4.2: use of module client helper 2006/01/03 07:49:08 oj 1.5.4.1: changed module client<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: directsql.cxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: rt $ $Date: 2007-07-06 08:15:27 $
 *
 *  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_dbaccess.hxx"

#ifndef _DBACCESS_UI_DIRECTSQL_HXX_
#include "directsql.hxx"
#endif
#ifndef _DBACCESS_UI_DIRECTSQL_HRC_
#include "directsql.hrc"
#endif
#ifndef _DBU_DLG_HRC_
#include "dbu_dlg.hrc"
#endif
#ifndef _SV_MSGBOX_HXX
#include <vcl/msgbox.hxx>
#endif
#ifndef _COMPHELPER_TYPES_HXX_
#include <comphelper/types.hxx>
#endif
#ifndef _SV_MSGBOX_HXX
#include <vcl/msgbox.hxx>
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif
#ifndef _VOS_MUTEX_HXX_
#include <vos/mutex.hxx>
#endif

//........................................................................
namespace dbaui
{
//........................................................................

    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::sdbc;
    using namespace ::com::sun::star::lang;

    //====================================================================
    //= LargeEntryListBox
    //====================================================================
    class LargeEntryListBox : public ListBox
    {
    public:
        LargeEntryListBox( Window* _pParent, const ResId& _rId );

    protected:
        virtual void    UserDraw( const UserDrawEvent& rUDEvt );
    };

    //--------------------------------------------------------------------
    LargeEntryListBox::LargeEntryListBox( Window* _pParent, const ResId& _rId )
        :ListBox(_pParent, _rId )
    {
        EnableUserDraw(sal_True);
    }

    //--------------------------------------------------------------------
    void LargeEntryListBox::UserDraw( const UserDrawEvent& _rUDEvt )
    {
        if (LISTBOX_ENTRY_NOTFOUND == _rUDEvt.GetItemId())
            ListBox::UserDraw( _rUDEvt );
        else
            _rUDEvt.GetDevice()->DrawText( _rUDEvt.GetRect(), GetEntry( _rUDEvt.GetItemId() ), TEXT_DRAW_LEFT | TEXT_DRAW_VCENTER | TEXT_DRAW_ENDELLIPSIS);
    }

    //====================================================================
    //= DirectSQLDialog
    //====================================================================
DBG_NAME(DirectSQLDialog)
//--------------------------------------------------------------------
    DirectSQLDialog::DirectSQLDialog( Window* _pParent, const Reference< XConnection >& _rxConn )
        :ModalDialog(_pParent, ModuleRes(DLG_DIRECTSQL))
        ,m_aFrame               (this, ModuleRes(FL_SQL))
        ,m_aSQLLabel            (this, ModuleRes(FT_SQL))
        ,m_aSQL                 (this, ModuleRes(ME_SQL))
        ,m_aExecute             (this, ModuleRes(PB_EXECUTE))
        ,m_aHistoryLabel        (this, ModuleRes(FT_HISTORY))
        ,m_pSQLHistory(new LargeEntryListBox(this, ModuleRes(LB_HISTORY)))
        ,m_aStatusFrame         (this, ModuleRes(FL_STATUS))
        ,m_aStatus              (this, ModuleRes(ME_STATUS))
        ,m_aButtonSeparator     (this, ModuleRes(FL_BUTTONS))
        ,m_aHelp                (this, ModuleRes(PB_HELP))
        ,m_aClose               (this, ModuleRes(PB_CLOSE))
        ,m_nHistoryLimit(20)
        ,m_nStatusCount(1)
        ,m_xConnection(_rxConn)
    {
        DBG_CTOR(DirectSQLDialog,NULL);

        FreeResource();

        m_aSQL.GrabFocus();

        m_aExecute.SetClickHdl(LINK(this, DirectSQLDialog, OnExecute));
        m_aClose.SetClickHdl(LINK(this, DirectSQLDialog, OnClose));
        m_pSQLHistory->SetSelectHdl(LINK(this, DirectSQLDialog, OnListEntrySelected));
        m_pSQLHistory->SetDropDownLineCount(10);

        // add a dispose listener to the connection
        Reference< XComponent > xConnComp(m_xConnection, UNO_QUERY);
        OSL_ENSURE(xConnComp.is(), "DirectSQLDialog::DirectSQLDialog: invalid connection!");
        if (xConnComp.is())
            startComponentListening(xConnComp);

        m_aSQL.SetModifyHdl(LINK(this, DirectSQLDialog, OnStatementModified));
        OnStatementModified(&m_aSQL);
    }

    //--------------------------------------------------------------------
    DirectSQLDialog::~DirectSQLDialog()
    {
        {
            ::osl::MutexGuard aGuard(m_aMutex);
            stopAllComponentListening();
        }
        delete m_pSQLHistory;

        DBG_DTOR(DirectSQLDialog,NULL);
    }

    //--------------------------------------------------------------------
    void DirectSQLDialog::_disposing( const EventObject& _rSource )
    {
        ::vos::OGuard aSolarGuard(Application::GetSolarMutex());
        ::osl::MutexGuard aGuard(m_aMutex);

        OSL_ENSURE(Reference< XConnection >(_rSource.Source, UNO_QUERY).get() == m_xConnection.get(),
            "DirectSQLDialog::_disposing: where does this come from?");
        (void)_rSource;

        {
            String sMessage(ModuleRes(STR_DIRECTSQL_CONNECTIONLOST));
            ErrorBox aError(this, WB_OK, sMessage);
            aError.Execute();
        }

        PostUserEvent(LINK(this, DirectSQLDialog, OnClose));
    }

    //--------------------------------------------------------------------
    void DirectSQLDialog::addHistoryEntry(const String& _rStatement)
    {
        CHECK_INVARIANTS("DirectSQLDialog::addHistoryEntry");
        implAddToStatementHistory(_rStatement);
    }

    //--------------------------------------------------------------------
    sal_Int32 DirectSQLDialog::getHistorySize() const
    {
        CHECK_INVARIANTS("DirectSQLDialog::getHistorySize");
        return m_aStatementHistory.size();
    }

    //--------------------------------------------------------------------
    void DirectSQLDialog::implEnsureHistoryLimit()
    {
        CHECK_INVARIANTS("DirectSQLDialog::implEnsureHistoryLimit");

        if (getHistorySize() <= m_nHistoryLimit)
            // nothing to do
            return;

        sal_Int32 nRemoveEntries = getHistorySize() - m_nHistoryLimit;
        while (nRemoveEntries--)
        {
            m_aStatementHistory.pop_front();
            m_aNormalizedHistory.pop_front();
            m_pSQLHistory->RemoveEntry((USHORT)0);
        }
    }

    //--------------------------------------------------------------------
    void DirectSQLDialog::implAddToStatementHistory(const String& _rStatement)
    {
        CHECK_INVARIANTS("DirectSQLDialog::implAddToStatementHistory");

        // add the statement to the history
        m_aStatementHistory.push_back(_rStatement);

        // normalize the statement, and remember the normalized form, too
        String sNormalized(_rStatement);
        sNormalized.SearchAndReplaceAll((sal_Unicode)'\n', ' ');
        m_aNormalizedHistory.push_back(sNormalized);

        // add the normalized version to the list box
        m_pSQLHistory->InsertEntry(sNormalized);

        // ensure that we don't exceed the history limit
        implEnsureHistoryLimit();
    }

#ifdef DBG_UTIL
    //--------------------------------------------------------------------
    const sal_Char* DirectSQLDialog::impl_CheckInvariants() const
    {
        if (m_aStatementHistory.size() != m_aNormalizedHistory.size())
            return "statement history is inconsistent!";

        if (!m_pSQLHistory)
            return "invalid listbox!";

        if (m_aStatementHistory.size() != m_pSQLHistory->GetEntryCount())
            return "invalid listbox entry count!";

        if (!m_xConnection.is())
            return "have no connection!";

        return NULL;
    }
#endif

    //--------------------------------------------------------------------
    void DirectSQLDialog::implExecuteStatement(const String& _rStatement)
    {
        CHECK_INVARIANTS("DirectSQLDialog::implExecuteStatement");

        ::osl::MutexGuard aGuard(m_aMutex);

        String sStatus;
        try
        {
            // create a statement
            Reference< XStatement > xStatement = m_xConnection->createStatement();
            OSL_ENSURE(xStatement.is(), "DirectSQLDialog::implExecuteStatement: no statement returned by the connection!");

            // execute it
            if (xStatement.is())
                xStatement->execute(_rStatement);

            // successfull
            sStatus = String(ModuleRes(STR_COMMAND_EXECUTED_SUCCESSFULLY));

            // dispose the statement
            ::comphelper::disposeComponent(xStatement);
        }
        catch(const SQLException& e)
        {
            sStatus = e.Message;
        }
        catch(const Exception&)
        {
            OSL_ENSURE(sal_False, "DirectSQLDialog::implExecuteStatement: caught an (unknown) exception!");
        }

        // add the status text
        addStatusText(sStatus);
    }

    //--------------------------------------------------------------------
    void DirectSQLDialog::addStatusText(const String& _rMessage)
    {
        String sAppendMessage = String::CreateFromInt32(m_nStatusCount++);
        sAppendMessage += String::CreateFromAscii(": ");
        sAppendMessage += _rMessage;
        sAppendMessage += String::CreateFromAscii("\n\n");

        String sCompleteMessage = m_aStatus.GetText();
        sCompleteMessage += sAppendMessage;
        m_aStatus.SetText(sCompleteMessage);

        m_aStatus.SetSelection(Selection(sCompleteMessage.Len(), sCompleteMessage.Len()));
    }

    //--------------------------------------------------------------------
    void DirectSQLDialog::executeCurrent()
    {
        CHECK_INVARIANTS("DirectSQLDialog::executeCurrent");

        String sStatement = m_aSQL.GetText();

        // execute
        implExecuteStatement(sStatement);

        // add the statement to the history
        implAddToStatementHistory(sStatement);

        m_aSQL.SetSelection(Selection());
        m_aSQL.GrabFocus();
    }

    //--------------------------------------------------------------------
    void DirectSQLDialog::switchToHistory(sal_Int32 _nHistoryPos, sal_Bool _bUpdateListBox)
    {
        CHECK_INVARIANTS("DirectSQLDialog::switchToHistory");

        if ((_nHistoryPos >= 0) && (_nHistoryPos < getHistorySize()))
        {
            // set the text in the statement editor
            String sStatement = m_aStatementHistory[_nHistoryPos];
            m_aSQL.SetText(sStatement);
            OnStatementModified(&m_aSQL);

            if (_bUpdateListBox)
            {
                // selecte the normalized statement in the list box
                m_pSQLHistory->SelectEntryPos((USHORT)_nHistoryPos);
                OSL_ENSURE(m_pSQLHistory->GetSelectEntry() == m_aNormalizedHistory[_nHistoryPos],
                    "DirectSQLDialog::switchToHistory: inconsistent listbox entries!");
            }

            m_aSQL.GrabFocus();
            m_aSQL.SetSelection(Selection(sStatement.Len(), sStatement.Len()));
        }
        else
            OSL_ENSURE(sal_False, "DirectSQLDialog::switchToHistory: invalid position!");
    }

    //--------------------------------------------------------------------
    IMPL_LINK( DirectSQLDialog, OnStatementModified, void*, /*NOTINTERESTEDIN*/ )
    {
        m_aExecute.Enable(0 != m_aSQL.GetText().Len());
        return 0L;
    }

    //--------------------------------------------------------------------
    IMPL_LINK( DirectSQLDialog, OnClose, void*, /*NOTINTERESTEDIN*/ )
    {
        EndDialog( RET_OK );
        return 0L;
    }

    //--------------------------------------------------------------------
    IMPL_LINK( DirectSQLDialog, OnExecute, void*, /*NOTINTERESTEDIN*/ )
    {
        executeCurrent();
        return 0L;
    }

    //--------------------------------------------------------------------
    IMPL_LINK( DirectSQLDialog, OnListEntrySelected, void*, /*NOTINTERESTEDIN*/ )
    {
        if (!m_pSQLHistory->IsTravelSelect())
        {
            const sal_uInt16 nSelected = m_pSQLHistory->GetSelectEntryPos();
            if (LISTBOX_ENTRY_NOTFOUND != nSelected)
                switchToHistory(nSelected, sal_False);
        }
        return 0L;
    }

//........................................................................
}   // namespace dbaui
//........................................................................

<|endoftext|>


<commit_before>
#ifndef MUSTACHE_NODE_HPP
#define MUSTACHE_NODE_HPP

#include <map>
#include <memory>
#include <stack>
#include <string>
#include <vector>

namespace mustache {

class Node {
  public:
    typedef std::auto_ptr<Node> Ptr;
    typedef std::vector<Node *> Children;
    typedef std::stack<Node *> Stack;
    typedef std::map<std::string,std::string> RawPartials;
    typedef std::map<std::string,Node::Ptr> Partials;
    typedef std::pair<std::string,Node::Ptr> PartialPair;
    enum Type {
      TypeNone = 0,
      TypeRoot = 1,
      TypeOutput = 2,
      TypeTag = 3
    };
    enum Flag {
      FlagNone = 0,
      FlagEscape = 1,
      FlagNegate = 2,
      FlagSection = 4,
      FlagStop = 8,
      FlagComment = 16,
      FlagPartial = 32,
      FlagInlinePartial = 64,

      FlagHasChildren = Node::FlagNegate | Node::FlagSection | Node::FlagPartial
    };

    Node::Type type;
    int flags;
    std::string * data;
    Node::Children children;

    ~Node();
};

} // namespace Mustache

#endif

<commit_msg>Working on partial support<commit_after>
#ifndef MUSTACHE_NODE_HPP
#define MUSTACHE_NODE_HPP

#include <map>
#include <memory>
#include <stack>
#include <string>
#include <vector>

namespace mustache {

class Node {
  public:
    typedef std::auto_ptr<Node> Ptr;
    typedef std::vector<Node *> Children;
    typedef std::stack<Node *> Stack;
    typedef std::map<std::string,std::string> RawPartials;
    typedef std::map<std::string,Node> Partials;
    typedef std::pair<std::string,Node> PartialPair;
    enum Type {
      TypeNone = 0,
      TypeRoot = 1,
      TypeOutput = 2,
      TypeTag = 3
    };
    enum Flag {
      FlagNone = 0,
      FlagEscape = 1,
      FlagNegate = 2,
      FlagSection = 4,
      FlagStop = 8,
      FlagComment = 16,
      FlagPartial = 32,
      FlagInlinePartial = 64,

      FlagHasChildren = Node::FlagNegate | Node::FlagSection | Node::FlagPartial
    };

    Node::Type type;
    int flags;
    std::string * data;
    Node::Children children;

    ~Node();
};

} // namespace Mustache

#endif

<|endoftext|>