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

#include <flatland_msgs/DeleteModel.h>
#include <flatland_msgs/MoveModel.h>
#include <flatland_msgs/SpawnModel.h>
#include <flatland_server/simulation_manager.h>
#include <flatland_server/timekeeper.h>
#include <flatland_server/world.h>
#include <gtest/gtest.h>
#include <regex>
#include <thread>

namespace fs = boost::filesystem;
using namespace flatland_server;

class ServiceManagerTest : public ::testing::Test {
 protected:
  SimulationManager* sim_man;
  boost::filesystem::path this_file_dir;
  boost::filesystem::path world_yaml;
  boost::filesystem::path robot_yaml;
  Timekeeper timekeeper;
  ros::NodeHandle nh;
  ros::ServiceClient client;
  std::thread simulation_thread;

  void SetUp() override {
    sim_man = nullptr;
    this_file_dir = boost::filesystem::path(__FILE__).parent_path();
    timekeeper.SetMaxStepSize(1.0);
  }

  void TearDown() override {
    StopSimulationThread();
    if (sim_man) delete sim_man;
  }

  void StartSimulationThread() {
    sim_man =
        new SimulationManager(world_yaml.string(), 1000, 1 / 1000.0, false, 0);
    simulation_thread = std::thread(&ServiceManagerTest::SimulationThread,
                                    dynamic_cast<ServiceManagerTest*>(this));
  }

  void StopSimulationThread() {
    sim_man->Shutdown();
    simulation_thread.join();
  }

  void SimulationThread() { sim_man->Main(); }
};

/**
 * Testing service for loading a model which should succeed
 */
TEST_F(ServiceManagerTest, spawn_valid_model) {
  world_yaml =
      this_file_dir / fs::path("load_world_tests/simple_test_A/world.yaml");

  robot_yaml = this_file_dir /
               fs::path("load_world_tests/simple_test_A/person.model.yaml");

  flatland_msgs::SpawnModel srv;

  srv.request.name = "service_manager_test_robot";
  srv.request.ns = "robot123";
  srv.request.yaml_path = robot_yaml.string();
  srv.request.pose.x = 101.1;
  srv.request.pose.y = 102.1;
  srv.request.pose.theta = 0.23;

  client = nh.serviceClient<flatland_msgs::SpawnModel>("spawn_model");

  // Threading is required since client.call blocks executing until return
  StartSimulationThread();

  ros::service::waitForService("spawn_model", 1000);
  ASSERT_TRUE(client.call(srv));

  ASSERT_TRUE(srv.response.success);
  ASSERT_STREQ("", srv.response.message.c_str());

  World* w = sim_man->world_;
  ASSERT_EQ(5, w->models_.size());
  EXPECT_STREQ("service_manager_test_robot", w->models_[4]->name_.c_str());
  EXPECT_STREQ("robot123", w->models_[4]->namespace_.c_str());
  EXPECT_FLOAT_EQ(101.1,
                  w->models_[4]->bodies_[0]->physics_body_->GetPosition().x);
  EXPECT_FLOAT_EQ(102.1,
                  w->models_[4]->bodies_[0]->physics_body_->GetPosition().y);
  EXPECT_FLOAT_EQ(0.23, w->models_[4]->bodies_[0]->physics_body_->GetAngle());
  EXPECT_EQ(1, w->models_[4]->bodies_.size());
}

/**
 * Testing service for loading a model which should fail
 */
TEST_F(ServiceManagerTest, spawn_invalid_model) {
  world_yaml =
      this_file_dir / fs::path("load_world_tests/simple_test_A/world.yaml");

  robot_yaml = this_file_dir / fs::path("random_path/turtlebot.model.yaml");

  flatland_msgs::SpawnModel srv;

  srv.request.name = "service_manager_test_robot";
  srv.request.yaml_path = robot_yaml.string();
  srv.request.pose.x = 1;
  srv.request.pose.y = 2;
  srv.request.pose.theta = 3;

  client = nh.serviceClient<flatland_msgs::SpawnModel>("spawn_model");

  StartSimulationThread();

  ros::service::waitForService("spawn_model", 1000);
  ASSERT_TRUE(client.call(srv));

  ASSERT_FALSE(srv.response.success);

  std::cmatch match;
  std::string regex_str =
      "Flatland YAML: File does not exist, "
      "path=\".*/random_path/turtlebot.model.yaml\".*";
  std::regex regex(regex_str);
  EXPECT_TRUE(std::regex_match(srv.response.message.c_str(), match, regex))
      << "Error Message '" + srv.response.message + "'" +
             " did not match against regex '" + regex_str + "'";
}

/**
 * Testing service for moving a valid model
 */
TEST_F(ServiceManagerTest, move_model) {
  world_yaml =
      this_file_dir / fs::path("load_world_tests/simple_test_A/world.yaml");

  flatland_msgs::MoveModel srv;
  srv.request.name = "turtlebot1";
  srv.request.pose.x = 5.5;
  srv.request.pose.y = 9.9;
  srv.request.pose.theta = 0.77;

  client = nh.serviceClient<flatland_msgs::MoveModel>("move_model");

  StartSimulationThread();

  ros::service::waitForService("move_model", 1000);
  ASSERT_TRUE(client.call(srv));

  ASSERT_TRUE(srv.response.success);

  World* w = sim_man->world_;
  EXPECT_NEAR(5.5, w->models_[0]->bodies_[0]->physics_body_->GetPosition().x,
              1e-4);
  EXPECT_NEAR(9.9, w->models_[0]->bodies_[0]->physics_body_->GetPosition().y,
              1e-4);
  EXPECT_NEAR(0.77, w->models_[0]->bodies_[0]->physics_body_->GetAngle(), 1e-2);
}

/**
 * Testing service for moving a nonexistent model
 */
TEST_F(ServiceManagerTest, move_nonexistent_model) {
  world_yaml =
      this_file_dir / fs::path("load_world_tests/simple_test_A/world.yaml");

  flatland_msgs::MoveModel srv;
  srv.request.name = "not_a_robot";
  srv.request.pose.x = 4;
  srv.request.pose.y = 5;
  srv.request.pose.theta = 0;

  client = nh.serviceClient<flatland_msgs::MoveModel>("move_model");

  StartSimulationThread();

  ros::service::waitForService("move_model", 1000);
  ASSERT_TRUE(client.call(srv));

  ASSERT_FALSE(srv.response.success);
  EXPECT_STREQ(
      "Flatland World: failed to move model, model with name "
      "\"not_a_robot\" does not exist",
      srv.response.message.c_str());
}

/**
 * Testing service for deleting a model
 */
TEST_F(ServiceManagerTest, delete_model) {
  world_yaml = this_file_dir /
               fs::path("plugin_manager_tests/load_dummy_test/world.yaml");

  flatland_msgs::DeleteModel srv;
  srv.request.name = "turtlebot1";

  client = nh.serviceClient<flatland_msgs::DeleteModel>("delete_model");

  StartSimulationThread();

  ros::service::waitForService("delete_model", 1000);
  ASSERT_TRUE(client.call(srv));

  ASSERT_TRUE(srv.response.success);
  World* w = sim_man->world_;
  // after deleting a mode, there should be one less model, and one less plugin
  ASSERT_EQ(w->models_.size(), 0);
  ASSERT_EQ(w->plugin_manager_.model_plugins_.size(), 0);
  int count = std::count_if(w->models_.begin(), w->models_.end(),
                            [](Model* m) { return m->name_ == "turtlebot1"; });
  ASSERT_EQ(count, 0);
}

/**
 * Testing service for deleting a model that does not exist, should fail
 */
TEST_F(ServiceManagerTest, delete_nonexistent_model) {
  world_yaml = this_file_dir /
               fs::path("plugin_manager_tests/load_dummy_test/world.yaml");

  flatland_msgs::DeleteModel srv;
  srv.request.name = "random_model";

  client = nh.serviceClient<flatland_msgs::DeleteModel>("delete_model");

  StartSimulationThread();

  ros::service::waitForService("delete_model", 1000);
  ASSERT_TRUE(client.call(srv));

  ASSERT_FALSE(srv.response.success);
  EXPECT_STREQ(
      "Flatland World: failed to delete model, model with name "
      "\"random_model\" does not exist",
      srv.response.message.c_str());
}

