<commit_before>#define GLM_FORCE_RADIANS
#define PI 3.14159265358979
#include <GL/glew.h>
#include <glfw3.h>
#include <glm/glm.hpp>
#include <iostream>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

#include "gfx/Renderer.hpp"
#include "gfx/VertexArray.hpp"
#include "gfx/SkyBox.hpp"
#include "gfx/importer/ObjLoader.hpp"
#include "gfx/lights/Light.hpp"
#include "gfx/lights/PointLight.hpp"
#include "gfx/lights/DirLight.hpp"
#include "gfx/shader/SimpleShader.hpp"

#include "input/Actions.hpp"
#include "input/Input.hpp"
#include "DebugUtils.h"

glm::vec3 get_random_color() {
  auto r = ((rand() % 100)/100.0);
  auto g = ((rand() % 100)/100.0);
  auto b = ((rand() % 100)/100.0);
  return glm::normalize(glm::vec3{r, g, b});
}

std::vector<std::pair<glm::vec3, glm::vec3>> rain;
void draw_rain(Renderer* r) {
  static float speed = 0.5;
  //if((rand() % 100)/100.0 < 0.5) {
  //for(int i = 0; i < 5; i++) {
  {
    auto x = ((rand() % 100)/100.0) * 10.0f;
    auto y = 20;
    auto z = ((rand() % 100)/100.0) * 10.0f;
    glm::vec3 from = glm::vec3(x,y,z);
    glm::vec3 to = from + glm::vec3{5, -16, 5};
    rain.push_back(std::make_pair(from, to));
  }
  std::vector<std::pair<glm::vec3, glm::vec3>> new_rain;
  for(auto& rain_pos: rain) {
    auto& from = std::get<0>(rain_pos);
    auto& to = std::get<1>(rain_pos);
    auto dir = glm::normalize(to - from);
    from += dir * speed;
    to += dir * speed;
    if(from.y > 0) {
      new_rain.push_back(rain_pos);
    }
  }
  r->draw_lines(rain, {0.1, 0.1, 0.1});
  rain = new_rain;
}

static void error_callback(int error, const char* description)
{
  fputs(description, stderr);
}

float step = 0.01f;
int selected_light = -1;

static void scroll_callback(GLFWwindow* window, double x_offset, double y_offset) {
  step = fmax(0.01f, fmin(step * pow(1.5, y_offset), 5));
}

void rotate_camera(Camera& camera) {
  camera.rotate(-Input::get_mouse_dx() / 100.0f, camera.up);
  camera.rotate(-Input::get_mouse_dy() / 100.0f, glm::cross(camera.up, camera.dir));
}

const int width = 1024;
const int height = 768;
int main(int argc, char ** argv) {
  glfwSetErrorCallback(error_callback);
  if (!glfwInit())
    exit(EXIT_FAILURE);

  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
  glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
  GLFWwindow* window = glfwCreateWindow(width, height, "glHondo", NULL, NULL);
  if (!window) {
    glfwTerminate();
    exit(EXIT_FAILURE);
  }
  glfwMakeContextCurrent(window);

  glewExperimental = GL_TRUE;
  GLenum err = glewInit();
  //To discard error 1280 from glewInit().
  glGetError();
  if(GLEW_OK != err)
    std::cout << glewGetErrorString(err) << std::endl;

  {
    const GLubyte* renderer = glGetString(GL_RENDERER);
    const GLubyte* version = glGetString(GL_VERSION);
    printf("Renderer: %s\n", renderer);
    printf("Version: %s\n", version);
    glfwSetCursorPosCallback(window, Input::cursor_pos_callback);
    glfwSetKeyCallback(window, Input::key_callback);
    glfwSetScrollCallback(window, scroll_callback);
    Input::set_active_window(window);
  }
  Renderer renderer(width, height);

  auto& camera = renderer.get_camera();

  Input::on(Actions::Forward, [&]() {
    camera.move_forward(step);
  });

  Input::on(Actions::Backward, [&]() {
    camera.move_forward(-step);
  });

  Input::on(Actions::Left, [&]() {
    camera.move_right(-step);
  });

  Input::on(Actions::Right, [&]() {
    camera.move_right(step);
  });

  Input::on(Actions::Up, [&]() {
    camera.translate({0, step, 0});
  });

  Input::on(Actions::Down, [&]() {
    camera.translate({0, -step, 0});
  });

  Input::on(GLFW_KEY_Z, [&] {
  renderer.toggle_wireframe();
  });

  Input::on(GLFW_KEY_G, []() {
    Input::lock_mouse();
  });
  ObjLoader loader;
  //loader.preload_file("assets/sponza.obj");
  loader.preload_file("assets/Cube.obj");
  loader.preload_file("assets/Floor.obj");
  loader.preload_file("assets/SkyDome16.obj");
  std::cout << "Load files\n";
  loader.load_files();
  std::cout << "Loading files done\n";
  Mesh skydome_mesh = loader.get_meshes("assets/SkyDome16.obj")[0];
  Mesh cube_mesh = loader.get_meshes("assets/Cube.obj")[0];
  Mesh floor_mesh = loader.get_meshes("assets/Floor.obj")[0];
  //std::vector<Mesh> sponza_meshes = loader.get_meshes("assets/sponza.obj");

  auto pl2 = std::make_shared<DirLight>(glm::vec3{-0, -1, -0}, glm::vec3{1, 1, 1});
  pl2->ambient_intensity = 0.2f;
  pl2->set_casts_shadow(true);
  pl2->diffuse_intensity = 0.0f;
  renderer.add_light(pl2);

  auto cube = std::make_shared<RenderObject>(cube_mesh);
  renderer.add_object(cube);

  /*
  for(auto& sponza_mesh: sponza_meshes) {
    auto mesh = std::make_shared<RenderObject>(sponza_mesh);
    mesh->scale({0.01, 0.01, 0.01});
    renderer.add_object(mesh);
  }
  */

  for(int i = -5; i < 5; i++) {
    for(int j = -5; j < 5; j++) {
      auto floor = std::make_shared<RenderObject>(floor_mesh);
      floor->translate({i * 2,-1,j * 2});
      renderer.add_object(floor);
    }
  }

  std::shared_ptr<SkyBox> sky = std::make_shared<SkyBox>(camera, skydome_mesh);
  sky->scale({2,2,2});
  renderer.set_skybox(sky);

  Input::on(GLFW_KEY_I, [&] {
    renderer.get_shown_light()->translate({ 0.01f, 0, 0});
  }, true);
  Input::on(GLFW_KEY_K, [&] {
    renderer.get_shown_light()->translate({-0.01f, 0, 0});
  }, true);
  Input::on(GLFW_KEY_J, [&] {
    renderer.get_shown_light()->translate({0, 0,  0.01f});
  }, true);
  Input::on(GLFW_KEY_L, [&] {
    renderer.get_shown_light()->translate({0, 0, -0.01f});
  }, true);
  Input::on(GLFW_KEY_O, [&] {
    renderer.get_shown_light()->translate({0,  0.01f, 0});
  }, true);

  Input::on(GLFW_KEY_U, [&] {
    renderer.get_shown_light()->translate({0,-0.01f, 0});
  }, true);

  Input::on(GLFW_KEY_PAGE_UP, [&] {
    if(selected_light < renderer.light_count()) {
      renderer.show_single_light(++selected_light);
    }
  }, false);
  Input::on(GLFW_KEY_PAGE_DOWN, [&] {
    if(selected_light > 0) {
      renderer.show_single_light(--selected_light);
    }
  }, false);
  Input::on(GLFW_KEY_1, [&] {
      renderer.toggle_shadow_map();
  }, false);
  Input::on(GLFW_KEY_P, [&] {
      auto light = std::make_shared<SpotLight>(camera.pos, -camera.dir, glm::vec3{1,1,1});
      light->ambient_intensity = 0.0f;
      light->diffuse_intensity = 2.0f;
      light->set_casts_shadow(true);
      renderer.add_light(light);
      std::cout << "Amount of lights: " << renderer.light_count() << "\n";
  }, false);
  Input::on(GLFW_KEY_RIGHT_CONTROL, [&] {
      renderer.show_single_light(-1);
  }, false);
  bool draw_main = true;
  Input::on(GLFW_KEY_T, [&] {
      draw_main = !draw_main;
  }, false);

  float i = 0;
  camera.translate({0, 2, 0});
  while (!glfwWindowShouldClose(window)) {
    glfwPollEvents();
    Input::handle_input();
    rotate_camera(camera);
    renderer.pre_render();

    if(draw_main) {
      renderer.render();
    }
    draw_rain(&renderer);

    glfwSwapBuffers(window);

    Input::reset_delta();
    if(i > 360) {
      i=0;
    }
    i += 0.1f;

    calcFPS(window, 1.0, "Current FPS: ");
    checkForGlError();
  }
  glfwDestroyWindow(window);
  glfwTerminate();
  return 0;
}

<commit_msg>Fixes<commit_after>#define GLM_FORCE_RADIANS
#define PI 3.14159265358979
#include <GL/glew.h>
#include <glfw3.h>
#include <glm/glm.hpp>
#include <iostream>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

#include "gfx/Renderer.hpp"
#include "gfx/VertexArray.hpp"
#include "gfx/SkyBox.hpp"
#include "gfx/importer/ObjLoader.hpp"
#include "gfx/lights/Light.hpp"
#include "gfx/lights/PointLight.hpp"
#include "gfx/lights/DirLight.hpp"
#include "gfx/shader/SimpleShader.hpp"

#include "input/Actions.hpp"
#include "input/Input.hpp"
#include "DebugUtils.h"

glm::vec3 get_random_color() {
  auto r = ((rand() % 100)/100.0);
  auto g = ((rand() % 100)/100.0);
  auto b = ((rand() % 100)/100.0);
  return glm::normalize(glm::vec3{r, g, b});
}

std::vector<std::pair<glm::vec3, glm::vec3>> rain;
void draw_rain(Renderer* r) {
  static float speed = 0.5;
  //if((rand() % 100)/100.0 < 0.5) {
  //for(int i = 0; i < 5; i++) {
  {
    auto x = ((rand() % 100)/100.0) * 10.0f;
    auto y = 20;
    auto z = ((rand() % 100)/100.0) * 10.0f;
    glm::vec3 from = glm::vec3(x,y,z);
    glm::vec3 to = from + glm::vec3{5, -16, 5};
    rain.push_back(std::make_pair(from, to));
  }
  std::vector<std::pair<glm::vec3, glm::vec3>> new_rain;
  for(auto& rain_pos: rain) {
    auto& from = std::get<0>(rain_pos);
    auto& to = std::get<1>(rain_pos);
    auto dir = glm::normalize(to - from);
    from += dir * speed;
    to += dir * speed;
    if(from.y > 0) {
      new_rain.push_back(rain_pos);
    }
  }
  r->draw_lines(rain, {0.1, 0.1, 0.1});
  rain = new_rain;
}

static void error_callback(int error, const char* description)
{
  fputs(description, stderr);
}

float step = 0.01f;
int selected_light = -1;

static void scroll_callback(GLFWwindow* window, double x_offset, double y_offset) {
  step = fmax(0.01f, fmin(step * pow(1.5, y_offset), 5));
}

void rotate_camera(Camera& camera) {
  camera.rotate(-Input::get_mouse_dx() / 100.0f, camera.up);
  camera.rotate(Input::get_mouse_dy() / 100.0f, glm::cross(camera.up, camera.dir));
}

