<commit_before>#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/transform.hpp>
#include <glm/gtx/quaternion.hpp>
#include <glm/gtc/quaternion.hpp>
#include <glm/gtx/matrix_interpolation.hpp>

#include <Utils/Containers/Vector.hpp>
#include <map>
#include <chrono>

#include <Core/Engine.hh>
#include <Core/SceneManager.hh>
#include <Core/Renderer.hh>

// DEPENDENCIES
#include <Context/SdlContext.hh>
#include <Core/ConfigurationManager.hpp>
#include <Physic/BulletDynamicManager.hpp>
#include <Core/Timer.hh>
#include <Utils/PubSub.hpp>
#include <Render/GeometryManager.hh>
#include <Utils/PerformanceDebugger.hh>
#include <Core/AssetsManager.hpp>

#include <Convertor/SkeletonLoader.hpp>
#include <Convertor/AnimationsLoader.hpp>
#include <Convertor/MeshLoader.hpp>
#include <Convertor/MaterialConvertor.hpp>
#include <Convertor/ImageLoader.hpp>

//SKINNING
#include <Skinning/Animation.hpp>
#include <Skinning/AnimationChannel.hpp>
#include <Skinning/AnimationInstance.hpp>
#include <Skinning/AnimationKey.hpp>
#include <Skinning/Bone.hpp>
#include <Skinning/Skeleton.hpp>

int			main(int ac, char **av)
{
	std::shared_ptr<Engine>	e = std::make_shared<Engine>();

	// Set Configurations
	auto config = e->setInstance<ConfigurationManager>(File("MyConfigurationFile.conf"));

	e->setInstance<PubSub::Manager>();
	e->setInstance<SdlContext, IRenderContext>();
	e->setInstance<Input>();
	e->setInstance<Timer>();
	e->setInstance<Renderer>();
	e->setInstance<SceneManager>();
	e->setInstance<AGE::AssetsManager>();
	e->setInstance<PerformanceDebugger>();
//	auto geometryManager = e->setInstance<gl::GeometryManager>();

	// init engine
	if (e->init(0, 800, 600, "~AGE~ V0.0 Demo") == false)
		return (EXIT_FAILURE);

	// Set default window size
	// If config file has different value, it'll be changed automaticaly
	config->setConfiguration<glm::uvec2>("windowSize", glm::uvec2(800, 600), [&e](const glm::uvec2 &v)
	{
		e->getInstance<IRenderContext>()->setScreenSize(std::move(v));
	});

	config->loadFile();

	// launch engine
	if (e->start() == false)
		return (EXIT_FAILURE);

	//////////////////////////
	/////
	//

	/////Convert fbx to AGE data structure

	bool isSkeleton = false;
	bool isAnimations = false;
	bool isMesh = false;
	bool isMaterial = false;
	bool isTexture = false;
	bool convert = true;
	if (convert)
	{
		//AGE::AssetDataSet dataSet;
		//dataSet.filePath = File("catwoman/atk close front 6.fbx");
		//dataSet.skeletonName = "catwoman";
		//dataSet.skinName = "catwoman";
		//dataSet.materialName = "catwoman";
		//dataSet.animationName = "catwoman-roulade";

		//dataSet.serializedDirectory = std::tr2::sys::basic_directory_entry<std::tr2::sys::path>("../../Assets/AGE-Assets-For-Test/Serialized");
		//dataSet.rawDirectory = std::tr2::sys::basic_directory_entry<std::tr2::sys::path>("../../Assets/Raw");

		//isMaterial = AGE::MaterialLoader::load(dataSet);
		//isTexture = AGE::ImageLoader::load(dataSet);
		//isSkeleton = AGE::SkeletonLoader::load(dataSet);
		//isAnimations = AGE::AnimationsLoader::load(dataSet);
		//isMesh = AGE::MeshLoader::load(dataSet);

		//AGE::MaterialLoader::save(dataSet);
		//AGE::ImageLoader::save(dataSet);
		//AGE::SkeletonLoader::save(dataSet);
		//AGE::AnimationsLoader::save(dataSet);
		//AGE::MeshLoader::save(dataSet);
	}
	{
		AGE::AssetDataSet dataSet;
		dataSet.filePath = File("ball/ball.obj");
		dataSet.skinName = "ball";
		dataSet.materialName = "ball";

		dataSet.serializedDirectory = std::tr2::sys::basic_directory_entry<std::tr2::sys::path>("../../Assets/AGE-Assets-For-Test/Serialized");
		dataSet.rawDirectory = std::tr2::sys::basic_directory_entry<std::tr2::sys::path>("../../Assets/AGE-Assets-For-Test/Raw");

		AGE::MaterialLoader::load(dataSet);
		AGE::ImageLoader::load(dataSet);
		AGE::MeshLoader::load(dataSet);

		AGE::MaterialLoader::save(dataSet);
		AGE::ImageLoader::save(dataSet);
		AGE::MeshLoader::save(dataSet);
	}
	{
		AGE::AssetDataSet dataSet;
		dataSet.filePath = File("cube/cube.obj");
		dataSet.skinName = "cube";
		dataSet.materialName = "cube";

		dataSet.serializedDirectory = std::tr2::sys::basic_directory_entry<std::tr2::sys::path>("../../Assets/AGE-Assets-For-Test/Serialized");
		dataSet.rawDirectory = std::tr2::sys::basic_directory_entry<std::tr2::sys::path>("../../Assets/AGE-Assets-For-Test/Raw");

		AGE::MaterialLoader::load(dataSet);
		AGE::ImageLoader::load(dataSet);
		AGE::MeshLoader::load(dataSet);

		AGE::MaterialLoader::save(dataSet);
		AGE::ImageLoader::save(dataSet);
		AGE::MeshLoader::save(dataSet);
	}
//
//	//Load assets from serialized file
//	auto assetsManager = e->getInstance<AGE::AssetsManager>();
//
//	auto catwomanMesh = assetsManager->loadMesh("../../Assets/NewSerialized/catwoman/catwoman.sage"); // load mesh
//	auto catwomanSkeleton = assetsManager->loadSkeleton("../../Assets/NewSerialized/catwoman/catwoman.skage"); // load skeleton
//	std::shared_ptr<AGE::Animation> catwomanRoulade = nullptr;
//	if (isAnimations)
//		catwomanRoulade = assetsManager->loadAnimation("../../Assets/NewSerialized/catwoman/catwoman-roulade.aage"); // load animation
//
// 	AGE::AnimationInstance catwomanAnimationInstance(catwomanSkeleton, catwomanRoulade);
//
//	//
//	/////
//	//////////////////////////
//
//
//
//	auto shader = e->getInstance<Renderer>()->addShader("basic",
//		"./basic.vp",
//		"./basic.fp");
//	if (shader->getId() < 0)
//		return EXIT_FAILURE;
//	shader->use();
//
//
//
//	// Projection matrix : 45 Field of View, 4:3 ratio, display range : 0.1 unit <-> 100 units
//	glm::mat4 Projection = glm::perspective(60.0f, 16.0f / 9.0f, 0.1f, 1000.0f);
//	// Camera matrix
//	float lookAtX = 0;
//	float lookAtY = 0;
//	// Model matrix : an identity matrix (model will be at the origin)
//	glm::mat4 Model = glm::mat4(1.0f);  // Changes for each model !
//	Model = glm::scale(Model, glm::vec3(0.2f));
//
//
//	// On enable la depth car par defaut elle est pas active
//	// Conseil : la mettre dans son game engine
//	glEnable(GL_DEPTH_TEST);
//	glDisable(GL_CULL_FACE);
//	// la depth de clear par defaut sera 1
//	glClearDepth(1.0f);
//	// la couleur de clear par defaut sera du noir
//	glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
//
//	do
//	{
//		auto time = e->getInstance<Timer>()->getElapsed();
//		static float totalTime = 0.0f;
//		totalTime += time;
//
//		glm::vec4 color;
//		shader->use();
//		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//		color = glm::vec4(1, 0, 1, 1);
//
//		if (e->getInstance<Input>()->getKey(SDLK_w))
//			lookAtY += 1;
//		if (e->getInstance<Input>()->getKey(SDLK_s))
//			lookAtY -= 1;
//		if (e->getInstance<Input>()->getKey(SDLK_a))
//			lookAtX -= 1;
//		if (e->getInstance<Input>()->getKey(SDLK_d))
//			lookAtX += 1;
//
//		glm::mat4 View = glm::lookAt(
//			glm::vec3(lookAtX, lookAtY, 150), // Camera is at (4,3,3), in World Space
//			glm::vec3(lookAtX, lookAtY, 0), // and looks at the origin
//			glm::vec3(0, 1, 0)  // Head is up (set to 0,-1,0 to look upside-down)
//			);
//
//		auto colorId = glGetUniformLocation(shader->getId(), "color");
//		auto modelId = glGetUniformLocation(shader->getId(), "model");
//		auto viewId = glGetUniformLocation(shader->getId(), "view");
//		auto projectionId = glGetUniformLocation(shader->getId(), "projection");
//
//		glUniform4fv(colorId, 1, &color[0]);
//		glUniformMatrix4fv(modelId, 1, GL_FALSE, &Model[0][0]);
//		glUniformMatrix4fv(viewId, 1, GL_FALSE, &View[0][0]);
//		glUniformMatrix4fv(projectionId, 1, GL_FALSE, &Projection[0][0]);
//
////		for (auto i = 0; i < 500; ++i)
//			catwomanAnimationInstance.update(totalTime);
//		catwomanSkeleton->updateSkinning();
//		glUniformMatrix4fv(glGetUniformLocation(shader->getId(), "bones"), catwomanAnimationInstance.transformations.size(), GL_FALSE, glm::value_ptr(catwomanAnimationInstance.transformations[0]));
//
//		for (unsigned int i = 0; i < catwomanMesh->subMeshs.size(); ++i)
//		{
//			geometryManager->draw(GL_TRIANGLES, catwomanMesh->subMeshs[i].indices, catwomanMesh->subMeshs[i].vertices);
//		}
//	} while (e->update());
//
//	config->saveToFile();
//	e->stop();
	return EXIT_SUCCESS;
}<commit_msg>clean assert-convert<commit_after>#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/transform.hpp>
#include <glm/gtx/quaternion.hpp>
#include <glm/gtc/quaternion.hpp>
#include <glm/gtx/matrix_interpolation.hpp>