// Run all the tests that were declared with TEST()
int main(int argc, char** argv) {
  ros::init(argc, argv, "service_manager_test");
  testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
<commit_msg>Loosened MoveModel unit test tolerance from 1e-4 to 0.01 meters<commit_after>/*
 *  ______                   __  __              __
 * /\  _  \           __    /\ \/\ \            /\ \__
 * \ \ \L\ \  __  __ /\_\   \_\ \ \ \____    ___\ \ ,_\   ____
 *  \ \  __ \/\ \/\ \\/\ \  /'_` \ \ '__`\  / __`\ \ \/  /',__\
 *   \ \ \/\ \ \ \_/ |\ \ \/\ \L\ \ \ \L\ \/\ \L\ \ \ \_/\__, `\
 *    \ \_\ \_\ \___/  \ \_\ \___,_\ \_,__/\ \____/\ \__\/\____/
 *     \/_/\/_/\/__/    \/_/\/__,_ /\/___/  \/___/  \/__/\/___/
 * @copyright Copyright 2017 Avidbots Corp.
 * @name  service_manager_test.cpp
 * @brief Testing service manager functionalities
 * @author Chunshang Li
 *
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2017, Avidbots Corp.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *      copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of the Avidbots Corp. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 */

#include <flatland_msgs/DeleteModel.h>
#include <flatland_msgs/MoveModel.h>
#include <flatland_msgs/SpawnModel.h>
#include <flatland_server/simulation_manager.h>
#include <flatland_server/timekeeper.h>
#include <flatland_server/world.h>
#include <gtest/gtest.h>
#include <regex>
#include <thread>

namespace fs = boost::filesystem;
using namespace flatland_server;

class ServiceManagerTest : public ::testing::Test {
 protected:
  SimulationManager* sim_man;
  boost::filesystem::path this_file_dir;
  boost::filesystem::path world_yaml;
  boost::filesystem::path robot_yaml;
  Timekeeper timekeeper;
  ros::NodeHandle nh;
  ros::ServiceClient client;
  std::thread simulation_thread;

  void SetUp() override {
    sim_man = nullptr;
    this_file_dir = boost::filesystem::path(__FILE__).parent_path();
    timekeeper.SetMaxStepSize(1.0);
  }

  void TearDown() override {
    StopSimulationThread();
    if (sim_man) delete sim_man;
  }

  void StartSimulationThread() {
    sim_man =
        new SimulationManager(world_yaml.string(), 1000, 1 / 1000.0, false, 0);
    simulation_thread = std::thread(&ServiceManagerTest::SimulationThread,
                                    dynamic_cast<ServiceManagerTest*>(this));
  }

  void StopSimulationThread() {
    sim_man->Shutdown();
    simulation_thread.join();
  }

  void SimulationThread() { sim_man->Main(); }
};

/**
 * Testing service for loading a model which should succeed
 */
TEST_F(ServiceManagerTest, spawn_valid_model) {
  world_yaml =
      this_file_dir / fs::path("load_world_tests/simple_test_A/world.yaml");

  robot_yaml = this_file_dir /
               fs::path("load_world_tests/simple_test_A/person.model.yaml");

  flatland_msgs::SpawnModel srv;

  srv.request.name = "service_manager_test_robot";
  srv.request.ns = "robot123";
  srv.request.yaml_path = robot_yaml.string();
  srv.request.pose.x = 101.1;
  srv.request.pose.y = 102.1;
  srv.request.pose.theta = 0.23;

  client = nh.serviceClient<flatland_msgs::SpawnModel>("spawn_model");

  // Threading is required since client.call blocks executing until return
  StartSimulationThread();

  ros::service::waitForService("spawn_model", 1000);
  ASSERT_TRUE(client.call(srv));

  ASSERT_TRUE(srv.response.success);
  ASSERT_STREQ("", srv.response.message.c_str());

  World* w = sim_man->world_;
  ASSERT_EQ(5, w->models_.size());
  EXPECT_STREQ("service_manager_test_robot", w->models_[4]->name_.c_str());
  EXPECT_STREQ("robot123", w->models_[4]->namespace_.c_str());
  EXPECT_FLOAT_EQ(101.1,
                  w->models_[4]->bodies_[0]->physics_body_->GetPosition().x);
  EXPECT_FLOAT_EQ(102.1,
                  w->models_[4]->bodies_[0]->physics_body_->GetPosition().y);
  EXPECT_FLOAT_EQ(0.23, w->models_[4]->bodies_[0]->physics_body_->GetAngle());
  EXPECT_EQ(1, w->models_[4]->bodies_.size());
}

/**
 * Testing service for loading a model which should fail
 */
TEST_F(ServiceManagerTest, spawn_invalid_model) {
  world_yaml =
      this_file_dir / fs::path("load_world_tests/simple_test_A/world.yaml");

  robot_yaml = this_file_dir / fs::path("random_path/turtlebot.model.yaml");

  flatland_msgs::SpawnModel srv;

  srv.request.name = "service_manager_test_robot";
  srv.request.yaml_path = robot_yaml.string();
  srv.request.pose.x = 1;
  srv.request.pose.y = 2;
  srv.request.pose.theta = 3;

  client = nh.serviceClient<flatland_msgs::SpawnModel>("spawn_model");

  StartSimulationThread();

  ros::service::waitForService("spawn_model", 1000);
  ASSERT_TRUE(client.call(srv));

  ASSERT_FALSE(srv.response.success);

  std::cmatch match;
  std::string regex_str =
      "Flatland YAML: File does not exist, "
      "path=\".*/random_path/turtlebot.model.yaml\".*";
  std::regex regex(regex_str);
  EXPECT_TRUE(std::regex_match(srv.response.message.c_str(), match, regex))
      << "Error Message '" + srv.response.message + "'" +
             " did not match against regex '" + regex_str + "'";
}

/**
 * Testing service for moving a valid model
 */
TEST_F(ServiceManagerTest, move_model) {
  world_yaml =
      this_file_dir / fs::path("load_world_tests/simple_test_A/world.yaml");

  flatland_msgs::MoveModel srv;
  srv.request.name = "turtlebot1";
  srv.request.pose.x = 5.5;
  srv.request.pose.y = 9.9;
  srv.request.pose.theta = 0.77;

  client = nh.serviceClient<flatland_msgs::MoveModel>("move_model");

  StartSimulationThread();

  ros::service::waitForService("move_model", 1000);
  ASSERT_TRUE(client.call(srv));

  ASSERT_TRUE(srv.response.success);

  World* w = sim_man->world_;
  EXPECT_NEAR(5.5, w->models_[0]->bodies_[0]->physics_body_->GetPosition().x,
              1e-2);
  EXPECT_NEAR(9.9, w->models_[0]->bodies_[0]->physics_body_->GetPosition().y,
              1e-2);
  EXPECT_NEAR(0.77, w->models_[0]->bodies_[0]->physics_body_->GetAngle(), 1e-2);
}

/**
 * Testing service for moving a nonexistent model
 */
TEST_F(ServiceManagerTest, move_nonexistent_model) {
  world_yaml =
      this_file_dir / fs::path("load_world_tests/simple_test_A/world.yaml");

  flatland_msgs::MoveModel srv;
  srv.request.name = "not_a_robot";
  srv.request.pose.x = 4;
  srv.request.pose.y = 5;
  srv.request.pose.theta = 0;

  client = nh.serviceClient<flatland_msgs::MoveModel>("move_model");

  StartSimulationThread();

  ros::service::waitForService("move_model", 1000);
  ASSERT_TRUE(client.call(srv));

  ASSERT_FALSE(srv.response.success);
  EXPECT_STREQ(
      "Flatland World: failed to move model, model with name "
      "\"not_a_robot\" does not exist",
      srv.response.message.c_str());
}

/**
 * Testing service for deleting a model
 */
TEST_F(ServiceManagerTest, delete_model) {
  world_yaml = this_file_dir /
               fs::path("plugin_manager_tests/load_dummy_test/world.yaml");

  flatland_msgs::DeleteModel srv;
  srv.request.name = "turtlebot1";

  client = nh.serviceClient<flatland_msgs::DeleteModel>("delete_model");

  StartSimulationThread();

  ros::service::waitForService("delete_model", 1000);
  ASSERT_TRUE(client.call(srv));

  ASSERT_TRUE(srv.response.success);
  World* w = sim_man->world_;
  // after deleting a mode, there should be one less model, and one less plugin
  ASSERT_EQ(w->models_.size(), 0);
  ASSERT_EQ(w->plugin_manager_.model_plugins_.size(), 0);
  int count = std::count_if(w->models_.begin(), w->models_.end(),
                            [](Model* m) { return m->name_ == "turtlebot1"; });
  ASSERT_EQ(count, 0);
}

/**
 * Testing service for deleting a model that does not exist, should fail
 */
TEST_F(ServiceManagerTest, delete_nonexistent_model) {
  world_yaml = this_file_dir /
               fs::path("plugin_manager_tests/load_dummy_test/world.yaml");

  flatland_msgs::DeleteModel srv;
  srv.request.name = "random_model";

  client = nh.serviceClient<flatland_msgs::DeleteModel>("delete_model");

  StartSimulationThread();

  ros::service::waitForService("delete_model", 1000);
  ASSERT_TRUE(client.call(srv));

  ASSERT_FALSE(srv.response.success);
  EXPECT_STREQ(
      "Flatland World: failed to delete model, model with name "
      "\"random_model\" does not exist",
      srv.response.message.c_str());
}

// Run all the tests that were declared with TEST()
int main(int argc, char** argv) {
  ros::init(argc, argv, "service_manager_test");
  testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
<|endoftext|>


<commit_before>/*
 *  Debug.cpp
 *  OpenLieroX
 *
 *  Created by Albert Zeyer on 01.01.09.
 *  code under LGPL
 *
 */

#include "Debug.h"

#if defined(__GLIBCXX__) || defined(__GLIBC__) || !defined(WIN32)

#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h>

void DumpCallstackPrintf() {
	void *callstack[128];
	int framesC = backtrace(callstack, sizeof(callstack));
	printf("backtrace() returned %d addresses\n", framesC);
	char** strs = backtrace_symbols(callstack, framesC);
	for(int i = 0; i < framesC; ++i) {
		if(strs[i])
			printf("%s\n", strs[i]);
		else
			break;
	}
	free(strs);
}

void DumpCallstack(void (*LineOutFct) (const std::string&)) {
	void *callstack[128];
	int framesC = backtrace(callstack, sizeof(callstack));
	(*LineOutFct) ("DumpCallstack: " + itoa(framesC) + " addresses:");
	char** strs = backtrace_symbols(callstack, framesC);
	for(int i = 0; i < framesC; ++i) {
		if(strs[i])
			(*LineOutFct) (std::string(" ") + strs[i]);
		else
			break;
	}
	free(strs);
}

#else

void DumpCallstackPrintf() { printf("DumpCallstackPrintf() not implemented in this version.\n"); }
void DumpCallstack(void (*LineOutFct) (const std::string&)) { (*LineOutFct) ("DumpCallstack() not implemented in this version."); }

#endif

Logger notes(1,2,1000, "n: ");
Logger hints(0,1,100, "H: ");
Logger warnings(0,0,10, "W: ");
Logger errors(-1,-1,1, "E: ");

#include <iostream>
#include <sstream>
#include "Options.h"
#include "console.h"
#include "StringUtils.h"

using namespace std;

static void CoutPrintLn(const std::string& str) {
	cout << str << "\n";
}

template<int col> void ConPrintLn(const std::string& str) {
	Con_AddText(col, str, false);
}

Logger& Logger::flush() {
	if(!tLXOptions || tLXOptions->iVerbosity >= minCoutVerb) {
		PrettyPrint(prefix, buffer, CoutPrintLn);
		cout.flush();
	}
	if(tLXOptions && tLXOptions->iVerbosity >= minCallstackVerb) {
		DumpCallstackPrintf();
	}
	if(tLXOptions && Con_IsInited() && tLXOptions->iVerbosity >= minIngameConVerb) {
		// the check is a bit hacky (see Con_AddText) but I really dont want to overcomplicate this
		if(!strStartsWith(buffer, "Ingame console: ")) {
			// we are not safing explicitly a color in the Logger, thus we try to assume a good color from the verbosity level
			if(minIngameConVerb < 0)
				PrettyPrint(prefix, buffer, ConPrintLn<CNC_ERROR>);
			else if(minIngameConVerb == 0)
				PrettyPrint(prefix, buffer, ConPrintLn<CNC_WARNING>);
			else if(minIngameConVerb == 1)
				PrettyPrint(prefix, buffer, ConPrintLn<CNC_NOTIFY>);
			else if(minIngameConVerb < 5)
				PrettyPrint(prefix, buffer, ConPrintLn<CNC_NORMAL>);
			else // >=5
				PrettyPrint(prefix, buffer, ConPrintLn<CNC_DEV>);
		}
		if(tLXOptions->iVerbosity >= minCallstackVerb) {
			DumpCallstack(ConPrintLn<CNC_DEV>);
		}
	}
	buffer = "";
	return *this;
}
<commit_msg>notes should be shown on console by default<commit_after>/*
 *  Debug.cpp
 *  OpenLieroX
 *
 *  Created by Albert Zeyer on 01.01.09.
 *  code under LGPL
 *
 */

#include "Debug.h"

#if defined(__GLIBCXX__) || defined(__GLIBC__) || !defined(WIN32)

#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h>

void DumpCallstackPrintf() {
	void *callstack[128];
	int framesC = backtrace(callstack, sizeof(callstack));
	printf("backtrace() returned %d addresses\n", framesC);
	char** strs = backtrace_symbols(callstack, framesC);
	for(int i = 0; i < framesC; ++i) {
		if(strs[i])
			printf("%s\n", strs[i]);
		else
			break;
	}
	free(strs);
}

void DumpCallstack(void (*LineOutFct) (const std::string&)) {
	void *callstack[128];
	int framesC = backtrace(callstack, sizeof(callstack));
	(*LineOutFct) ("DumpCallstack: " + itoa(framesC) + " addresses:");
	char** strs = backtrace_symbols(callstack, framesC);
	for(int i = 0; i < framesC; ++i) {
		if(strs[i])
			(*LineOutFct) (std::string(" ") + strs[i]);
		else
			break;
	}
	free(strs);
}

#else

void DumpCallstackPrintf() { printf("DumpCallstackPrintf() not implemented in this version.\n"); }
void DumpCallstack(void (*LineOutFct) (const std::string&)) { (*LineOutFct) ("DumpCallstack() not implemented in this version."); }

#endif

Logger notes(0,2,1000, "n: ");
Logger hints(0,1,100, "H: ");
Logger warnings(0,0,10, "W: ");
Logger errors(-1,-1,1, "E: ");

#include <iostream>
#include <sstream>
#include "Options.h"
#include "console.h"
#include "StringUtils.h"

using namespace std;

static void CoutPrintLn(const std::string& str) {
	cout << str << "\n";
}

template<int col> void ConPrintLn(const std::string& str) {
	Con_AddText(col, str, false);
}

Logger& Logger::flush() {
	if(!tLXOptions || tLXOptions->iVerbosity >= minCoutVerb) {
		PrettyPrint(prefix, buffer, CoutPrintLn);
		cout.flush();
	}
	if(tLXOptions && tLXOptions->iVerbosity >= minCallstackVerb) {
		DumpCallstackPrintf();
	}
	if(tLXOptions && Con_IsInited() && tLXOptions->iVerbosity >= minIngameConVerb) {
		// the check is a bit hacky (see Con_AddText) but I really dont want to overcomplicate this
		if(!strStartsWith(buffer, "Ingame console: ")) {
			// we are not safing explicitly a color in the Logger, thus we try to assume a good color from the verbosity level
			if(minIngameConVerb < 0)
				PrettyPrint(prefix, buffer, ConPrintLn<CNC_ERROR>);
			else if(minIngameConVerb == 0)
				PrettyPrint(prefix, buffer, ConPrintLn<CNC_WARNING>);
			else if(minIngameConVerb == 1)
				PrettyPrint(prefix, buffer, ConPrintLn<CNC_NOTIFY>);
			else if(minIngameConVerb < 5)
				PrettyPrint(prefix, buffer, ConPrintLn<CNC_NORMAL>);
			else // >=5
				PrettyPrint(prefix, buffer, ConPrintLn<CNC_DEV>);
		}
		if(tLXOptions->iVerbosity >= minCallstackVerb) {
			DumpCallstack(ConPrintLn<CNC_DEV>);
		}
	}
	buffer = "";
	return *this;
}
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#include <uielement/menubarwrapper.hxx>
#include <threadhelp/resetableguard.hxx>
#include <framework/actiontriggerhelper.hxx>
#include <services.h>

#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/awt/XSystemDependentMenuPeer.hpp>
#include <com/sun/star/awt/XMenuBar.hpp>
#include <com/sun/star/container/XIndexContainer.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/ui/UIElementType.hpp>
#include <com/sun/star/frame/ModuleManager.hpp>
#include <com/sun/star/util/URLTransformer.hpp>

#include <comphelper/processfactory.hxx>
#include <tools/solar.h>
#include <vcl/svapp.hxx>
#include <rtl/logfile.hxx>

using namespace com::sun::star;
using namespace com::sun::star::uno;
using namespace com::sun::star::beans;
using namespace com::sun::star::frame;
using namespace com::sun::star::lang;
using namespace com::sun::star::container;
using namespace com::sun::star::awt;
using namespace com::sun::star::util;
using namespace ::com::sun::star::ui;

namespace framework
{

//*****************************************************************************************************************
//  XInterface, XTypeProvider
//*****************************************************************************************************************
DEFINE_XINTERFACE_11    (   MenuBarWrapper                                                    ,
                            UIConfigElementWrapperBase                                        ,
                            DIRECT_INTERFACE( ::com::sun::star::lang::XTypeProvider          ),
                            DIRECT_INTERFACE( ::com::sun::star::ui::XUIElement               ),
                            DIRECT_INTERFACE( ::com::sun::star::ui::XUIElementSettings       ),
                            DIRECT_INTERFACE( ::com::sun::star::beans::XMultiPropertySet     ),
                            DIRECT_INTERFACE( ::com::sun::star::beans::XFastPropertySet      ),
                            DIRECT_INTERFACE( ::com::sun::star::beans::XPropertySet          ),
                            DIRECT_INTERFACE( ::com::sun::star::lang::XInitialization        ),
                            DIRECT_INTERFACE( ::com::sun::star::lang::XComponent             ),
                            DIRECT_INTERFACE( ::com::sun::star::util::XUpdatable             ),
                            DIRECT_INTERFACE( ::com::sun::star::ui::XUIConfigurationListener ),
                            DERIVED_INTERFACE( ::com::sun::star::container::XNameAccess, ::com::sun::star::container::XElementAccess )
                        )

DEFINE_XTYPEPROVIDER_11 (   MenuBarWrapper                                  ,
                            ::com::sun::star::lang::XTypeProvider           ,
                            ::com::sun::star::ui::XUIElement                ,
                            ::com::sun::star::ui::XUIElementSettings        ,
                            ::com::sun::star::beans::XMultiPropertySet      ,
                            ::com::sun::star::beans::XFastPropertySet       ,
                            ::com::sun::star::beans::XPropertySet           ,
                            ::com::sun::star::lang::XInitialization         ,
                            ::com::sun::star::lang::XComponent              ,
                            ::com::sun::star::util::XUpdatable              ,
                            ::com::sun::star::ui::XUIConfigurationListener  ,
                            ::com::sun::star::container::XNameAccess
                        )

MenuBarWrapper::MenuBarWrapper(
    const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& xServiceManager
    )
:    UIConfigElementWrapperBase( UIElementType::MENUBAR,xServiceManager ),
     m_bRefreshPopupControllerCache( sal_True )
{
}

MenuBarWrapper::~MenuBarWrapper()
{
}

void SAL_CALL MenuBarWrapper::dispose() throw (::com::sun::star::uno::RuntimeException)
{
    Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY );

    com::sun::star::lang::EventObject aEvent( xThis );
    m_aListenerContainer.disposeAndClear( aEvent );

    ResetableGuard aLock( m_aLock );

    m_xMenuBarManager->dispose();
    m_xMenuBarManager.clear();
    m_xConfigSource.clear();
    m_xConfigData.clear();

    m_xMenuBar.clear();
    m_bDisposed = sal_True;
}

//void generateFullMenuBar( MenuBarManager *pMenuBarManager, MenuBar *pMenuBar )
//{
//    for (int i=0; i < pMenuBar->GetItemCount(); i++)
//    {
//        sal_Int16 nId = pMenuBar->GetItemId( i );

//        String aCommandLabel = pMenuBar->GetItemCommand( nId );

//        String label = pMenuBarManager->RetrieveLabelFromCommand( aCommandLabel );
//        pMenuBar->SetItemText( nId, label );
//    }
//}

// XInitialization
void SAL_CALL MenuBarWrapper::initialize( const Sequence< Any >& aArguments ) throw ( Exception, RuntimeException )
{
    RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::MenuBarWrapper::initialize" );

    ResetableGuard aLock( m_aLock );

    if ( m_bDisposed )
        throw DisposedException();

    if ( !m_bInitialized )
    {
        rtl::OUString aModuleIdentifier;
        UIConfigElementWrapperBase::initialize( aArguments );

        Reference< XFrame > xFrame( m_xWeakFrame );
        if ( xFrame.is() && m_xConfigSource.is() )
        {
            // Create VCL menubar which will be filled with settings data
            MenuBar*        pVCLMenuBar = 0;
            VCLXMenuBar*    pAwtMenuBar = 0;
            {
                SolarMutexGuard aSolarMutexGuard;
                pVCLMenuBar = new MenuBar();
            }

            Reference< XModuleManager2 > xModuleManager = ModuleManager::create( comphelper::getComponentContext(m_xServiceFactory) );

            try
            {
                aModuleIdentifier = xModuleManager->identify( xFrame );
            }
            catch( const Exception& )
            {
            }

            Reference< XURLTransformer > xTrans;
            try
            {
                xTrans.set( URLTransformer::create(::comphelper::getComponentContext(m_xServiceFactory)) );
                m_xConfigData = m_xConfigSource->getSettings( m_aResourceURL, sal_False );
                if ( m_xConfigData.is() )
                {
                    // Fill menubar with container contents
                    sal_uInt16 nId = 1;
                    MenuBarManager::FillMenuWithConfiguration( nId, pVCLMenuBar, aModuleIdentifier, m_xConfigData, xTrans );
                }
            }
            catch ( const NoSuchElementException& )
            {
            }

            sal_Bool bMenuOnly( sal_False );
            for ( sal_Int32 n = 0; n < aArguments.getLength(); n++ )
            {
                PropertyValue aPropValue;
                if ( aArguments[n] >>= aPropValue )
                {
                    if ( aPropValue.Name == "MenuOnly" )
                        aPropValue.Value >>= bMenuOnly;
                }
            }

            if ( !bMenuOnly )
            {
                // Initialize menubar manager with our vcl menu bar. There are some situations where we only want to get the menu without any
                // interaction which is done by the menu bar manager. This must be requested by a special property called "MenuOnly". Be careful
                // a menu bar created with this property is not fully supported. It must be attached to a real menu bar manager to have full
                // support. This feature is currently used for "Inplace editing"!
                Reference< XDispatchProvider > xDispatchProvider;

                MenuBarManager* pMenuBarManager = new MenuBarManager( m_xServiceFactory,
                                                                      xFrame,
                                                                      xTrans,
                                                                      xDispatchProvider,
                                                                      aModuleIdentifier,
                                                                      pVCLMenuBar,
                                                                      sal_False,
                                                                      sal_True );

                m_xMenuBarManager = Reference< XComponent >( static_cast< OWeakObject *>( pMenuBarManager ), UNO_QUERY );

//                pMenuBarManager->GenerateFullMenuHierarchy( pVCLMenuBar );
                pVCLMenuBar->Freeze();
            }

            // Initialize toolkit menu bar implementation to have awt::XMenuBar for data exchange.
            // Don't use this toolkit menu bar or one of its functions. It is only used as a data container!
            pAwtMenuBar = new VCLXMenuBar( pVCLMenuBar );
            m_xMenuBar = Reference< XMenuBar >( static_cast< OWeakObject *>( pAwtMenuBar ), UNO_QUERY );
        }
    }
}

// XUIElementSettings
void SAL_CALL MenuBarWrapper::updateSettings() throw ( RuntimeException )
{
    ResetableGuard aLock( m_aLock );

    if ( m_bDisposed )
        throw DisposedException();

    if ( m_xMenuBarManager.is() )
    {
        if ( m_xConfigSource.is() && m_bPersistent )
        {
            try
            {
                MenuBarManager* pMenuBarManager = static_cast< MenuBarManager *>( m_xMenuBarManager.get() );

                m_xConfigData = m_xConfigSource->getSettings( m_aResourceURL, sal_False );
                if ( m_xConfigData.is() )
                    pMenuBarManager->SetItemContainer( m_xConfigData );
            }
            catch ( const NoSuchElementException& )
            {
            }
        }
        else if ( !m_bPersistent )
        {
            // Transient menubar: do nothing
        }
    }
}
void MenuBarWrapper::impl_fillNewData()
{
    // Transient menubar => Fill menubar with new data
    MenuBarManager* pMenuBarManager = static_cast< MenuBarManager *>( m_xMenuBarManager.get() );

    if ( pMenuBarManager )
        pMenuBarManager->SetItemContainer( m_xConfigData );
}

void MenuBarWrapper::fillPopupControllerCache()
{
    if ( m_bRefreshPopupControllerCache )
    {
        MenuBarManager* pMenuBarManager = static_cast< MenuBarManager *>( m_xMenuBarManager.get() );
        if ( pMenuBarManager )
            pMenuBarManager->GetPopupController( m_aPopupControllerCache );
        if ( !m_aPopupControllerCache.empty() )
            m_bRefreshPopupControllerCache = sal_False;
    }
}

// XElementAccess
Type SAL_CALL MenuBarWrapper::getElementType()
throw (::com::sun::star::uno::RuntimeException)
{
    return ::getCppuType(( Reference< XDispatchProvider >*)0);
}

::sal_Bool SAL_CALL MenuBarWrapper::hasElements()
throw (::com::sun::star::uno::RuntimeException)
{
    ResetableGuard aLock( m_aLock );

    if ( m_bDisposed )
        throw DisposedException();

    fillPopupControllerCache();
    return ( !m_aPopupControllerCache.empty() );
}

// XNameAccess
Any SAL_CALL MenuBarWrapper::getByName(
    const ::rtl::OUString& aName )
throw ( container::NoSuchElementException,
        lang::WrappedTargetException,
        uno::RuntimeException)
{
    ResetableGuard aLock( m_aLock );

    if ( m_bDisposed )
        throw DisposedException();

    fillPopupControllerCache();

    PopupControllerCache::const_iterator pIter = m_aPopupControllerCache.find( aName );
    if ( pIter != m_aPopupControllerCache.end() )
    {
        uno::Reference< frame::XDispatchProvider > xDispatchProvider;
        xDispatchProvider = pIter->second.m_xDispatchProvider;
        return uno::makeAny( xDispatchProvider );
    }
    else
        throw container::NoSuchElementException();
}

Sequence< ::rtl::OUString > SAL_CALL MenuBarWrapper::getElementNames()
throw (::com::sun::star::uno::RuntimeException)
{
    ResetableGuard aLock( m_aLock );

    if ( m_bDisposed )
        throw DisposedException();

    fillPopupControllerCache();

    Sequence< rtl::OUString > aSeq( m_aPopupControllerCache.size() );

    sal_Int32 i( 0 );
    PopupControllerCache::const_iterator pIter = m_aPopupControllerCache.begin();
    while ( pIter != m_aPopupControllerCache.end() )
    {
        aSeq[i++] = pIter->first;
        ++pIter;
    }

    return aSeq;
}

::sal_Bool SAL_CALL MenuBarWrapper::hasByName(
    const ::rtl::OUString& aName )
throw (::com::sun::star::uno::RuntimeException)
{
    ResetableGuard aLock( m_aLock );

    if ( m_bDisposed )
        throw DisposedException();

    fillPopupControllerCache();

    PopupControllerCache::const_iterator pIter = m_aPopupControllerCache.find( aName );
    if ( pIter != m_aPopupControllerCache.end() )
        return sal_True;
    else
        return sal_False;
}

// XUIElement
Reference< XInterface > SAL_CALL MenuBarWrapper::getRealInterface() throw ( RuntimeException )
{
    if ( m_bDisposed )
        throw DisposedException();

    return Reference< XInterface >( m_xMenuBarManager, UNO_QUERY );
}

} // namespace framework

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>more cleanup<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#include <uielement/menubarwrapper.hxx>
#include <threadhelp/resetableguard.hxx>
#include <framework/actiontriggerhelper.hxx>
#include <services.h>

#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/awt/XSystemDependentMenuPeer.hpp>
#include <com/sun/star/awt/XMenuBar.hpp>
#include <com/sun/star/container/XIndexContainer.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/ui/UIElementType.hpp>
#include <com/sun/star/frame/ModuleManager.hpp>
#include <com/sun/star/util/URLTransformer.hpp>

#include <comphelper/processfactory.hxx>
#include <tools/solar.h>
#include <vcl/svapp.hxx>
#include <rtl/logfile.hxx>

using namespace com::sun::star;
using namespace com::sun::star::uno;
using namespace com::sun::star::beans;
using namespace com::sun::star::frame;
using namespace com::sun::star::lang;
using namespace com::sun::star::container;
using namespace com::sun::star::awt;
using namespace com::sun::star::util;
using namespace ::com::sun::star::ui;

namespace framework
{

//*****************************************************************************************************************
//  XInterface, XTypeProvider
//*****************************************************************************************************************
DEFINE_XINTERFACE_11    (   MenuBarWrapper                                                    ,
                            UIConfigElementWrapperBase                                        ,
                            DIRECT_INTERFACE( ::com::sun::star::lang::XTypeProvider          ),
                            DIRECT_INTERFACE( ::com::sun::star::ui::XUIElement               ),
                            DIRECT_INTERFACE( ::com::sun::star::ui::XUIElementSettings       ),
                            DIRECT_INTERFACE( ::com::sun::star::beans::XMultiPropertySet     ),
                            DIRECT_INTERFACE( ::com::sun::star::beans::XFastPropertySet      ),
                            DIRECT_INTERFACE( ::com::sun::star::beans::XPropertySet          ),
                            DIRECT_INTERFACE( ::com::sun::star::lang::XInitialization        ),
                            DIRECT_INTERFACE( ::com::sun::star::lang::XComponent             ),
                            DIRECT_INTERFACE( ::com::sun::star::util::XUpdatable             ),
                            DIRECT_INTERFACE( ::com::sun::star::ui::XUIConfigurationListener ),
                            DERIVED_INTERFACE( ::com::sun::star::container::XNameAccess, ::com::sun::star::container::XElementAccess )
                        )

DEFINE_XTYPEPROVIDER_11 (   MenuBarWrapper                                  ,
                            ::com::sun::star::lang::XTypeProvider           ,
                            ::com::sun::star::ui::XUIElement                ,
                            ::com::sun::star::ui::XUIElementSettings        ,
                            ::com::sun::star::beans::XMultiPropertySet      ,
                            ::com::sun::star::beans::XFastPropertySet       ,
                            ::com::sun::star::beans::XPropertySet           ,
                            ::com::sun::star::lang::XInitialization         ,
                            ::com::sun::star::lang::XComponent              ,
                            ::com::sun::star::util::XUpdatable              ,
                            ::com::sun::star::ui::XUIConfigurationListener  ,
                            ::com::sun::star::container::XNameAccess
                        )

MenuBarWrapper::MenuBarWrapper(
    const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& xServiceManager
    )
:    UIConfigElementWrapperBase( UIElementType::MENUBAR,xServiceManager ),
     m_bRefreshPopupControllerCache( sal_True )
{
}

MenuBarWrapper::~MenuBarWrapper()
{
}

void SAL_CALL MenuBarWrapper::dispose() throw (::com::sun::star::uno::RuntimeException)
{
    Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY );

    com::sun::star::lang::EventObject aEvent( xThis );
    m_aListenerContainer.disposeAndClear( aEvent );

    ResetableGuard aLock( m_aLock );

    m_xMenuBarManager->dispose();
    m_xMenuBarManager.clear();
    m_xConfigSource.clear();
    m_xConfigData.clear();

    m_xMenuBar.clear();
    m_bDisposed = sal_True;
}

// XInitialization
void SAL_CALL MenuBarWrapper::initialize( const Sequence< Any >& aArguments ) throw ( Exception, RuntimeException )
{
    RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::MenuBarWrapper::initialize" );

    ResetableGuard aLock( m_aLock );

    if ( m_bDisposed )
        throw DisposedException();

    if ( !m_bInitialized )
    {
        rtl::OUString aModuleIdentifier;
        UIConfigElementWrapperBase::initialize( aArguments );

        Reference< XFrame > xFrame( m_xWeakFrame );
        if ( xFrame.is() && m_xConfigSource.is() )
        {
            // Create VCL menubar which will be filled with settings data
            MenuBar*        pVCLMenuBar = 0;
            VCLXMenuBar*    pAwtMenuBar = 0;
            {
                SolarMutexGuard aSolarMutexGuard;
                pVCLMenuBar = new MenuBar();
            }

            Reference< XModuleManager2 > xModuleManager = ModuleManager::create( comphelper::getComponentContext(m_xServiceFactory) );

            try
            {
                aModuleIdentifier = xModuleManager->identify( xFrame );
            }
            catch( const Exception& )
            {
            }

            Reference< XURLTransformer > xTrans;
            try
            {
                xTrans.set( URLTransformer::create(::comphelper::getComponentContext(m_xServiceFactory)) );
                m_xConfigData = m_xConfigSource->getSettings( m_aResourceURL, sal_False );
                if ( m_xConfigData.is() )
                {
                    // Fill menubar with container contents
                    sal_uInt16 nId = 1;
                    MenuBarManager::FillMenuWithConfiguration( nId, pVCLMenuBar, aModuleIdentifier, m_xConfigData, xTrans );
                }
            }
            catch ( const NoSuchElementException& )
            {
            }

            sal_Bool bMenuOnly( sal_False );
            for ( sal_Int32 n = 0; n < aArguments.getLength(); n++ )
            {
                PropertyValue aPropValue;
                if ( aArguments[n] >>= aPropValue )
                {
                    if ( aPropValue.Name == "MenuOnly" )
                        aPropValue.Value >>= bMenuOnly;
                }
            }

            if ( !bMenuOnly )
            {
                // Initialize menubar manager with our vcl menu bar. There are some situations where we only want to get the menu without any
                // interaction which is done by the menu bar manager. This must be requested by a special property called "MenuOnly". Be careful
                // a menu bar created with this property is not fully supported. It must be attached to a real menu bar manager to have full
                // support. This feature is currently used for "Inplace editing"!
                Reference< XDispatchProvider > xDispatchProvider;

                MenuBarManager* pMenuBarManager = new MenuBarManager( m_xServiceFactory,
                                                                      xFrame,
                                                                      xTrans,
                                                                      xDispatchProvider,
                                                                      aModuleIdentifier,
                                                                      pVCLMenuBar,
                                                                      sal_False,
                                                                      sal_True );

                m_xMenuBarManager = Reference< XComponent >( static_cast< OWeakObject *>( pMenuBarManager ), UNO_QUERY );

                pVCLMenuBar->Freeze();
            }

            // Initialize toolkit menu bar implementation to have awt::XMenuBar for data exchange.
            // Don't use this toolkit menu bar or one of its functions. It is only used as a data container!
            pAwtMenuBar = new VCLXMenuBar( pVCLMenuBar );
            m_xMenuBar = Reference< XMenuBar >( static_cast< OWeakObject *>( pAwtMenuBar ), UNO_QUERY );
        }
    }
}

// XUIElementSettings
void SAL_CALL MenuBarWrapper::updateSettings() throw ( RuntimeException )
{
    ResetableGuard aLock( m_aLock );

    if ( m_bDisposed )
        throw DisposedException();

    if ( m_xMenuBarManager.is() )
    {
        if ( m_xConfigSource.is() && m_bPersistent )
        {
            try
            {
                MenuBarManager* pMenuBarManager = static_cast< MenuBarManager *>( m_xMenuBarManager.get() );

                m_xConfigData = m_xConfigSource->getSettings( m_aResourceURL, sal_False );
                if ( m_xConfigData.is() )
                    pMenuBarManager->SetItemContainer( m_xConfigData );
            }
            catch ( const NoSuchElementException& )
            {
            }
        }
        else if ( !m_bPersistent )
        {
            // Transient menubar: do nothing
        }
    }
}
void MenuBarWrapper::impl_fillNewData()
{
    // Transient menubar => Fill menubar with new data
    MenuBarManager* pMenuBarManager = static_cast< MenuBarManager *>( m_xMenuBarManager.get() );

    if ( pMenuBarManager )
        pMenuBarManager->SetItemContainer( m_xConfigData );
}

void MenuBarWrapper::fillPopupControllerCache()
{
    if ( m_bRefreshPopupControllerCache )
    {
        MenuBarManager* pMenuBarManager = static_cast< MenuBarManager *>( m_xMenuBarManager.get() );
        if ( pMenuBarManager )
            pMenuBarManager->GetPopupController( m_aPopupControllerCache );
        if ( !m_aPopupControllerCache.empty() )
            m_bRefreshPopupControllerCache = sal_False;
    }
}

// XElementAccess
Type SAL_CALL MenuBarWrapper::getElementType()
throw (::com::sun::star::uno::RuntimeException)
{
    return ::getCppuType(( Reference< XDispatchProvider >*)0);
}

::sal_Bool SAL_CALL MenuBarWrapper::hasElements()
throw (::com::sun::star::uno::RuntimeException)
{
    ResetableGuard aLock( m_aLock );

    if ( m_bDisposed )
        throw DisposedException();

    fillPopupControllerCache();
    return ( !m_aPopupControllerCache.empty() );
}

// XNameAccess
Any SAL_CALL MenuBarWrapper::getByName(
    const ::rtl::OUString& aName )
throw ( container::NoSuchElementException,
        lang::WrappedTargetException,
        uno::RuntimeException)
{
    ResetableGuard aLock( m_aLock );

    if ( m_bDisposed )
        throw DisposedException();

    fillPopupControllerCache();

    PopupControllerCache::const_iterator pIter = m_aPopupControllerCache.find( aName );
    if ( pIter != m_aPopupControllerCache.end() )
    {
        uno::Reference< frame::XDispatchProvider > xDispatchProvider;
        xDispatchProvider = pIter->second.m_xDispatchProvider;
        return uno::makeAny( xDispatchProvider );
    }
    else
        throw container::NoSuchElementException();
}

Sequence< ::rtl::OUString > SAL_CALL MenuBarWrapper::getElementNames()
throw (::com::sun::star::uno::RuntimeException)
{
    ResetableGuard aLock( m_aLock );

    if ( m_bDisposed )
        throw DisposedException();

    fillPopupControllerCache();

    Sequence< rtl::OUString > aSeq( m_aPopupControllerCache.size() );

    sal_Int32 i( 0 );
    PopupControllerCache::const_iterator pIter = m_aPopupControllerCache.begin();
    while ( pIter != m_aPopupControllerCache.end() )
    {
        aSeq[i++] = pIter->first;
        ++pIter;
    }

    return aSeq;
}

::sal_Bool SAL_CALL MenuBarWrapper::hasByName(
    const ::rtl::OUString& aName )
throw (::com::sun::star::uno::RuntimeException)
{
    ResetableGuard aLock( m_aLock );

    if ( m_bDisposed )
        throw DisposedException();

    fillPopupControllerCache();

    PopupControllerCache::const_iterator pIter = m_aPopupControllerCache.find( aName );
    if ( pIter != m_aPopupControllerCache.end() )
        return sal_True;
    else
        return sal_False;
}

// XUIElement
Reference< XInterface > SAL_CALL MenuBarWrapper::getRealInterface() throw ( RuntimeException )
{
    if ( m_bDisposed )
        throw DisposedException();

    return Reference< XInterface >( m_xMenuBarManager, UNO_QUERY );
}

} // namespace framework

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: menubarwrapper.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: kz $ $Date: 2005-01-21 09:51:50 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