const int width = 1024;
const int height = 768;
int main(int argc, char ** argv) {
  glfwSetErrorCallback(error_callback);
  if (!glfwInit())
    exit(EXIT_FAILURE);

  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
  glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
  GLFWwindow* window = glfwCreateWindow(width, height, "glHondo", NULL, NULL);
  if (!window) {
    glfwTerminate();
    exit(EXIT_FAILURE);
  }
  glfwMakeContextCurrent(window);

  glewExperimental = GL_TRUE;
  GLenum err = glewInit();
  //To discard error 1280 from glewInit().
  glGetError();
  if(GLEW_OK != err)
    std::cout << glewGetErrorString(err) << std::endl;

  {
    const GLubyte* renderer = glGetString(GL_RENDERER);
    const GLubyte* version = glGetString(GL_VERSION);
    printf("Renderer: %s\n", renderer);
    printf("Version: %s\n", version);
    glfwSetCursorPosCallback(window, Input::cursor_pos_callback);
    glfwSetKeyCallback(window, Input::key_callback);
    glfwSetScrollCallback(window, scroll_callback);
    Input::set_active_window(window);
  }
  Renderer renderer(width, height);

  auto& camera = renderer.get_camera();

  Input::on(Actions::Forward, [&]() {
    camera.move_forward(step);
  });

  Input::on(Actions::Backward, [&]() {
    camera.move_forward(-step);
  });

  Input::on(Actions::Left, [&]() {
    camera.move_right(-step);
  });

  Input::on(Actions::Right, [&]() {
    camera.move_right(step);
  });

  Input::on(Actions::Up, [&]() {
    camera.translate({0, step, 0});
  });

  Input::on(Actions::Down, [&]() {
    camera.translate({0, -step, 0});
  });

  Input::on(GLFW_KEY_Z, [&] {
  renderer.toggle_wireframe();
  });

  Input::on(GLFW_KEY_G, []() {
    Input::lock_mouse();
  });
  ObjLoader loader;
  //loader.preload_file("assets/sponza.obj");
  loader.preload_file("assets/Cube.obj");
  loader.preload_file("assets/Floor.obj");
  loader.preload_file("assets/sphere.obj");
  loader.preload_file("assets/SkyDome16.obj");
  std::cout << "Load files\n";
  loader.load_files();
  std::cout << "Loading files done\n";
  Mesh skydome_mesh = loader.get_meshes("assets/SkyDome16.obj")[0];
  Mesh cube_mesh = loader.get_meshes("assets/Cube.obj")[0];
  Mesh sphere_mesh = loader.get_meshes("assets/sphere.obj")[0];
  Mesh floor_mesh = loader.get_meshes("assets/Floor.obj")[0];
  //std::vector<Mesh> sponza_meshes = loader.get_meshes("assets/sponza.obj");

  auto pl2 = std::make_shared<DirLight>(glm::vec3{-0, -1, -0}, glm::vec3{1, 1, 1});
  pl2->ambient_intensity = 0.2f;
  pl2->set_casts_shadow(true);
  pl2->diffuse_intensity = 0.0f;
  renderer.add_light(pl2);

  auto sphere = std::make_shared<RenderObject>(sphere_mesh);
  sphere->translate({0, 1, 2});
  sphere->scale({0.5, 0.5, 0.5});
  renderer.add_object(sphere);
  auto cube = std::make_shared<RenderObject>(cube_mesh);
  renderer.add_object(cube);

  /*
  for(auto& sponza_mesh: sponza_meshes) {
    auto mesh = std::make_shared<RenderObject>(sponza_mesh);
    mesh->scale({0.01, 0.01, 0.01});
    renderer.add_object(mesh);
  }
  */

  for(int i = -5; i < 5; i++) {
    for(int j = -5; j < 5; j++) {
      auto floor = std::make_shared<RenderObject>(floor_mesh);
      floor->translate({i * 2,-1,j * 2});
      renderer.add_object(floor);
    }
  }

  std::shared_ptr<SkyBox> sky = std::make_shared<SkyBox>(camera, skydome_mesh);
  sky->scale({2,2,2});
  renderer.set_skybox(sky);

  Input::on(GLFW_KEY_I, [&] {
    renderer.get_shown_light()->translate({ 0.01f, 0, 0});
  }, true);
  Input::on(GLFW_KEY_K, [&] {
    renderer.get_shown_light()->translate({-0.01f, 0, 0});
  }, true);
  Input::on(GLFW_KEY_J, [&] {
    renderer.get_shown_light()->translate({0, 0,  0.01f});
  }, true);
  Input::on(GLFW_KEY_L, [&] {
    renderer.get_shown_light()->translate({0, 0, -0.01f});
  }, true);
  Input::on(GLFW_KEY_O, [&] {
    renderer.get_shown_light()->translate({0,  0.01f, 0});
  }, true);
  Input::on(GLFW_KEY_U, [&] {
    renderer.get_shown_light()->translate({0, -0.01f, 0});
  }, true);

  Input::on(GLFW_KEY_PAGE_UP, [&] {
    if(selected_light < renderer.light_count()) {
      renderer.show_single_light(++selected_light);
    }
  }, false);

  Input::on(GLFW_KEY_DELETE, [&] {
    renderer.clear_lights();
  }, false);
  Input::on(GLFW_KEY_PAGE_DOWN, [&] {
    if(selected_light > 0) {
      renderer.show_single_light(--selected_light);
    }
  }, false);
  Input::on(GLFW_KEY_1, [&] {
      renderer.toggle_shadow_map();
  }, false);
  Input::on(GLFW_KEY_P, [&] {
      auto light = std::make_shared<SpotLight>(camera.pos, camera.dir, glm::vec3{1,1,1});
      light->ambient_intensity = 0.0f;
      light->diffuse_intensity = 2.0f;
      light->set_casts_shadow(true);
      renderer.add_light(light);
      std::cout << "Amount of lights: " << renderer.light_count() << "\n";
  }, false);
  Input::on(GLFW_KEY_RIGHT_CONTROL, [&] {
      renderer.show_single_light(-1);
  }, false);
  bool draw_main = true;
  Input::on(GLFW_KEY_T, [&] {
      draw_main = !draw_main;
  }, false);

  float i = 0;
  camera.translate({0, 2, 0});
  while (!glfwWindowShouldClose(window)) {
    glfwPollEvents();
    Input::handle_input();
    rotate_camera(camera);
    renderer.pre_render();

    if(draw_main) {
      renderer.render();
    }
    draw_rain(&renderer);

    glfwSwapBuffers(window);

    Input::reset_delta();
    if(i > 360) {
      i=0;
    }
    i += 0.1f;

    calcFPS(window, 1.0, "Current FPS: ");
    checkForGlError();
  }
  glfwDestroyWindow(window);
  glfwTerminate();
  return 0;
}

<|endoftext|>


<commit_before>#include "Video/ScreenBuffer.hh"
#include "SDLConfig.hh"

namespace RAGE
{
	namespace SDL
	{

		ScreenBuffer::ScreenBuffer(int width, int height, int bpp) throw (std::logic_error)
		: m_width(width), m_height(height),m_bpp(bpp), m_background(RGBColor(0,0,0)),
		m_initcb(NULL),m_resizecb(NULL), m_newframecb(NULL), m_rendercb(NULL)
		{

            //setting the static videoInfo to be used by all surfaces...
            BaseSurface::_vinfo = &m_videoinfo;

			//force usage of DEFAULT_DISPLAY_WIDTH & DEFAULT_DISPLAY_HEIGHT when only one param is equal to 0.
			if ((width == 0 && height != 0) || (width != 0 && height == 0))
			{
				width = DEFAULT_DISPLAY_WIDTH;
				height = DEFAULT_DISPLAY_HEIGHT;
			}
			//TODO get rid of default display size and try 4/3 size, or pick first of suggested size by video info

			//Both equal to 0 means use dekstop/current mode.
			if (width == 0 && height == 0)
			{
				width = VideoSurface::getVideoInfo()->get_current_width();
				height = VideoSurface::getVideoInfo()->get_current_height();
			}

			if ( bpp == 0 ) //here 0 means autodetection
			{
				bpp=VideoSurface::getSuggestedBPP(width, height);
			}
			else
			{
				//TODO : check that the value of bpp asked for is supported...
			}

			m_width = width;
			m_height = height;
			m_bpp = bpp;

	        //but beware about bpp == 0...
        	if (m_bpp == 0 )
			{//0 as return code mean the current format is not supported
	        	Log << nl << "The requested video mode is not supported under any bit depth. Screen creation cancelled !";
				throw std::logic_error("VideoSurface::getSuggestedBPP(width, height) returned 0");
        	}
		}

        //recreating Engine here to make sure both origin and destination engines are independant.
        //maybe not really needed, but safer in case of copy ( or should we completely forbid copy ? )
		ScreenBuffer::ScreenBuffer( const ScreenBuffer & sb )
		: m_width(sb.m_width), m_height(sb.m_height),m_bpp(sb.m_bpp), m_background(sb.m_background),
		m_initcb(sb.m_initcb),m_resizecb(sb.m_resizecb), m_newframecb(sb.m_newframecb), m_rendercb(sb.m_rendercb)
		{
		    //warning no protection offered here in case of wrong / unsupported size ( for the moment )
		}

		ScreenBuffer::~ScreenBuffer()
		{
            BaseSurface::_vinfo = NULL;
		}

	    bool ScreenBuffer::setResizable(bool val)
	    {
	    	bool res = true;
	    	if (!m_screen.get()) //if not already created, set the static flag.
	    	    VideoSurface::setResizable(val);
	    	else if (m_screen->isResizableset() !=val ) //if called inside mainLoop while screen is active
	    	{
				hide();
				VideoSurface::setResizable(val); //set static flag
				if (! show()) //reset the screen
				res=false;
			}
			return res;
		}

		bool ScreenBuffer::setFullscreen(bool val)
		{
#ifdef DEBUG
			Log << nl << "Window::setFullscreen(" << val << ") called" << std::endl;
#endif

            bool res = true;
            if (!m_screen.get())
	    	{
                VideoSurface::setFullscreen(val);
	    	}
            else
            {
#ifdef DEBUG
                Log << nl << m_screen->isFullScreenset() << " != " << val << std::endl;
#endif
		        if (m_screen->isFullScreenset() != val ) //if called inside mainLoop while screen is active
                {
					hide();
					VideoSurface::setFullscreen(val);
					if (! show() )//resetDisplay(m_screen->getWidth(),m_screen->getHeight(),m_screen->getBPP()))
					{
						res=false;
					}
                }
            }

#ifdef DEBUG
            Log << nl << "Window::setFullscreen(" << val << ") done" << std::endl;
#endif
            return res;
        }

        bool ScreenBuffer::setNoFrame(bool val)
        {
            bool res = true;
            if (!m_screen.get())
                VideoSurface::setNoFrame(val);
            else if (m_screen->isNoFrameset() !=val )  //if called inside mainLoop while screen is active
            {
				hide();
				VideoSurface::setNoFrame(val);
                if (! show() ) //resetDisplay(m_screen->getWidth(),m_screen->getHeight(),m_screen->getBPP()))
                    res=false;
            }
            return res;
        }

#ifdef HAVE_OPENGL
        bool ScreenBuffer::setOpenGL(bool val)
        {
            bool res = true;

            if (!m_screen.get())
			{
				VideoSurface::setOpenGL(val);
			}
            else if ( m_screen->isOpenGLset() !=val ) //if called inside mainLoop while screen is active
            {
				hide();
                VideoSurface::setOpenGL(val);
                if (! show() )//resetDisplay(m_screen->getWidth(),m_screen->getHeight(),m_screen->getBPP()))
                    res=false;
            }
            return res;
        }
#endif

	//to check the current properties of the display
	bool ScreenBuffer::isFullscreen()
	{
		if (m_screen.get())
		{
			return m_screen->isFullScreenset();
		}
		else
		{
			return ( SDL_FULLSCREEN & VideoSurface::_defaultflags ) != 0;
		}
	}
	bool ScreenBuffer::isResizable()
	{
		if (m_screen.get())
		{
			return m_screen->isResizableset();
		}
		else
		{
			return ( SDL_RESIZABLE & VideoSurface::_defaultflags ) != 0;
		}
	}
	bool ScreenBuffer::isOpenGL()
	{
		if (m_screen.get())
		{
			return m_screen->isOpenGLset();
		}
		else
		{
			return ( SDL_OPENGL & VideoSurface::_defaultflags ) != 0;
		}
	}
	bool ScreenBuffer::isNoFrame()
	{

		if (m_screen.get())
		{
			return m_screen->isNoFrameset();
		}
		else
		{
			return ( SDL_NOFRAME & VideoSurface::_defaultflags ) != 0;
		}
	}

	void ScreenBuffer::applyBGColor() const
    {
    	if (m_screen.get()) // if auto pointer valid
		{
#ifdef HAVE_OPENGL
			if (m_screen->isOpenGLset())
			{
				glClearColor(static_cast<float> (m_background.getR() ) / 255.0f, static_cast<float> (m_background.getG() ) / 255.0f,static_cast<float> (m_background.getB() ) / 255.0f,0.0f);
				glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
			}
			else
			{
#endif
				//TODO background can be null, andthis will not be called.... ( speed improvemnt )
				m_screen->fill(m_background);
#ifdef HAVE_OPENGL
			}
#endif
		}
	}

	bool ScreenBuffer::show()
    {
#ifdef DEBUG
		Log << nl << "SceenBuffer::show() called ..." << std::endl;
#endif
		if ( m_screen.get() != NULL ) // no need to reset the display
		{			//if reset is wanted the buffer shoul be recreated
			return true;
		}
		//else the screen hasnt been displayed yet, or has been hidden.
		bool res = false;

       	Log << nl <<"SDL is using " << m_width << "x" << m_height << "@" <<m_bpp;
       	//create a new screen
        try
        {
			if ( isOpenGL() )
			{
				m_screen.reset(new VideoGLSurface(m_width, m_height, m_bpp));
			}
			else
			{
				m_screen.reset(new VideoSurface(m_width, m_height, m_bpp));
			}
			//initializing engine
			m_engine.init(m_width, m_height);

			//calling user init callback if it exists
			if ( m_initcb ) m_initcb->call( m_width, m_height );

			applyBGColor();
			res=true;
        }
        catch(std::exception & e)
        {
            Log << nl << " Exception caught in Window::resetDisplay() : " << e.what();
		    res=false;
        }
#ifdef DEBUG
	    Log << nl << "ScreenBuffer::show() done." << std::endl;
#endif
	    return res;
	}

	bool ScreenBuffer::hide()
	{
		delete m_screen.release();// to test...
	}

