<commit_before>/*-----------------------------------------------------------------------------
 This source file is part of Hopsan NG

 Copyright (c) 2011
    <NAME>, <NAME>, <NAME>, <NAME>,
    <NAME>, <NAME>, <NAME>, <NAME>

 This file is provided "as is", with no guarantee or warranty for the
 functionality or reliability of the contents. All contents in this file is
 the original work of the copyright holders at the Division of Fluid and
 Mechatronic Systems (Flumes) at Linköping University. Modifying, using or
 redistributing any part of this file is prohibited without explicit
 permission from the copyright holders.
-----------------------------------------------------------------------------*/

//!
//! @file   AnimationWidget.cpp
//! @author <NAME> <<EMAIL>>
//! @author <NAME> <<EMAIL>>
//! @date   2012-04-25
//!
//! @brief Contains a widget for showing animations
//!
//$Id$

//Qt includes
#include <QVector>
#include <QLineEdit>
#include <QGridLayout>
#include <QDialogButtonBox>
#include <QMessageBox>

//Hopsan includes
#include "global.h"
#include "AnimatedConnector.h"
#include "Configuration.h"
#include "GraphicsView.h"
#include "GUIConnector.h"
#include "GUIObjects/AnimatedComponent.h"
#include "GUIObjects/GUIContainerObject.h"
#include "GUIObjects/GUISystem.h"
#include "GUIObjects/GUIWidgets.h"
#include "GUIPort.h"
#include "ModelHandler.h"
#include "ModelWidget.h"
#include "Widgets/AnimationWidget.h"
#include "Widgets/LibraryWidget.h"
#include "MainWindow.h"
#include "LibraryHandler.h"