#include <Utils/Containers/Vector.hpp>
#include <map>
#include <chrono>

#include <Core/Engine.hh>
#include <Core/SceneManager.hh>

// DEPENDENCIES
#include <Context/SdlContext.hh>
#include <Core/ConfigurationManager.hpp>
#include <Physic/BulletDynamicManager.hpp>
#include <Core/Timer.hh>
#include <Utils/PubSub.hpp>
#include <Render/GeometryManager.hh>
#include <Utils/PerformanceDebugger.hh>
#include <Core/AssetsManager.hpp>

#include <Convertor/SkeletonLoader.hpp>
#include <Convertor/AnimationsLoader.hpp>
#include <Convertor/MeshLoader.hpp>
#include <Convertor/MaterialConvertor.hpp>
#include <Convertor/ImageLoader.hpp>

//SKINNING
#include <Skinning/Animation.hpp>
#include <Skinning/AnimationChannel.hpp>
#include <Skinning/AnimationInstance.hpp>
#include <Skinning/AnimationKey.hpp>
#include <Skinning/Bone.hpp>
#include <Skinning/Skeleton.hpp>

int			main(int ac, char **av)
{
	{
		AGE::AssetDataSet dataSet;
		dataSet.filePath = File("ball/ball.obj");
		dataSet.skinName = "ball";
		dataSet.materialName = "ball";

		dataSet.serializedDirectory = std::tr2::sys::basic_directory_entry<std::tr2::sys::path>("../../Assets/AGE-Assets-For-Test/Serialized");
		dataSet.rawDirectory = std::tr2::sys::basic_directory_entry<std::tr2::sys::path>("../../Assets/AGE-Assets-For-Test/Raw");

		AGE::MaterialLoader::load(dataSet);
		AGE::ImageLoader::load(dataSet);
		AGE::MeshLoader::load(dataSet);

		AGE::MaterialLoader::save(dataSet);
		AGE::ImageLoader::save(dataSet);
		AGE::MeshLoader::save(dataSet);
	}
	{
		AGE::AssetDataSet dataSet;
		dataSet.filePath = File("cube/cube.obj");
		dataSet.skinName = "cube";
		dataSet.materialName = "cube";

		dataSet.serializedDirectory = std::tr2::sys::basic_directory_entry<std::tr2::sys::path>("../../Assets/AGE-Assets-For-Test/Serialized");
		dataSet.rawDirectory = std::tr2::sys::basic_directory_entry<std::tr2::sys::path>("../../Assets/AGE-Assets-For-Test/Raw");

		AGE::MaterialLoader::load(dataSet);
		AGE::ImageLoader::load(dataSet);
		AGE::MeshLoader::load(dataSet);

		AGE::MaterialLoader::save(dataSet);
		AGE::ImageLoader::save(dataSet);
		AGE::MeshLoader::save(dataSet);
	}
	return (0);
}<|endoftext|>


<commit_before>/*******************************************************
 * Copyright (c) 2014, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

#include <af/array.h>
#include <af/dim4.hpp>
#include <af/defines.h>
#include <Array.hpp>
#include <diagonal.hpp>
#include <math.hpp>
#include <err_cpu.hpp>

namespace cpu
{
    template<typename T>
    Array<T> diagCreate(const Array<T> &in, const int num)
    {
        int size = in.dims()[0] + std::abs(num);
        int batch = in.dims()[1];
        Array<T> out = createEmptyArray<T>(dim4(size, size, batch));

        const T *iptr = in.get();
        T *optr = out.get();

        for (int k = 0; k < batch; k++) {
            for (int j = 0; j < size; j++) {
                for (int i = 0; i < size; i++) {
                    T val = scalar<T>(0);
                    if (i == j - num) {
                        val = (num > 0) ? iptr[i] : iptr[j];
                    }
                    optr[i + j * out.strides()[1]] = val;
                }
            }
            optr += out.strides()[2];
            iptr += in.strides()[1];
        }

        return out;
    }

    template<typename T>
    Array<T> diagExtract(const Array<T> &in, const int num)
    {
        const dim_t *idims = in.dims().get();
        dim_t size = std::max(idims[0], idims[1]) - std::abs(num);
        Array<T> out = createEmptyArray<T>(dim4(size, 1, idims[2], idims[3]));

        const dim_t *odims = out.dims().get();

        const int i_off = (num > 0) ? (num * in.strides()[1]) : (-num);

        for (int l = 0; l < (int)odims[3]; l++) {

            for (int k = 0; k < (int)odims[2]; k++) {
                const T *iptr = in.get() + l * in.strides()[3] + k * in.strides()[2] + i_off;
                T *optr = out.get() + l * out.strides()[3] + k * out.strides()[2];

                for (int i = 0; i < (int)odims[0]; i++) {
                    T val = scalar<T>(0);
                    if (i < idims[0] && i < idims[1]) val =  iptr[i * in.strides()[1] + i];
                    optr[i] = val;
                }
            }
        }

        return out;
    }

#define INSTANTIATE_DIAGONAL(T)                                          \
    template Array<T>  diagExtract<T>    (const Array<T> &in, const int num); \
    template Array<T>  diagCreate <T>    (const Array<T> &in, const int num);

    INSTANTIATE_DIAGONAL(float)
    INSTANTIATE_DIAGONAL(double)
    INSTANTIATE_DIAGONAL(cfloat)
    INSTANTIATE_DIAGONAL(cdouble)
    INSTANTIATE_DIAGONAL(int)
    INSTANTIATE_DIAGONAL(uint)
    INSTANTIATE_DIAGONAL(intl)
    INSTANTIATE_DIAGONAL(uintl)
    INSTANTIATE_DIAGONAL(char)
    INSTANTIATE_DIAGONAL(uchar)

}
<commit_msg>Async CPU diagonal<commit_after>/*******************************************************
 * Copyright (c) 2014, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

#include <af/array.h>
#include <af/dim4.hpp>
#include <af/defines.h>
#include <Array.hpp>
#include <diagonal.hpp>
#include <math.hpp>
#include <err_cpu.hpp>
#include <platform.hpp>
#include <async_queue.hpp>

namespace cpu
{
    template<typename T>
    Array<T> diagCreate(const Array<T> &in, const int num)
    {
        int size = in.dims()[0] + std::abs(num);
        int batch = in.dims()[1];
        Array<T> out = createEmptyArray<T>(dim4(size, size, batch));

        auto func = [=] (Array<T> out, const Array<T> in) {
            const T *iptr = in.get();
                  T *optr = out.get();

            for (int k = 0; k < batch; k++) {
                for (int j = 0; j < size; j++) {
                    for (int i = 0; i < size; i++) {
                        T val = scalar<T>(0);
                        if (i == j - num) {
                            val = (num > 0) ? iptr[i] : iptr[j];
                        }
                        optr[i + j * out.strides()[1]] = val;
                    }
                }
                optr += out.strides()[2];
                iptr += in.strides()[1];
            }
        };
        getQueue().enqueue(func, out, in);

        return out;
    }

    template<typename T>
    Array<T> diagExtract(const Array<T> &in, const int num)
    {
        const dim_t *idims = in.dims().get();
        dim_t size = std::max(idims[0], idims[1]) - std::abs(num);
        Array<T> out = createEmptyArray<T>(dim4(size, 1, idims[2], idims[3]));

        auto func = [=] (Array<T> out, const Array<T> in) {
            const dim_t *odims = out.dims().get();

            const int i_off = (num > 0) ? (num * in.strides()[1]) : (-num);

            for (int l = 0; l < (int)odims[3]; l++) {

                for (int k = 0; k < (int)odims[2]; k++) {
                    const T *iptr = in.get() + l * in.strides()[3] + k * in.strides()[2] + i_off;
                    T *optr = out.get() + l * out.strides()[3] + k * out.strides()[2];

                    for (int i = 0; i < (int)odims[0]; i++) {
                        T val = scalar<T>(0);
                        if (i < idims[0] && i < idims[1]) val =  iptr[i * in.strides()[1] + i];
                        optr[i] = val;
                    }
                }
            }
        };

        getQueue().enqueue(func, out, in);

        return out;
    }

#define INSTANTIATE_DIAGONAL(T)                                          \
    template Array<T>  diagExtract<T>    (const Array<T> &in, const int num); \
    template Array<T>  diagCreate <T>    (const Array<T> &in, const int num);

    INSTANTIATE_DIAGONAL(float)
    INSTANTIATE_DIAGONAL(double)
    INSTANTIATE_DIAGONAL(cfloat)
    INSTANTIATE_DIAGONAL(cdouble)
    INSTANTIATE_DIAGONAL(int)
    INSTANTIATE_DIAGONAL(uint)
    INSTANTIATE_DIAGONAL(intl)
    INSTANTIATE_DIAGONAL(uintl)
    INSTANTIATE_DIAGONAL(char)
    INSTANTIATE_DIAGONAL(uchar)

}
<|endoftext|>


<commit_before>#pragma once
#ifndef NIFTY_PYTHON_GRAPH_LIFTED_MULTICUT_LEARNABLE_LIFTED_MULTICUT_OBJECTIVE_NAME_HXX
#define NIFTY_PYTHON_GRAPH_LIFTED_MULTICUT_LEARNABLE_LIFTED_MULTICUT_OBJECTIVE_NAME_HXX

#include "nifty/graph/optimization/lifted_multicut/learnable_lifted_multicut_objective.hxx"
#include "nifty/python/graph/graph_name.hxx"

namespace nifty{
namespace graph{
namespace lifted_multicut{

    template<class OBJECTIVE>
    struct LiftedMulticutObjectiveName;

    template<class GRAPH>
    struct LiftedMulticutObjectiveName<LearnableLiftedMulticutObjective<GRAPH, float> >{
        static std::string name(){
            return std::string("LearnableLiftedMulticutObjective") + GraphName<GRAPH>::name();
        }
    };

}
}
}

#endif /* NIFTY_PYTHON_GRAPH_LIFTED_MULTICUT_LEARNABLE_LIFTED_MULTICUT_OBJECTIVE_NAME_HXX */
<commit_msg>fixed template issue in glue<commit_after>#pragma once
#ifndef NIFTY_PYTHON_GRAPH_LIFTED_MULTICUT_LEARNABLE_LIFTED_MULTICUT_OBJECTIVE_NAME_HXX
#define NIFTY_PYTHON_GRAPH_LIFTED_MULTICUT_LEARNABLE_LIFTED_MULTICUT_OBJECTIVE_NAME_HXX