	bool ScreenBuffer::resize (int width, int height)
    {

#ifdef DEBUG
    	Log << nl << "Screen::resize() called ...";
#endif

		bool res = true;

    	if (m_screen.get())
        {
    		res = res && m_screen->resize(width,height);//doesnt keep content

    		//calling our engine resize method
			res = res && m_engine.resize(width,height);

			//calling user callback for resize if it exists
			if ( m_resizecb ) m_resizecb->call(width, height);
			//this order otherwise we lose opengl context from the engine just after the resize ( reinit )
			//because screen resize recreates the window, and lose opengl context as documented in SDL docs...
			applyBGColor();
		}
		else
		{
			if (width>0) { m_width = width; }
			if (height>0) { m_height= height; }
		}
#ifdef DEBUG
		Log << nl << "ScreenBuffer::resize() done.";
#endif

		//Forcing the refresh (display the backcolor)
		m_screen->refresh();

        return res;
	}

		bool ScreenBuffer::renderpass( unsigned long framerate, unsigned long& lastframe)
		{
		    //Callback for preparing new frame
		    if ( m_newframecb ) m_newframecb->call( framerate, SDL_GetTicks() - lastframe );

			//applying the background
					//if (!ShowingLoadingScreen)
						applyBGColor();

					//if (!ShowingLoadingScreen)
                		if ( m_rendercb ) m_rendercb->call( *m_screen );

                		//calling our engine render function ( on top of user render )
                		//TODO : add a timer if not demo release...
                		m_engine.render(*m_screen);

					//refresh screen
					//Log << nl << "before :" << SDL_GetTicks() - lastframe ;
					if ( SDL_GetTicks() - lastframe < 1000/framerate)//wait if needed - IMPORTANT otherwise the next value is far too high (not 0)
						SDL_Delay( 1000/framerate - ( SDL_GetTicks() - lastframe ) );

					m_screen->refresh();
					//Log << nl << "after :" << SDL_GetTicks() - lastframe ;

					lastframe=SDL_GetTicks();

					//calling engine for postrender events
					//m_engine ->postrender();

		}

	} // SDL
} // RAGE
<commit_msg>stupid gcc mistakes removed^^<commit_after>#include "Video/ScreenBuffer.hh"
#include "SDLConfig.hh"

namespace RAGE
{
	namespace SDL
	{

		ScreenBuffer::ScreenBuffer(int width, int height, int bpp) throw (std::logic_error)
		: m_width(width), m_height(height),m_bpp(bpp), m_background(RGBColor(0,0,0)),
		m_initcb(NULL),m_resizecb(NULL), m_newframecb(NULL), m_rendercb(NULL)
		{

            //setting the static videoInfo to be used by all surfaces...
            BaseSurface::_vinfo = &m_videoinfo;

			//force usage of DEFAULT_DISPLAY_WIDTH & DEFAULT_DISPLAY_HEIGHT when only one param is equal to 0.
			if ((width == 0 && height != 0) || (width != 0 && height == 0))
			{
				width = DEFAULT_DISPLAY_WIDTH;
				height = DEFAULT_DISPLAY_HEIGHT;
			}
			//TODO get rid of default display size and try 4/3 size, or pick first of suggested size by video info

			//Both equal to 0 means use dekstop/current mode.
			if (width == 0 && height == 0)
			{
				width = VideoSurface::getVideoInfo()->get_current_width();
				height = VideoSurface::getVideoInfo()->get_current_height();
			}

			if ( bpp == 0 ) //here 0 means autodetection
			{
				bpp=VideoSurface::getSuggestedBPP(width, height);
			}
			else
			{
				//TODO : check that the value of bpp asked for is supported...
			}

			m_width = width;
			m_height = height;
			m_bpp = bpp;

	        //but beware about bpp == 0...
        	if (m_bpp == 0 )
			{//0 as return code mean the current format is not supported
	        	Log << nl << "The requested video mode is not supported under any bit depth. Screen creation cancelled !";
				throw std::logic_error("VideoSurface::getSuggestedBPP(width, height) returned 0");
        	}
		}

        //recreating Engine here to make sure both origin and destination engines are independant.
        //maybe not really needed, but safer in case of copy ( or should we completely forbid copy ? )
		ScreenBuffer::ScreenBuffer( const ScreenBuffer & sb )
		: m_width(sb.m_width), m_height(sb.m_height),m_bpp(sb.m_bpp), m_background(sb.m_background),
		m_initcb(sb.m_initcb),m_resizecb(sb.m_resizecb), m_newframecb(sb.m_newframecb), m_rendercb(sb.m_rendercb)
		{
		    //warning no protection offered here in case of wrong / unsupported size ( for the moment )
		}

		ScreenBuffer::~ScreenBuffer()
		{
            BaseSurface::_vinfo = NULL;
		}

	    bool ScreenBuffer::setResizable(bool val)
	    {
	    	bool res = true;
	    	if (!m_screen.get()) //if not already created, set the static flag.
	    	    VideoSurface::setResizable(val);
	    	else if (m_screen->isResizableset() !=val ) //if called inside mainLoop while screen is active
	    	{
				hide();
				VideoSurface::setResizable(val); //set static flag
				if (! show()) //reset the screen
				res=false;
			}
			return res;
		}

		bool ScreenBuffer::setFullscreen(bool val)
		{
#ifdef DEBUG
			Log << nl << "Window::setFullscreen(" << val << ") called" << std::endl;
#endif

            bool res = true;
            if (!m_screen.get())
	    	{
                VideoSurface::setFullscreen(val);
	    	}
            else
            {
#ifdef DEBUG
                Log << nl << m_screen->isFullScreenset() << " != " << val << std::endl;
#endif
		        if (m_screen->isFullScreenset() != val ) //if called inside mainLoop while screen is active
                {
					hide();
					VideoSurface::setFullscreen(val);
					if (! show() )//resetDisplay(m_screen->getWidth(),m_screen->getHeight(),m_screen->getBPP()))
					{
						res=false;
					}
                }
            }

#ifdef DEBUG
            Log << nl << "Window::setFullscreen(" << val << ") done" << std::endl;
#endif
            return res;
        }

        bool ScreenBuffer::setNoFrame(bool val)
        {
            bool res = true;
            if (!m_screen.get())
                VideoSurface::setNoFrame(val);
            else if (m_screen->isNoFrameset() !=val )  //if called inside mainLoop while screen is active
            {
				hide();
				VideoSurface::setNoFrame(val);
                if (! show() ) //resetDisplay(m_screen->getWidth(),m_screen->getHeight(),m_screen->getBPP()))
                    res=false;
            }
            return res;
        }

#ifdef HAVE_OPENGL
        bool ScreenBuffer::setOpenGL(bool val)
        {
            bool res = true;

            if (!m_screen.get())
			{
				VideoSurface::setOpenGL(val);
			}
            else if ( m_screen->isOpenGLset() !=val ) //if called inside mainLoop while screen is active
            {
				hide();
                VideoSurface::setOpenGL(val);
                if (! show() )//resetDisplay(m_screen->getWidth(),m_screen->getHeight(),m_screen->getBPP()))
                    res=false;
            }
            return res;
        }
#endif

	//to check the current properties of the display
	bool ScreenBuffer::isFullscreen()
	{
		if (m_screen.get())
		{
			return m_screen->isFullScreenset();
		}
		else
		{
			return ( SDL_FULLSCREEN & VideoSurface::_defaultflags ) != 0;
		}
	}
	bool ScreenBuffer::isResizable()
	{
		if (m_screen.get())
		{
			return m_screen->isResizableset();
		}
		else
		{
			return ( SDL_RESIZABLE & VideoSurface::_defaultflags ) != 0;
		}
	}
	bool ScreenBuffer::isOpenGL()
	{
		if (m_screen.get())
		{
			return m_screen->isOpenGLset();
		}
		else
		{
			return ( SDL_OPENGL & VideoSurface::_defaultflags ) != 0;
		}
	}
	bool ScreenBuffer::isNoFrame()
	{

		if (m_screen.get())
		{
			return m_screen->isNoFrameset();
		}
		else
		{
			return ( SDL_NOFRAME & VideoSurface::_defaultflags ) != 0;
		}
	}

	void ScreenBuffer::applyBGColor() const
    {
    	if (m_screen.get()) // if auto pointer valid
		{
#ifdef HAVE_OPENGL
			if (m_screen->isOpenGLset())
			{
				glClearColor(static_cast<float> (m_background.getR() ) / 255.0f, static_cast<float> (m_background.getG() ) / 255.0f,static_cast<float> (m_background.getB() ) / 255.0f,0.0f);
				glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
			}
			else
			{
#endif
				//TODO background can be null, andthis will not be called.... ( speed improvemnt )
				m_screen->fill(m_background);
#ifdef HAVE_OPENGL
			}
#endif
		}
	}

	bool ScreenBuffer::show()
    {
#ifdef DEBUG
		Log << nl << "SceenBuffer::show() called ..." << std::endl;
#endif
		if ( m_screen.get() != NULL ) // no need to reset the display
		{			//if reset is wanted the buffer shoul be recreated
			return true;
		}
		//else the screen hasnt been displayed yet, or has been hidden.
		bool res = false;

       	Log << nl <<"SDL is using " << m_width << "x" << m_height << "@" <<m_bpp;
       	//create a new screen
        try
        {
			if ( isOpenGL() )
			{
				m_screen.reset(new VideoGLSurface(m_width, m_height, m_bpp));
			}
			else
			{
				m_screen.reset(new VideoSurface(m_width, m_height, m_bpp));
			}
			//initializing engine
			m_engine.init(m_width, m_height);

			//calling user init callback if it exists
			if ( m_initcb ) m_initcb->call( m_width, m_height );

			applyBGColor();
			res=true;
        }
        catch(std::exception & e)
        {
            Log << nl << " Exception caught in Window::resetDisplay() : " << e.what();
		    res=false;
        }
#ifdef DEBUG
	    Log << nl << "ScreenBuffer::show() done." << std::endl;
#endif
	    return res;
	}

	bool ScreenBuffer::hide()
	{
		delete m_screen.release();// to test...
		return true; //not used for now
	}

	bool ScreenBuffer::resize (int width, int height)
    {

#ifdef DEBUG
    	Log << nl << "Screen::resize() called ...";
#endif

		bool res = true;

    	if (m_screen.get())
        {
    		res = res && m_screen->resize(width,height);//doesnt keep content

    		//calling our engine resize method
			res = res && m_engine.resize(width,height);

			//calling user callback for resize if it exists
			if ( m_resizecb ) m_resizecb->call(width, height);
			//this order otherwise we lose opengl context from the engine just after the resize ( reinit )
			//because screen resize recreates the window, and lose opengl context as documented in SDL docs...
			applyBGColor();
		}
		else
		{
			if (width>0) { m_width = width; }
			if (height>0) { m_height= height; }
		}
#ifdef DEBUG
		Log << nl << "ScreenBuffer::resize() done.";
#endif

		//Forcing the refresh (display the backcolor)
		m_screen->refresh();

        return res;
	}

		bool ScreenBuffer::renderpass( unsigned long framerate, unsigned long& lastframe)
		{
		    //Callback for preparing new frame
		    if ( m_newframecb )
				m_newframecb->call( framerate, SDL_GetTicks() - lastframe );

			//applying the background
					//if (!ShowingLoadingScreen)
						applyBGColor();

					//if (!ShowingLoadingScreen)
                		if ( m_rendercb )
							m_rendercb->call( *m_screen );

                		//calling our engine render function ( on top of user render )
                		//TODO : add a timer if not demo release...
                		m_engine.render(*m_screen);

					//refresh screen
					//Log << nl << "before :" << SDL_GetTicks() - lastframe ;
					if ( SDL_GetTicks() - lastframe < 1000/framerate)//wait if needed - IMPORTANT otherwise the next value is far too high (not 0)
						SDL_Delay( 1000/framerate - ( SDL_GetTicks() - lastframe ) );

					m_screen->refresh();
					//Log << nl << "after :" << SDL_GetTicks() - lastframe ;

					lastframe=SDL_GetTicks();

					//calling engine for postrender events
					//m_engine ->postrender();

					return true; //not used for now
		}

	} // SDL
} // RAGE
<|endoftext|>


<commit_before>///////////////////////////////////////////////////////////////////////////////
//
// FlowManager.cpp
//
// Access to the GPII flowmanager to log in and out
//
//	Project Files:
//		FlowManager.cpp
//		FlowManager.h
//
///////////////////////////////////////////////////////////////////////////////
#include <FlowManager.h>
#include <libcurl\curl.h>

#ifdef __MINGW_H
// not included in mingw headers
extern void WINAPI OutputDebugString(
    LPCTSTR lpOutputString
);
#endif

// Set TRUE to use fiddler2.com to debug http
#if defined(_DEBUG)
#define USE_FIDDLER	FALSE
#endif

//---------------------------------------------------------
// Flow Manager Constants
//---------------------------------------------------------
const char * const FLOW_MANAGER_URL = "http://localhost:8081/user";
const char * const FLOW_LOGIN = "login";
const char * const FLOW_LOGOUT = "logout";

