<commit_before>#include "robotsPluginFacade.h"

#include "src/coreBlocks/coreBlocksFactory.h"
#include "managers/paletteUpdateManager.h"
#include "managers/kitAutoSwitcher.h"
#include "managers/kitExtensionsUpdateManager.h"

#include <interpreterBase/robotModel/portInfo.h>

using namespace interpreterCore;

RobotsPluginFacade::RobotsPluginFacade()
	: mInterpreter(nullptr)
	, mKitPluginManager("plugins/tools/kitPlugins")
	, mActionsManager(mKitPluginManager, mRobotModelManager)
	, mDockDevicesConfigurer(nullptr)
	, mGraphicsWatcherManager(nullptr)
{
	connect(&mRobotModelManager, &RobotModelManager::robotModelChanged
			, &mActionsManager, &ActionsManager::onRobotModelChanged);
}

RobotsPluginFacade::~RobotsPluginFacade()
{
	delete mInterpreter;
}

void RobotsPluginFacade::init(qReal::PluginConfigurator const &configurer)
{
	mRobotSettingsPage = new ui::RobotsSettingsPage(mKitPluginManager, mRobotModelManager);

	mDevicesConfigurationManager.reset(new DevicesConfigurationManager(
			configurer.graphicalModelApi()
			, configurer.logicalModelApi()
			, configurer.mainWindowInterpretersInterface()
			, configurer.systemEvents()
			));

	mTitlesVisibilityManager.reset(
			new TitlesVisibilityManager(mActionsManager.titlesVisibilityAction(), configurer.sceneCustomizer())
			);

	if (!selectKit(configurer)) {
		/// @todo Correctly handle unselected kit.
		return;
	}

	mParser.reset(new textLanguage::RobotsBlockParser(mRobotModelManager
			, [this]() { return mInterpreter ? mInterpreter->timeElapsed() : 0; }));

	interpreterBase::blocksBase::BlocksFactoryInterface * const coreFactory = new coreBlocks::CoreBlocksFactory();
	coreFactory->configure(configurer.graphicalModelApi()
			, configurer.logicalModelApi()
			, mRobotModelManager
			, *configurer.mainWindowInterpretersInterface().errorReporter()
			, *mParser
			);

	mBlocksFactoryManager.addFactory(coreFactory);

	interpreter::Interpreter *interpreter = new interpreter::Interpreter(
			configurer.graphicalModelApi()
			, configurer.logicalModelApi()
			, configurer.mainWindowInterpretersInterface()
			, configurer.projectManager()
			, mBlocksFactoryManager
			, mRobotModelManager
			, *mParser
			, mActionsManager.connectToRobotAction()
			);

	mInterpreter = interpreter;

	connect(&configurer.systemEvents(), &SystemEventsInterface::closedMainWindow
			, mInterpreter, &interpreter::InterpreterInterface::stopRobot);
	connect(&mRobotModelManager, &RobotModelManager::robotModelChanged
			, mInterpreter, &interpreter::InterpreterInterface::stopRobot);

	initKitPlugins(configurer);

	initSensorWidgets();

	auto paletteUpdateManager = new PaletteUpdateManager(configurer.mainWindowInterpretersInterface()
			, mBlocksFactoryManager, this);
	connect(&mRobotModelManager, &RobotModelManager::robotModelChanged
			, paletteUpdateManager, &PaletteUpdateManager::updatePalette);
	mDevicesConfigurationManager->connectDevicesConfigurationProvider(interpreter);

	auto kitExtensionsUpdateManager = new KitExtensionsUpdateManager(mKitPluginManager
			, configurer.textManager(), this);
	connect(&mRobotModelManager, &RobotModelManager::robotModelChanged
			, kitExtensionsUpdateManager, &KitExtensionsUpdateManager::updateExtensions);

	// It will subscribe to all signals itself and free memory too.
	new KitAutoSwitcher(configurer.projectManager(), configurer.logicalModelApi()
			, mBlocksFactoryManager, mKitPluginManager, mRobotModelManager, this);

	connectInterpreterToActions();

	connectEventsForKitPlugin();

	connect(&mActionsManager.robotSettingsAction(), &QAction::triggered
			, [=] () { configurer.mainWindowInterpretersInterface().openSettingsDialog(tr("Robots")); });
	connect(&configurer.systemEvents(), &SystemEventsInterface::activeTabChanged
			, &mActionsManager, &ActionsManager::onActiveTabChanged);

	sync();
}