#include "nifty/graph/optimization/lifted_multicut/learnable_lifted_multicut_objective.hxx"
#include "nifty/python/graph/graph_name.hxx"

namespace nifty{
namespace graph{
namespace lifted_multicut{

    template<class OBJECTIVE>
    struct LiftedMulticutObjectiveName;

    template<class GRAPH, class T>
    struct LiftedMulticutObjectiveName<LearnableLiftedMulticutObjective<GRAPH, T> >{
        static std::string name(){
            return std::string("LearnableLiftedMulticutObjective") + GraphName<GRAPH>::name();
        }
    };

}
}
}

#endif /* NIFTY_PYTHON_GRAPH_LIFTED_MULTICUT_LEARNABLE_LIFTED_MULTICUT_OBJECTIVE_NAME_HXX */
<|endoftext|>


<commit_before>#include "settings.h"

#include "ui_settings.h"

#include <ui/settings/camerainfo.h>
#include <ui/settings/microphoneinfo.h>
#include <ui/settings/screeninfo.h>
#include "settingshelper.h"

#include "settingskeys.h"

#include <common.h>

#include <QScreen>

const QStringList neededSettings = {SettingsKey::localRealname,
                                    SettingsKey::localUsername,
                                    SettingsKey::sipServerAddress,
                                    SettingsKey::sipAutoConnect};

Settings::Settings(QWidget *parent) :
  QDialog(parent),
  basicUI_(new Ui::BasicSettings),
  cam_(std::shared_ptr<CameraInfo> (new CameraInfo())),
  mic_(std::shared_ptr<MicrophoneInfo> (new MicrophoneInfo())),
  screen_(std::shared_ptr<ScreenInfo> (new ScreenInfo())),
  sipSettings_(this),
  videoSettings_(this, cam_),
  audioSettings_(this, mic_),
  settings_(settingsFile, settingsFileFormat)
{}

Settings::~Settings()
{
  // I believe the UI:s are destroyed when parents are destroyed
}

void Settings::init()
{
  basicUI_->setupUi(this);

  // Checks that settings values are correct for the program to start. Also sets GUI.
  getSettings(false);

  int videoID    = getDeviceID(basicUI_->videoDevice_combo, SettingsKey::videoDeviceID,
                               SettingsKey::videoDevice);
  int audioIndex = getDeviceID(basicUI_->audioDevice_combo, SettingsKey::audioDeviceID,
                               SettingsKey::audioDevice);

  audioSettings_.init(audioIndex);
  videoSettings_.init(videoID);
  sipSettings_.init();

  //QObject::connect(basicUI_->save, &QPushButton::clicked, this, &Settings::on_ok_clicked);
  //QObject::connect(basicUI_->close, &QPushButton::clicked, this, &Settings::on_cancel_clicked);

  QObject::connect(&videoSettings_, &VideoSettings::updateVideoSettings,
                   this, &Settings::updateVideoSettings);
  QObject::connect(&videoSettings_, &VideoSettings::hidden, this, &Settings::show);

  QObject::connect(&audioSettings_, &AudioSettings::updateAudioSettings,
                   this, &Settings::updateAudioSettings);
  QObject::connect(&audioSettings_, &AudioSettings::hidden, this, &Settings::show);

  QObject::connect(&sipSettings_, &SIPSettings::updateCallSettings,
                   this, &Settings::updateCallSettings);
  QObject::connect(&sipSettings_, &SIPSettings::hidden,
                   this, &Settings::show);

  QObject::connect(basicUI_->serverAddress_edit, &QLineEdit::textChanged,
                   this, &Settings::changedSIPText);
  QObject::connect(basicUI_->username_edit, &QLineEdit::textChanged,
                   this, &Settings::changedSIPText);

  QObject::connect(basicUI_->serverAddress_edit, &QLineEdit::textChanged,
                   this, &Settings::uiChangedString);

  QObject::connect(basicUI_->name_edit, &QLineEdit::textChanged,
                   this, &Settings::uiChangedString);

  QObject::connect(basicUI_->username_edit, &QLineEdit::textChanged,
                   this, &Settings::uiChangedString);

  QObject::connect(basicUI_->auto_connect_box, &QCheckBox::stateChanged,
                   this, &Settings::uiChangedBool);

  QObject::connect(basicUI_->videoDevice_combo, &QComboBox::currentTextChanged,
                   this, &Settings::uiChangedString);
  QObject::connect(basicUI_->audioDevice_combo, &QComboBox::currentTextChanged,
                   this, &Settings::uiChangedString);
  QObject::connect(basicUI_->screenDevice_combo, &QComboBox::currentTextChanged,
                   this, &Settings::uiChangedString);

  // TODO: Also emit the position of closed window and move this setting there
}

void Settings::show()
{
  printNormal(this, "Opening settings");
  // initialize everytime in case they have changed
  initDeviceSelector(basicUI_->videoDevice_combo, SettingsKey::videoDeviceID,
                     SettingsKey::videoDevice, cam_);
  initDeviceSelector(basicUI_->audioDevice_combo, SettingsKey::audioDeviceID,
                     SettingsKey::audioDevice, mic_);
  initDeviceSelector(basicUI_->screenDevice_combo, SettingsKey::userScreenID,
                     SettingsKey::userScreen, screen_);

  QWidget::show();
  basicUI_->save->hide();
}

void Settings::setMicState(bool enabled)
{
  if (enabled)
  {
    settings_.setValue(SettingsKey::micStatus, "1");
  }
  else
  {
    settings_.setValue(SettingsKey::micStatus, "0");
  }
}

void Settings::setCameraState(bool enabled)
{
  if (enabled)
  {
    settings_.setValue(SettingsKey::cameraStatus, "1");
  }
  else
  {
    settings_.setValue(SettingsKey::cameraStatus, "0");
  }
}