///////////////////////////////////////////////////////////////////////////////
//
//  FUNCTION: MakeCurlRequest(char szUser,char szAction)
//
//  PURPOSE:  Uses libcurl to make a HTTP GET request to a specified URL.
//
//  EXAMPLES:
//
//            http://localhost:8081/user/123/login
//
//            http://localhost:8081/user/123/logout
//
///////////////////////////////////////////////////////////////////////////////
static int _MakeCurlRequest(const char* szUser, const char* szAction)
{
    static const int MAX_BUFFER = 256;

    if (lstrlen(szUser) > 0)
    {
        CURL *curl = curl_easy_init();
        if (curl)
        {
            char szRequest[MAX_BUFFER];
            char * szUserEscaped = curl_easy_escape(curl, szUser, 0);
            wsprintf(szRequest,"%s/%s/%s",FLOW_MANAGER_URL,szUserEscaped,szAction);

#ifdef _DEBUG
            OutputDebugString(szRequest); // will show in gdb
#endif

#if defined(USE_FIDDLER)
            (void) curl_easy_setopt(curl, CURLOPT_PROXY, "127.0.0.1:8888"); // use http://fiddler2.com to monitor HTTP
#endif
            (void) curl_easy_setopt(curl, CURLOPT_URL, szRequest);
            // TODO Check the response code and handle errors.
            CURLcode responseCode = curl_easy_perform(curl); // expect CURLE_WRITE_ERROR as no buffer given for incoming data
            (void) responseCode; // tell compiler we're not doing anything with it - just for debugging
            curl_free(szUserEscaped);
            curl_easy_cleanup(curl);
            return 1;
        }
    }
    return 0;
}

void FlowManagerLogin(const char * szToken)
{
    _MakeCurlRequest(szToken, FLOW_LOGIN);
}

void FlowManagerLogout(const char * szToken) // FIXME should we keep state or can we have multiple concurrent logins?
{
    _MakeCurlRequest(szToken, FLOW_LOGOUT);
}

// End of file
<commit_msg>removed tabs<commit_after>///////////////////////////////////////////////////////////////////////////////
//
// FlowManager.cpp
//
// Access to the GPII flowmanager to log in and out
//
//	Project Files:
//		FlowManager.cpp
//		FlowManager.h
//
///////////////////////////////////////////////////////////////////////////////
#include <FlowManager.h>
#include <libcurl\curl.h>

#ifdef __MINGW_H
// not included in mingw headers
extern void WINAPI OutputDebugString(
    LPCTSTR lpOutputString
);
#endif

// Set TRUE to use fiddler2.com to debug http
#if defined(_DEBUG)
#define USE_FIDDLER	FALSE
#endif

//---------------------------------------------------------
// Flow Manager Constants
//---------------------------------------------------------
const char * const FLOW_MANAGER_URL = "http://localhost:8081/user";
const char * const FLOW_LOGIN = "login";
const char * const FLOW_LOGOUT = "logout";

///////////////////////////////////////////////////////////////////////////////
//
//  FUNCTION: MakeCurlRequest(char szUser,char szAction)
//
//  PURPOSE:  Uses libcurl to make a HTTP GET request to a specified URL.
//
//  EXAMPLES:
//
//            http://localhost:8081/user/123/login
//
//            http://localhost:8081/user/123/logout
//
///////////////////////////////////////////////////////////////////////////////
static int _MakeCurlRequest(const char* szUser, const char* szAction)
{
    static const int MAX_BUFFER = 256;

    if (lstrlen(szUser) > 0)
    {
        CURL *curl = curl_easy_init();
        if (curl)
        {
            char szRequest[MAX_BUFFER];
            char * szUserEscaped = curl_easy_escape(curl, szUser, 0);
            wsprintf(szRequest,"%s/%s/%s",FLOW_MANAGER_URL,szUserEscaped,szAction);

#ifdef _DEBUG
            OutputDebugString(szRequest); // will show in VisualStudio and gdb
            OutputDebugString("\r\n");
#endif

#if defined(USE_FIDDLER)
            (void) curl_easy_setopt(curl, CURLOPT_PROXY, "127.0.0.1:8888"); // use http://fiddler2.com to monitor HTTP
#endif
            (void) curl_easy_setopt(curl, CURLOPT_URL, szRequest);
            // TODO Check the response code and handle errors.
            CURLcode responseCode = curl_easy_perform(curl); // expect CURLE_WRITE_ERROR as no buffer given for incoming data
            (void) responseCode; // tell compiler we're not doing anything with it - just for debugging
            curl_free(szUserEscaped);
            curl_easy_cleanup(curl);
            return 1;
        }
    }
    return 0;
}

void FlowManagerLogin(const char * szToken)
{
    _MakeCurlRequest(szToken, FLOW_LOGIN);
}

void FlowManagerLogout(const char * szToken) // FIXME should we keep state or can we have multiple concurrent logins?
{
    _MakeCurlRequest(szToken, FLOW_LOGOUT);
}

// End of file
<|endoftext|>


<commit_before>#include <algorithm>
#include <array>
#include <iomanip>
#include <curl/curl.h>
#include <memory>
#include <string>
#include <sstream>
#include <iostream>
#include <fstream>
#include <vector>
#include <sys/stat.h>
#include <cerrno>
#include <cstring>
#include <system_error>
#include <openssl/md5.h>
#include <openssl/sha.h>
#include <openssl/evp.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <string.h>

const std::string listing("http://nwn.efupw.com/rootdir/index.dat");
const std::string patch_dir("http://nwn.efupw.com/rootdir/patch/");
const std::string update_check("");

size_t writefunction(const char *ptr, size_t size, size_t nmemb, void *userdata)
{
    std::string *s = static_cast<std::string *>(userdata);
    s->append(ptr, size * nmemb);
    return size * nmemb;
}

std::vector<std::string> &split(const std::string &s, char delim,
        std::vector<std::string> &elems)
{
    std::stringstream ss(s);
    std::string item;
    while (std::getline(ss, item, delim))
    {
        elems.push_back(item);
    }
    return elems;
}

std::vector<std::string> split(const std::string &s, char delim)
{
    std::vector<std::string> elems;
    return split(s, delim, elems);
}

class Target
{
    public:
        enum class Status {
            Nonexistent,
            Outdated,
            Current
        };
        explicit Target(const std::string &name, const std::string &checksum):
            m_name(name.find_first_of('/') == std::string::npos ?
                    name
                    : name, name.find_first_of('/') + 1, name.size() - 1), m_checksum(checksum)
    {}
        std::string name() const { return m_name; }
        std::string checksum() const { return m_checksum; }
        void fetch()
        {
            std::cout << "pretending to fetch " << name() << std::endl;
            std::string path;
            std::ofstream ofs(name());
            if (!ofs.good())
            {
                auto elems = split(name(), '/');
                for (size_t i = 0, k = elems.size(); i < k; ++i)
                    //for (auto s : elems)
                {
                    const std::string &s(elems[i]);
                    if (s.size() && s != ".")
                    {
                        path.append((i > 0 ? "/" : "") + s);
                        if (k > 1 && i < k - 1)
                        {
                            auto status = mkdir(path.c_str(), S_IRWXU);
                            if (status == -1)
                            {
                                std::error_code err(errno, std::generic_category());
                                if (err == std::errc::file_exists)
                                {
                                    std::cout << "error making dir: "
                                        << err.message() << std::endl;
                                }
                            }
                        }
                        std::cout << "the path: " << path << std::endl;
                    }
                }
                ofs.open(path);
                if (ofs.good())
                {
                    std::cout << "opened path " << path << std::endl;
                }
            }
            if (ofs.good())
            {
                const std::string md5("38eaad974c15e5f3119469f17e8e97a9");
                //if (md5 != checksum())
                {
                    std::cout << "Downloading new " << name() << std::endl;
                    std::string s;
                    std::shared_ptr<CURL *> phandle =
                        std::make_shared<CURL *>(curl_easy_init());
                    std::string url(patch_dir + name());
                    curl_easy_setopt(*phandle, CURLOPT_URL, url.c_str());
                    curl_easy_setopt(*phandle, CURLOPT_WRITEFUNCTION, &writefunction);
                    curl_easy_setopt(*phandle, CURLOPT_WRITEDATA, &s);
                    //curl_easy_setopt(*phandle, CURLOPT_NOPROGRESS, 0);
                    curl_easy_perform(*phandle);
                    curl_easy_cleanup(*phandle);
                    phandle.reset();
                    ofs << s;
                    ofs.close();
                }
                //else
                {
                    std::cout << name() << " already up to date." << std::endl;
                }
            }
        }
        Status status()
        {
            return Status::Nonexistent;
        }

    private:
        std::string m_name;
        std::string m_checksum;
};

std::ostream& operator<<(std::ostream &os, const Target &t)
{
    return os << "name: " << t.name() << ", checksum: " << t.checksum();
}

class CurlGlobalInit
{
    public:
        CurlGlobalInit()
        {
            curl_global_init(CURL_GLOBAL_ALL);
        }

        ~CurlGlobalInit()
        {
            curl_global_cleanup();
        }
};

bool file_checksum_test(const std::string &path,
        const std::string &checksum)
{
#define md_md5
#ifdef md_md5
    auto md = EVP_md5();
    const int md_len = MD5_DIGEST_LENGTH;
#else
    auto md = EVP_sha1();
    const int md_len = SHA_DIGEST_LENGTH;
#endif
    std::array<unsigned char, md_len> result;
    EVP_MD_CTX *mdctx = nullptr;
    std::ifstream is(path, std::ifstream::binary);

    const int length = 8192;
    std::array<unsigned char, length> buffer;
    auto buf = reinterpret_cast<char *>(buffer.data());
    mdctx = EVP_MD_CTX_create();
    int status = EVP_DigestInit_ex(mdctx, md, nullptr);
    while (status && is)
    {
        is.read(buf, length);
        status = EVP_DigestUpdate(mdctx, buffer.data(), is.gcount());
    }
    status = EVP_DigestFinal_ex(mdctx, result.data(), nullptr);
    EVP_MD_CTX_destroy(mdctx);
    std::stringstream calcsum;
    calcsum << std::setfill('0');

    std::for_each(std::begin(result), std::end(result),
            [&calcsum](unsigned char c)
            {
            calcsum << std::hex << std::setw(2)
            << static_cast<unsigned int>(c);
            });
    std::cout << calcsum.str() << std::endl;
    return calcsum.str() == checksum;
}

int main(int argc, char *argv[])
{
    CurlGlobalInit curl_global;
    std::string fetch;
    std::shared_ptr<CURL *> phandle = std::make_shared<CURL *>(curl_easy_init());
    curl_easy_setopt(*phandle, CURLOPT_URL, listing.c_str());
    curl_easy_setopt(*phandle, CURLOPT_WRITEFUNCTION, &writefunction);
    curl_easy_setopt(*phandle, CURLOPT_WRITEDATA, &fetch);
    //curl_easy_setopt(*phandle, CURLOPT_NOPROGRESS, 0);
    curl_easy_perform(*phandle);
    curl_easy_cleanup(*phandle);
    phandle.reset();
    //std::cout << fetch << std::endl;
    std::vector<std::string> v(split(fetch, '\n'));
    //split(fetch, '\n', v);
    //std::cout << v[1] << std::endl;
    std::vector<Target> new_targets, old_targets;
    for (auto beg = std::begin(v), end = std::end(v);
            beg != end; ++beg)
    {
        auto w(split(*beg, '@'));
        /*
        for (const auto & sss : w)
        {
            std::cout << sss << ", " << std::endl;
        }
        */
        Target t(w[0], w[w.size() - 1]);
        auto status = t.status();
        if (status == Target::Status::Nonexistent)
        {
            new_targets.push_back(std::move(t));
        }
        else if (status == Target::Status::Outdated)
        {
            old_targets.push_back(std::move(t));
        }
        //std::cout << *beg << std::endl;
    }
    std::stringstream ss(fetch);
    std::string item;
    //std::vector<std::pair<std::string, std::string>> new_targets;
    while (std::getline(ss, item))
    {
        //new_targets.push_back(item);
    }
    if (new_targets.size())
    {
        std::cout << "New targets: " << new_targets.size() << std::endl;
        //for (auto &t : new_targets)
        {
            //std::cout << t << std::endl;
            //t.fetch();
        }
        std::cout << new_targets[4] << std::endl;
        new_targets[1].fetch();
        new_targets[4].fetch();
        /*
        for (auto s : split(new_targets[4].name(), '/'))
        {
            if (s.length())
            {
                std::cout << s << ", ";
            }
        }
        */
    }
    else
    {
        std::cout << "No new targets." << std::endl;
    }
    if (old_targets.size())
    {
        std::cout << "Outdated targets: " << old_targets.size() << std::endl;
        for (auto &t : old_targets)
        {
            std::cout << t << std::endl;
        }
    }
    else
    {
        std::cout << "No targets out of date." << std::endl;
    }
    const std::string path = "bin/override/spells.2da";
    const std::string checksum("38eaad974c15e5f3119469f17e8e97a9");
    std::cout << "file checksum test: "
        << path << " = " << checksum
        << " : " << file_checksum_test(path, checksum)
        << std::endl;

    std::cout << std::endl;
    return 0;
}
<commit_msg>Use foreach loop now that we have std::array base.<commit_after>#include <algorithm>
#include <array>
#include <iomanip>
#include <curl/curl.h>
#include <memory>
#include <string>
#include <sstream>
#include <iostream>
#include <fstream>
#include <vector>
#include <sys/stat.h>
#include <cerrno>
#include <cstring>
#include <system_error>
#include <openssl/md5.h>
#include <openssl/sha.h>
#include <openssl/evp.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <string.h>