//_________________________________________________________________________________________________________________
//  my own includes
//_________________________________________________________________________________________________________________

#ifndef __FRAMEWORK_UIELEMENT_MENUBARWRAPPER_HXX_
#include <uielement/menubarwrapper.hxx>
#endif

#ifndef __FRAMEWORK_THREADHELP_RESETABLEGUARD_HXX_
#include <threadhelp/resetableguard.hxx>
#endif

#ifndef __FRAMEWORK_HELPER_ACTIONTRIGGERHELPER_HXX_
#include <helper/actiontriggerhelper.hxx>
#endif

#ifndef __FRAMEWORK_UIELEMENT_CONSTITEMCONTAINER_HXX_
#include <uielement/constitemcontainer.hxx>
#endif

#ifndef __FRAMEWORK_UIELEMENT_ROOTITEMCONTAINER_HXX_
#include <uielement/rootitemcontainer.hxx>
#endif

//_________________________________________________________________________________________________________________
//  interface includes
//_________________________________________________________________________________________________________________

#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif

#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif

#ifndef _COM_SUN_STAR_AWT_XSYSTEMDEPENDENTMENUPEER_HPP_
#include <com/sun/star/awt/XSystemDependentMenuPeer.hpp>
#endif

#ifndef _COM_SUN_STAR_AWT_XMENUBAR_HPP_
#include <com/sun/star/awt/XMenuBar.hpp>
#endif