void Settings::setScreenShareState(bool enabled)
{
  if (enabled)
  {
    int screenIndex = getDeviceID(basicUI_->screenDevice_combo, SettingsKey::userScreenID,
                                  SettingsKey::userScreen);

    if (screenIndex < QGuiApplication::screens().size())
    {
      QScreen *screen = QGuiApplication::screens().at(screenIndex);

      if (screen != nullptr)
      {
        QSize resolution;
        resolution.setWidth(screen->size().width() - screen->size().width()%8);
        resolution.setHeight(screen->size().height() - screen->size().height()%8);

        settings_.setValue(SettingsKey::screenShareStatus, "1");
        settings_.setValue(SettingsKey::videoResultionWidth, resolution.width());
        settings_.setValue(SettingsKey::videoResultionHeight, resolution.height());
        settings_.setValue(SettingsKey::videoFramerate, "5");
        videoSettings_.setScreenShareState(enabled);

        printNormal(this, "Enabled Screen sharing", "Screen resolution",
                    QString::number(resolution.width()) + "x" + QString::number(resolution.height()));
      }
    }
  }
  else
  {
    settings_.setValue(SettingsKey::screenShareStatus, "0");
    videoSettings_.setScreenShareState(enabled);
    videoSettings_.saveCameraCapabilities(getDeviceID(basicUI_->audioDevice_combo,
                                                      SettingsKey::videoDeviceID,
                                                      SettingsKey::videoDevice), !enabled);
  }
}

void Settings::uiChangedString(QString text)
{
  Q_UNUSED(text);
  basicUI_->save->show();
}

void Settings::uiChangedBool(bool state)
{
  Q_UNUSED(state);
  basicUI_->save->show();
}

void Settings::on_save_clicked()
{
  printNormal(this, "Saving settings");
  // The UI values are saved to settings.
  saveSettings();
  setScreenShareState(settingEnabled(SettingsKey::screenShareStatus));

  emit updateCallSettings();
  emit updateVideoSettings();
  emit updateAudioSettings();

  basicUI_->save->hide();
}

void Settings::on_close_clicked()
{
  printNormal(this, "Closing Settings. Gettings settings from file.");

  if (checkSettingsList(settings_, neededSettings))
  {
    // discard UI values and restore the settings from file
    getSettings(false);
    hide();
  }
}

void Settings::on_sip_settings_button_clicked()
{
  saveSettings();
  hide();
  sipSettings_.show();
}

void Settings::on_video_settings_button_clicked()
{
  saveSettings();
  hide();
  videoSettings_.show();
}

void Settings::on_audio_settings_button_clicked()
{
  saveSettings();
  hide();
  audioSettings_.show();
}

// records the settings
void Settings::saveSettings()
{
  printNormal(this, "Recording settings");

  // Local settings
  saveTextValue(SettingsKey::localRealname, basicUI_->name_edit->text(), settings_);
  saveTextValue(SettingsKey::localUsername, basicUI_->username_edit->text(), settings_);
  saveTextValue(SettingsKey::sipServerAddress, basicUI_->serverAddress_edit->text(), settings_);

  saveCheckBox(SettingsKey::sipAutoConnect, basicUI_->auto_connect_box, settings_);

  saveDevice(basicUI_->videoDevice_combo, SettingsKey::videoDeviceID,
             SettingsKey::videoDevice, true);
  saveDevice(basicUI_->audioDevice_combo, SettingsKey::audioDeviceID,
             SettingsKey::audioDevice, false);
  saveDevice(basicUI_->screenDevice_combo, SettingsKey::userScreenID,
             SettingsKey::userScreen, false);
}

// restores recorded settings
void Settings::getSettings(bool changedDevice)
{
  initDeviceSelector(basicUI_->videoDevice_combo, SettingsKey::videoDeviceID,
                     SettingsKey::videoDevice, cam_);
  initDeviceSelector(basicUI_->audioDevice_combo, SettingsKey::audioDeviceID,
                     SettingsKey::audioDevice, mic_);
  initDeviceSelector(basicUI_->screenDevice_combo, SettingsKey::userScreenID,
                     SettingsKey::userScreen, screen_);

  //get values from QSettings
  if (checkSettingsList(settings_, neededSettings))
  {
    printNormal(this, "Loading settings from file", {"File"}, {settings_.fileName()});

    basicUI_->name_edit->setText      (settings_.value(SettingsKey::localRealname).toString());
    basicUI_->username_edit->setText  (settings_.value(SettingsKey::localUsername).toString());

    basicUI_->serverAddress_edit->setText(settings_.value(SettingsKey::sipServerAddress).toString());

    restoreCheckBox(SettingsKey::sipAutoConnect, basicUI_->auto_connect_box, settings_);

    // updates the sip text label
    changedSIPText("");

    // set index for camera
    int videoIndex = getDeviceID(basicUI_->videoDevice_combo, SettingsKey::videoDeviceID,
                                 SettingsKey::videoDevice);
    if(changedDevice)
    {
      videoSettings_.changedDevice(videoIndex);
    }
    basicUI_->videoDevice_combo->setCurrentIndex(videoIndex);

    // set correct entry for microphone selector
    int audioIndex = getDeviceID(basicUI_->audioDevice_combo, SettingsKey::audioDeviceID,
                                 SettingsKey::audioDevice);
    if (basicUI_->audioDevice_combo->count() != 0)
    {
      if (audioIndex != -1)
      {
        basicUI_->audioDevice_combo->setCurrentIndex(audioIndex);
      }
      else
      {
        basicUI_->audioDevice_combo->setCurrentIndex(0);
      }
    }

    // set index for screen
    int screenIndex = getDeviceID(basicUI_->screenDevice_combo, SettingsKey::userScreenID,
                                  SettingsKey::userScreen);
    if (basicUI_->screenDevice_combo->count() != 0)
    {
      if (screenIndex != -1)
      {
        basicUI_->screenDevice_combo->setCurrentIndex(screenIndex);
      }
      else
      {
        basicUI_->screenDevice_combo->setCurrentIndex(0);
      }
    }
  }
  else
  {
    resetFaultySettings();
  }
}

void Settings::resetFaultySettings()
{
  printWarning(this, "Could not restore settings! Resetting settings from defaults.");

  // record GUI settings in hope that they are correct ( is case by default )
  saveSettings();

  videoSettings_.resetSettings(getDeviceID(basicUI_->videoDevice_combo,
                                           SettingsKey::videoDeviceID,
                                           SettingsKey::videoDevice));

  audioSettings_.resetSettings(getDeviceID(basicUI_->audioDevice_combo,
                                           SettingsKey::audioDeviceID,
                                           SettingsKey::audioDevice));

  // we set the connecting to true at this point because we want two things:
  // 1) that Kvazzup doesn't connect to any server without user permission
  // 2) that connecting to server is default since it is the easiest way to use Kvazzup
  // These two conditions can only be achieved by modifying UI after settings have been saved
  basicUI_->auto_connect_box->setChecked(true);

  // Show resetted settings to user so she can fix them manually
  show();
}

void Settings::initDeviceSelector(QComboBox* deviceSelector,
                                  QString settingID,
                                  QString settingsDevice,
                                  std::shared_ptr<DeviceInfoInterface> interface)
{
  deviceSelector->clear();
  QStringList devices = interface->getDeviceList();
  for(int i = 0; i < devices.size(); ++i)
  {
    deviceSelector->addItem( devices[i]);
  }
  int deviceIndex = getDeviceID(deviceSelector, settingID, settingsDevice);

  if(deviceIndex >= deviceSelector->count())
  {
    deviceSelector->setCurrentIndex(0);
  }
  else
  {
    deviceSelector->setCurrentIndex(deviceIndex);
  }

  //printNormal(this, "Added " + QString::number(deviceSelector->count()) + " devices to selector",
  //    {"SettingsID"}, {settingID});
}

int Settings::getDeviceID(QComboBox* deviceSelector, QString settingID,
                          QString settingsDevice)
{
  Q_ASSERT(deviceSelector);
  QString deviceName = settings_.value(settingsDevice).toString();

  int deviceIndex = deviceSelector->findText(deviceName);
  int deviceID = settings_.value(settingID).toInt();

//  printDebug(DEBUG_NORMAL, this, "Getting device ID from selector list",
//      {"SettingsID", "DeviceName", "List Index", "Number of items"},
//      {settingID, deviceName, QString::number(deviceIndex),
//       QString::number(deviceSelector->count())});

  // if the device exists in list
  if(deviceIndex != -1 && deviceSelector->count() != 0)
  {
    // if we have multiple devices with same name we use id
    if(deviceID != deviceIndex
       && deviceSelector->itemText(deviceID) == settings_.value(settingsDevice).toString())
    {
      return deviceID;
    }
    else
    {
      // the recorded info was false and our found device is chosen
      settings_.setValue(settingID, deviceIndex);
      return deviceIndex;
    }
  } // if there are devices available, use first
  else if(deviceSelector->count() != 0)
  {
    // could not find the device. Choosing first one
    settings_.setValue(settingID, 0);
    return 0;
  }

  // no devices attached
  return -1;
}

void Settings::saveDevice(QComboBox* deviceSelector, QString settingsID,
                          QString settingsDevice, bool video)
{
  int currentIndex = deviceSelector->currentIndex();
  if( currentIndex != -1)
  {
    if(deviceSelector->currentText() != settings_.value(settingsDevice))
    {
      settings_.setValue(settingsDevice, deviceSelector->currentText());
      // set capability to first

      if (video)
      {
        videoSettings_.changedDevice(currentIndex);
      }
      else
      {
        audioSettings_.changedDevice(currentIndex);
      }
    }
    else if(basicUI_->videoDevice_combo->currentIndex() != settings_.value(settingsID))
    {
      if (video)
      {
        videoSettings_.changedDevice(currentIndex);
      }
      else
      {
        audioSettings_.changedDevice(currentIndex);
      }
    }

    // record index in all cases
    settings_.setValue(settingsID,      currentIndex);
  }
}