const std::string listing("http://nwn.efupw.com/rootdir/index.dat");
const std::string patch_dir("http://nwn.efupw.com/rootdir/patch/");
const std::string update_check("");

size_t writefunction(const char *ptr, size_t size, size_t nmemb, void *userdata)
{
    std::string *s = static_cast<std::string *>(userdata);
    s->append(ptr, size * nmemb);
    return size * nmemb;
}

std::vector<std::string> &split(const std::string &s, char delim,
        std::vector<std::string> &elems)
{
    std::stringstream ss(s);
    std::string item;
    while (std::getline(ss, item, delim))
    {
        elems.push_back(item);
    }
    return elems;
}

std::vector<std::string> split(const std::string &s, char delim)
{
    std::vector<std::string> elems;
    return split(s, delim, elems);
}

class Target
{
    public:
        enum class Status {
            Nonexistent,
            Outdated,
            Current
        };
        explicit Target(const std::string &name, const std::string &checksum):
            m_name(name.find_first_of('/') == std::string::npos ?
                    name
                    : name, name.find_first_of('/') + 1, name.size() - 1), m_checksum(checksum)
    {}
        std::string name() const { return m_name; }
        std::string checksum() const { return m_checksum; }
        void fetch()
        {
            std::cout << "pretending to fetch " << name() << std::endl;
            std::string path;
            std::ofstream ofs(name());
            if (!ofs.good())
            {
                auto elems = split(name(), '/');
                for (size_t i = 0, k = elems.size(); i < k; ++i)
                    //for (auto s : elems)
                {
                    const std::string &s(elems[i]);
                    if (s.size() && s != ".")
                    {
                        path.append((i > 0 ? "/" : "") + s);
                        if (k > 1 && i < k - 1)
                        {
                            auto status = mkdir(path.c_str(), S_IRWXU);
                            if (status == -1)
                            {
                                std::error_code err(errno, std::generic_category());
                                if (err == std::errc::file_exists)
                                {
                                    std::cout << "error making dir: "
                                        << err.message() << std::endl;
                                }
                            }
                        }
                        std::cout << "the path: " << path << std::endl;
                    }
                }
                ofs.open(path);
                if (ofs.good())
                {
                    std::cout << "opened path " << path << std::endl;
                }
            }
            if (ofs.good())
            {
                const std::string md5("38eaad974c15e5f3119469f17e8e97a9");
                //if (md5 != checksum())
                {
                    std::cout << "Downloading new " << name() << std::endl;
                    std::string s;
                    std::shared_ptr<CURL *> phandle =
                        std::make_shared<CURL *>(curl_easy_init());
                    std::string url(patch_dir + name());
                    curl_easy_setopt(*phandle, CURLOPT_URL, url.c_str());
                    curl_easy_setopt(*phandle, CURLOPT_WRITEFUNCTION, &writefunction);
                    curl_easy_setopt(*phandle, CURLOPT_WRITEDATA, &s);
                    //curl_easy_setopt(*phandle, CURLOPT_NOPROGRESS, 0);
                    curl_easy_perform(*phandle);
                    curl_easy_cleanup(*phandle);
                    phandle.reset();
                    ofs << s;
                    ofs.close();
                }
                //else
                {
                    std::cout << name() << " already up to date." << std::endl;
                }
            }
        }
        Status status()
        {
            return Status::Nonexistent;
        }

    private:
        std::string m_name;
        std::string m_checksum;
};

std::ostream& operator<<(std::ostream &os, const Target &t)
{
    return os << "name: " << t.name() << ", checksum: " << t.checksum();
}

class CurlGlobalInit
{
    public:
        CurlGlobalInit()
        {
            curl_global_init(CURL_GLOBAL_ALL);
        }

        ~CurlGlobalInit()
        {
            curl_global_cleanup();
        }
};

bool file_checksum_test(const std::string &path,
        const std::string &checksum)
{
#define md_md5
#ifdef md_md5
    auto md = EVP_md5();
    const int md_len = MD5_DIGEST_LENGTH;
#else
    auto md = EVP_sha1();
    const int md_len = SHA_DIGEST_LENGTH;
#endif
    std::array<unsigned char, md_len> result;
    EVP_MD_CTX *mdctx = nullptr;
    std::ifstream is(path, std::ifstream::binary);

    const int length = 8192;
    std::array<unsigned char, length> buffer;
    auto buf = reinterpret_cast<char *>(buffer.data());
    mdctx = EVP_MD_CTX_create();
    int status = EVP_DigestInit_ex(mdctx, md, nullptr);
    while (status && is)
    {
        is.read(buf, length);
        status = EVP_DigestUpdate(mdctx, buffer.data(), is.gcount());
    }
    status = EVP_DigestFinal_ex(mdctx, result.data(), nullptr);
    EVP_MD_CTX_destroy(mdctx);
    std::stringstream calcsum;
    calcsum << std::setfill('0');

    for (unsigned char c : result)
    {
        calcsum << std::hex << std::setw(2)
            << static_cast<unsigned int>(c);
    }
    /*
    std::for_each(std::begin(result), std::end(result),
            [&calcsum](unsigned char c)
            {
            calcsum << std::hex << std::setw(2)
            << static_cast<unsigned int>(c);
            });
            */
    std::cout << calcsum.str() << std::endl;
    return calcsum.str() == checksum;
}

int main(int argc, char *argv[])
{
    CurlGlobalInit curl_global;
    std::string fetch;
    std::shared_ptr<CURL *> phandle = std::make_shared<CURL *>(curl_easy_init());
    curl_easy_setopt(*phandle, CURLOPT_URL, listing.c_str());
    curl_easy_setopt(*phandle, CURLOPT_WRITEFUNCTION, &writefunction);
    curl_easy_setopt(*phandle, CURLOPT_WRITEDATA, &fetch);
    //curl_easy_setopt(*phandle, CURLOPT_NOPROGRESS, 0);
    curl_easy_perform(*phandle);
    curl_easy_cleanup(*phandle);
    phandle.reset();
    //std::cout << fetch << std::endl;
    std::vector<std::string> v(split(fetch, '\n'));
    //split(fetch, '\n', v);
    //std::cout << v[1] << std::endl;
    std::vector<Target> new_targets, old_targets;
    for (auto beg = std::begin(v), end = std::end(v);
            beg != end; ++beg)
    {
        auto w(split(*beg, '@'));
        /*
        for (const auto & sss : w)
        {
            std::cout << sss << ", " << std::endl;
        }
        */
        Target t(w[0], w[w.size() - 1]);
        auto status = t.status();
        if (status == Target::Status::Nonexistent)
        {
            new_targets.push_back(std::move(t));
        }
        else if (status == Target::Status::Outdated)
        {
            old_targets.push_back(std::move(t));
        }
        //std::cout << *beg << std::endl;
    }
    std::stringstream ss(fetch);
    std::string item;
    //std::vector<std::pair<std::string, std::string>> new_targets;
    while (std::getline(ss, item))
    {
        //new_targets.push_back(item);
    }
    if (new_targets.size())
    {
        std::cout << "New targets: " << new_targets.size() << std::endl;
        //for (auto &t : new_targets)
        {
            //std::cout << t << std::endl;
            //t.fetch();
        }
        std::cout << new_targets[4] << std::endl;
        new_targets[1].fetch();
        new_targets[4].fetch();
        /*
        for (auto s : split(new_targets[4].name(), '/'))
        {
            if (s.length())
            {
                std::cout << s << ", ";
            }
        }
        */
    }
    else
    {
        std::cout << "No new targets." << std::endl;
    }
    if (old_targets.size())
    {
        std::cout << "Outdated targets: " << old_targets.size() << std::endl;
        for (auto &t : old_targets)
        {
            std::cout << t << std::endl;
        }
    }
    else
    {
        std::cout << "No targets out of date." << std::endl;
    }
    const std::string path = "bin/override/spells.2da";
    const std::string checksum("38eaad974c15e5f3119469f17e8e97a9");
    std::cout << "file checksum test: "
        << path << " = " << checksum
        << " : " << file_checksum_test(path, checksum)
        << std::endl;

    std::cout << std::endl;
    return 0;
}
<|endoftext|>


<commit_before>// This code is based on Sabberstone project.
// Copyright (c) 2017-2019 SabberStone Team, darkfriend77 & rnilva
// RosettaStone is hearthstone simulator using C++ with reinforcement learning.
// Copyright (c) 2019 Chris Ohk, Youngjoong Kim, SeungHyun Jeon

#ifndef ROSETTASTONE_EFFECTS_HPP
#define ROSETTASTONE_EFFECTS_HPP

#include <Rosetta/Enchants/Effect.hpp>

namespace RosettaStone
{
//!
//! \brief Effects class.
//!
//! This class lists specific effects such as Taunt, Poisonous and Stealth.
//!
class Effects
{
 public:
    //! Creates effect that increases attack by \p n.
    static Effect* AttackN(int n)
    {
        return new Effect(GameTag::ATK, EffectOperator::ADD, n);
    }

    //! Creates effect that increases health by \p n.
    static Effect* HealthN(int n)
    {
        return new Effect(GameTag::HEALTH, EffectOperator::ADD, n);
    }

    //! Creates effect that increases attack and health by \p n.
    static std::vector<Effect*> AttackHealthN(int n)
    {
        return { AttackN(n), HealthN(n) };
    }

    //! Creates effect that reduces cost by \p n.
    static Effect* ReduceCost(int n)
    {
        return new Effect(GameTag::COST, EffectOperator::SUB, n);
    }

    //! A minion ability which forces the opposing player to direct any
    //! melee attacks toward enemy targets with this ability.
    inline static Effect* Taunt =
        new Effect(GameTag::TAUNT, EffectOperator::SET, 1);

    //! A minion ability that causes any minion damaged by them to be destroyed.
    inline static Effect* Poisonous =
        new Effect(GameTag::POISONOUS, EffectOperator::SET, 1);

    //! An ability which causes a minion to ignore the next damage it receives.
    inline static Effect* DivineShield =
        new Effect(GameTag::DIVINE_SHIELD, EffectOperator::SET, 1);

    //! An ability which allows a character to attack twice per turn.
    inline static Effect* Windfury =
        new Effect(GameTag::WINDFURY, EffectOperator::SET, 1);

    //! An ability allowing a minion to attack the same turn it is summoned or
    //! brought under a new player's control.
    inline static Effect* Charge =
        new Effect(GameTag::CHARGE, EffectOperator::SET, 1);

    //! A minion ability which prevents that minion from being the target of
    //! enemy attacks, spells and effects until they attack.
    inline static Effect* Stealth =
        new Effect(GameTag::STEALTH, EffectOperator::SET, 1);
};
}  // namespace RosettaStone

#endif  // ROSETTASTONE_EFFECTS_HPP
<commit_msg>feat(card-impl): Add effect 'Immune'<commit_after>// This code is based on Sabberstone project.
// Copyright (c) 2017-2019 SabberStone Team, darkfriend77 & rnilva
// RosettaStone is hearthstone simulator using C++ with reinforcement learning.
// Copyright (c) 2019 Chris Ohk, Youngjoong Kim, SeungHyun Jeon

#ifndef ROSETTASTONE_EFFECTS_HPP
#define ROSETTASTONE_EFFECTS_HPP

#include <Rosetta/Enchants/Effect.hpp>

namespace RosettaStone
{
//!
//! \brief Effects class.
//!
//! This class lists specific effects such as Taunt, Poisonous and Stealth.
//!
class Effects
{
 public:
    //! Creates effect that increases attack by \p n.
    static Effect* AttackN(int n)
    {
        return new Effect(GameTag::ATK, EffectOperator::ADD, n);
    }

    //! Creates effect that increases health by \p n.
    static Effect* HealthN(int n)
    {
        return new Effect(GameTag::HEALTH, EffectOperator::ADD, n);
    }

    //! Creates effect that increases attack and health by \p n.
    static std::vector<Effect*> AttackHealthN(int n)
    {
        return { AttackN(n), HealthN(n) };
    }

    //! Creates effect that reduces cost by \p n.
    static Effect* ReduceCost(int n)
    {
        return new Effect(GameTag::COST, EffectOperator::SUB, n);
    }

    //! A minion ability which forces the opposing player to direct any
    //! melee attacks toward enemy targets with this ability.
    inline static Effect* Taunt =
        new Effect(GameTag::TAUNT, EffectOperator::SET, 1);

    //! A minion ability that causes any minion damaged by them to be destroyed.
    inline static Effect* Poisonous =
        new Effect(GameTag::POISONOUS, EffectOperator::SET, 1);