#ifndef _COM_SUN_STAR_CONTAINER_XINDEXCONTAINER_HPP_
#include <com/sun/star/container/XIndexContainer.hpp>
#endif

#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
#include <com/sun/star/container/XNameAccess.hpp>
#endif

#ifndef _DRAFTS_COM_SUN_STAR_UI_UIELEMENTTYPE_HPP_
#include <drafts/com/sun/star/ui/UIElementType.hpp>
#endif

//_________________________________________________________________________________________________________________
//  other includes
//_________________________________________________________________________________________________________________

#ifndef _COMPHELPER_PROCESSFACTORY_HXX_
#include <comphelper/processfactory.hxx>
#endif
#include <tools/solar.h>
#include <vcl/svapp.hxx>
#include <rtl/logfile.hxx>

using namespace rtl;
using namespace com::sun::star::uno;
using namespace com::sun::star::beans;
using namespace com::sun::star::frame;
using namespace com::sun::star::lang;
using namespace com::sun::star::container;
using namespace com::sun::star::awt;
using namespace drafts::com::sun::star::ui;

namespace framework
{

// #110897#
MenuBarWrapper::MenuBarWrapper(
    const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& xServiceManager
    )
:   // #110897#
    mxServiceFactory( xServiceManager ),
    UIConfigElementWrapperBase( UIElementType::MENUBAR )
{
}

MenuBarWrapper::~MenuBarWrapper()
{
}

// #110897#
const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& MenuBarWrapper::getServiceFactory()
{
    // #110897#
    return mxServiceFactory;
}

void SAL_CALL MenuBarWrapper::dispose() throw (::com::sun::star::uno::RuntimeException)
{
    Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY );

    com::sun::star::lang::EventObject aEvent( xThis );
    m_aListenerContainer.disposeAndClear( aEvent );

    ResetableGuard aLock( m_aLock );

    m_xMenuBarManager->dispose();
    m_xMenuBarManager.clear();
    m_xConfigSource.clear();
    m_xConfigData.clear();

    m_xMenuBar.clear();
    m_bDisposed = sal_True;
}

// XInitialization
void SAL_CALL MenuBarWrapper::initialize( const Sequence< Any >& aArguments ) throw ( Exception, RuntimeException )
{
    RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::MenuBarWrapper::initialize" );

    ResetableGuard aLock( m_aLock );

    if ( m_bDisposed )
        throw DisposedException();

    if ( !m_bInitialized )
    {
        UIConfigElementWrapperBase::initialize( aArguments );

        Reference< XFrame > xFrame( m_xWeakFrame );
        if ( xFrame.is() && m_xConfigSource.is() )
        {
            // Create VCL menubar which will be filled with settings data
            MenuBar*        pVCLMenuBar = 0;
            VCLXMenuBar*    pAwtMenuBar = 0;
            {
                vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
                pVCLMenuBar = new MenuBar();
            }

            try
            {
                m_xConfigData = m_xConfigSource->getSettings( m_aResourceURL, sal_False );
                if ( m_xConfigData.is() )
                {
                    // Fill menubar with container contents
                    USHORT nId = 1;
                    MenuBarManager::FillMenu( nId, pVCLMenuBar, m_xConfigData );
                }
            }
            catch ( NoSuchElementException& )
            {
            }

            sal_Bool bMenuOnly( sal_False );
            for ( sal_Int32 n = 0; n < aArguments.getLength(); n++ )
            {
                PropertyValue aPropValue;
                if ( aArguments[n] >>= aPropValue )
                {
                    if ( aPropValue.Name.equalsAscii( "MenuOnly" ))
                        aPropValue.Value >>= bMenuOnly;
                }
            }

            if ( !bMenuOnly )
            {
                // Initialize menubar manager with our vcl menu bar. There are some situations where we only want to get the menu without any
                // interaction which is done by the menu bar manager. This must be requested by a special property called "MenuOnly". Be careful
                // a menu bar created with this property is not fully supported. It must be attached to a real menu bar manager to have full
                // support. This feature is currently used for "Inplace editing"!
                // #110897# MenuBarManager* pMenuBarManager = new MenuBarManager( xFrame, pVCLMenuBar, sal_False, sal_True );
                MenuBarManager* pMenuBarManager = new MenuBarManager( getServiceFactory(), xFrame, pVCLMenuBar, sal_False, sal_True );

                m_xMenuBarManager = Reference< XComponent >( static_cast< OWeakObject *>( pMenuBarManager ), UNO_QUERY );
            }

            // Initialize toolkit menu bar implementation to have awt::XMenuBar for data exchange.
            // Don't use this toolkit menu bar or one of its functions. It is only used as a data container!
            pAwtMenuBar = new VCLXMenuBar( pVCLMenuBar );
            m_xMenuBar = Reference< XMenuBar >( static_cast< OWeakObject *>( pAwtMenuBar ), UNO_QUERY );
        }
    }
}