void Settings::changedSIPText(const QString &text)
{
  Q_UNUSED(text);
  basicUI_->sipAddress->setText("sip:" + basicUI_->username_edit->text()
                                + "@" + basicUI_->serverAddress_edit->text());
}

void Settings::updateServerStatus(QString status)
{
  basicUI_->status->setText(status);
}
<commit_msg>fix(Settings): Initialize camera and mic buttons when starting the first time<commit_after>#include "settings.h"

#include "ui_settings.h"

#include <ui/settings/camerainfo.h>
#include <ui/settings/microphoneinfo.h>
#include <ui/settings/screeninfo.h>
#include "settingshelper.h"

#include "settingskeys.h"

#include <common.h>

#include <QScreen>

const QStringList neededSettings = {SettingsKey::localRealname,
                                    SettingsKey::localUsername,
                                    SettingsKey::sipServerAddress,
                                    SettingsKey::sipAutoConnect};

Settings::Settings(QWidget *parent) :
  QDialog(parent),
  basicUI_(new Ui::BasicSettings),
  cam_(std::shared_ptr<CameraInfo> (new CameraInfo())),
  mic_(std::shared_ptr<MicrophoneInfo> (new MicrophoneInfo())),
  screen_(std::shared_ptr<ScreenInfo> (new ScreenInfo())),
  sipSettings_(this),
  videoSettings_(this, cam_),
  audioSettings_(this, mic_),
  settings_(settingsFile, settingsFileFormat)
{}

Settings::~Settings()
{
  // I believe the UI:s are destroyed when parents are destroyed
}

void Settings::init()
{
  basicUI_->setupUi(this);

  // Checks that settings values are correct for the program to start. Also sets GUI.
  getSettings(false);

  int videoID    = getDeviceID(basicUI_->videoDevice_combo, SettingsKey::videoDeviceID,
                               SettingsKey::videoDevice);
  int audioIndex = getDeviceID(basicUI_->audioDevice_combo, SettingsKey::audioDeviceID,
                               SettingsKey::audioDevice);

  audioSettings_.init(audioIndex);
  videoSettings_.init(videoID);
  sipSettings_.init();

  //QObject::connect(basicUI_->save, &QPushButton::clicked, this, &Settings::on_ok_clicked);
  //QObject::connect(basicUI_->close, &QPushButton::clicked, this, &Settings::on_cancel_clicked);

  QObject::connect(&videoSettings_, &VideoSettings::updateVideoSettings,
                   this, &Settings::updateVideoSettings);
  QObject::connect(&videoSettings_, &VideoSettings::hidden, this, &Settings::show);

  QObject::connect(&audioSettings_, &AudioSettings::updateAudioSettings,
                   this, &Settings::updateAudioSettings);
  QObject::connect(&audioSettings_, &AudioSettings::hidden, this, &Settings::show);

  QObject::connect(&sipSettings_, &SIPSettings::updateCallSettings,
                   this, &Settings::updateCallSettings);
  QObject::connect(&sipSettings_, &SIPSettings::hidden,
                   this, &Settings::show);

  QObject::connect(basicUI_->serverAddress_edit, &QLineEdit::textChanged,
                   this, &Settings::changedSIPText);
  QObject::connect(basicUI_->username_edit, &QLineEdit::textChanged,
                   this, &Settings::changedSIPText);

  QObject::connect(basicUI_->serverAddress_edit, &QLineEdit::textChanged,
                   this, &Settings::uiChangedString);

  QObject::connect(basicUI_->name_edit, &QLineEdit::textChanged,
                   this, &Settings::uiChangedString);

  QObject::connect(basicUI_->username_edit, &QLineEdit::textChanged,
                   this, &Settings::uiChangedString);

  QObject::connect(basicUI_->auto_connect_box, &QCheckBox::stateChanged,
                   this, &Settings::uiChangedBool);

  QObject::connect(basicUI_->videoDevice_combo, &QComboBox::currentTextChanged,
                   this, &Settings::uiChangedString);
  QObject::connect(basicUI_->audioDevice_combo, &QComboBox::currentTextChanged,
                   this, &Settings::uiChangedString);
  QObject::connect(basicUI_->screenDevice_combo, &QComboBox::currentTextChanged,
                   this, &Settings::uiChangedString);

  if (!settings_.value(SettingsKey::micStatus).isValid())
  {
    setMicState(true);
  }

  if (!settings_.value(SettingsKey::cameraStatus).isValid())
  {
    setCameraState(true);
  }

  // TODO: Also emit the position of closed window and move this setting there
}

void Settings::show()
{
  printNormal(this, "Opening settings");
  // initialize everytime in case they have changed
  initDeviceSelector(basicUI_->videoDevice_combo, SettingsKey::videoDeviceID,
                     SettingsKey::videoDevice, cam_);
  initDeviceSelector(basicUI_->audioDevice_combo, SettingsKey::audioDeviceID,
                     SettingsKey::audioDevice, mic_);
  initDeviceSelector(basicUI_->screenDevice_combo, SettingsKey::userScreenID,
                     SettingsKey::userScreen, screen_);

  QWidget::show();
  basicUI_->save->hide();
}

void Settings::setMicState(bool enabled)
{
  if (enabled)
  {
    settings_.setValue(SettingsKey::micStatus, "1");
  }
  else
  {
    settings_.setValue(SettingsKey::micStatus, "0");
  }
}

void Settings::setCameraState(bool enabled)
{
  if (enabled)
  {
    settings_.setValue(SettingsKey::cameraStatus, "1");
  }
  else
  {
    settings_.setValue(SettingsKey::cameraStatus, "0");
  }
}

void Settings::setScreenShareState(bool enabled)
{
  if (enabled)
  {
    int screenIndex = getDeviceID(basicUI_->screenDevice_combo, SettingsKey::userScreenID,
                                  SettingsKey::userScreen);

    if (screenIndex < QGuiApplication::screens().size())
    {
      QScreen *screen = QGuiApplication::screens().at(screenIndex);

      if (screen != nullptr)
      {
        QSize resolution;
        resolution.setWidth(screen->size().width() - screen->size().width()%8);
        resolution.setHeight(screen->size().height() - screen->size().height()%8);

        settings_.setValue(SettingsKey::screenShareStatus, "1");
        settings_.setValue(SettingsKey::videoResultionWidth, resolution.width());
        settings_.setValue(SettingsKey::videoResultionHeight, resolution.height());
        settings_.setValue(SettingsKey::videoFramerate, "5");
        videoSettings_.setScreenShareState(enabled);

        printNormal(this, "Enabled Screen sharing", "Screen resolution",
                    QString::number(resolution.width()) + "x" + QString::number(resolution.height()));
      }
    }
  }
  else
  {
    settings_.setValue(SettingsKey::screenShareStatus, "0");
    videoSettings_.setScreenShareState(enabled);
    videoSettings_.saveCameraCapabilities(getDeviceID(basicUI_->audioDevice_combo,
                                                      SettingsKey::videoDeviceID,
                                                      SettingsKey::videoDevice), !enabled);
  }
}

void Settings::uiChangedString(QString text)
{
  Q_UNUSED(text);
  basicUI_->save->show();
}

void Settings::uiChangedBool(bool state)
{
  Q_UNUSED(state);
  basicUI_->save->show();
}

void Settings::on_save_clicked()
{
  printNormal(this, "Saving settings");
  // The UI values are saved to settings.
  saveSettings();
  setScreenShareState(settingEnabled(SettingsKey::screenShareStatus));

  emit updateCallSettings();
  emit updateVideoSettings();
  emit updateAudioSettings();

  basicUI_->save->hide();
}

void Settings::on_close_clicked()
{
  printNormal(this, "Closing Settings. Gettings settings from file.");

  if (checkSettingsList(settings_, neededSettings))
  {
    // discard UI values and restore the settings from file
    getSettings(false);
    hide();
  }
}

void Settings::on_sip_settings_button_clicked()
{
  saveSettings();
  hide();
  sipSettings_.show();
}

void Settings::on_video_settings_button_clicked()
{
  saveSettings();
  hide();
  videoSettings_.show();
}

void Settings::on_audio_settings_button_clicked()
{
  saveSettings();
  hide();
  audioSettings_.show();
}

// records the settings
void Settings::saveSettings()
{
  printNormal(this, "Recording settings");

  // Local settings
  saveTextValue(SettingsKey::localRealname, basicUI_->name_edit->text(), settings_);
  saveTextValue(SettingsKey::localUsername, basicUI_->username_edit->text(), settings_);
  saveTextValue(SettingsKey::sipServerAddress, basicUI_->serverAddress_edit->text(), settings_);

  saveCheckBox(SettingsKey::sipAutoConnect, basicUI_->auto_connect_box, settings_);

  saveDevice(basicUI_->videoDevice_combo, SettingsKey::videoDeviceID,
             SettingsKey::videoDevice, true);
  saveDevice(basicUI_->audioDevice_combo, SettingsKey::audioDeviceID,
             SettingsKey::audioDevice, false);
  saveDevice(basicUI_->screenDevice_combo, SettingsKey::userScreenID,
             SettingsKey::userScreen, false);
}