PreferencesPage *RobotsPluginFacade::robotsSettingsPage() const
{
	return mRobotSettingsPage;
}

interpreterCore::Customizer &RobotsPluginFacade::customizer()
{
	return mCustomizer;
}

ActionsManager &RobotsPluginFacade::actionsManager()
{
	return mActionsManager;
}

QStringList RobotsPluginFacade::defaultSettingsFiles() const
{
	QStringList result = { ":/interpreterCoreDefaultSettings.ini" };
	for (QString const &kitId : mKitPluginManager.kitIds()) {
		for (interpreterBase::KitPluginInterface * const kit : mKitPluginManager.kitsById(kitId)) {
			QString const defaultSettings = kit->defaultSettingsFile();
			if (!defaultSettings.isEmpty()) {
				result << defaultSettings;
			}
		}
	}

	return result;
}

void RobotsPluginFacade::connectInterpreterToActions()
{
	QObject::connect(
			&mActionsManager.runAction()
			, &QAction::triggered
			, mInterpreter
			, &interpreter::InterpreterInterface::interpret
			);

	QObject::connect(
			&mActionsManager.stopRobotAction()
			, &QAction::triggered
			, mInterpreter
			, &interpreter::InterpreterInterface::stopRobot
			);

	QObject::connect(
			&mActionsManager.connectToRobotAction()
			, &QAction::triggered
			, mInterpreter
			, &interpreter::InterpreterInterface::connectToRobot
			);
}

bool RobotsPluginFacade::selectKit(PluginConfigurator const &configurer)
{
	/// @todo reinit it each time when robot model changes
	/// @todo: do we need this method?
	QString const selectedKit = SettingsManager::value("SelectedRobotKit").toString();
	if (selectedKit.isEmpty() && !mKitPluginManager.kitIds().isEmpty()) {
		SettingsManager::setValue("SelectedRobotKit", mKitPluginManager.kitIds()[0]);
	} else if (mKitPluginManager.kitIds().isEmpty()) {
		configurer.mainWindowInterpretersInterface().setEnabledForAllElementsInPalette(false);

		/// @todo Correctly handle unselected kit.
		return false;
	}

	return true;
}

void RobotsPluginFacade::initSensorWidgets()
{
	mDockDevicesConfigurer = new interpreterBase::DevicesConfigurationWidget(nullptr, true);
	mDockDevicesConfigurer->loadRobotModels(mKitPluginManager.allRobotModels());
	connect(&mRobotModelManager, &RobotModelManager::robotModelChanged
			, mDockDevicesConfigurer, &interpreterBase::DevicesConfigurationWidget::selectRobotModel);
	for (interpreterBase::robotModel::RobotModelInterface * const model : mKitPluginManager.allRobotModels()) {
		for (interpreterBase::KitPluginInterface * const kit : mKitPluginManager.kitsById(model->kitId())) {
			mDockDevicesConfigurer->prependCustomWidget(*model, kit->quickPreferencesFor(*model));
		}
	}

	mWatchListWindow = new utils::WatchListWindow(*mParser);

	mWatchListWindow->hideVariables(mParser->specialVariables());

	mGraphicsWatcherManager = new GraphicsWatcherManager(*mParser, this);

	mCustomizer.placeDevicesConfig(mDockDevicesConfigurer);
	mCustomizer.placeWatchPlugins(mWatchListWindow, mGraphicsWatcherManager->widget());

	mDevicesConfigurationManager->connectDevicesConfigurationProvider(mRobotSettingsPage);
	mDevicesConfigurationManager->connectDevicesConfigurationProvider(mDockDevicesConfigurer);
	mDevicesConfigurationManager->connectDevicesConfigurationProvider(mGraphicsWatcherManager);
}