    //! An ability which causes a minion to ignore the next damage it receives.
    inline static Effect* DivineShield =
        new Effect(GameTag::DIVINE_SHIELD, EffectOperator::SET, 1);

    //! An ability which allows a character to attack twice per turn.
    inline static Effect* Windfury =
        new Effect(GameTag::WINDFURY, EffectOperator::SET, 1);

    //! An ability allowing a minion to attack the same turn it is summoned or
    //! brought under a new player's control.
    inline static Effect* Charge =
        new Effect(GameTag::CHARGE, EffectOperator::SET, 1);

    //! A minion ability which prevents that minion from being the target of
    //! enemy attacks, spells and effects until they attack.
    inline static Effect* Stealth =
        new Effect(GameTag::STEALTH, EffectOperator::SET, 1);

    //! An ability that prevents characters from receiving any damage, and
    //! prevents the opponent from specifically targeting them with any type of
    //! action.
    inline static Effect* Immune =
        new Effect(GameTag::IMMUNE, EffectOperator::SET, 1);
};
}  // namespace RosettaStone

#endif  // ROSETTASTONE_EFFECTS_HPP
<|endoftext|>


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

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center (DKFZ)
All rights reserved.

Use of this source code is governed by a 3-clause BSD license that can be
found in the LICENSE file.

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

#include "QmitkAddNewPropertyDialog.h"
#include "QmitkPropertyItemDelegate.h"
#include "QmitkPropertyItemModel.h"
#include "QmitkPropertyItemSortFilterProxyModel.h"
#include "QmitkPropertyTreeView.h"
#include <berryIBerryPreferences.h>
#include <berryQtStyleManager.h>
#include <mitkIPropertyAliases.h>
#include <mitkIPropertyDescriptions.h>
#include <mitkIPropertyPersistence.h>
#include <QmitkRenderWindow.h>
#include <QPainter>
#include <memory>

const std::string QmitkPropertyTreeView::VIEW_ID = "org.mitk.views.properties";

QmitkPropertyTreeView::QmitkPropertyTreeView()
  : m_PropertyAliases(mitk::CoreServices::GetPropertyAliases(nullptr), nullptr),
    m_PropertyDescriptions(mitk::CoreServices::GetPropertyDescriptions(nullptr), nullptr),
    m_PropertyPersistence(mitk::CoreServices::GetPropertyPersistence(nullptr), nullptr),
    m_ProxyModel(nullptr),
    m_Model(nullptr),
    m_Delegate(nullptr),
    m_Renderer(nullptr)
{
}

QmitkPropertyTreeView::~QmitkPropertyTreeView()
{
}

void QmitkPropertyTreeView::SetFocus()
{
  m_Controls.filterLineEdit->setFocus();
}

void QmitkPropertyTreeView::RenderWindowPartActivated(mitk::IRenderWindowPart* renderWindowPart)
{
  if (m_Controls.propertyListComboBox->count() == 2)
  {
    QHash<QString, QmitkRenderWindow*> renderWindows = renderWindowPart->GetQmitkRenderWindows();

    Q_FOREACH(QString renderWindow, renderWindows.keys())
    {
      m_Controls.propertyListComboBox->insertItem(m_Controls.propertyListComboBox->count() - 1, QString("Data node: ") + renderWindow);
    }
  }
}

void QmitkPropertyTreeView::RenderWindowPartDeactivated(mitk::IRenderWindowPart*)
{
  if (m_Controls.propertyListComboBox->count() > 2)
  {
    m_Controls.propertyListComboBox->clear();
    m_Controls.propertyListComboBox->addItem("Data node: common");
    m_Controls.propertyListComboBox->addItem("Base data");
  }
}

void QmitkPropertyTreeView::CreateQtPartControl(QWidget* parent)
{
  m_Controls.setupUi(parent);

  m_Controls.propertyListComboBox->addItem("Data node: common");

  mitk::IRenderWindowPart* renderWindowPart = this->GetRenderWindowPart();
  if (renderWindowPart != nullptr)
  {
    QHash<QString, QmitkRenderWindow*> renderWindows = renderWindowPart->GetQmitkRenderWindows();

    for(const auto& renderWindow : renderWindows.keys())
    {
      m_Controls.propertyListComboBox->addItem(QString("Data node: ") + renderWindow);
    }
  }

  m_Controls.propertyListComboBox->addItem("Base data");

  m_Controls.newButton->setEnabled(false);

  this->HideAllIcons();

  m_ProxyModel = new QmitkPropertyItemSortFilterProxyModel(m_Controls.treeView);
  m_Model = new QmitkPropertyItemModel(m_ProxyModel);

  m_ProxyModel->setSourceModel(m_Model);
  m_ProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
  m_ProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
  m_ProxyModel->setDynamicSortFilter(true);

  m_Delegate = new QmitkPropertyItemDelegate(m_Controls.treeView);

  m_Controls.singleSlot->SetDataStorage(GetDataStorage());
  m_Controls.singleSlot->SetSelectionIsOptional(true);
  m_Controls.singleSlot->SetAutoSelectNewNodes(true);
  m_Controls.singleSlot->SetEmptyInfo(QString("Please select a data node"));
  m_Controls.singleSlot->SetPopUpTitel(QString("Select data node"));

  m_SelectionServiceConnector = std::make_unique<QmitkSelectionServiceConnector>();
  SetAsSelectionListener(true);

  m_Controls.filterLineEdit->setClearButtonEnabled(true);

  m_Controls.treeView->setItemDelegateForColumn(1, m_Delegate);
  m_Controls.treeView->setModel(m_ProxyModel);
  m_Controls.treeView->setColumnWidth(0, 160);
  m_Controls.treeView->sortByColumn(0, Qt::AscendingOrder);
  m_Controls.treeView->setSelectionBehavior(QAbstractItemView::SelectRows);
  m_Controls.treeView->setSelectionMode(QAbstractItemView::SingleSelection);
  m_Controls.treeView->setEditTriggers(QAbstractItemView::SelectedClicked | QAbstractItemView::DoubleClicked);

  const int ICON_SIZE = 32;

  auto icon = berry::QtStyleManager::ThemeIcon(QStringLiteral(":/org_mitk_icons/icons/awesome/scalable/tags.svg"));
  m_Controls.tagsLabel->setPixmap(icon.pixmap(ICON_SIZE));

  icon = berry::QtStyleManager::ThemeIcon(QStringLiteral(":/org_mitk_icons/icons/awesome/scalable/tag.svg"));
  m_Controls.tagLabel->setPixmap(icon.pixmap(ICON_SIZE));

  icon = berry::QtStyleManager::ThemeIcon(QStringLiteral(":/org_mitk_icons/icons/awesome/scalable/actions/document-save.svg"));
  m_Controls.saveLabel->setPixmap(icon.pixmap(ICON_SIZE));

  connect(m_Controls.singleSlot, &QmitkSingleNodeSelectionWidget::CurrentSelectionChanged,
    this, &QmitkPropertyTreeView::OnCurrentSelectionChanged);
  connect(m_Controls.filterLineEdit, &QLineEdit::textChanged,
    this, &QmitkPropertyTreeView::OnFilterTextChanged);
  connect(m_Controls.propertyListComboBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
    this, &QmitkPropertyTreeView::OnPropertyListChanged);
  connect(m_Controls.newButton, &QPushButton::clicked,
    this, &QmitkPropertyTreeView::OnAddNewProperty);
  connect(m_Controls.treeView->selectionModel(), &QItemSelectionModel::currentRowChanged,
    this, &QmitkPropertyTreeView::OnCurrentRowChanged);
  connect(m_Model, &QmitkPropertyItemModel::modelReset,
    this, &QmitkPropertyTreeView::OnModelReset);
}

void QmitkPropertyTreeView::SetAsSelectionListener(bool checked)
{
  if (checked)
  {
    m_SelectionServiceConnector->AddPostSelectionListener(GetSite()->GetWorkbenchWindow()->GetSelectionService());
    connect(m_SelectionServiceConnector.get(), &QmitkSelectionServiceConnector::ServiceSelectionChanged, m_Controls.singleSlot, &QmitkSingleNodeSelectionWidget::SetCurrentSelection);
  }
  else
  {
    m_SelectionServiceConnector->RemovePostSelectionListener();
    disconnect(m_SelectionServiceConnector.get(), &QmitkSelectionServiceConnector::ServiceSelectionChanged, m_Controls.singleSlot, &QmitkSingleNodeSelectionWidget::SetCurrentSelection);
  }
}

QString QmitkPropertyTreeView::GetPropertyNameOrAlias(const QModelIndex& index)
{
  QString propertyName;

  if (index.isValid())
  {
    QModelIndex current = index;

    while (current.isValid())
    {
      QString name = m_ProxyModel->data(m_ProxyModel->index(current.row(), 0, current.parent())).toString();

      propertyName.prepend(propertyName.isEmpty()
        ? name
        : name.append('.'));

      current = current.parent();
    }
  }

  return propertyName;
}

void QmitkPropertyTreeView::OnCurrentSelectionChanged(QList<mitk::DataNode::Pointer> nodes)
{
  if (nodes.empty() || nodes.front().IsNull())
  {
    m_SelectedNode = nullptr;

    this->SetPartName("Properties");
    m_Model->SetPropertyList(nullptr);
    m_Delegate->SetPropertyList(nullptr);

    m_Controls.newButton->setEnabled(false);

    return;
  }

  // node is selected, create tree with node properties
  m_SelectedNode = nodes.front();
  mitk::PropertyList* propertyList = m_Model->GetPropertyList();
  if (m_Renderer == nullptr && m_Controls.propertyListComboBox->currentText() == "Base data")
  {
    propertyList = m_SelectedNode->GetData() != nullptr
      ? m_SelectedNode->GetData()->GetPropertyList()
      : nullptr;
  }
  else
  {
    propertyList = m_SelectedNode->GetPropertyList(m_Renderer);
  }

  QString selectionClassName = m_SelectedNode->GetData() != nullptr
    ? m_SelectedNode->GetData()->GetNameOfClass()
    : "";

  m_SelectionClassName = selectionClassName.toStdString();

  m_Model->SetPropertyList(propertyList, selectionClassName);
  m_Delegate->SetPropertyList(propertyList);

  m_Controls.newButton->setEnabled(true);

  if (!m_ProxyModel->filterRegExp().isEmpty())
  {
    m_Controls.treeView->expandAll();
  }
}

void QmitkPropertyTreeView::HideAllIcons()
{
  m_Controls.tagLabel->hide();
  m_Controls.tagsLabel->hide();
  m_Controls.saveLabel->hide();
}

void QmitkPropertyTreeView::OnCurrentRowChanged(const QModelIndex& current, const QModelIndex&)
{
  if (current.isValid())
  {
    QString name = this->GetPropertyNameOrAlias(current);

    if (!name.isEmpty())
    {
      QString alias;
      bool isTrueName = true;

      std::string trueName = m_PropertyAliases->GetPropertyName(name.toStdString());

      if (trueName.empty() && !m_SelectionClassName.empty())
        trueName = m_PropertyAliases->GetPropertyName(name.toStdString(), m_SelectionClassName);

      if (!trueName.empty())
      {
        alias = name;
        name = QString::fromStdString(trueName);
        isTrueName = false;
      }

      QString description = QString::fromStdString(m_PropertyDescriptions->GetDescription(name.toStdString()));
      std::vector<std::string> aliases;

      if (!isTrueName)
      {
        aliases = m_PropertyAliases->GetAliases(name.toStdString(), m_SelectionClassName);

        if (aliases.empty() && !m_SelectionClassName.empty())
          aliases = m_PropertyAliases->GetAliases(name.toStdString());
      }

      bool isPersistent = m_PropertyPersistence->HasInfo(name.toStdString());

      if (!description.isEmpty() || !aliases.empty() || isPersistent)
      {
        QString customizedDescription;

        if (!aliases.empty())
        {
          customizedDescription = "
" + name + "
";

          std::size_t numAliases = aliases.size();
          std::size_t lastAlias = numAliases - 1;

          for (std::size_t i = 0; i < numAliases; ++i)
          {
            customizedDescription += i != lastAlias
              ? "
"
              : "
";

            customizedDescription += QString::fromStdString(aliases[i]) + "
";
          }
        }
        else
        {
          customizedDescription = "
" + name + "
";
        }

        if (!description.isEmpty())
          customizedDescription += "
" + description + "
";

        m_Controls.tagsLabel->setVisible(!aliases.empty() && aliases.size() > 1);
        m_Controls.tagLabel->setVisible(!aliases.empty() && aliases.size() == 1);
        m_Controls.saveLabel->setVisible(isPersistent);

        m_Controls.descriptionLabel->setText(customizedDescription);
        m_Controls.descriptionLabel->show();

        return;
      }
    }
  }

  m_Controls.descriptionLabel->hide();
  this->HideAllIcons();
}