// restores recorded settings
void Settings::getSettings(bool changedDevice)
{
  initDeviceSelector(basicUI_->videoDevice_combo, SettingsKey::videoDeviceID,
                     SettingsKey::videoDevice, cam_);
  initDeviceSelector(basicUI_->audioDevice_combo, SettingsKey::audioDeviceID,
                     SettingsKey::audioDevice, mic_);
  initDeviceSelector(basicUI_->screenDevice_combo, SettingsKey::userScreenID,
                     SettingsKey::userScreen, screen_);

  //get values from QSettings
  if (checkSettingsList(settings_, neededSettings))
  {
    printNormal(this, "Loading settings from file", {"File"}, {settings_.fileName()});

    basicUI_->name_edit->setText      (settings_.value(SettingsKey::localRealname).toString());
    basicUI_->username_edit->setText  (settings_.value(SettingsKey::localUsername).toString());

    basicUI_->serverAddress_edit->setText(settings_.value(SettingsKey::sipServerAddress).toString());

    restoreCheckBox(SettingsKey::sipAutoConnect, basicUI_->auto_connect_box, settings_);

    // updates the sip text label
    changedSIPText("");

    // set index for camera
    int videoIndex = getDeviceID(basicUI_->videoDevice_combo, SettingsKey::videoDeviceID,
                                 SettingsKey::videoDevice);
    if(changedDevice)
    {
      videoSettings_.changedDevice(videoIndex);
    }
    basicUI_->videoDevice_combo->setCurrentIndex(videoIndex);

    // set correct entry for microphone selector
    int audioIndex = getDeviceID(basicUI_->audioDevice_combo, SettingsKey::audioDeviceID,
                                 SettingsKey::audioDevice);
    if (basicUI_->audioDevice_combo->count() != 0)
    {
      if (audioIndex != -1)
      {
        basicUI_->audioDevice_combo->setCurrentIndex(audioIndex);
      }
      else
      {
        basicUI_->audioDevice_combo->setCurrentIndex(0);
      }
    }

    // set index for screen
    int screenIndex = getDeviceID(basicUI_->screenDevice_combo, SettingsKey::userScreenID,
                                  SettingsKey::userScreen);
    if (basicUI_->screenDevice_combo->count() != 0)
    {
      if (screenIndex != -1)
      {
        basicUI_->screenDevice_combo->setCurrentIndex(screenIndex);
      }
      else
      {
        basicUI_->screenDevice_combo->setCurrentIndex(0);
      }
    }
  }
  else
  {
    resetFaultySettings();
  }
}

void Settings::resetFaultySettings()
{
  printWarning(this, "Could not restore settings! Resetting settings from defaults.");

  // record GUI settings in hope that they are correct ( is case by default )
  saveSettings();

  videoSettings_.resetSettings(getDeviceID(basicUI_->videoDevice_combo,
                                           SettingsKey::videoDeviceID,
                                           SettingsKey::videoDevice));

  audioSettings_.resetSettings(getDeviceID(basicUI_->audioDevice_combo,
                                           SettingsKey::audioDeviceID,
                                           SettingsKey::audioDevice));

  // we set the connecting to true at this point because we want two things:
  // 1) that Kvazzup doesn't connect to any server without user permission
  // 2) that connecting to server is default since it is the easiest way to use Kvazzup
  // These two conditions can only be achieved by modifying UI after settings have been saved
  basicUI_->auto_connect_box->setChecked(true);

  // Show resetted settings to user so she can fix them manually
  show();
}

void Settings::initDeviceSelector(QComboBox* deviceSelector,
                                  QString settingID,
                                  QString settingsDevice,
                                  std::shared_ptr<DeviceInfoInterface> interface)
{
  deviceSelector->clear();
  QStringList devices = interface->getDeviceList();
  for(int i = 0; i < devices.size(); ++i)
  {
    deviceSelector->addItem( devices[i]);
  }
  int deviceIndex = getDeviceID(deviceSelector, settingID, settingsDevice);

  if(deviceIndex >= deviceSelector->count())
  {
    deviceSelector->setCurrentIndex(0);
  }
  else
  {
    deviceSelector->setCurrentIndex(deviceIndex);
  }

  //printNormal(this, "Added " + QString::number(deviceSelector->count()) + " devices to selector",
  //    {"SettingsID"}, {settingID});
}

int Settings::getDeviceID(QComboBox* deviceSelector, QString settingID,
                          QString settingsDevice)
{
  Q_ASSERT(deviceSelector);
  QString deviceName = settings_.value(settingsDevice).toString();

  int deviceIndex = deviceSelector->findText(deviceName);
  int deviceID = settings_.value(settingID).toInt();

//  printDebug(DEBUG_NORMAL, this, "Getting device ID from selector list",
//      {"SettingsID", "DeviceName", "List Index", "Number of items"},
//      {settingID, deviceName, QString::number(deviceIndex),
//       QString::number(deviceSelector->count())});

  // if the device exists in list
  if(deviceIndex != -1 && deviceSelector->count() != 0)
  {
    // if we have multiple devices with same name we use id
    if(deviceID != deviceIndex
       && deviceSelector->itemText(deviceID) == settings_.value(settingsDevice).toString())
    {
      return deviceID;
    }
    else
    {
      // the recorded info was false and our found device is chosen
      settings_.setValue(settingID, deviceIndex);
      return deviceIndex;
    }
  } // if there are devices available, use first
  else if(deviceSelector->count() != 0)
  {
    // could not find the device. Choosing first one
    settings_.setValue(settingID, 0);
    return 0;
  }

  // no devices attached
  return -1;
}

void Settings::saveDevice(QComboBox* deviceSelector, QString settingsID,
                          QString settingsDevice, bool video)
{
  int currentIndex = deviceSelector->currentIndex();
  if( currentIndex != -1)
  {
    if(deviceSelector->currentText() != settings_.value(settingsDevice))
    {
      settings_.setValue(settingsDevice, deviceSelector->currentText());
      // set capability to first

      if (video)
      {
        videoSettings_.changedDevice(currentIndex);
      }
      else
      {
        audioSettings_.changedDevice(currentIndex);
      }
    }
    else if(basicUI_->videoDevice_combo->currentIndex() != settings_.value(settingsID))
    {
      if (video)
      {
        videoSettings_.changedDevice(currentIndex);
      }
      else
      {
        audioSettings_.changedDevice(currentIndex);
      }
    }

    // record index in all cases
    settings_.setValue(settingsID,      currentIndex);
  }
}

void Settings::changedSIPText(const QString &text)
{
  Q_UNUSED(text);
  basicUI_->sipAddress->setText("sip:" + basicUI_->username_edit->text()
                                + "@" + basicUI_->serverAddress_edit->text());
}

void Settings::updateServerStatus(QString status)
{
  basicUI_->status->setText(status);
}
<|endoftext|>


<commit_before>/******************************************************************************
 * Copyright 2018 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (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.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.
 *****************************************************************************/

/**
 * @file
 **/

#include "modules/planning/scenarios/stop_sign/unprotected/stage_pre_stop.h"

#include <algorithm>
#include <utility>

#include "modules/perception/proto/perception_obstacle.pb.h"

#include "cyber/common/log.h"
#include "modules/common/time/time.h"
#include "modules/common/vehicle_state/vehicle_state_provider.h"
#include "modules/map/pnc_map/path.h"
#include "modules/planning/common/frame.h"
#include "modules/planning/common/planning_context.h"
#include "modules/planning/scenarios/util/util.h"
#include "modules/planning/tasks/deciders/decider_creep.h"