void RobotsPluginFacade::initKitPlugins(qReal::PluginConfigurator const &configurer)
{
	/// @todo: Check that this code works when different kit is selected
	for (QString const &kitId : mKitPluginManager.kitIds()) {
		for (interpreterBase::KitPluginInterface * const kit : mKitPluginManager.kitsById(kitId)) {
			kit->init(mEventsForKitPlugin, configurer.systemEvents(), configurer.graphicalModelApi()
					, configurer.logicalModelApi(), configurer.mainWindowInterpretersInterface(), *mInterpreter);
<commit_msg>Fixed hidden variables appearing in watch list window after switching kits<commit_after>#include "robotsPluginFacade.h"

#include "src/coreBlocks/coreBlocksFactory.h"
#include "managers/paletteUpdateManager.h"
#include "managers/kitAutoSwitcher.h"
#include "managers/kitExtensionsUpdateManager.h"

#include <interpreterBase/robotModel/portInfo.h>

using namespace interpreterCore;

RobotsPluginFacade::RobotsPluginFacade()
	: mInterpreter(nullptr)
	, mKitPluginManager("plugins/tools/kitPlugins")
	, mActionsManager(mKitPluginManager, mRobotModelManager)
	, mDockDevicesConfigurer(nullptr)
	, mGraphicsWatcherManager(nullptr)
{
	connect(&mRobotModelManager, &RobotModelManager::robotModelChanged
			, &mActionsManager, &ActionsManager::onRobotModelChanged);
}

RobotsPluginFacade::~RobotsPluginFacade()
{
	delete mInterpreter;
}

void RobotsPluginFacade::init(qReal::PluginConfigurator const &configurer)
{
	mRobotSettingsPage = new ui::RobotsSettingsPage(mKitPluginManager, mRobotModelManager);

	mDevicesConfigurationManager.reset(new DevicesConfigurationManager(
			configurer.graphicalModelApi()
			, configurer.logicalModelApi()
			, configurer.mainWindowInterpretersInterface()
			, configurer.systemEvents()
			));

	mTitlesVisibilityManager.reset(
			new TitlesVisibilityManager(mActionsManager.titlesVisibilityAction(), configurer.sceneCustomizer())
			);

	if (!selectKit(configurer)) {
		/// @todo Correctly handle unselected kit.
		return;
	}

	mParser.reset(new textLanguage::RobotsBlockParser(mRobotModelManager
			, [this]() { return mInterpreter ? mInterpreter->timeElapsed() : 0; }));

	interpreterBase::blocksBase::BlocksFactoryInterface * const coreFactory = new coreBlocks::CoreBlocksFactory();
	coreFactory->configure(configurer.graphicalModelApi()
			, configurer.logicalModelApi()
			, mRobotModelManager
			, *configurer.mainWindowInterpretersInterface().errorReporter()
			, *mParser
			);

	mBlocksFactoryManager.addFactory(coreFactory);

	interpreter::Interpreter *interpreter = new interpreter::Interpreter(
			configurer.graphicalModelApi()
			, configurer.logicalModelApi()
			, configurer.mainWindowInterpretersInterface()
			, configurer.projectManager()
			, mBlocksFactoryManager
			, mRobotModelManager
			, *mParser
			, mActionsManager.connectToRobotAction()
			);

	mInterpreter = interpreter;

	connect(&configurer.systemEvents(), &SystemEventsInterface::closedMainWindow
			, mInterpreter, &interpreter::InterpreterInterface::stopRobot);
	connect(&mRobotModelManager, &RobotModelManager::robotModelChanged
			, mInterpreter, &interpreter::InterpreterInterface::stopRobot);

	initKitPlugins(configurer);

	initSensorWidgets();

	auto paletteUpdateManager = new PaletteUpdateManager(configurer.mainWindowInterpretersInterface()
			, mBlocksFactoryManager, this);
	connect(&mRobotModelManager, &RobotModelManager::robotModelChanged
			, paletteUpdateManager, &PaletteUpdateManager::updatePalette);
	mDevicesConfigurationManager->connectDevicesConfigurationProvider(interpreter);

	auto kitExtensionsUpdateManager = new KitExtensionsUpdateManager(mKitPluginManager
			, configurer.textManager(), this);
	connect(&mRobotModelManager, &RobotModelManager::robotModelChanged
			, kitExtensionsUpdateManager, &KitExtensionsUpdateManager::updateExtensions);

	// It will subscribe to all signals itself and free memory too.
	new KitAutoSwitcher(configurer.projectManager(), configurer.logicalModelApi()
			, mBlocksFactoryManager, mKitPluginManager, mRobotModelManager, this);

	connectInterpreterToActions();

	connectEventsForKitPlugin();

	connect(&mActionsManager.robotSettingsAction(), &QAction::triggered
			, [=] () { configurer.mainWindowInterpretersInterface().openSettingsDialog(tr("Robots")); });
	connect(&configurer.systemEvents(), &SystemEventsInterface::activeTabChanged
			, &mActionsManager, &ActionsManager::onActiveTabChanged);

	sync();
}

PreferencesPage *RobotsPluginFacade::robotsSettingsPage() const
{
	return mRobotSettingsPage;
}

interpreterCore::Customizer &RobotsPluginFacade::customizer()
{
	return mCustomizer;
}

ActionsManager &RobotsPluginFacade::actionsManager()
{
	return mActionsManager;
}

QStringList RobotsPluginFacade::defaultSettingsFiles() const
{
	QStringList result = { ":/interpreterCoreDefaultSettings.ini" };
	for (QString const &kitId : mKitPluginManager.kitIds()) {
		for (interpreterBase::KitPluginInterface * const kit : mKitPluginManager.kitsById(kitId)) {
			QString const defaultSettings = kit->defaultSettingsFile();
			if (!defaultSettings.isEmpty()) {
				result << defaultSettings;
			}
		}
	}

	return result;
}

void RobotsPluginFacade::connectInterpreterToActions()
{
	QObject::connect(
			&mActionsManager.runAction()
			, &QAction::triggered
			, mInterpreter
			, &interpreter::InterpreterInterface::interpret
			);

	QObject::connect(
			&mActionsManager.stopRobotAction()
			, &QAction::triggered
			, mInterpreter
			, &interpreter::InterpreterInterface::stopRobot
			);

	QObject::connect(
			&mActionsManager.connectToRobotAction()
			, &QAction::triggered
			, mInterpreter
			, &interpreter::InterpreterInterface::connectToRobot
			);
}

bool RobotsPluginFacade::selectKit(PluginConfigurator const &configurer)
{
	/// @todo reinit it each time when robot model changes
	/// @todo: do we need this method?
	QString const selectedKit = SettingsManager::value("SelectedRobotKit").toString();
	if (selectedKit.isEmpty() && !mKitPluginManager.kitIds().isEmpty()) {
		SettingsManager::setValue("SelectedRobotKit", mKitPluginManager.kitIds()[0]);
	} else if (mKitPluginManager.kitIds().isEmpty()) {
		configurer.mainWindowInterpretersInterface().setEnabledForAllElementsInPalette(false);

		/// @todo Correctly handle unselected kit.
		return false;
	}

	return true;
}

void RobotsPluginFacade::initSensorWidgets()
{
	mDockDevicesConfigurer = new interpreterBase::DevicesConfigurationWidget(nullptr, true);
	mDockDevicesConfigurer->loadRobotModels(mKitPluginManager.allRobotModels());
	connect(&mRobotModelManager, &RobotModelManager::robotModelChanged
			, mDockDevicesConfigurer, &interpreterBase::DevicesConfigurationWidget::selectRobotModel);
	for (interpreterBase::robotModel::RobotModelInterface * const model : mKitPluginManager.allRobotModels()) {
		for (interpreterBase::KitPluginInterface * const kit : mKitPluginManager.kitsById(model->kitId())) {
			mDockDevicesConfigurer->prependCustomWidget(*model, kit->quickPreferencesFor(*model));
		}
	}

	mWatchListWindow = new utils::WatchListWindow(*mParser);

	auto hideVariables = [=]() { mWatchListWindow->hideVariables(mParser->specialVariables()); };
	hideVariables();
	connect(&mRobotModelManager, &RobotModelManager::robotModelChanged, hideVariables);

	mGraphicsWatcherManager = new GraphicsWatcherManager(*mParser, this);

	mCustomizer.placeDevicesConfig(mDockDevicesConfigurer);
	mCustomizer.placeWatchPlugins(mWatchListWindow, mGraphicsWatcherManager->widget());

	mDevicesConfigurationManager->connectDevicesConfigurationProvider(mRobotSettingsPage);
	mDevicesConfigurationManager->connectDevicesConfigurationProvider(mDockDevicesConfigurer);
	mDevicesConfigurationManager->connectDevicesConfigurationProvider(mGraphicsWatcherManager);
}

void RobotsPluginFacade::initKitPlugins(qReal::PluginConfigurator const &configurer)
{
	/// @todo: Check that this code works when different kit is selected
	for (QString const &kitId : mKitPluginManager.kitIds()) {
		for (interpreterBase::KitPluginInterface * const kit : mKitPluginManager.kitsById(kitId)) {
			kit->init(mEventsForKitPlugin, configurer.systemEvents(), configurer.graphicalModelApi()
					, configurer.logicalModelApi(), configurer.mainWindowInterpretersInterface(), *mInterpreter);

{'fraction_non_alphanumeric': 0.10749506903353057, 'fraction_numerical': 0.00026298487836949375, 'mean_word_length': 7.9005266237565825, 'pattern_counts': {'":': 2, '<': 9, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6273440', 'n_tokens_mistral': 4711, 'n_tokens_neox': 4479, 'n_words': 638}