//! @brief Constructor for the animation widget class
//! @param [in] parent Pointer to parent widget
AnimationWidget::AnimationWidget(QWidget *parent) :
    QWidget(parent)
{
    //Define public member pointer variables
    mpContainer = gpModelHandler->getCurrentViewContainerObject();

    mpAnimationData = mpContainer->getAppearanceData()->getAnimationDataPtr();

    //Set palette
    this->setPalette(gpConfig->getPalette());

    //Create graphics scene
    mpGraphicsScene = new QGraphicsScene();
    mpGraphicsScene->setSceneRect(0,0,5000,5000);

    //Create graphics view
    GraphicsView *pOrgView = mpContainer->mpModelWidget->getGraphicsView();
    mpGraphicsView = new AnimatedGraphicsView(mpGraphicsScene,0);
    mpGraphicsView->setGeometry(0,0,500,500);
    mpGraphicsView->setInteractive(true);
    mpGraphicsView->setEnabled(true);
    mpGraphicsView->setAcceptDrops(false);
    mpGraphicsView->setViewportUpdateMode(QGraphicsView::MinimalViewportUpdate);
    mpGraphicsView->setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
    mpGraphicsView->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
    mpGraphicsView->setCacheMode(QGraphicsView::CacheBackground);
    mpGraphicsView->setOptimizationFlags(QGraphicsView::DontSavePainterState | QGraphicsView::DontAdjustForAntialiasing);
    //mpGraphicsView->centerOn(mpGraphicsView->sceneRect().topLeft());
    mpGraphicsView->setZoomFactor(pOrgView->getZoomFactor());
    mpGraphicsView->setRenderHint(QPainter::Antialiasing, gpConfig->getAntiAliasing());
    double X,Y,Z;
    pOrgView->getViewPort(X,Y,Z);
    mpGraphicsView->centerOn(X,Y+3/Z);

    connect(gpMainWindow->mpResetZoomAction,    SIGNAL(triggered()),    mpGraphicsView,    SLOT(resetZoom()),   Qt::UniqueConnection);
    connect(gpMainWindow->mpZoomInAction,       SIGNAL(triggered()),    mpGraphicsView,    SLOT(zoomIn()),      Qt::UniqueConnection);
    connect(gpMainWindow->mpZoomOutAction,      SIGNAL(triggered()),    mpGraphicsView,    SLOT(zoomOut()),     Qt::UniqueConnection);
    connect(gpMainWindow->mpCenterViewAction,   SIGNAL(triggered()),    mpGraphicsView,    SLOT(centerView()),  Qt::UniqueConnection);

    //Create control panel widgets
    mpTimeDisplay = new QLineEdit(this);
    mpTimeDisplay->setBaseSize(20,10);

    mpSettingsButton = new QToolButton(this);
    mpSettingsButton->setIcon(QIcon(QString(QString(ICONPATH) + "Hopsan-Configure.png")));

    mpStopButton = new QToolButton(this);
    mpStopButton->setIcon(QIcon(QString(QString(ICONPATH) + "Hopsan-Stop.png")));

    mpRewindButton = new QToolButton(this);
    mpRewindButton->setIcon(QIcon(QString(QString(ICONPATH) + "Hopsan-Rewind.png")));

    mpPauseButton = new QToolButton(this);
    mpPauseButton->setIcon(QIcon(QString(QString(ICONPATH) + "Hopsan-Pause.png")));

    mpPlayButton = new QToolButton(this);
    mpPlayButton->setIcon(QIcon(QString(QString(ICONPATH) + "Hopsan-Play.png")));

    mpPlayRealTimeButton = new QToolButton(this);
    mpPlayRealTimeButton->setIcon(QIcon(QString(QString(ICONPATH) + "Hopsan-PlayRealTime.png")));

    mpCloseButton = new QToolButton(this);
    mpCloseButton->setIcon(QIcon(QString(ICONPATH)+"Hopsan-Discard.png"));

    mpTimeLabel = new QLabel(" Time:", this);
    mpSpeedLabel = new QLabel(" Speed:", this);

    mpTimeSlider = new QSlider(Qt::Horizontal);

    mpSpeedSpinBox = new QDoubleSpinBox(this);
    mpSpeedSpinBox->setMinimum(-10.0);
    mpSpeedSpinBox->setMaximum(10.0);
    mpSpeedSpinBox->setDecimals(10);
    mpSpeedSpinBox->setSingleStep(0.01);

    //Create the layout and add widgets
    mpLayout= new QGridLayout(this);
    mpLayout->addWidget(mpSettingsButton,       0,  0);
    mpLayout->addWidget(mpStopButton,           0,  1);
    mpLayout->addWidget(mpPauseButton,          0,  2);
    mpLayout->addWidget(mpPlayButton,           0,  3);
    mpLayout->addWidget(mpPlayRealTimeButton,   0,  4);
    mpLayout->addWidget(mpRewindButton,         0,  5);
    mpLayout->addWidget(mpSpeedLabel,           0,  6);
    //mpLayout->addWidget(mpSpeedSlider,          0,  7);
    mpLayout->addWidget(mpSpeedSpinBox,         0,  7);
    mpLayout->addWidget(mpTimeLabel,            0,  8);
    mpLayout->addWidget(mpTimeSlider,           0,  9);
    mpLayout->addWidget(mpTimeDisplay,          0,  10);
    mpLayout->addWidget(mpCloseButton,          0,  11);
    mpLayout->addWidget(mpGraphicsView,         1,  0,  1,  12);
    mpLayout->setColumnStretch(9,1);
    mpLayout->setRowStretch(1,1);
    this->setLayout(mpLayout);

    //Create the timer object
    mpTimer = new QTimer(0);
    mpTime = new QTime();

    //Set default values for animation variables
    mRealTime=true;
    mCurrentAnimationTime = 0;
    mLastAnimationTime = 0;
    mSimulationSpeed = 1;
    mTimeStep = gpModelHandler->getCurrentTopLevelSystem()->getTimeStep(); //! @todo This is not used, but it should be
    mFps=60;   //Frames per second

    mIntensityMaxMap.insert("NodeHydraulic", mpAnimationData->hydraulicMaxPressure);
    mIntensityMinMap.insert("NodeHydraulic", mpAnimationData->hydraulicMinPressure);
    mFlowSpeedMap.insert("NodeHydraulic",mpAnimationData->flowSpeed);

    mHydraulicIntensityMax = mpAnimationData->hydraulicMaxPressure;
    mHydraulicIntensityMin = mpAnimationData->hydraulicMinPressure;
    mHydraulicSpeed = mpAnimationData->flowSpeed;

    //Collect plot data from container (for non-realtime animations)
    //mpContainer->collectPlotData();
    mpPlotData = mpContainer->getLogDataHandler();
    mpPlayButton->setDisabled(mpPlotData->isEmpty());
    mpRewindButton->setDisabled(mpPlotData->isEmpty());

    if(!mpPlotData->isEmpty() && !mpPlotData->getTimeVectorVariable(-1).isNull())
    {
        //Obtain time values from plot data
        mTimeValues = mpContainer->getLogDataHandler()->getTimeVectorVariable(-1)->getDataVectorCopy();

        //Calculate total simulation time and number of samples
        mTotalTime = mTimeValues.last();
        mnSamples = mTimeValues.size();

        //Set min, max and step values for time slider
        mpTimeSlider->setMinimum(0);
        mpTimeSlider->setMaximum(mTimeValues.size());
        mpTimeSlider->setSingleStep(mTimeValues.size()/mFps);
    }
    else
    {
        mpTimeSlider->setMinimum(0);
        mpTimeSlider->setMaximum(0);
    }

    //Set initial values for speed slider
    mpSpeedSpinBox->setValue(1.0);


    QStringList hiddenComponents;
    hiddenComponents << "SignalInputInterface" << "SignalOutputInterface";

    //Generate list of model objects from container object
    QStringList modelObjectNames = mpContainer->getModelObjectNames();
    for(int i=0; i<modelObjectNames.size(); ++i)
    {
        if(!hiddenComponents.contains(mpContainer->getModelObject(modelObjectNames.at(i))->getTypeName()))
        {
            mModelObjectsList.append(mpContainer->getModelObject(modelObjectNames.at(i)));
        }
    }

    //Generate list of connectors from container object
    for(int d=0;d<mModelObjectsList.size();d++)
    {
        for(int e=0;e<mModelObjectsList.at(d)->getConnectorPtrs().size();e++)
        {
            Connector* tempConnector = mModelObjectsList.at(d)->getConnectorPtrs().at(e);
            if(!mConnectorList.contains(tempConnector) &&
               !hiddenComponents.contains(tempConnector->getStartPort()->getParentModelObject()->getTypeName()) &&
               !hiddenComponents.contains(tempConnector->getEndPort()->getParentModelObject()->getTypeName()))
            {
                mConnectorList.append(tempConnector);
            }
        }
    }

    //Create animated components from components list
    for(int g=0;g<mModelObjectsList.size();g++)<commit_msg>Prevent crash if a connector is being created while entering animation mode Related to #1419<commit_after>/*-----------------------------------------------------------------------------
 This source file is part of Hopsan NG

 Copyright (c) 2011
    <NAME>, <NAME>, A<NAME>, <NAME>,
    <NAME>, <NAME>, <NAME>, <NAME>

 This file is provided "as is", with no guarantee or warranty for the
 functionality or reliability of the contents. All contents in this file is
 the original work of the copyright holders at the Division of Fluid and
 Mechatronic Systems (Flumes) at Linköping University. Modifying, using or
 redistributing any part of this file is prohibited without explicit
 permission from the copyright holders.
-----------------------------------------------------------------------------*/

//!
//! @file   AnimationWidget.cpp
//! @author <NAME> <<EMAIL>>
//! @author <NAME> <<EMAIL>>
//! @date   2012-04-25
//!
//! @brief Contains a widget for showing animations
//!
//$Id$

//Qt includes
#include <QVector>
#include <QLineEdit>
#include <QGridLayout>
#include <QDialogButtonBox>
#include <QMessageBox>

//Hopsan includes
#include "global.h"
#include "AnimatedConnector.h"
#include "Configuration.h"
#include "GraphicsView.h"
#include "GUIConnector.h"
#include "GUIObjects/AnimatedComponent.h"
#include "GUIObjects/GUIContainerObject.h"
#include "GUIObjects/GUISystem.h"
#include "GUIObjects/GUIWidgets.h"
#include "GUIPort.h"
#include "ModelHandler.h"
#include "ModelWidget.h"
#include "Widgets/AnimationWidget.h"
#include "Widgets/LibraryWidget.h"
#include "MainWindow.h"
#include "LibraryHandler.h"

//! @brief Constructor for the animation widget class
//! @param [in] parent Pointer to parent widget
AnimationWidget::AnimationWidget(QWidget *parent) :
    QWidget(parent)
{
    //Define public member pointer variables
    mpContainer = gpModelHandler->getCurrentViewContainerObject();

    mpAnimationData = mpContainer->getAppearanceData()->getAnimationDataPtr();

    //Set palette
    this->setPalette(gpConfig->getPalette());

    //Create graphics scene
    mpGraphicsScene = new QGraphicsScene();
    mpGraphicsScene->setSceneRect(0,0,5000,5000);

    //Create graphics view
    GraphicsView *pOrgView = mpContainer->mpModelWidget->getGraphicsView();
    mpGraphicsView = new AnimatedGraphicsView(mpGraphicsScene,0);
    mpGraphicsView->setGeometry(0,0,500,500);
    mpGraphicsView->setInteractive(true);
    mpGraphicsView->setEnabled(true);
    mpGraphicsView->setAcceptDrops(false);
    mpGraphicsView->setViewportUpdateMode(QGraphicsView::MinimalViewportUpdate);
    mpGraphicsView->setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
    mpGraphicsView->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
    mpGraphicsView->setCacheMode(QGraphicsView::CacheBackground);
    mpGraphicsView->setOptimizationFlags(QGraphicsView::DontSavePainterState | QGraphicsView::DontAdjustForAntialiasing);
    //mpGraphicsView->centerOn(mpGraphicsView->sceneRect().topLeft());
    mpGraphicsView->setZoomFactor(pOrgView->getZoomFactor());
    mpGraphicsView->setRenderHint(QPainter::Antialiasing, gpConfig->getAntiAliasing());
    double X,Y,Z;
    pOrgView->getViewPort(X,Y,Z);
    mpGraphicsView->centerOn(X,Y+3/Z);

    connect(gpMainWindow->mpResetZoomAction,    SIGNAL(triggered()),    mpGraphicsView,    SLOT(resetZoom()),   Qt::UniqueConnection);
    connect(gpMainWindow->mpZoomInAction,       SIGNAL(triggered()),    mpGraphicsView,    SLOT(zoomIn()),      Qt::UniqueConnection);
    connect(gpMainWindow->mpZoomOutAction,      SIGNAL(triggered()),    mpGraphicsView,    SLOT(zoomOut()),     Qt::UniqueConnection);
    connect(gpMainWindow->mpCenterViewAction,   SIGNAL(triggered()),    mpGraphicsView,    SLOT(centerView()),  Qt::UniqueConnection);

    //Create control panel widgets
    mpTimeDisplay = new QLineEdit(this);
    mpTimeDisplay->setBaseSize(20,10);

    mpSettingsButton = new QToolButton(this);
    mpSettingsButton->setIcon(QIcon(QString(QString(ICONPATH) + "Hopsan-Configure.png")));

    mpStopButton = new QToolButton(this);
    mpStopButton->setIcon(QIcon(QString(QString(ICONPATH) + "Hopsan-Stop.png")));

    mpRewindButton = new QToolButton(this);
    mpRewindButton->setIcon(QIcon(QString(QString(ICONPATH) + "Hopsan-Rewind.png")));

    mpPauseButton = new QToolButton(this);
    mpPauseButton->setIcon(QIcon(QString(QString(ICONPATH) + "Hopsan-Pause.png")));

    mpPlayButton = new QToolButton(this);
    mpPlayButton->setIcon(QIcon(QString(QString(ICONPATH) + "Hopsan-Play.png")));

    mpPlayRealTimeButton = new QToolButton(this);
    mpPlayRealTimeButton->setIcon(QIcon(QString(QString(ICONPATH) + "Hopsan-PlayRealTime.png")));

    mpCloseButton = new QToolButton(this);
    mpCloseButton->setIcon(QIcon(QString(ICONPATH)+"Hopsan-Discard.png"));

    mpTimeLabel = new QLabel(" Time:", this);
    mpSpeedLabel = new QLabel(" Speed:", this);

    mpTimeSlider = new QSlider(Qt::Horizontal);

    mpSpeedSpinBox = new QDoubleSpinBox(this);
    mpSpeedSpinBox->setMinimum(-10.0);
    mpSpeedSpinBox->setMaximum(10.0);
    mpSpeedSpinBox->setDecimals(10);
    mpSpeedSpinBox->setSingleStep(0.01);

    //Create the layout and add widgets
    mpLayout= new QGridLayout(this);
    mpLayout->addWidget(mpSettingsButton,       0,  0);
    mpLayout->addWidget(mpStopButton,           0,  1);
    mpLayout->addWidget(mpPauseButton,          0,  2);
    mpLayout->addWidget(mpPlayButton,           0,  3);
    mpLayout->addWidget(mpPlayRealTimeButton,   0,  4);
    mpLayout->addWidget(mpRewindButton,         0,  5);
    mpLayout->addWidget(mpSpeedLabel,           0,  6);
    //mpLayout->addWidget(mpSpeedSlider,          0,  7);
    mpLayout->addWidget(mpSpeedSpinBox,         0,  7);
    mpLayout->addWidget(mpTimeLabel,            0,  8);
    mpLayout->addWidget(mpTimeSlider,           0,  9);
    mpLayout->addWidget(mpTimeDisplay,          0,  10);
    mpLayout->addWidget(mpCloseButton,          0,  11);
    mpLayout->addWidget(mpGraphicsView,         1,  0,  1,  12);
    mpLayout->setColumnStretch(9,1);
    mpLayout->setRowStretch(1,1);
    this->setLayout(mpLayout);

    //Create the timer object
    mpTimer = new QTimer(0);
    mpTime = new QTime();

    //Set default values for animation variables
    mRealTime=true;
    mCurrentAnimationTime = 0;
    mLastAnimationTime = 0;
    mSimulationSpeed = 1;
    mTimeStep = gpModelHandler->getCurrentTopLevelSystem()->getTimeStep(); //! @todo This is not used, but it should be
    mFps=60;   //Frames per second

    mIntensityMaxMap.insert("NodeHydraulic", mpAnimationData->hydraulicMaxPressure);
    mIntensityMinMap.insert("NodeHydraulic", mpAnimationData->hydraulicMinPressure);
    mFlowSpeedMap.insert("NodeHydraulic",mpAnimationData->flowSpeed);

    mHydraulicIntensityMax = mpAnimationData->hydraulicMaxPressure;
    mHydraulicIntensityMin = mpAnimationData->hydraulicMinPressure;
    mHydraulicSpeed = mpAnimationData->flowSpeed;

    //Collect plot data from container (for non-realtime animations)
    //mpContainer->collectPlotData();
    mpPlotData = mpContainer->getLogDataHandler();
    mpPlayButton->setDisabled(mpPlotData->isEmpty());
    mpRewindButton->setDisabled(mpPlotData->isEmpty());

    if(!mpPlotData->isEmpty() && !mpPlotData->getTimeVectorVariable(-1).isNull())
    {
        //Obtain time values from plot data
        mTimeValues = mpContainer->getLogDataHandler()->getTimeVectorVariable(-1)->getDataVectorCopy();

        //Calculate total simulation time and number of samples
        mTotalTime = mTimeValues.last();
        mnSamples = mTimeValues.size();

        //Set min, max and step values for time slider
        mpTimeSlider->setMinimum(0);
        mpTimeSlider->setMaximum(mTimeValues.size());
        mpTimeSlider->setSingleStep(mTimeValues.size()/mFps);
    }
    else
    {
        mpTimeSlider->setMinimum(0);
        mpTimeSlider->setMaximum(0);
    }

    //Set initial values for speed slider
    mpSpeedSpinBox->setValue(1.0);


    QStringList hiddenComponents;
    hiddenComponents << "SignalInputInterface" << "SignalOutputInterface";

    //Generate list of model objects from container object
    QStringList modelObjectNames = mpContainer->getModelObjectNames();
    for(int i=0; i<modelObjectNames.size(); ++i)
    {
        if(!hiddenComponents.contains(mpContainer->getModelObject(modelObjectNames.at(i))->getTypeName()))
        {
            mModelObjectsList.append(mpContainer->getModelObject(modelObjectNames.at(i)));
        }
    }

    //Generate list of connectors from container object
    for(int d=0;d<mModelObjectsList.size();d++)
    {
        QList<Connector*> moConnectors = mModelObjectsList.at(d)->getConnectorPtrs();
        for(int e=0;e<moConnectors.size();e++)
        {
            Connector* tempConnector = moConnectors.at(e);
            if(tempConnector->isConnected() &&
               !mConnectorList.contains(tempConnector) &&
               !hiddenComponents.contains(tempConnector->getStartPort()->getParentModelObject()->getTypeName()) &&
               !hiddenComponents.contains(tempConnector->getEndPort()->getParentModelObject()->getTypeName()))
            {
                mConnectorList.append(tempConnector);
            }
        }
    }

    //Create animated components from components list
    for(int g=0;g<mModelObjectsList.size();g++)
{'fraction_non_alphanumeric': 0.14066111260413866, 'fraction_numerical': 0.011072292394517604, 'mean_word_length': 3.781804163454125, 'pattern_counts': {'":': 0, '<': 58, '<?xml version=': 0, '>': 232, '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': '4212123', 'n_tokens_mistral': 5762, 'n_tokens_neox': 5535, 'n_words': 1021}