namespace apollo {
namespace planning {
namespace scenario {
namespace stop_sign {

using common::TrajectoryPoint;
using common::time::Clock;
using hdmap::HDMapUtil;
using hdmap::LaneInfoConstPtr;
using hdmap::OverlapInfoConstPtr;
using perception::PerceptionObstacle;

using StopSignLaneVehicles =
    std::unordered_map<std::string, std::vector<std::string>>;

Stage::StageStatus StopSignUnprotectedStagePreStop::Process(
    const TrajectoryPoint& planning_init_point, Frame* frame) {
  ADEBUG << "stage: PreStop";
  CHECK_NOTNULL(frame);

  scenario_config_.CopyFrom(GetContext()->scenario_config);

  bool plan_ok = ExecuteTaskOnReferenceLine(planning_init_point, frame);
  if (!plan_ok) {
    AERROR << "StopSignUnprotectedStagePreStop planning error";
  }

  const auto& reference_line_info = frame->reference_line_info().front();

  // check if the stop_sign is still along reference_line
  std::string stop_sign_overlap_id =
      PlanningContext::GetScenarioInfo()->current_stop_sign_overlap.object_id;
  if (scenario::CheckStopSignDone(reference_line_info, stop_sign_overlap_id)) {
    return FinishScenario();
  }

  constexpr double kPassStopLineBuffer = 0.3;  // unit: m
  const double adc_front_edge_s = reference_line_info.AdcSlBoundary().end_s();
  const double distance_adc_pass_stop_sign =
      adc_front_edge_s -
      PlanningContext::GetScenarioInfo()->current_stop_sign_overlap.start_s;
  if (distance_adc_pass_stop_sign <= kPassStopLineBuffer) {
    // not passed stop line, check valid stop
    if (CheckADCStop(reference_line_info)) {
      return FinishStage();
    }
  } else {
    // passed stop line
    return FinishStage();
  }

  // PRE-STOP
  const PathDecision& path_decision = reference_line_info.path_decision();
  auto& watch_vehicles = GetContext()->watch_vehicles;

  std::vector<std::string> watch_vehicle_ids;
  for (auto it = watch_vehicles.begin(); it != watch_vehicles.end(); ++it) {
    std::copy(it->second.begin(), it->second.end(),
              std::back_inserter(watch_vehicle_ids));

    // for debug string
    std::string associated_lane_id = it->first;
    std::string s;
    for (size_t i = 0; i < it->second.size(); ++i) {
      std::string vehicle_id = (it->second)[i];
      s = s.empty() ? vehicle_id : s + "," + vehicle_id;
    }
    ADEBUG << "watch_vehicles: lane_id[" << associated_lane_id << "] vehicle["
           << s << "]";
  }

  // pass vehicles being watched to DECIDER_RULE_BASED_STOP task
  // for visualization
  PlanningContext::GetScenarioInfo()->stop_sign_wait_for_obstacles.clear();
  std::copy(
      watch_vehicle_ids.begin(), watch_vehicle_ids.end(),
      std::back_inserter(
          PlanningContext::GetScenarioInfo()->stop_sign_wait_for_obstacles));

  for (const auto* obstacle : path_decision.obstacles().Items()) {
    // add to watch_vehicles if adc is still proceeding to stop sign
    AddWatchVehicle(*obstacle, &watch_vehicles);
  }

  return Stage::RUNNING;
}

/**
 * @brief: add a watch vehicle which arrives at stop sign ahead of adc
 */
int StopSignUnprotectedStagePreStop::AddWatchVehicle(
    const Obstacle& obstacle, StopSignLaneVehicles* watch_vehicles) {
  CHECK_NOTNULL(watch_vehicles);

  const PerceptionObstacle& perception_obstacle = obstacle.Perception();
  const std::string& obstacle_id = std::to_string(perception_obstacle.id());
  PerceptionObstacle::Type obstacle_type = perception_obstacle.type();
  std::string obstacle_type_name = PerceptionObstacle_Type_Name(obstacle_type);

  // check type
  if (obstacle_type != PerceptionObstacle::UNKNOWN &&
      obstacle_type != PerceptionObstacle::UNKNOWN_MOVABLE &&
      obstacle_type != PerceptionObstacle::BICYCLE &&
      obstacle_type != PerceptionObstacle::VEHICLE) {
    ADEBUG << "obstacle_id[" << obstacle_id << "] type[" << obstacle_type_name
           << "]. skip";
    return 0;
  }

  auto point = common::util::MakePointENU(perception_obstacle.position().x(),
                                          perception_obstacle.position().y(),
                                          perception_obstacle.position().z());
  double obstacle_s = 0.0;
  double obstacle_l = 0.0;
  LaneInfoConstPtr obstacle_lane;
  if (HDMapUtil::BaseMap().GetNearestLaneWithHeading(
          point, 5.0, perception_obstacle.theta(), M_PI / 3.0, &obstacle_lane,
          &obstacle_s, &obstacle_l) != 0) {
    ADEBUG << "obstacle_id[" << obstacle_id << "] type[" << obstacle_type_name
           << "]: Failed to find nearest lane from map for position: "
           << point.DebugString()
           << "; heading:" << perception_obstacle.theta();
    return -1;
  }

  // check obstacle is on an associate lane guarded by stop sign
  std::string obstable_lane_id = obstacle_lane.get()->id().id();
  auto assoc_lane_it = std::find_if(
      GetContext()->associated_lanes.begin(),
      GetContext()->associated_lanes.end(),
      [&obstable_lane_id](
          std::pair<LaneInfoConstPtr, OverlapInfoConstPtr>& assc_lane) {
        return assc_lane.first.get()->id().id() == obstable_lane_id;
      });
  if (assoc_lane_it == GetContext()->associated_lanes.end()) {
    ADEBUG << "obstacle_id[" << obstacle_id << "] type[" << obstacle_type_name
           << "] lane_id[" << obstable_lane_id
           << "] not associated with current stop_sign. skip";
    return -1;
  }

  // check a valid stop for stop line of the stop_sign
  auto over_lap_info = assoc_lane_it->second.get()->GetObjectOverlapInfo(
      obstacle_lane.get()->id());
  if (over_lap_info == nullptr) {
    AERROR << "can't find over_lap_info for id: " << obstable_lane_id;
    return -1;
  }
  const double stop_line_s = over_lap_info->lane_overlap_info().start_s();
  const double obstacle_end_s = obstacle_s + perception_obstacle.length() / 2;
  const double distance_to_stop_line = stop_line_s - obstacle_end_s;

  if (distance_to_stop_line < 0 ||
      scenario_config_.watch_vehicle_max_valid_stop_distance()) {
    ADEBUG << "obstacle_id[" << obstacle_id << "] type[" << obstacle_type_name
           << "] distance_to_stop_line[" << distance_to_stop_line
           << "]; stop_line_s" << stop_line_s << "]; obstacle_end_s["
           << obstacle_end_s
           << "] too far from stop line or pass stop line. skip";
    return -1;
  }

  // use a vector since motocycles/bicycles can be more than one
  std::vector<std::string> vehicles =
      (*watch_vehicles)[obstacle_lane->id().id()];
  if (std::find(vehicles.begin(), vehicles.end(), obstacle_id) ==
      vehicles.end()) {
    ADEBUG << "AddWatchVehicle: lane[" << obstacle_lane->id().id()
           << "] obstacle_id[" << obstacle_id << "]";
    (*watch_vehicles)[obstacle_lane->id().id()].push_back(obstacle_id);
  }

  return 0;
}

/**
 * @brief: check valid stop_sign stop
 */
bool StopSignUnprotectedStagePreStop::CheckADCStop(
    const ReferenceLineInfo& reference_line_info) {
  const double adc_speed =
      common::VehicleStateProvider::Instance()->linear_velocity();
  if (adc_speed > scenario_config_.max_adc_stop_speed()) {
    ADEBUG << "ADC not stopped: speed[" << adc_speed << "]";
    return false;
  }

  // check stop close enough to stop line of the stop_sign
  const double adc_front_edge_s = reference_line_info.AdcSlBoundary().end_s();
  const double stop_line_start_s =
      PlanningContext::GetScenarioInfo()->current_stop_sign_overlap.start_s;
  const double distance_stop_line_to_adc_front_edge =
      stop_line_start_s - adc_front_edge_s;
  ADEBUG << "distance_stop_line_to_adc_front_edge["
      << distance_stop_line_to_adc_front_edge
      << "] stop_sign["
      << PlanningContext::GetScenarioInfo()->current_stop_sign_overlap.object_id
      << "] stop_line_start_s[" << stop_line_start_s
      << "] adc_front_edge_s[" << adc_front_edge_s << "]";

  if (distance_stop_line_to_adc_front_edge >
      scenario_config_.max_valid_stop_distance()) {
    ADEBUG << "not a valid stop. too far from stop line.";
    return false;
  }

  // TODO(all): check no BICYCLE in between.

  return true;
}

Stage::StageStatus StopSignUnprotectedStagePreStop::FinishStage() {
  GetContext()->stop_start_time = Clock::NowInSeconds();
  next_stage_ = ScenarioConfig::STOP_SIGN_UNPROTECTED_STOP;

  return Stage::FINISHED;
}

}  // namespace stop_sign
}  // namespace scenario
}  // namespace planning
}  // namespace apollo
<commit_msg>planning: fix a bug in stop-sign scenario<commit_after>/******************************************************************************
 * Copyright 2018 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (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.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.
 *****************************************************************************/

/**
 * @file
 **/

#include "modules/planning/scenarios/stop_sign/unprotected/stage_pre_stop.h"

#include <algorithm>
#include <utility>

#include "modules/perception/proto/perception_obstacle.pb.h"

#include "cyber/common/log.h"
#include "modules/common/time/time.h"
#include "modules/common/vehicle_state/vehicle_state_provider.h"
#include "modules/map/pnc_map/path.h"
#include "modules/planning/common/frame.h"
#include "modules/planning/common/planning_context.h"
#include "modules/planning/scenarios/util/util.h"
#include "modules/planning/tasks/deciders/decider_creep.h"