// XUIElementSettings
void SAL_CALL MenuBarWrapper::updateSettings() throw ( RuntimeException )
{
    ResetableGuard aLock( m_aLock );

    if ( m_bDisposed )
        throw DisposedException();

    if ( m_bPersistent &&
         m_xConfigSource.is() &&
         m_xMenuBarManager.is() )
    {
        try
        {
            MenuBarManager* pMenuBarManager = static_cast< MenuBarManager *>( m_xMenuBarManager.get() );

            m_xConfigData = m_xConfigSource->getSettings( m_aResourceURL, sal_False );
            if ( m_xConfigData.is() )
                pMenuBarManager->SetItemContainer( m_xConfigData );
        }
        catch ( NoSuchElementException& )
        {
        }
    }
}

void SAL_CALL MenuBarWrapper::setSettings( const Reference< XIndexAccess >& xSettings ) throw ( RuntimeException )
{
    ResetableGuard aLock( m_aLock );

    if ( m_bDisposed )
        throw DisposedException();

    if ( xSettings.is() )
    {
        // Create a copy of the data if the container is not const
        Reference< XIndexReplace > xReplace( xSettings, UNO_QUERY );
        if ( xReplace.is() )
            m_xConfigData = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( xSettings ) ), UNO_QUERY );
        else
            m_xConfigData = xSettings;

        if ( m_xConfigSource.is() && m_bPersistent )
        {
            OUString aResourceURL( m_aResourceURL );
            Reference< XUIConfigurationManager > xUICfgMgr( m_xConfigSource );

            aLock.unlock();

            try
            {
                xUICfgMgr->replaceSettings( aResourceURL, m_xConfigData );
            }
            catch( NoSuchElementException& )
            {
            }
        }
    }
}

Reference< XIndexAccess > SAL_CALL MenuBarWrapper::getSettings( sal_Bool bWriteable ) throw ( RuntimeException )
{
    ResetableGuard aLock( m_aLock );

    if ( m_bDisposed )
        throw DisposedException();

    if ( bWriteable )
        return Reference< XIndexAccess >( static_cast< OWeakObject * >( new RootItemContainer( m_xConfigData ) ), UNO_QUERY );
    else
        return m_xConfigData;
}

Reference< XInterface > SAL_CALL MenuBarWrapper::getRealInterface() throw ( RuntimeException )
{
    if ( m_bDisposed )
        throw DisposedException();

    return Reference< XInterface >( m_xMenuBarManager, UNO_QUERY );
}

} // namespace framework
<commit_msg>INTEGRATION: CWS perform01 (1.4.102); FILE MERGED 2005/02/03 15:14:30 mt 1.4.102.4: fixed wrong solved merge conflict 2005/02/02 15:22:25 mt 1.4.102.3: fixed compile error 2005/02/01 13:31:12 mt 1.4.102.2: RESYNC: (1.4-1.5); FILE MERGED 2005/01/26 10:11:25 cd 1.4.102.1: #i40989# Performance and usability improvements<commit_after>/*************************************************************************
 *
 *  $RCSfile: menubarwrapper.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: vg $ $Date: 2005-02-16 16:32:12 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

//_________________________________________________________________________________________________________________
//  my own includes
//_________________________________________________________________________________________________________________

#ifndef __FRAMEWORK_UIELEMENT_MENUBARWRAPPER_HXX_
#include <uielement/menubarwrapper.hxx>
#endif

#ifndef __FRAMEWORK_THREADHELP_RESETABLEGUARD_HXX_
#include <threadhelp/resetableguard.hxx>
#endif

#ifndef __FRAMEWORK_HELPER_ACTIONTRIGGERHELPER_HXX_
#include <helper/actiontriggerhelper.hxx>
#endif

#ifndef __FRAMEWORK_UIELEMENT_CONSTITEMCONTAINER_HXX_
#include <uielement/constitemcontainer.hxx>
#endif

#ifndef __FRAMEWORK_UIELEMENT_ROOTITEMCONTAINER_HXX_
#include <uielement/rootitemcontainer.hxx>
#endif

//_________________________________________________________________________________________________________________
//  interface includes
//_________________________________________________________________________________________________________________

#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif

#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif

#ifndef _COM_SUN_STAR_AWT_XSYSTEMDEPENDENTMENUPEER_HPP_
#include <com/sun/star/awt/XSystemDependentMenuPeer.hpp>
#endif

#ifndef _COM_SUN_STAR_AWT_XMENUBAR_HPP_
#include <com/sun/star/awt/XMenuBar.hpp>
#endif

#ifndef _COM_SUN_STAR_CONTAINER_XINDEXCONTAINER_HPP_
#include <com/sun/star/container/XIndexContainer.hpp>
#endif

#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
#include <com/sun/star/container/XNameAccess.hpp>
#endif

#ifndef _DRAFTS_COM_SUN_STAR_UI_UIELEMENTTYPE_HPP_
#include <drafts/com/sun/star/ui/UIElementType.hpp>
#endif

//_________________________________________________________________________________________________________________
//  other includes
//_________________________________________________________________________________________________________________

#ifndef _COMPHELPER_PROCESSFACTORY_HXX_
#include <comphelper/processfactory.hxx>
#endif
#include <tools/solar.h>
#include <vcl/svapp.hxx>
#include <rtl/logfile.hxx>

using namespace rtl;
using namespace com::sun::star::uno;
using namespace com::sun::star::beans;
using namespace com::sun::star::frame;
using namespace com::sun::star::lang;
using namespace com::sun::star::container;
using namespace com::sun::star::awt;
using namespace drafts::com::sun::star::ui;

namespace framework
{

// #110897#
MenuBarWrapper::MenuBarWrapper(
    const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& xServiceManager
    )
:   // #110897#
    mxServiceFactory( xServiceManager ),
    UIConfigElementWrapperBase( UIElementType::MENUBAR )
{
}

MenuBarWrapper::~MenuBarWrapper()
{
}

// #110897#
const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& MenuBarWrapper::getServiceFactory()
{
    // #110897#
    return mxServiceFactory;
}

void SAL_CALL MenuBarWrapper::dispose() throw (::com::sun::star::uno::RuntimeException)
{
    Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY );

    com::sun::star::lang::EventObject aEvent( xThis );
    m_aListenerContainer.disposeAndClear( aEvent );

    ResetableGuard aLock( m_aLock );

    m_xMenuBarManager->dispose();
    m_xMenuBarManager.clear();
    m_xConfigSource.clear();
    m_xConfigData.clear();

    m_xMenuBar.clear();
    m_bDisposed = sal_True;
}