void QmitkPropertyTreeView::OnPropertyListChanged(int index)
{
  if (index == -1)
    return;

  QString renderer = m_Controls.propertyListComboBox->itemText(index);

  if (renderer.startsWith("Data node: "))
    renderer = QString::fromStdString(renderer.toStdString().substr(11));

  m_Renderer = nullptr;

  if (renderer != "common" && renderer != "Base data")
  {
    auto* renderWindowPart = this->GetRenderWindowPart();

    if (nullptr != renderWindowPart)
      m_Renderer = renderWindowPart->GetQmitkRenderWindow(renderer)->GetRenderer();
  }

  QList<mitk::DataNode::Pointer> nodes;

  if (m_SelectedNode.IsNotNull())
    nodes << m_SelectedNode;

  this->OnCurrentSelectionChanged(nodes);
}

void QmitkPropertyTreeView::OnAddNewProperty()
{
  std::unique_ptr<QmitkAddNewPropertyDialog> dialog(m_Controls.propertyListComboBox->currentText() != "Base data"
    ? new QmitkAddNewPropertyDialog(m_SelectedNode, m_Renderer)
    : new QmitkAddNewPropertyDialog(m_SelectedNode->GetData()));

  if (dialog->exec() == QDialog::Accepted)
    this->m_Model->Update();
}

void QmitkPropertyTreeView::OnFilterTextChanged(const QString& filter)
{
  m_ProxyModel->setFilterWildcard(filter);

  if (filter.isEmpty())
    m_Controls.treeView->collapseAll();
  else
    m_Controls.treeView->expandAll();
}

void QmitkPropertyTreeView::OnModelReset()
{
  m_Controls.descriptionLabel->hide();
  this->HideAllIcons();
}
<commit_msg>Fix initial selection and auto-selection of invisible nodes<commit_after>/*============================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center (DKFZ)
All rights reserved.

Use of this source code is governed by a 3-clause BSD license that can be
found in the LICENSE file.

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

#include "QmitkAddNewPropertyDialog.h"
#include "QmitkPropertyItemDelegate.h"
#include "QmitkPropertyItemModel.h"
#include "QmitkPropertyItemSortFilterProxyModel.h"
#include "QmitkPropertyTreeView.h"
#include <berryIBerryPreferences.h>
#include <berryQtStyleManager.h>
#include <mitkIPropertyAliases.h>
#include <mitkIPropertyDescriptions.h>
#include <mitkIPropertyPersistence.h>
#include <QmitkRenderWindow.h>
#include <QPainter>
#include <memory>

namespace
{
  QmitkAbstractNodeSelectionWidget::NodeList GetInitialSelection(berry::ISelection::ConstPointer selection)
  {
    if (selection.IsNotNull() && !selection->IsEmpty())
    {
      auto* dataNodeSelection = dynamic_cast<const mitk::DataNodeSelection*>(selection.GetPointer());

      if (nullptr != dataNodeSelection)
      {
        auto firstSelectedDataNode = dataNodeSelection->GetSelectedDataNodes().front();

        if (firstSelectedDataNode.IsNotNull())
        {
          QmitkAbstractNodeSelectionWidget::NodeList initialSelection;
          initialSelection.push_back(firstSelectedDataNode);

          return initialSelection;
        }
      }
    }

    return QmitkAbstractNodeSelectionWidget::NodeList();
  }
}

const std::string QmitkPropertyTreeView::VIEW_ID = "org.mitk.views.properties";

QmitkPropertyTreeView::QmitkPropertyTreeView()
  : m_PropertyAliases(mitk::CoreServices::GetPropertyAliases(nullptr), nullptr),
    m_PropertyDescriptions(mitk::CoreServices::GetPropertyDescriptions(nullptr), nullptr),
    m_PropertyPersistence(mitk::CoreServices::GetPropertyPersistence(nullptr), nullptr),
    m_ProxyModel(nullptr),
    m_Model(nullptr),
    m_Delegate(nullptr),
    m_Renderer(nullptr)
{
}

QmitkPropertyTreeView::~QmitkPropertyTreeView()
{
}

void QmitkPropertyTreeView::SetFocus()
{
  m_Controls.filterLineEdit->setFocus();
}

void QmitkPropertyTreeView::RenderWindowPartActivated(mitk::IRenderWindowPart* renderWindowPart)
{
  if (m_Controls.propertyListComboBox->count() == 2)
  {
    QHash<QString, QmitkRenderWindow*> renderWindows = renderWindowPart->GetQmitkRenderWindows();

    Q_FOREACH(QString renderWindow, renderWindows.keys())
    {
      m_Controls.propertyListComboBox->insertItem(m_Controls.propertyListComboBox->count() - 1, QString("Data node: ") + renderWindow);
    }
  }
}

void QmitkPropertyTreeView::RenderWindowPartDeactivated(mitk::IRenderWindowPart*)
{
  if (m_Controls.propertyListComboBox->count() > 2)
  {
    m_Controls.propertyListComboBox->clear();
    m_Controls.propertyListComboBox->addItem("Data node: common");
    m_Controls.propertyListComboBox->addItem("Base data");
  }
}

void QmitkPropertyTreeView::CreateQtPartControl(QWidget* parent)
{
  m_Controls.setupUi(parent);

  m_Controls.propertyListComboBox->addItem("Data node: common");

  mitk::IRenderWindowPart* renderWindowPart = this->GetRenderWindowPart();
  if (renderWindowPart != nullptr)
  {
    QHash<QString, QmitkRenderWindow*> renderWindows = renderWindowPart->GetQmitkRenderWindows();

    for(const auto& renderWindow : renderWindows.keys())
    {
      m_Controls.propertyListComboBox->addItem(QString("Data node: ") + renderWindow);
    }
  }

  m_Controls.propertyListComboBox->addItem("Base data");

  m_Controls.newButton->setEnabled(false);

  this->HideAllIcons();

  m_ProxyModel = new QmitkPropertyItemSortFilterProxyModel(m_Controls.treeView);
  m_Model = new QmitkPropertyItemModel(m_ProxyModel);

  m_ProxyModel->setSourceModel(m_Model);
  m_ProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
  m_ProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
  m_ProxyModel->setDynamicSortFilter(true);

  m_Delegate = new QmitkPropertyItemDelegate(m_Controls.treeView);

  m_Controls.singleSlot->SetDataStorage(GetDataStorage());
  m_Controls.singleSlot->SetSelectionIsOptional(true);
  m_Controls.singleSlot->SetEmptyInfo(QString("Please select a data node"));
  m_Controls.singleSlot->SetPopUpTitel(QString("Select data node"));

  m_SelectionServiceConnector = std::make_unique<QmitkSelectionServiceConnector>();
  SetAsSelectionListener(true);

  auto selection = this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->GetSelection();
  auto currentSelection = GetInitialSelection(selection);

  if (!currentSelection.isEmpty())
    m_Controls.singleSlot->SetCurrentSelection(currentSelection);

  m_Controls.filterLineEdit->setClearButtonEnabled(true);

  m_Controls.treeView->setItemDelegateForColumn(1, m_Delegate);
  m_Controls.treeView->setModel(m_ProxyModel);
  m_Controls.treeView->setColumnWidth(0, 160);
  m_Controls.treeView->sortByColumn(0, Qt::AscendingOrder);
  m_Controls.treeView->setSelectionBehavior(QAbstractItemView::SelectRows);
  m_Controls.treeView->setSelectionMode(QAbstractItemView::SingleSelection);
  m_Controls.treeView->setEditTriggers(QAbstractItemView::SelectedClicked | QAbstractItemView::DoubleClicked);

  const int ICON_SIZE = 32;

  auto icon = berry::QtStyleManager::ThemeIcon(QStringLiteral(":/org_mitk_icons/icons/awesome/scalable/tags.svg"));
  m_Controls.tagsLabel->setPixmap(icon.pixmap(ICON_SIZE));

  icon = berry::QtStyleManager::ThemeIcon(QStringLiteral(":/org_mitk_icons/icons/awesome/scalable/tag.svg"));
  m_Controls.tagLabel->setPixmap(icon.pixmap(ICON_SIZE));

  icon = berry::QtStyleManager::ThemeIcon(QStringLiteral(":/org_mitk_icons/icons/awesome/scalable/actions/document-save.svg"));
  m_Controls.saveLabel->setPixmap(icon.pixmap(ICON_SIZE));

  connect(m_Controls.singleSlot, &QmitkSingleNodeSelectionWidget::CurrentSelectionChanged,
    this, &QmitkPropertyTreeView::OnCurrentSelectionChanged);
  connect(m_Controls.filterLineEdit, &QLineEdit::textChanged,
    this, &QmitkPropertyTreeView::OnFilterTextChanged);
  connect(m_Controls.propertyListComboBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
    this, &QmitkPropertyTreeView::OnPropertyListChanged);
  connect(m_Controls.newButton, &QPushButton::clicked,
    this, &QmitkPropertyTreeView::OnAddNewProperty);
  connect(m_Controls.treeView->selectionModel(), &QItemSelectionModel::currentRowChanged,
    this, &QmitkPropertyTreeView::OnCurrentRowChanged);
  connect(m_Model, &QmitkPropertyItemModel::modelReset,
    this, &QmitkPropertyTreeView::OnModelReset);
}

void QmitkPropertyTreeView::SetAsSelectionListener(bool checked)
{
  if (checked)
  {
    m_SelectionServiceConnector->AddPostSelectionListener(GetSite()->GetWorkbenchWindow()->GetSelectionService());
    connect(m_SelectionServiceConnector.get(), &QmitkSelectionServiceConnector::ServiceSelectionChanged, m_Controls.singleSlot, &QmitkSingleNodeSelectionWidget::SetCurrentSelection);
  }
  else
  {
    m_SelectionServiceConnector->RemovePostSelectionListener();
    disconnect(m_SelectionServiceConnector.get(), &QmitkSelectionServiceConnector::ServiceSelectionChanged, m_Controls.singleSlot, &QmitkSingleNodeSelectionWidget::SetCurrentSelection);
  }
}

QString QmitkPropertyTreeView::GetPropertyNameOrAlias(const QModelIndex& index)
{
  QString propertyName;

  if (index.isValid())
  {
    QModelIndex current = index;

    while (current.isValid())
    {
      QString name = m_ProxyModel->data(m_ProxyModel->index(current.row(), 0, current.parent())).toString();

      propertyName.prepend(propertyName.isEmpty()
        ? name
        : name.append('.'));

      current = current.parent();
    }
  }

  return propertyName;
}

void QmitkPropertyTreeView::OnCurrentSelectionChanged(QList<mitk::DataNode::Pointer> nodes)
{
  if (nodes.empty() || nodes.front().IsNull())
  {
    m_SelectedNode = nullptr;

    this->SetPartName("Properties");
    m_Model->SetPropertyList(nullptr);
    m_Delegate->SetPropertyList(nullptr);

    m_Controls.newButton->setEnabled(false);

    return;
  }

  // node is selected, create tree with node properties
  m_SelectedNode = nodes.front();
  mitk::PropertyList* propertyList = m_Model->GetPropertyList();
  if (m_Renderer == nullptr && m_Controls.propertyListComboBox->currentText() == "Base data")
  {
    propertyList = m_SelectedNode->GetData() != nullptr
      ? m_SelectedNode->GetData()->GetPropertyList()
      : nullptr;
  }
  else
  {
    propertyList = m_SelectedNode->GetPropertyList(m_Renderer);
  }

  QString selectionClassName = m_SelectedNode->GetData() != nullptr
    ? m_SelectedNode->GetData()->GetNameOfClass()
    : "";

  m_SelectionClassName = selectionClassName.toStdString();

  m_Model->SetPropertyList(propertyList, selectionClassName);
  m_Delegate->SetPropertyList(propertyList);

  m_Controls.newButton->setEnabled(true);

  if (!m_ProxyModel->filterRegExp().isEmpty())
  {
    m_Controls.treeView->expandAll();
  }
}

void QmitkPropertyTreeView::HideAllIcons()
{
  m_Controls.tagLabel->hide();
  m_Controls.tagsLabel->hide();
  m_Controls.saveLabel->hide();
}

void QmitkPropertyTreeView::OnCurrentRowChanged(const QModelIndex& current, const QModelIndex&)
{
  if (current.isValid())
  {
    QString name = this->GetPropertyNameOrAlias(current);

    if (!name.isEmpty())
    {
      QString alias;
      bool isTrueName = true;

      std::string trueName = m_PropertyAliases->GetPropertyName(name.toStdString());

      if (trueName.empty() && !m_SelectionClassName.empty())
        trueName = m_PropertyAliases->GetPropertyName(name.toStdString(), m_SelectionClassName);

      if (!trueName.empty())
      {
        alias = name;
        name = QString::fromStdString(trueName);
        isTrueName = false;
      }

      QString description = QString::fromStdString(m_PropertyDescriptions->GetDescription(name.toStdString()));
      std::vector<std::string> aliases;

      if (!isTrueName)
      {
        aliases = m_PropertyAliases->GetAliases(name.toStdString(), m_SelectionClassName);

        if (aliases.empty() && !m_SelectionClassName.empty())
          aliases = m_PropertyAliases->GetAliases(name.toStdString());
      }

      bool isPersistent = m_PropertyPersistence->HasInfo(name.toStdString());

      if (!description.isEmpty() || !aliases.empty() || isPersistent)
      {
        QString customizedDescription;

        if (!aliases.empty())
        {
          customizedDescription = "
" + name + "
";

          std::size_t numAliases = aliases.size();
          std::size_t lastAlias = numAliases - 1;

          for (std::size_t i = 0; i < numAliases; ++i)
          {
            customizedDescription += i != lastAlias
              ? "
"
              : "
";

            customizedDescription += QString::fromStdString(aliases[i]) + "
";
          }
        }
        else
        {
          customizedDescription = "
" + name + "
";
        }

        if (!description.isEmpty())
          customizedDescription += "
" + description + "
";

        m_Controls.tagsLabel->setVisible(!aliases.empty() && aliases.size() > 1);
        m_Controls.tagLabel->setVisible(!aliases.empty() && aliases.size() == 1);
        m_Controls.saveLabel->setVisible(isPersistent);

        m_Controls.descriptionLabel->setText(customizedDescription);
        m_Controls.descriptionLabel->show();

        return;
      }
    }
  }

  m_Controls.descriptionLabel->hide();
  this->HideAllIcons();
}

void QmitkPropertyTreeView::OnPropertyListChanged(int index)
{
  if (index == -1)
    return;

  QString renderer = m_Controls.propertyListComboBox->itemText(index);

  if (renderer.startsWith("Data node: "))
    renderer = QString::fromStdString(renderer.toStdString().substr(11));

  m_Renderer = nullptr;

  if (renderer != "common" && renderer != "Base data")
  {
    auto* renderWindowPart = this->GetRenderWindowPart();

    if (nullptr != renderWindowPart)
      m_Renderer = renderWindowPart->GetQmitkRenderWindow(renderer)->GetRenderer();
  }

  QList<mitk::DataNode::Pointer> nodes;

  if (m_SelectedNode.IsNotNull())
    nodes << m_SelectedNode;

  this->OnCurrentSelectionChanged(nodes);
}

void QmitkPropertyTreeView::OnAddNewProperty()
{
  std::unique_ptr<QmitkAddNewPropertyDialog> dialog(m_Controls.propertyListComboBox->currentText() != "Base data"
    ? new QmitkAddNewPropertyDialog(m_SelectedNode, m_Renderer)
    : new QmitkAddNewPropertyDialog(m_SelectedNode->GetData()));

  if (dialog->exec() == QDialog::Accepted)
    this->m_Model->Update();
}

void QmitkPropertyTreeView::OnFilterTextChanged(const QString& filter)
{
  m_ProxyModel->setFilterWildcard(filter);

  if (filter.isEmpty())
    m_Controls.treeView->collapseAll();
  else
    m_Controls.treeView->expandAll();
}

void QmitkPropertyTreeView::OnModelReset()
{
  m_Controls.descriptionLabel->hide();
  this->HideAllIcons();
}
<|endoftext|>


<commit_before>/*
    kopetexsl.cpp - Kopete XSL Routines

    Copyright (c) 2003 by Jason Keirstead <jason@keirstead.org>

    *************************************************************************
    *                                                                       *
    * This program is free software; you can redistribute it and/or modify  *
    * it under the terms of the GNU General Public License as published by  *
    * the Free Software Foundation; either version 2 of the License, or     *
    * (at your option) any later version.                                   *
    *                                                                       *
    *************************************************************************
*/