namespace apollo {
namespace planning {
namespace scenario {
namespace stop_sign {

using common::TrajectoryPoint;
using common::time::Clock;
using hdmap::HDMapUtil;
using hdmap::LaneInfoConstPtr;
using hdmap::OverlapInfoConstPtr;
using perception::PerceptionObstacle;

using StopSignLaneVehicles =
    std::unordered_map<std::string, std::vector<std::string>>;

Stage::StageStatus StopSignUnprotectedStagePreStop::Process(
    const TrajectoryPoint& planning_init_point, Frame* frame) {
  ADEBUG << "stage: PreStop";
  CHECK_NOTNULL(frame);

  scenario_config_.CopyFrom(GetContext()->scenario_config);

  bool plan_ok = ExecuteTaskOnReferenceLine(planning_init_point, frame);
  if (!plan_ok) {
    AERROR << "StopSignUnprotectedStagePreStop planning error";
  }

  const auto& reference_line_info = frame->reference_line_info().front();

  // check if the stop_sign is still along reference_line
  std::string stop_sign_overlap_id =
      PlanningContext::GetScenarioInfo()->current_stop_sign_overlap.object_id;
  if (scenario::CheckStopSignDone(reference_line_info, stop_sign_overlap_id)) {
    return FinishScenario();
  }

  constexpr double kPassStopLineBuffer = 0.3;  // unit: m
  const double adc_front_edge_s = reference_line_info.AdcSlBoundary().end_s();
  const double distance_adc_pass_stop_sign =
      adc_front_edge_s -
      PlanningContext::GetScenarioInfo()->current_stop_sign_overlap.start_s;
  if (distance_adc_pass_stop_sign <= kPassStopLineBuffer) {
    // not passed stop line, check valid stop
    if (CheckADCStop(reference_line_info)) {
      return FinishStage();
    }
  } else {
    // passed stop line
    return FinishStage();
  }

  // PRE-STOP
  const PathDecision& path_decision = reference_line_info.path_decision();
  auto& watch_vehicles = GetContext()->watch_vehicles;

  std::vector<std::string> watch_vehicle_ids;
  for (auto it = watch_vehicles.begin(); it != watch_vehicles.end(); ++it) {
    std::copy(it->second.begin(), it->second.end(),
              std::back_inserter(watch_vehicle_ids));

    // for debug string
    std::string associated_lane_id = it->first;
    std::string s;
    for (size_t i = 0; i < it->second.size(); ++i) {
      std::string vehicle_id = (it->second)[i];
      s = s.empty() ? vehicle_id : s + "," + vehicle_id;
    }
    ADEBUG << "watch_vehicles: lane_id[" << associated_lane_id << "] vehicle["
           << s << "]";
  }

  // pass vehicles being watched to DECIDER_RULE_BASED_STOP task
  // for visualization
  PlanningContext::GetScenarioInfo()->stop_sign_wait_for_obstacles.clear();
  std::copy(
      watch_vehicle_ids.begin(), watch_vehicle_ids.end(),
      std::back_inserter(
          PlanningContext::GetScenarioInfo()->stop_sign_wait_for_obstacles));

  for (const auto* obstacle : path_decision.obstacles().Items()) {
    // add to watch_vehicles if adc is still proceeding to stop sign
    AddWatchVehicle(*obstacle, &watch_vehicles);
  }

  return Stage::RUNNING;
}

/**
 * @brief: add a watch vehicle which arrives at stop sign ahead of adc
 */
int StopSignUnprotectedStagePreStop::AddWatchVehicle(
    const Obstacle& obstacle, StopSignLaneVehicles* watch_vehicles) {
  CHECK_NOTNULL(watch_vehicles);

  const PerceptionObstacle& perception_obstacle = obstacle.Perception();
  const std::string& obstacle_id = std::to_string(perception_obstacle.id());
  PerceptionObstacle::Type obstacle_type = perception_obstacle.type();
  std::string obstacle_type_name = PerceptionObstacle_Type_Name(obstacle_type);

  // check type
  if (obstacle_type != PerceptionObstacle::UNKNOWN &&
      obstacle_type != PerceptionObstacle::UNKNOWN_MOVABLE &&
      obstacle_type != PerceptionObstacle::BICYCLE &&
      obstacle_type != PerceptionObstacle::VEHICLE) {
    ADEBUG << "obstacle_id[" << obstacle_id << "] type[" << obstacle_type_name
           << "]. skip";
    return 0;
  }

  auto point = common::util::MakePointENU(perception_obstacle.position().x(),
                                          perception_obstacle.position().y(),
                                          perception_obstacle.position().z());
  double obstacle_s = 0.0;
  double obstacle_l = 0.0;
  LaneInfoConstPtr obstacle_lane;
  if (HDMapUtil::BaseMap().GetNearestLaneWithHeading(
          point, 5.0, perception_obstacle.theta(), M_PI / 3.0, &obstacle_lane,
          &obstacle_s, &obstacle_l) != 0) {
    ADEBUG << "obstacle_id[" << obstacle_id << "] type[" << obstacle_type_name
           << "]: Failed to find nearest lane from map for position: "
           << point.DebugString()
           << "; heading:" << perception_obstacle.theta();
    return -1;
  }

  // check obstacle is on an associate lane guarded by stop sign
  std::string obstable_lane_id = obstacle_lane.get()->id().id();
  auto assoc_lane_it = std::find_if(
      GetContext()->associated_lanes.begin(),
      GetContext()->associated_lanes.end(),
      [&obstable_lane_id](
          std::pair<LaneInfoConstPtr, OverlapInfoConstPtr>& assc_lane) {
        return assc_lane.first.get()->id().id() == obstable_lane_id;
      });
  if (assoc_lane_it == GetContext()->associated_lanes.end()) {
    ADEBUG << "obstacle_id[" << obstacle_id << "] type[" << obstacle_type_name
           << "] lane_id[" << obstable_lane_id
           << "] not associated with current stop_sign. skip";
    return -1;
  }

  // check a valid stop for stop line of the stop_sign
  auto over_lap_info = assoc_lane_it->second.get()->GetObjectOverlapInfo(
      obstacle_lane.get()->id());
  if (over_lap_info == nullptr) {
    AERROR << "can't find over_lap_info for id: " << obstable_lane_id;
    return -1;
  }
  const double stop_line_s = over_lap_info->lane_overlap_info().start_s();
  const double obstacle_end_s = obstacle_s + perception_obstacle.length() / 2;
  const double distance_to_stop_line = stop_line_s - obstacle_end_s;

  if (distance_to_stop_line >
        scenario_config_.watch_vehicle_max_valid_stop_distance()) {
    ADEBUG << "obstacle_id[" << obstacle_id << "] type[" << obstacle_type_name
           << "] distance_to_stop_line[" << distance_to_stop_line
           << "]; stop_line_s" << stop_line_s << "]; obstacle_end_s["
           << obstacle_end_s << "] too far from stop line. skip";
    return -1;
  }

  // use a vector since motocycles/bicycles can be more than one
  std::vector<std::string> vehicles =
      (*watch_vehicles)[obstacle_lane->id().id()];
  if (std::find(vehicles.begin(), vehicles.end(), obstacle_id) ==
      vehicles.end()) {
    ADEBUG << "AddWatchVehicle: lane[" << obstacle_lane->id().id()
           << "] obstacle_id[" << obstacle_id << "]";
    (*watch_vehicles)[obstacle_lane->id().id()].push_back(obstacle_id);
  }

  return 0;
}

/**
 * @brief: check valid stop_sign stop
 */
bool StopSignUnprotectedStagePreStop::CheckADCStop(
    const ReferenceLineInfo& reference_line_info) {
  const double adc_speed =
      common::VehicleStateProvider::Instance()->linear_velocity();
  if (adc_speed > scenario_config_.max_adc_stop_speed()) {
    ADEBUG << "ADC not stopped: speed[" << adc_speed << "]";
    return false;
  }

  // check stop close enough to stop line of the stop_sign
  const double adc_front_edge_s = reference_line_info.AdcSlBoundary().end_s();
  const double stop_line_start_s =
      PlanningContext::GetScenarioInfo()->current_stop_sign_overlap.start_s;
  const double distance_stop_line_to_adc_front_edge =
      stop_line_start_s - adc_front_edge_s;
  ADEBUG << "distance_stop_line_to_adc_front_edge["
      << distance_stop_line_to_adc_front_edge
      << "] stop_sign["
      << PlanningContext::GetScenarioInfo()->current_stop_sign_overlap.object_id
      << "] stop_line_start_s[" << stop_line_start_s
      << "] adc_front_edge_s[" << adc_front_edge_s << "]";

  if (distance_stop_line_to_adc_front_edge >
      scenario_config_.max_valid_stop_distance()) {
    ADEBUG << "not a valid stop. too far from stop line.";
    return false;
  }

  // TODO(all): check no BICYCLE in between.

  return true;
}

Stage::StageStatus StopSignUnprotectedStagePreStop::FinishStage() {
  GetContext()->stop_start_time = Clock::NowInSeconds();
  next_stage_ = ScenarioConfig::STOP_SIGN_UNPROTECTED_STOP;

  return Stage::FINISHED;
}

}  // namespace stop_sign
}  // namespace scenario
}  // namespace planning
}  // namespace apollo
<|endoftext|>