// XInitialization
void SAL_CALL MenuBarWrapper::initialize( const Sequence< Any >& aArguments ) throw ( Exception, RuntimeException )
{
    RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::MenuBarWrapper::initialize" );

    ResetableGuard aLock( m_aLock );

    if ( m_bDisposed )
        throw DisposedException();

    if ( !m_bInitialized )
    {
        UIConfigElementWrapperBase::initialize( aArguments );

        Reference< XFrame > xFrame( m_xWeakFrame );
        if ( xFrame.is() && m_xConfigSource.is() )
        {
            // Create VCL menubar which will be filled with settings data
            MenuBar*        pVCLMenuBar = 0;
            VCLXMenuBar*    pAwtMenuBar = 0;
            {
                vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
                pVCLMenuBar = new MenuBar();
            }

            try
            {
                m_xConfigData = m_xConfigSource->getSettings( m_aResourceURL, sal_False );
                if ( m_xConfigData.is() )
                {
                    // Fill menubar with container contents
                    USHORT nId = 1;
                    MenuBarManager::FillMenu( nId, pVCLMenuBar, m_xConfigData );
                }
            }
            catch ( NoSuchElementException& )
            {
            }

            sal_Bool bMenuOnly( sal_False );
            for ( sal_Int32 n = 0; n < aArguments.getLength(); n++ )
            {
                PropertyValue aPropValue;
                if ( aArguments[n] >>= aPropValue )
                {
                    if ( aPropValue.Name.equalsAscii( "MenuOnly" ))
                        aPropValue.Value >>= bMenuOnly;
                }
            }

            if ( !bMenuOnly )
            {
                // Initialize menubar manager with our vcl menu bar. There are some situations where we only want to get the menu without any
                // interaction which is done by the menu bar manager. This must be requested by a special property called "MenuOnly". Be careful
                // a menu bar created with this property is not fully supported. It must be attached to a real menu bar manager to have full
                // support. This feature is currently used for "Inplace editing"!
                // #110897# MenuBarManager* pMenuBarManager = new MenuBarManager( xFrame, pVCLMenuBar, sal_False, sal_True );
                MenuBarManager* pMenuBarManager = new MenuBarManager( getServiceFactory(), xFrame, pVCLMenuBar, sal_False, sal_True );

                m_xMenuBarManager = Reference< XComponent >( static_cast< OWeakObject *>( pMenuBarManager ), UNO_QUERY );
            }

            // Initialize toolkit menu bar implementation to have awt::XMenuBar for data exchange.
            // Don't use this toolkit menu bar or one of its functions. It is only used as a data container!
            pAwtMenuBar = new VCLXMenuBar( pVCLMenuBar );
            m_xMenuBar = Reference< XMenuBar >( static_cast< OWeakObject *>( pAwtMenuBar ), UNO_QUERY );
        }
    }
}

// XUIElementSettings
void SAL_CALL MenuBarWrapper::updateSettings() throw ( RuntimeException )
{
    ResetableGuard aLock( m_aLock );

    if ( m_bDisposed )
        throw DisposedException();

    if ( m_bPersistent &&
         m_xConfigSource.is() &&
         m_xMenuBarManager.is() )
    {
        try
        {
            MenuBarManager* pMenuBarManager = static_cast< MenuBarManager *>( m_xMenuBarManager.get() );

            m_xConfigData = m_xConfigSource->getSettings( m_aResourceURL, sal_False );
            if ( m_xConfigData.is() )
                pMenuBarManager->SetItemContainer( m_xConfigData );
        }
        catch ( NoSuchElementException& )
        {
        }
    }
}

void SAL_CALL MenuBarWrapper::setSettings( const Reference< XIndexAccess >& xSettings ) throw ( RuntimeException )
{
    ResetableGuard aLock( m_aLock );

    if ( m_bDisposed )
        throw DisposedException();

    if ( xSettings.is() )
    {
        // Create a copy of the data if the container is not const
        Reference< XIndexReplace > xReplace( xSettings, UNO_QUERY );
        if ( xReplace.is() )
            m_xConfigData = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( xSettings ) ), UNO_QUERY );
        else
            m_xConfigData = xSettings;

        if ( m_xConfigSource.is() && m_bPersistent )
        {
            OUString aResourceURL( m_aResourceURL );
            Reference< XUIConfigurationManager > xUICfgMgr( m_xConfigSource );

            aLock.unlock();

            try
            {
                xUICfgMgr->replaceSettings( aResourceURL, m_xConfigData );
            }
            catch( NoSuchElementException& )
            {
            }
        }
    }
}

Reference< XIndexAccess > SAL_CALL MenuBarWrapper::getSettings( sal_Bool bWriteable ) throw ( RuntimeException )
{
    ResetableGuard aLock( m_aLock );

    if ( m_bDisposed )
        throw DisposedException();

    if ( bWriteable )
        return Reference< XIndexAccess >( static_cast< OWeakObject * >( new RootItemContainer( m_xConfigData ) ), UNO_QUERY );
    else
        return m_xConfigData;
}

Reference< XInterface > SAL_CALL MenuBarWrapper::getRealInterface() throw ( RuntimeException )
{
    if ( m_bDisposed )
        throw DisposedException();

    return Reference< XInterface >( m_xMenuBarManager, UNO_QUERY );
}

} // namespace framework

<|endoftext|>


<commit_before>#include "configparser.h"

#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <pwd.h>
#include <sys/types.h>

#include "config.h"
#include "exceptions.h"
#include "logger.h"
#include "strprintf.h"
#include "tagsouppullparser.h"
#include "utils.h"

namespace newsboat {

ConfigParser::ConfigParser()
{
	register_handler("include", this);
}

ConfigParser::~ConfigParser() {}

void ConfigParser::handle_action(const std::string& action,
	const std::vector<std::string>& params)
{
	/*
	 * ConfigParser also acts as ConfigActionHandler to implement
	 * recursive "include" command.
	 */
	if (action == "include") {
		if (params.size() < 1) {
			throw ConfigHandlerException(
				ActionHandlerStatus::TOO_FEW_PARAMS);
		}

		if (!this->parse(utils::resolve_tilde(params[0])))
			throw ConfigHandlerException(
				ActionHandlerStatus::FILENOTFOUND);
	} else
		throw ConfigHandlerException(
			ActionHandlerStatus::INVALID_COMMAND);
}

bool ConfigParser::parse(const std::string& filename, bool double_include)
{
	/*
	 * this function parses a config file.
	 *
	 * First, it checks whether this file has already been included, and if
	 * not, it does the following:
	 *   - open the file
	 *   - read it line by line
	 *   - tokenize every line
	 *   - if there is at least one token, look up a registered
	 * ConfigActionHandler to handle the command (which is specified in
	 * the first token)
	 *   - hand over the tokenize results to the ConfigActionHandler
	 *   - if an error happens, react accordingly.
	 */
	if (!double_include &&
		std::find(included_files.begin(), included_files.end(), filename) != included_files.end()) {
		LOG(Level::WARN,
			"ConfigParser::parse: file %s has already been "
			"included",
			filename);
		return true;
	}
	included_files.push_back(filename);

	unsigned int linecounter = 0;
	std::ifstream f(filename.c_str());
	std::string line;
	if (!f.is_open()) {
		LOG(Level::WARN,
			"ConfigParser::parse: file %s couldn't be opened",
			filename);
		return false;
	}

	while (f.is_open() && !f.eof()) {
		getline(f, line);
		++linecounter;
		LOG(Level::DEBUG, "ConfigParser::parse: tokenizing %s", line);
		std::vector<std::string> tokens = utils::tokenize_quoted(line);
		if (!tokens.empty()) {
			std::string cmd = tokens[0];
			ConfigActionHandler* handler = action_handlers[cmd];
			if (handler) {
				tokens.erase(
					tokens.begin()); // delete first element
				try {
					evaluate_backticks(tokens);
					handler->handle_action(cmd, tokens);
				} catch (const ConfigHandlerException& e) {
					throw ConfigException(strprintf::fmt(
						_("Error while processing "
						  "command `%s' (%s line %u): "
						  "%s"),
						line,
						filename,
						linecounter,
						e.what()));
				}
			} else {
				throw ConfigException(strprintf::fmt(
					_("unknown command `%s'"), cmd));
			}
		}
	}
	included_files.pop_back();
	return true;
}

void ConfigParser::register_handler(const std::string& cmd,
	ConfigActionHandler* handler)
{
	action_handlers[cmd] = handler;
}

void ConfigParser::unregister_handler(const std::string& cmd)
{
	action_handlers[cmd] = 0;
}

void ConfigParser::evaluate_backticks(std::vector<std::string>& tokens)
{
	for (auto& token : tokens) {
		token = evaluate_backticks(token);
	}
}

/* Note that this function not only finds next backtick that isn't prefixed
 * with a backslash, but also un-escapes all the escaped backticks it finds in
 * the process */
std::string::size_type find_non_escaped_backtick(std::string& input,
	const std::string::size_type startpos)
{
	if (startpos == std::string::npos)
		return startpos;

	std::string::size_type result = startpos;
	result = input.find_first_of("`", result);

	while (result != std::string::npos && result > 0 &&
		input[result - 1] == '\\') {
		// remove the backslash
		input.erase(result - 1, 1);

		// *not* adding one to start position as we already shortened
		// the input by one character
		result = input.find_first_of("`", result);
	}

	return result;
}

std::string ConfigParser::evaluate_backticks(std::string token)
{
	std::string::size_type pos1 = find_non_escaped_backtick(token, 0);
	std::string::size_type pos2 =
		find_non_escaped_backtick(token, pos1 + 1);

	while (pos1 != std::string::npos && pos2 != std::string::npos) {
		std::string cmd = token.substr(pos1 + 1, pos2 - pos1 - 1);
		token.erase(pos1, pos2 - pos1 + 1);
		std::string result = utils::get_command_output(cmd);
		utils::trim_end(result);
		token.insert(pos1, result);

		pos1 = find_non_escaped_backtick(
			token, pos1 + result.length() + 1);
		pos2 = find_non_escaped_backtick(token, pos1 + 1);
	}

	return token;
}

} // namespace newsboat
<commit_msg>Enable relative path including<commit_after>#include "configparser.h"

#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <pwd.h>
#include <sys/types.h>

#include "config.h"
#include "exceptions.h"
#include "logger.h"
#include "strprintf.h"
#include "tagsouppullparser.h"
#include "utils.h"