#include <libxslt/xsltconfig.h>
#include <libxslt/xsltInternals.h>
#include <libxslt/transform.h>
#include <libxml/parser.h>

#include <kdebug.h>
#include <kopetexsl.h>
#include <qregexp.h>
#include <qsignal.h>

/**
 * @author Jason Keirstead <jason@keirstead.org>
 *
 * The thread class that actually performs the XSL processing.
 * Using a thread allows for async operation.
 */
class KopeteXSLThread : public QThread
{
	public:
		/**
		 * Thread constructor
		 *
		 * @param xmlString The XML to be transformed
		 * @param xslString The XSL string we will use to transform
		 * @param target Target object to connect to for async operation
		 * @param slotCompleted Slot to fire on completion in asnc operation
		 */
		KopeteXSLThread( const QString &xmlString, const QString &xslString,
			QObject *target = 0L, const char* slotCompleted = 0L );

		/**
		 * Re implimented from QThread. Does the processing.
		 */
		virtual void run();

		/**
		 * Returns the result string
		 */
		const QString &result() { return m_resultString; };

	private:
		QString m_xml;
		QString m_xsl;
		QString m_resultString;
		QObject *m_target;
		const char* m_slotCompleted;
};

KopeteXSLThread::KopeteXSLThread( const QString &xmlString, const QString &xslString, QObject *target, const char* slotCompleted )
{
	m_xml = xmlString;
	m_xsl = xslString;

	m_target = target;
	m_slotCompleted = slotCompleted;
}

void KopeteXSLThread::run()
{
	xsltStylesheetPtr style_sheet = NULL;
	xmlDocPtr xmlDoc, xslDoc, resultDoc;

	//Init Stuff
	xmlLoadExtDtdDefaultValue = 0;
	xmlSubstituteEntitiesDefault(1);

	// Convert QString into a C string
	QCString xmlCString = m_xml.utf8();
	QCString xslCString = m_xsl.utf8();

	// Read XML docs in from memory
	xmlDoc = xmlParseMemory( xmlCString, xmlCString.length() );
	xslDoc = xmlParseMemory( xslCString, xslCString.length() );

	if( xmlDoc != NULL )
	{
		if( xslDoc != NULL )
		{
			style_sheet = xsltParseStylesheetDoc( xslDoc );
			if( style_sheet != NULL )
			{
				resultDoc = xsltApplyStylesheet(style_sheet, xmlDoc, NULL);
				if( resultDoc != NULL )
				{
					//Save the result into the QString
					xmlChar *mem;
					int size;
					xmlDocDumpMemory( resultDoc, &mem, &size );
					m_resultString = QString::fromUtf8( QCString( (char*)mem, size + 1 ) );
					delete mem;
					xmlFreeDoc(resultDoc);
				}
				else
				{
					kdDebug() << "Transformed document is null!!!" << endl;
				}
				xsltFreeStylesheet(style_sheet);
			}
			else
			{
				kdDebug() << "Document is not valid XSL!!!" << endl;
				xmlFreeDoc(xslDoc);
			}
		}
		else
		{
			kdDebug() << "XSL Document could not be parsed!!!" << endl;
		}
		xmlFreeDoc(xmlDoc);
	}
	else
	{
		kdDebug() << "XML Document could not be parsed!!!" << endl;
	}

	//Signal completion
	if( m_target && m_slotCompleted )
	{
		QSignal completeSignal( m_target );
		completeSignal.connect( m_target, m_slotCompleted );
		completeSignal.setValue( m_resultString );
		completeSignal.activate();

		delete this;
	}
}

extern int xmlLoadExtDtdDefaultValue;

const QString KopeteXSL::xsltTransform( const QString &xmlString, const QString &xslString )
{
	KopeteXSLThread mThread( xmlString, xslString );
	mThread.start();
	mThread.wait();
	return mThread.result();
}

void KopeteXSL::xsltTransformAsync( const QString &xmlString, const QString &xslString,
			QObject *target, const char* slotCompleted )
{
	KopeteXSLThread *mThread = new KopeteXSLThread( xmlString, xslString, target, slotCompleted );
	mThread->start();
}

bool KopeteXSL::isValid( const QString &xslString )
{
	xsltStylesheetPtr style_sheet = NULL;
	xmlDocPtr xslDoc = NULL;
	bool retVal = false;

	// Convert QString into a C string
	QCString xslCString = xslString.utf8();

	xslDoc = xmlParseMemory( xslCString, xslCString.length() );

	if( xslDoc != NULL )
	{
		style_sheet = xsltParseStylesheetDoc( xslDoc );
		if( style_sheet != NULL )
		{
			retVal = true;
			xsltFreeStylesheet(style_sheet);
		}
		else
		{
			xmlFreeDoc(xslDoc);
		}
	}

	return retVal;
}
<commit_msg>Free not delete<commit_after>/*
    kopetexsl.cpp - Kopete XSL Routines

    Copyright (c) 2003 by Jason Keirstead <jason@keirstead.org>

    *************************************************************************
    *                                                                       *
    * This program is free software; you can redistribute it and/or modify  *
    * it under the terms of the GNU General Public License as published by  *
    * the Free Software Foundation; either version 2 of the License, or     *
    * (at your option) any later version.                                   *
    *                                                                       *
    *************************************************************************
*/

#include <libxslt/xsltconfig.h>
#include <libxslt/xsltInternals.h>
#include <libxslt/transform.h>
#include <libxml/parser.h>

#include <kdebug.h>
#include <kopetexsl.h>
#include <qregexp.h>
#include <qsignal.h>

/**
 * @author Jason Keirstead <jason@keirstead.org>
 *
 * The thread class that actually performs the XSL processing.
 * Using a thread allows for async operation.
 */
class KopeteXSLThread : public QThread
{
	public:
		/**
		 * Thread constructor
		 *
		 * @param xmlString The XML to be transformed
		 * @param xslString The XSL string we will use to transform
		 * @param target Target object to connect to for async operation
		 * @param slotCompleted Slot to fire on completion in asnc operation
		 */
		KopeteXSLThread( const QString &xmlString, const QString &xslString,
			QObject *target = 0L, const char* slotCompleted = 0L );

		/**
		 * Re implimented from QThread. Does the processing.
		 */
		virtual void run();

		/**
		 * Returns the result string
		 */
		const QString &result() { return m_resultString; };

	private:
		QString m_xml;
		QString m_xsl;
		QString m_resultString;
		QObject *m_target;
		const char* m_slotCompleted;
};

KopeteXSLThread::KopeteXSLThread( const QString &xmlString, const QString &xslString, QObject *target, const char* slotCompleted )
{
	m_xml = xmlString;
	m_xsl = xslString;

	m_target = target;
	m_slotCompleted = slotCompleted;
}

void KopeteXSLThread::run()
{
	xsltStylesheetPtr style_sheet = NULL;
	xmlDocPtr xmlDoc, xslDoc, resultDoc;

	//Init Stuff
	xmlLoadExtDtdDefaultValue = 0;
	xmlSubstituteEntitiesDefault(1);

	// Convert QString into a C string
	QCString xmlCString = m_xml.utf8();
	QCString xslCString = m_xsl.utf8();

	// Read XML docs in from memory
	xmlDoc = xmlParseMemory( xmlCString, xmlCString.length() );
	xslDoc = xmlParseMemory( xslCString, xslCString.length() );

	if( xmlDoc != NULL )
	{
		if( xslDoc != NULL )
		{
			style_sheet = xsltParseStylesheetDoc( xslDoc );
			if( style_sheet != NULL )
			{
				resultDoc = xsltApplyStylesheet(style_sheet, xmlDoc, NULL);
				if( resultDoc != NULL )
				{
					//Save the result into the QString
					xmlChar *mem;
					int size;
					xmlDocDumpMemory( resultDoc, &mem, &size );
					m_resultString = QString::fromUtf8( QCString( (char*)mem, size + 1 ) );
					free(mem);
					xmlFreeDoc(resultDoc);
				}
				else
				{
					kdDebug() << "Transformed document is null!!!" << endl;
				}
				xsltFreeStylesheet(style_sheet);
			}
			else
			{
				kdDebug() << "Document is not valid XSL!!!" << endl;
				xmlFreeDoc(xslDoc);
			}
		}
		else
		{
			kdDebug() << "XSL Document could not be parsed!!!" << endl;
		}
		xmlFreeDoc(xmlDoc);
	}
	else
	{
		kdDebug() << "XML Document could not be parsed!!!" << endl;
	}

	//Signal completion
	if( m_target && m_slotCompleted )
	{
		QSignal completeSignal( m_target );
		completeSignal.connect( m_target, m_slotCompleted );
		completeSignal.setValue( m_resultString );
		completeSignal.activate();

		delete this;
	}
}

extern int xmlLoadExtDtdDefaultValue;

const QString KopeteXSL::xsltTransform( const QString &xmlString, const QString &xslString )
{
	KopeteXSLThread mThread( xmlString, xslString );
	mThread.start();
	mThread.wait();
	return mThread.result();
}

void KopeteXSL::xsltTransformAsync( const QString &xmlString, const QString &xslString,
			QObject *target, const char* slotCompleted )
{
	KopeteXSLThread *mThread = new KopeteXSLThread( xmlString, xslString, target, slotCompleted );
	mThread->start();
}

bool KopeteXSL::isValid( const QString &xslString )
{
	xsltStylesheetPtr style_sheet = NULL;
	xmlDocPtr xslDoc = NULL;
	bool retVal = false;

	// Convert QString into a C string
	QCString xslCString = xslString.utf8();

	xslDoc = xmlParseMemory( xslCString, xslCString.length() );

	if( xslDoc != NULL )
	{
		style_sheet = xsltParseStylesheetDoc( xslDoc );
		if( style_sheet != NULL )
		{
			retVal = true;
			xsltFreeStylesheet(style_sheet);
		}
		else
		{
			xmlFreeDoc(xslDoc);
		}
	}

	return retVal;
}
<|endoftext|>