namespace newsboat {

ConfigParser::ConfigParser()
{
	register_handler("include", this);
}

ConfigParser::~ConfigParser() {}

void ConfigParser::handle_action(const std::string& action,
	const std::vector<std::string>& params)
{
	/*
	 * ConfigParser also acts as ConfigActionHandler to implement
	 * recursive "include" command.
	 */
	if (action == "include") {
		if (params.size() < 1) {
			throw ConfigHandlerException(
				ActionHandlerStatus::TOO_FEW_PARAMS);
		}

		std::string tilde_expanded = utils::resolve_tilde(params[0]);
		std::string current_fpath = included_files.back();
		if (!this->parse(utils::resolve_relative(current_fpath, tilde_expanded)))
			throw ConfigHandlerException(
				ActionHandlerStatus::FILENOTFOUND);
	} else
		throw ConfigHandlerException(
			ActionHandlerStatus::INVALID_COMMAND);
}

bool ConfigParser::parse(const std::string& tmp_filename, bool double_include)
{
	/*
	 * this function parses a config file.
	 *
	 * First, it checks whether this file has already been included, and if
	 * not, it does the following:
	 *   - open the file
	 *   - read it line by line
	 *   - tokenize every line
	 *   - if there is at least one token, look up a registered
	 * ConfigActionHandler to handle the command (which is specified in
	 * the first token)
	 *   - hand over the tokenize results to the ConfigActionHandler
	 *   - if an error happens, react accordingly.
	 */

	// It would be nice if this function was only give absolute paths, but the
	// tests are easier as relative paths
	const std::string filename = (tmp_filename.front() == '/') ? tmp_filename : utils::getcwd() + '/' + tmp_filename;

	if (!double_include &&
		std::find(included_files.begin(), included_files.end(), filename) != included_files.end()) {
		LOG(Level::WARN,
			"ConfigParser::parse: file %s has already been "
			"included",
			filename);
		return true;
	}
	included_files.push_back(filename);

	unsigned int linecounter = 0;
	std::ifstream f(filename.c_str());
	std::string line;
	if (!f.is_open()) {
		LOG(Level::WARN,
			"ConfigParser::parse: file %s couldn't be opened",
			filename);
		return false;
	}

	while (f.is_open() && !f.eof()) {
		getline(f, line);
		++linecounter;
		LOG(Level::DEBUG, "ConfigParser::parse: tokenizing %s", line);
		std::vector<std::string> tokens = utils::tokenize_quoted(line);
		if (!tokens.empty()) {
			std::string cmd = tokens[0];
			ConfigActionHandler* handler = action_handlers[cmd];
			if (handler) {
				tokens.erase(
					tokens.begin()); // delete first element
				try {
					evaluate_backticks(tokens);
					handler->handle_action(cmd, tokens);
				} catch (const ConfigHandlerException& e) {
					throw ConfigException(strprintf::fmt(
						_("Error while processing "
						  "command `%s' (%s line %u): "
						  "%s"),
						line,
						filename,
						linecounter,
						e.what()));
				}
			} else {
				throw ConfigException(strprintf::fmt(
					_("unknown command `%s'"), cmd));
			}
		}
	}
	included_files.pop_back();
	return true;
}

void ConfigParser::register_handler(const std::string& cmd,
	ConfigActionHandler* handler)
{
	action_handlers[cmd] = handler;
}

void ConfigParser::unregister_handler(const std::string& cmd)
{
	action_handlers[cmd] = 0;
}

void ConfigParser::evaluate_backticks(std::vector<std::string>& tokens)
{
	for (auto& token : tokens) {
		token = evaluate_backticks(token);
	}
}

/* Note that this function not only finds next backtick that isn't prefixed
 * with a backslash, but also un-escapes all the escaped backticks it finds in
 * the process */
std::string::size_type find_non_escaped_backtick(std::string& input,
	const std::string::size_type startpos)
{
	if (startpos == std::string::npos)
		return startpos;

	std::string::size_type result = startpos;
	result = input.find_first_of("`", result);

	while (result != std::string::npos && result > 0 &&
		input[result - 1] == '\\') {
		// remove the backslash
		input.erase(result - 1, 1);

		// *not* adding one to start position as we already shortened
		// the input by one character
		result = input.find_first_of("`", result);
	}

	return result;
}

std::string ConfigParser::evaluate_backticks(std::string token)
{
	std::string::size_type pos1 = find_non_escaped_backtick(token, 0);
	std::string::size_type pos2 =
		find_non_escaped_backtick(token, pos1 + 1);

	while (pos1 != std::string::npos && pos2 != std::string::npos) {
		std::string cmd = token.substr(pos1 + 1, pos2 - pos1 - 1);
		token.erase(pos1, pos2 - pos1 + 1);
		std::string result = utils::get_command_output(cmd);
		utils::trim_end(result);
		token.insert(pos1, result);

		pos1 = find_non_escaped_backtick(
			token, pos1 + result.length() + 1);
		pos2 = find_non_escaped_backtick(token, pos1 + 1);
	}

	return token;
}

} // namespace newsboat
<|endoftext|>


<commit_before>/*
 * This file is open source software, licensed to you under the terms
 * of the Apache License, Version 2.0 (the "License").  See the NOTICE file
 * distributed with this work for additional information regarding copyright
 * ownership.  You may not use this file except in compliance with the License.
 *
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
#ifdef SEASTAR_HAVE_DPDK

#include <cinttypes>
#include <seastar/net/dpdk.hh>
#include <seastar/core/dpdk_rte.hh>
#include <seastar/util/conversions.hh>
#include <seastar/util/std-compat.hh>
#include <rte_pci.h>

namespace seastar {

namespace dpdk {

bool eal::initialized = false;

void eal::init(cpuset cpus, const std::string& argv0, const std::optional<std::string>& hugepages_path, bool dpdk_pmd)
{
    if (initialized) {
        return;
    }

    std::stringstream mask;
    cpuset nibble = 0xF;
    while (cpus.any()) {
        mask << std::hex << (cpus & nibble).to_ulong();
        cpus >>= 4;
    }

    std::string mask_str = mask.str();
    std::reverse(mask_str.begin(), mask_str.end());

    std::vector<std::vector<char>> args {
        string2vector(argv0),
        string2vector("-c"), string2vector(mask_str),
        string2vector("-n"), string2vector("1")
    };

    // If "hugepages" is not provided and DPDK PMD drivers mode is requested -
    // use the default DPDK huge tables configuration.
    if (hugepages_path) {
        args.push_back(string2vector("--huge-dir"));
        args.push_back(string2vector(hugepages_path.value()));

        //
        // We don't know what is going to be our networking configuration so we
        // assume there is going to be a queue per-CPU. Plus we'll give a DPDK
        // 64MB for "other stuff".
        //
        size_t size_MB = mem_size(cpus.count()) >> 20;
        std::stringstream size_MB_str;
        size_MB_str << size_MB;

        args.push_back(string2vector("-m"));
        args.push_back(string2vector(size_MB_str.str()));
    } else if (!dpdk_pmd) {
        args.push_back(string2vector("--no-huge"));
    }
#ifdef HAVE_OSV
    args.push_back(string2vector("--no-shconf"));
#endif

    std::vector<char*> cargs;

    for (auto&& a: args) {
        cargs.push_back(a.data());
    }
    /* initialise the EAL for all */
    int ret = rte_eal_init(cargs.size(), cargs.data());
    if (ret < 0) {
        rte_exit(EXIT_FAILURE, "Cannot init EAL\n");
    }

    initialized = true;
}

uint32_t __attribute__((weak)) qp_mempool_obj_size(bool hugetlbfs_membackend)
{
    return 0;
}

size_t eal::mem_size(int num_cpus, bool hugetlbfs_membackend)
{
    size_t memsize = 0;
    //
    // PMD mempool memory:
    //
    // We don't know what is going to be our networking configuration so we
    // assume there is going to be a queue per-CPU.
    //
    memsize += num_cpus * qp_mempool_obj_size(hugetlbfs_membackend);

    // Plus we'll give a DPDK 64MB for "other stuff".
    memsize += (64UL << 20);

    return memsize;
}

} // namespace dpdk

}

#endif // SEASTAR_HAVE_DPDK
<commit_msg>fix cpuset count is zero after shift<commit_after>/*
 * This file is open source software, licensed to you under the terms
 * of the Apache License, Version 2.0 (the "License").  See the NOTICE file
 * distributed with this work for additional information regarding copyright
 * ownership.  You may not use this file except in compliance with the License.
 *
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
#ifdef SEASTAR_HAVE_DPDK

#include <cinttypes>
#include <seastar/net/dpdk.hh>
#include <seastar/core/dpdk_rte.hh>
#include <seastar/util/conversions.hh>
#include <seastar/util/std-compat.hh>
#include <rte_pci.h>

namespace seastar {

namespace dpdk {

bool eal::initialized = false;

void eal::init(cpuset cpus, const std::string& argv0, const std::optional<std::string>& hugepages_path, bool dpdk_pmd)
{
    if (initialized) {
        return;
    }

    size_t cpu_count = cpus.count();
    std::stringstream mask;
    cpuset nibble = 0xF;
    while (cpus.any()) {
        mask << std::hex << (cpus & nibble).to_ulong();
        cpus >>= 4;
    }

    std::string mask_str = mask.str();
    std::reverse(mask_str.begin(), mask_str.end());

    std::vector<std::vector<char>> args {
        string2vector(argv0),
        string2vector("-c"), string2vector(mask_str),
        string2vector("-n"), string2vector("1")
    };

    // If "hugepages" is not provided and DPDK PMD drivers mode is requested -
    // use the default DPDK huge tables configuration.
    if (hugepages_path) {
        args.push_back(string2vector("--huge-dir"));
        args.push_back(string2vector(hugepages_path.value()));

        //
        // We don't know what is going to be our networking configuration so we
        // assume there is going to be a queue per-CPU. Plus we'll give a DPDK
        // 64MB for "other stuff".
        //
        size_t size_MB = mem_size(cpu_count) >> 20;
        std::stringstream size_MB_str;
        size_MB_str << size_MB;

        args.push_back(string2vector("-m"));
        args.push_back(string2vector(size_MB_str.str()));
    } else if (!dpdk_pmd) {
        args.push_back(string2vector("--no-huge"));
    }
#ifdef HAVE_OSV
    args.push_back(string2vector("--no-shconf"));
#endif

    std::vector<char*> cargs;

    for (auto&& a: args) {
        cargs.push_back(a.data());
    }
    /* initialise the EAL for all */
    int ret = rte_eal_init(cargs.size(), cargs.data());
    if (ret < 0) {
        rte_exit(EXIT_FAILURE, "Cannot init EAL\n");
    }

    initialized = true;
}

uint32_t __attribute__((weak)) qp_mempool_obj_size(bool hugetlbfs_membackend)
{
    return 0;
}

size_t eal::mem_size(int num_cpus, bool hugetlbfs_membackend)
{
    size_t memsize = 0;
    //
    // PMD mempool memory:
    //
    // We don't know what is going to be our networking configuration so we
    // assume there is going to be a queue per-CPU.
    //
    memsize += num_cpus * qp_mempool_obj_size(hugetlbfs_membackend);

    // Plus we'll give a DPDK 64MB for "other stuff".
    memsize += (64UL << 20);

    return memsize;
}

} // namespace dpdk

}

#endif // SEASTAR_HAVE_DPDK
<|endoftext|>