/******************************************************************************* * * * Société de Transports de Montréal. * * 2012 * * * * Projet Zones Tests * * * * * * * *******************************************************************************/ /* Description: Page de visualisation des passages de train. C'est cette classe qui gère la création et l'affichage des éléments graphiques ainsi que les événements de l'utilisateur. */ /* ************************************************************************** */ /* Revision: ### 20131024 JFM Verision d'origine. ### YYYMMDD Description du besoin ou du bug Description du changement. */ /* ************************************************************************** */ #include "LogViewPage.h" #include #include "Zonetest.h" #include CLogViewPage::CLogViewPage(QGraphicsWidget *Parent) { setParentItem(Parent); setAcceptsHoverEvents(true); mProgramHandle = 0; mZoomValue = 100; mStartTime = mStopTime = 0; mCurTimeSpan = 0; mMinTime = mMaxTime = 0; mCurPixelTickValue = 1; mMouseDragging = false; mViewType = UNKNOWN_LOG_TYPE; mPGTreshold = 0; mCtrlKeyDown = false; mShiftKeyDown = false; setFlag(QGraphicsItem::ItemIsFocusable); mStaticCursor1Pos = mStaticCursor2Pos = 0; mCursorPos = 0; mBackgroundRect = new QGraphicsRectItem(boundingRect(), this); QPen rectpen; QBrush BackgroundBrush(QColor(245, 245, 255)); mBackgroundRect->setBrush(BackgroundBrush); mCancelButton = new CTextButtonWidget("Fermer"); mCancelButton->setParentItem(this); mCancelButton->setPos(850,700); connect(mCancelButton,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*))); //Setup ZT1 plots qreal PlotsHeight = ((GRAPH_ZONE_HEIGHT - 60) / (ZT1_DISCREET_PLOTTABLE_NB_PARAM + ZT1_ANALOG_PLOTTABLE_NB_PARAM + 1));//SDF analog plot is 3 units high, so add 2 units for this plot (hence the +2) PlotsHeight -= (20 + (10/(ZT1_DISCREET_PLOTTABLE_NB_PARAM + ZT1_ANALOG_PLOTTABLE_NB_PARAM))) ; //space between plots int CurPlot = 0; for(int param = 0; param < ZT1_DISCREET_PLOTTABLE_NB_PARAM; param++) { mZT1DiscreetPlots[param].mParamID = param; mZT1DiscreetPlots[param].mDataSet = new QList; CGraphItem * NewGraph = new CGraphItem(this); //NewGraph->setPos(GRAPH_ZONE_X_OFFSET,param * (40 + 20)+10); NewGraph->setPos(GRAPH_ZONE_X_OFFSET,CurPlot++ * (PlotsHeight + 20) + 10); NewGraph->resize(GRAPH_ZONE_WIDTH,PlotsHeight); mZT1DiscreetPlots[param].mPlotGaph = NewGraph; mZT1DiscreetPlots[param].mPlotGaph->SetData(mZT1DiscreetPlots[param].mDataSet); } mZT1DiscreetPlots[ZT1_DISCREET_PLOTTABLE_S1_PARAM].mPlotGaph->SetLabel("S1",GRAPH_ZONE_X_OFFSET); mZT1DiscreetPlots[ZT1_DISCREET_PLOTTABLE_S2_PARAM].mPlotGaph->SetLabel("S2",GRAPH_ZONE_X_OFFSET); mZT1DiscreetPlots[ZT1_DISCREET_PLOTTABLE_PPINT_PARAM].mPlotGaph->SetLabel("PP Int",GRAPH_ZONE_X_OFFSET); mZT1DiscreetPlots[ZT1_DISCREET_PLOTTABLE_PPEXT_PARAM].mPlotGaph->SetLabel("PP Ext",GRAPH_ZONE_X_OFFSET); //mZT1DiscreetPlots[ZT1_DISCREET_PLOTTABLE_PG_PARAM].mPlotGaph->SetLabel("PG",GRAPH_ZONE_X_OFFSET); mZT1DiscreetPlots[ZT1_DISCREET_PLOTTABLE_FN_PARAM].mPlotGaph->SetLabel("FN",GRAPH_ZONE_X_OFFSET); mZT1DiscreetPlots[ZT1_DISCREET_PLOTTABLE_CI_PARAM].mPlotGaph->SetLabel("CI",GRAPH_ZONE_X_OFFSET); mZT1DiscreetPlots[ZT1_DISCREET_PLOTTABLE_ZT1_CDV_PARAM].mPlotGaph->SetLabel("CDV",GRAPH_ZONE_X_OFFSET); for(int param = 0; param < ZT1_ANALOG_PLOTTABLE_NB_PARAM; param++) { mZT1AnalogPlots[param].mParamID = param; mZT1AnalogPlots[param].mDataSet = new QList; CAnalogGraphItem *NewGraph = new CAnalogGraphItem(this); // NewGraph->setPos(GRAPH_ZONE_X_OFFSET,(param+DISCREET_PLOTTABLE_NB_PARAM)*(40+20)+10); NewGraph->setPos(GRAPH_ZONE_X_OFFSET,CurPlot++ * (PlotsHeight + 20) + 10); NewGraph->resize(GRAPH_ZONE_WIDTH,PlotsHeight); mZT1AnalogPlots[param].mPlotGaph = NewGraph; mZT1AnalogPlots[param].mPlotGaph->SetData(mZT1AnalogPlots[param].mDataSet); } mZT1AnalogPlots[ZT1_ANALOG_PLOTTABLE_PGINT_PARAM].mPlotGaph->SetLabel("PG Int",GRAPH_ZONE_X_OFFSET); mZT1AnalogPlots[ZT1_ANALOG_PLOTTABLE_PGEXT_PARAM].mPlotGaph->SetLabel("PG Ext",GRAPH_ZONE_X_OFFSET); mZT1AnalogPlots[ZT1_ANALOG_PLOTTABLE_TRAIN_SPEED_PARAM].mPlotGaph->SetLabel("Vitesse",GRAPH_ZONE_X_OFFSET); mZT1AnalogPlots[ZT1_ANALOG_PLOTTABLE_PGCOMBINED_PARAM].mPlotGaph->SetLabel("Détection",GRAPH_ZONE_X_OFFSET); mZT1AnalogPlots[ZT1_ANALOG_PLOTTABLE_SDF_DATA_PARAM].mPlotGaph->SetLabel("SDF",GRAPH_ZONE_X_OFFSET); mZT1AnalogPlots[ZT1_ANALOG_PLOTTABLE_SDF_DATA_PARAM].mPlotGaph->resize(GRAPH_ZONE_WIDTH,PlotsHeight*3); //JFM: make SDF plot 3 times higher to help visualization. //Setup ZT2 Plots PlotsHeight = ((GRAPH_ZONE_HEIGHT - 60) / (ZT2_DISCREET_PLOTTABLE_NB_PARAM + ZT2_ANALOG_PLOTTABLE_NB_PARAM)); PlotsHeight -= (20 + (10/(ZT2_DISCREET_PLOTTABLE_NB_PARAM + ZT2_ANALOG_PLOTTABLE_NB_PARAM))) ; //space between plots CurPlot = 0; for(int param = 0; param < ZT2_DISCREET_PLOTTABLE_NB_PARAM; param++) { mZT2DiscreetPlots[param].mParamID = param; mZT2DiscreetPlots[param].mDataSet = new QList; CGraphItem * NewGraph = new CGraphItem(this); //NewGraph->setPos(GRAPH_ZONE_X_OFFSET,param * (40 + 20)+10); NewGraph->setPos(GRAPH_ZONE_X_OFFSET,CurPlot++ * (PlotsHeight + 20) + 10); NewGraph->resize(900,PlotsHeight); mZT2DiscreetPlots[param].mPlotGaph = NewGraph; mZT2DiscreetPlots[param].mPlotGaph->SetData(mZT2DiscreetPlots[param].mDataSet); } mZT2DiscreetPlots[ZT2_DISCREET_PLOTTABLE_S1_PARAM].mPlotGaph->SetLabel("S1",GRAPH_ZONE_X_OFFSET); mZT2DiscreetPlots[ZT2_DISCREET_PLOTTABLE_PPEXT_PARAM].mPlotGaph->SetLabel("PP Ext",GRAPH_ZONE_X_OFFSET); mZT2DiscreetPlots[ZT2_DISCREET_PLOTTABLE_PPINT_PARAM].mPlotGaph->SetLabel("PP Int",GRAPH_ZONE_X_OFFSET); mZT2DiscreetPlots[ZT2_DISCREET_PLOTTABLE_CI_PARAM].mPlotGaph->SetLabel("CI",GRAPH_ZONE_X_OFFSET); mZT2DiscreetPlots[ZT2_DISCREET_PLOTTABLE_APPROACH_CDV_PARAM].mPlotGaph->SetLabel("CDV App.",GRAPH_ZONE_X_OFFSET); mZT2DiscreetPlots[ZT2_DISCREET_PLOTTABLE_CDV_PARAM].mPlotGaph->SetLabel("CDV",GRAPH_ZONE_X_OFFSET); mVCursor = new CVerticalGraphCursorWidget(GRAPH_ZONE_HEIGHT,this); mVCursor->setPos(0,0); mVCursor->resize(3,GRAPH_ZONE_HEIGHT); mVCursor->setZValue(2); mHCursor = new CHorizontalGraphCursorWidget(GRAPH_ZONE_WIDTH,this); mHCursor->setPos(0,0); mHCursor->resize(GRAPH_ZONE_WIDTH,3); mHCursor->setZValue(2); // mCursorPosTxt = new QGraphicsTextItem(this); // mCursorPosTxt->setPos(650,690); mCursorsZoomButton = new CTextButtonWidget("Zoom curseurs"); mCursorsZoomButton->setParentItem(this); mCursorsZoomButton->setPos(10,700); connect(mCursorsZoomButton,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*))); mZoomInButton = new CTextButtonWidget(" +",0,25,25); mZoomInButton->setParentItem(this); mZoomInButton->setPos(95,730); connect(mZoomInButton,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*))); mZoomOutButton = new CTextButtonWidget(" -",0,25,25); mZoomOutButton->setParentItem(this); mZoomOutButton->setPos(10,730); connect(mZoomOutButton,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*))); mZoomResetButton = new CTextButtonWidget(" R",0,25,25); mZoomResetButton->setParentItem(this); mZoomResetButton->setPos(50,730); connect(mZoomResetButton,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*))); mStaticCursor1 = new CVerticalGraphCursorWidget(GRAPH_ZONE_HEIGHT,this); mStaticCursor1->setPos(0,0); mStaticCursor1->setZValue(1); mStaticCursor1->SetColor(QColor(Qt::red)); mStaticCursor1->hide(); mStaticCursor2 = new CVerticalGraphCursorWidget(GRAPH_ZONE_HEIGHT,this); mStaticCursor2->setPos(0,0); mStaticCursor2->setZValue(1); mStaticCursor2->SetColor(QColor(Qt::green)); mStaticCursor2->hide(); mStaticCursorDeltaTimeTxt = new QGraphicsTextItem(this); mStaticCursorDeltaTimeTxt->setPos(130,700); mStaticCursorDeltaTimeTxt->setPlainText("Delta curseurs: ?"); mCursor1TimeTxt = new QGraphicsTextItem(this); mCursor1TimeTxt->setPlainText("Position curseur 1 : ?"); mCursor1TimeTxt->setPos(130,720); mCursor2TimeTxt = new QGraphicsTextItem(this); mCursor2TimeTxt->setPlainText("Position curseur 2 : ?"); mCursor2TimeTxt->setPos(130,740); mPassageStats1Txt = new QGraphicsTextItem(this); mPassageStats1Txt->setPos(350,700); mPassageStats1Txt->setPlainText("Date & heure: \nStation : \nPosition : "); mPassageStats2Txt = new QGraphicsTextItem(this); mPassageStats2Txt->setPos(600,700); mPassageStats2Txt->setPlainText("Vitesse Max : Mph\nVitesse Min: Mph\nSeuil PG : "); mRuler = new CGraphRulerWidget(GRAPH_ZONE_WIDTH,this); mRuler->setZValue(1); mRuler->setPos(GRAPH_ZONE_X_OFFSET,670); mRuler->resize(GRAPH_ZONE_WIDTH,20); mRankRuler = new CRankRulerWidget(GRAPH_ZONE_WIDTH,this); mRankRuler->setZValue(1); mRankRuler->resize(GRAPH_ZONE_WIDTH,10); mRankRuler->setPos(GRAPH_ZONE_X_OFFSET,655); mRankRuler->SetLabel("Rang:",GRAPH_ZONE_X_OFFSET); mEventRuler = new CEventRulerWidget(GRAPH_ZONE_WIDTH,this); mEventRuler->setZValue(1); mEventRuler->resize(GRAPH_ZONE_WIDTH,10); mEventRuler->setPos(GRAPH_ZONE_X_OFFSET,640); mEventRuler->SetLabel("Décl:",GRAPH_ZONE_X_OFFSET); DestroyData(); mScrollRefreshTimer.start(); } CLogViewPage::~CLogViewPage() { DestroyData(); } void CLogViewPage::resizeEvent(QGraphicsSceneResizeEvent *event) { Q_UNUSED(event) mBackgroundRect->setRect(boundingRect()); } void CLogViewPage::ButtonClicked(CTextButtonWidget *BtnPtr) { if(BtnPtr == mCancelButton) { DestroyData(); mProgramHandle->LogViewCloseRequest(); } else if(BtnPtr == mCursorsZoomButton) { if(mStaticCursor1->IsCursorSet() && mStaticCursor2->IsCursorSet()) ShowSpan(mStaticCursor1->GetPixelPos(),mStaticCursor2->GetPixelPos()); } else if(BtnPtr == mZoomInButton) { ZoomIn(false); } else if(BtnPtr == mZoomOutButton) { ZoomOut(false); } else if(BtnPtr == mZoomResetButton) { ShowSpan(mMinTime,mMaxTime); } } void CLogViewPage::SetLogData(CLogElement *element) { DestroyData(); mLogElement = element; mViewType = mLogElement->mZTLogType; mStaticCursor1->ClearCursor(); mStaticCursor2->ClearCursor(); mStaticCursorDeltaTimeTxt->setPlainText("Delta : ?"); if(mViewType == ZT1_LOG_TYPE) { CZT1LogElement *ZT1LogElement = (CZT1LogElement*)element; int CurRank = 0; quint64 mRankStartTime = 0; bool Done; mPassageStation = ZT1LogElement->mStationName; mPassageDateTime = ZT1LogElement->mPassageDateTime.toString("yyyy/MM/dd hh:mm:ss"); qreal MaxTrainSpeed = 0, MinTrainSpeed = 10000; //Build all the datasets from the raw data. //JFM 2016-05-31 //Check for invalid data in the last slot... if(ZT1LogElement->mZTLogData.at(ZT1LogElement->mZTLogData.size()-1)->mTimestamp < ZT1LogElement->mZTLogData.at(ZT1LogElement->mZTLogData.size()-2)->mTimestamp) { delete ZT1LogElement->mZTLogData.at(ZT1LogElement->mZTLogData.size()-1); ZT1LogElement->mZTLogData.remove(ZT1LogElement->mZTLogData.size()-1); } //Discreet signals for(int i = 0; i < ZT1LogElement->mZTLogData.size(); i++) { for(int param = 0; param < ZT1_DISCREET_PLOTTABLE_NB_PARAM; param++) { CGraphDiscreteDataPair *DataSet = new CGraphDiscreteDataPair(0,ZT1LogElement->mZTLogData.at(i)->mTimestamp); if(ZT1LogElement->mZTLogData.at(i)->mZT1ThreadData != 0) { if(ZT1LogElement->mZTLogData.at(i)->mZT1ThreadData->mRank > (unsigned int)CurRank) { if(CurRank == 0) { mRankStartTime = ZT1LogElement->mZTLogData.at(i)->mTimestamp; CurRank = ZT1LogElement->mZTLogData.at(i)->mZT1ThreadData->mRank; } else { mRankRuler->AddRankItem(QString().sprintf("%d",CurRank),mRankStartTime,ZT1LogElement->mZTLogData.at(i)->mTimestamp); mRankStartTime = ZT1LogElement->mZTLogData.at(i)->mTimestamp; CurRank = ZT1LogElement->mZTLogData.at(i)->mZT1ThreadData->mRank; mRankStartTime = ZT1LogElement->mZTLogData.at(i)->mTimestamp; } } switch(param) { case ZT1_DISCREET_PLOTTABLE_S1_PARAM: { DataSet->mValue = ZT1LogElement->mZTLogData.at(i)->mZT1ThreadData->mS1; break; } case ZT1_DISCREET_PLOTTABLE_S2_PARAM: { DataSet->mValue = ZT1LogElement->mZTLogData.at(i)->mZT1ThreadData->mS2; break; } case ZT1_DISCREET_PLOTTABLE_PPINT_PARAM: { DataSet->mValue = ZT1LogElement->mZTLogData.at(i)->mZT1ThreadData->mPInt; break; } case ZT1_DISCREET_PLOTTABLE_PPEXT_PARAM: { DataSet->mValue = ZT1LogElement->mZTLogData.at(i)->mZT1ThreadData->mPExt; break; } // case ZT1_DISCREET_PLOTTABLE_PG_PARAM: // { // DataSet->mValue = ZT1LogElement->mZTLogData.at(i)->mZT1ThreadData->mPG; // break; // } case ZT1_DISCREET_PLOTTABLE_FN_PARAM: { DataSet->mValue = ZT1LogElement->mZTLogData.at(i)->mZT1ThreadData->mFN; break; } case ZT1_DISCREET_PLOTTABLE_CI_PARAM: { DataSet->mValue = ZT1LogElement->mZTLogData.at(i)->mZT1ThreadData->mFN; break; } case ZT1_DISCREET_PLOTTABLE_ZT1_CDV_PARAM: { break; } } } else if(i > 0) //if there is no data available, use the previous value... { DataSet->mValue = mZT1DiscreetPlots[param].mDataSet->at(i-1)->mValue; if(CurRank > 0 && Done == false) { Done = true; mRankRuler->AddRankItem(QString().sprintf("%d",CurRank),mRankStartTime,ZT1LogElement->mZTLogData.at(i-1)->mTimestamp); } } switch(param) { case ZT1_DISCREET_PLOTTABLE_CI_PARAM: { DataSet->mValue = ZT1LogElement->mZTLogData.at(i)->mCIZT1; break; } case ZT1_DISCREET_PLOTTABLE_ZT1_CDV_PARAM: { DataSet->mValue = ZT1LogElement->mZTLogData.at(i)->mCDVARM_ZT1; break; } } mZT1DiscreetPlots[param].mDataSet->append(DataSet); } for(int param = 0; param < ZT1_ANALOG_PLOTTABLE_NB_PARAM; param++) { CGraphAnalogDataPair *DataSet = new CGraphAnalogDataPair(0,ZT1LogElement->mZTLogData.at(i)->mTimestamp); if(ZT1LogElement->mZTLogData.at(i)->mZT1ThreadData != 0) { switch(param) { case ZT1_ANALOG_PLOTTABLE_PGEXT_PARAM: { DataSet->mValue = (qreal)ZT1LogElement->mZTLogData.at(i)->mZT1ThreadData->mPGExtValue; break; } case ZT1_ANALOG_PLOTTABLE_PGINT_PARAM: { DataSet->mValue = (qreal)ZT1LogElement->mZTLogData.at(i)->mZT1ThreadData->mPGIntValue; break; } case ZT1_ANALOG_PLOTTABLE_TRAIN_SPEED_PARAM: { DataSet->mValue = ZT1LogElement->mZTLogData.at(i)->mZT1ThreadData->mTrainSpeed; if(DataSet->mValue > MaxTrainSpeed) MaxTrainSpeed = DataSet->mValue; if(DataSet->mValue != 0 && DataSet->mValue < MinTrainSpeed) MinTrainSpeed = DataSet->mValue; break; } case ZT1_ANALOG_PLOTTABLE_PGCOMBINED_PARAM: { qint32 PI = ZT1LogElement->mZTLogData.at(i)->mZT1ThreadData->mPGIntValue,PE = ZT1LogElement->mZTLogData.at(i)->mZT1ThreadData->mPGExtValue; qint32 offsetint = ZT1LogElement->mFlags.mIntPGOffset; qint32 offsetext = ZT1LogElement->mFlags.mExtPGOffset; qint32 tempint = (PI - offsetint); qint32 tempext = (PE - offsetext); qint32 Quadra = tempint*tempext; DataSet->mValue = (qreal)Quadra; //qDebug("%f",DataSet->mValue); break; } case ZT1_ANALOG_PLOTTABLE_SDF_DATA_PARAM: { if(ZT1LogElement->mFlags.mAnalogTracePresent == true) { DataSet->mValue = (qreal)ZT1LogElement->mZTLogData.at(i)->mAnalogData/* * 10 / 4096*/; //JFM 20140821 } break; } } } else //No analog data... set to 0 { DataSet->mValue = 0; } mZT1AnalogPlots[param].mDataSet->append(DataSet); } } for(int param = 0; param < ZT1_ANALOG_PLOTTABLE_NB_PARAM; param++) { mZT1AnalogPlots[param].mPlotGaph->SetAbsoluteLimits(ZT1LogElement->mThreadDataStartTime,ZT1LogElement->mThreadDataEndTime); } mZT1AnalogPlots[ZT1_ANALOG_PLOTTABLE_PGCOMBINED_PARAM].mPlotGaph->AddHorizontalLine(ZT1LogElement->mFlags.mPGTresholdValue); mPGTreshold = ZT1LogElement->mFlags.mPGTresholdValue; // mRankRuler->AddRankItem(QString().sprintf("%d",CurRank),mRankStartTime,ZT1LogElement->mZTLogData.last()->mTimestamp); mMinTime = mStartTime = mZT1DiscreetPlots[0].mDataSet->first()->mTime; mMaxTime = mZT1DiscreetPlots[0].mDataSet->last()->mTime; if(ZT1LogElement->mZTDetections.size() == 0) { mEventRuler->ClearRuler(); } else { for(int event = 0; event < ZT1LogElement->mZTDetections.size(); event++) { mEventRuler->AddEventItem(CZTData::GetShortErrorString(ZT1LogElement->mZTDetections.at(event)->mDetectionID),ZT1LogElement->mZTDetections.at(event)->mTimeStamp); } } mPassageStats2Txt->setPlainText(QString().sprintf("Vitesse Max : %.3f Mph\nVitesse Min: %.3f Mph\nSeuil PG : %d",MaxTrainSpeed,MinTrainSpeed,mPGTreshold)); } else if(mViewType == ZT2_LOG_TYPE) { int CurRank = 0; quint64 mRankStartTime = 0; CZT2LogElement *ZT2LogElement = (CZT2LogElement*)element; mPassageDateTime = ZT2LogElement->mPassageDateTime.toString("yyyy/MM/dd hh:mm:ss");; mPassageStation = ZT2LogElement->mStationName; mPassageStats2Txt->setPlainText("Vitesse Max : N/A\nVitesse Min: N/A\nSeuil PG : N/A"); for(int i = 0; i < ZT2LogElement->mZTLogData.size(); i++) { for(int param = 0; param < ZT2_DISCREET_PLOTTABLE_NB_PARAM; param++) { CGraphDiscreteDataPair *DataSet = new CGraphDiscreteDataPair(0,ZT2LogElement->mZTLogData.at(i)->mTimestamp); if(ZT2LogElement->mZTLogData.at(i)->mZT2ThreadData != 0) { if(ZT2LogElement->mZTLogData.at(i)->mZT2ThreadData->mRank > (unsigned int)CurRank) { if(CurRank == 0) { mRankStartTime = ZT2LogElement->mZTLogData.at(i)->mTimestamp; CurRank = ZT2LogElement->mZTLogData.at(i)->mZT2ThreadData->mRank; } else { mRankRuler->AddRankItem(QString().sprintf("%d",CurRank),mRankStartTime,ZT2LogElement->mZTLogData.at(i)->mTimestamp); mRankStartTime = ZT2LogElement->mZTLogData.at(i)->mTimestamp; CurRank = ZT2LogElement->mZTLogData.at(i)->mZT2ThreadData->mRank; mRankStartTime = ZT2LogElement->mZTLogData.at(i)->mTimestamp; } } switch(param) { case ZT2_DISCREET_PLOTTABLE_S1_PARAM: { DataSet->mValue = ZT2LogElement->mZTLogData.at(i)->mZT2ThreadData->mS1; break; } case ZT2_DISCREET_PLOTTABLE_PPEXT_PARAM: { DataSet->mValue = ZT2LogElement->mZTLogData.at(i)->mZT2ThreadData->mPPExt; break; } case ZT2_DISCREET_PLOTTABLE_PPINT_PARAM: { DataSet->mValue = ZT2LogElement->mZTLogData.at(i)->mZT2ThreadData->mPPInt; break; } } } else if(i > 0) //if there is no data available, use the previous value... { DataSet->mValue = mZT2DiscreetPlots[param].mDataSet->at(i-1)->mValue; } switch(param) { case ZT2_DISCREET_PLOTTABLE_CI_PARAM: { DataSet->mValue = ZT2LogElement->mZTLogData.at(i)->mCIZT2; break; } case ZT2_DISCREET_PLOTTABLE_CDV_PARAM: { DataSet->mValue = ZT2LogElement->mZTLogData.at(i)->mCDVARM_ZT2; break; } case ZT2_DISCREET_PLOTTABLE_APPROACH_CDV_PARAM: { DataSet->mValue = ZT2LogElement->mZTLogData.at(i)->mCDVApproach_ZT2; } } mZT2DiscreetPlots[param].mDataSet->append(DataSet); } // for(int param = 0; param < ZT1_ANALOG_PLOTTABLE_NB_PARAM; param++) // { // CGraphAnalogDataPair *DataSet = new CGraphAnalogDataPair(0,ZT1LogElement->mZTLogData.at(i)->mTimestamp); // if(ZT1LogElement->mZTLogData.at(i)->mZT1ThreadData != 0) // { // switch(param) // { // case ZT1_ANALOG_PLOTTABLE_PGEXT_PARAM: // { // DataSet->mValue = (qreal)ZT1LogElement->mZTLogData.at(i)->mZT1ThreadData->mPGExtValue; // break; // } // case ZT1_ANALOG_PLOTTABLE_PGINT_PARAM: // { // DataSet->mValue = (qreal)ZT1LogElement->mZTLogData.at(i)->mZT1ThreadData->mPGIntValue; // break; // } // case ZT1_ANALOG_PLOTTABLE_TRAIN_SPEED_PARAM: // { // DataSet->mValue = ZT1LogElement->mZTLogData.at(i)->mZT1ThreadData->mTrainSpeed; // // if(DataSet->mValue == 0) // // DataSet->mValue = -1; // break; // } // } // } // else //No analog data... set to 0 // { // DataSet->mValue = 0; // } // mZT1AnalogPlots[param].mDataSet->append(DataSet); // } } mRankRuler->AddRankItem(QString().sprintf("%d",CurRank),mRankStartTime,ZT2LogElement->mZTLogData.last()->mTimestamp); mMinTime = mStartTime = mZT2DiscreetPlots[0].mDataSet->first()->mTime; mMaxTime = mZT2DiscreetPlots[0].mDataSet->last()->mTime; if(ZT2LogElement->mZTDetections.size() == 0) { mEventRuler->ClearRuler(); } else { for(int event = 0; event < ZT2LogElement->mZTDetections.size(); event++) { mEventRuler->AddEventItem(CZTData::GetShortErrorString(ZT2LogElement->mZTDetections.at(event)->mDetectionID),ZT2LogElement->mZTDetections.at(event)->mTimeStamp); } } } else { return; } mStopTime = mMaxTime; mTotalTimeSpan = mMaxTime - mMinTime; mCurTimeSpan = mStopTime - mStartTime; mCurPixelTickValue = (qreal)GRAPH_ZONE_WIDTH/(qreal)mCurTimeSpan; //pixels per microsecs mCursorPos = mStartTime; mPassageStats1Txt->setPlainText(QString().sprintf("Date & heure: %s\nStation : %s\nPosition : %s",mPassageDateTime.toUtf8().data(),mPassageStation.toUtf8().data()," ")); ShowSpan(mStartTime,mStopTime); ShowPlots(mViewType); // for(int param = 0; param < DISCREET_PLOTTABLE_NB_PARAM; param++) // { // mZT1DiscreetPlots[param].mPlotGaph->DisplayData(mStartTime,mStopTime); // } } void CLogViewPage::ShowPlots(unsigned int ViewType) { if(ViewType == ZT1_LOG_TYPE) { for(int param = 0; param < ZT1_DISCREET_PLOTTABLE_NB_PARAM; param++) { mZT1DiscreetPlots[param].mPlotGaph->show(); } for(int param = 0; param < ZT1_ANALOG_PLOTTABLE_NB_PARAM; param++) { mZT1AnalogPlots[param].mPlotGaph->show(); } for(int param = 0; param < ZT2_DISCREET_PLOTTABLE_NB_PARAM; param++) { mZT2DiscreetPlots[param].mPlotGaph->hide(); } for(int param = 0; param < ZT2_ANALOG_PLOTTABLE_NB_PARAM; param++) { // mZT1AnalogPlots[param].mPlotGaph->show(); } } else if(ViewType == ZT2_LOG_TYPE) { for(int param = 0; param < ZT1_DISCREET_PLOTTABLE_NB_PARAM; param++) { mZT1DiscreetPlots[param].mPlotGaph->hide(); } for(int param = 0; param < ZT1_ANALOG_PLOTTABLE_NB_PARAM; param++) { mZT1AnalogPlots[param].mPlotGaph->hide(); } for(int param = 0; param < ZT2_DISCREET_PLOTTABLE_NB_PARAM; param++) { mZT2DiscreetPlots[param].mPlotGaph->show(); } for(int param = 0; param < ZT2_ANALOG_PLOTTABLE_NB_PARAM; param++) { // mZT1AnalogPlots[param].mPlotGaph->show(); } } } void CLogViewPage::DestroyData() { for(int item = 0; item < ZT1_DISCREET_PLOTTABLE_NB_PARAM; item++) { for(int i = 0; i < mZT1DiscreetPlots[item].mDataSet->size(); i++) { delete mZT1DiscreetPlots[item].mDataSet->at(i); } mZT1DiscreetPlots[item].mDataSet->clear(); } for(int item = 0; item < ZT1_ANALOG_PLOTTABLE_NB_PARAM; item++) { for(int i = 0; i < mZT1AnalogPlots[item].mDataSet->size(); i++) { delete mZT1AnalogPlots[item].mDataSet->at(i); } mZT1AnalogPlots[item].mDataSet->clear(); } for(int item = 0; item < ZT2_DISCREET_PLOTTABLE_NB_PARAM; item++) { for(int i = 0; i < mZT2DiscreetPlots[item].mDataSet->size(); i++) { delete mZT2DiscreetPlots[item].mDataSet->at(i); } mZT2DiscreetPlots[item].mDataSet->clear(); } for(int item = 0; item < ZT2_ANALOG_PLOTTABLE_NB_PARAM; item++) { // for(int i = 0; i < mZT2AnalogPlots[item].mDataSet->size(); i++) // { // delete mZT1AnalogPlots[item].mDataSet->at(i); // } // mZT1AnalogPlots[item].mDataSet->clear(); } mRankRuler->ClearRuler(); mEventRuler->ClearRuler(); } void CLogViewPage::ZoomIn(bool CenterOnCursor) { //First, compute a zoom centered on the center of the area qint64 NewSpan = mCurTimeSpan - (mCurTimeSpan/5); if(NewSpan < 1000000) { NewSpan = mCurTimeSpan; //stop zooming } qint64 delta = mCurTimeSpan - NewSpan; quint64 StartTime = mStartTime + delta/2; quint64 StopTime = StartTime + NewSpan; if(StopTime > mMaxTime) { StopTime = mMaxTime; StartTime = StopTime - NewSpan; } if(CenterOnCursor) { #ifdef ZOOM_CENTERED_ON_CURSOR //Now let's find how many pixels have moved from the cursor //by finding the position of the cursor time in the new timespan quint64 CursorTime = GetTimeForPixel(mCursorPos); //Convert time to pixels (in the new timespan) quint64 AbsoluteTime = CursorTime - StartTime; qreal PixelsPernSecs = (qreal)GRAPH_ZONE_WIDTH/(NewSpan); qreal Pixel = AbsoluteTime * PixelsPernSecs; Pixel += GRAPH_ZONE_X_OFFSET; //Find from how much pixels we have moved qreal DeltaX = Pixel - mCursorPos; //convert this to an amount of time qint64 DeltaTime = ((qint64)DeltaX * NewSpan)/GRAPH_ZONE_WIDTH; //Shift the timespan to center the zoom on the cursor. StartTime += DeltaTime; if(StartTime < mMinTime) { StartTime = mMinTime; } StopTime = StartTime + NewSpan; if(StopTime > mMaxTime) { StopTime = mMaxTime; StartTime = StopTime - NewSpan; } #endif } ShowSpan(StartTime,StopTime); } void CLogViewPage::ZoomOut(bool CenterOnCursor) { qint64 NewSpan = mCurTimeSpan + (mCurTimeSpan/5); if(NewSpan > (qint64)(mMaxTime - mMinTime)) { ShowSpan(mMinTime,mMaxTime); } else { qint64 delta = NewSpan - mCurTimeSpan; qint64 StartTime = mStartTime - delta/2; if(StartTime < (qint64)mMinTime/* || StartTime < 0*/) { StartTime = mMinTime; } quint64 StopTime = StartTime + NewSpan; if(StopTime > mMaxTime) { StopTime = mMaxTime; StartTime = StopTime - NewSpan; } if(CenterOnCursor == true) { #ifdef ZOOM_CENTERED_ON_CURSOR quint64 CursorTime = GetTimeForPixel(mCursorPos); //Convert time to pixels (in the new timespan) quint64 AbsoluteTime = CursorTime - StartTime; qreal PixelsPernSecs = (qreal)GRAPH_ZONE_WIDTH/(NewSpan); qreal Pixel = AbsoluteTime * PixelsPernSecs; Pixel += GRAPH_ZONE_X_OFFSET; //Find from how much pixels we have moved qreal DeltaX = Pixel - mCursorPos; //convert this to an amount of time qint64 DeltaTime = ((qint64)DeltaX * NewSpan)/GRAPH_ZONE_WIDTH; //Shift the timespan to center the zoom on the cursor. StartTime += DeltaTime; if(StartTime < (qint64)mMinTime/* || StartTime < 0*/) { StartTime = mMinTime; } StopTime = StartTime + NewSpan; if(StopTime > mMaxTime) { StopTime = mMaxTime; StartTime = StopTime - NewSpan; } #endif } ShowSpan(StartTime,StopTime); } } void CLogViewPage::SetZoom(int ZoomValue) { Q_UNUSED(ZoomValue) } //Grab the mouse if the user clicks outside buttons void CLogViewPage::mousePressEvent(QGraphicsSceneMouseEvent *event) { if(event->button() == Qt::LeftButton) { mMouseDragging = true; mMouseMoved = false; } event->accept(); } void CLogViewPage::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { if(event->button() == Qt::LeftButton) { mMouseDragging = false; if(mMouseMoved == false) { mStaticCursor1->setPos(event->pos().x(),0); mStaticCursor1->SetTime(GetTimeForPixel(event->pos().x())); mStaticCursor1->SetCursor(); mStaticCursor1->show(); UpdateStaticCursorsDeltaTime(); mCursor1TimeTxt->setPlainText(QString().sprintf("Position curseur 1 : %d ms",(int)(mStaticCursor1->GetTime()/1000000))); } } if(event->button() == Qt::RightButton) { mStaticCursor2->setPos(event->pos().x(),0); mStaticCursor2->SetTime(GetTimeForPixel(event->pos().x())); mStaticCursor2->SetCursor(); mStaticCursor2->show(); mCursor2TimeTxt->setPlainText(QString().sprintf("Position curseur 2 : %d ms",(int)(mStaticCursor2->GetTime()/1000000))); UpdateStaticCursorsDeltaTime(); } event->accept(); } void CLogViewPage::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { if(mMouseDragging) { DragPlots(event->lastPos().x() - event->pos().x()); // mMouseMoved = true; // qreal Drag = event->lastPos().x() - event->pos().x(); // //qreal Drag = 50; // if(Drag != 0) // { // qreal TickValue = (qreal)GRAPH_ZONE_WIDTH/(qreal)mCurTimeSpan; // qreal temp = TickValue/Drag; // //quint64 usecsDrag = 1/(mCurPixelTickValue/Drag); // qint64 usecsDrag = 1/temp; // ScrollGraphs(usecsDrag); // } } AdjustMouseCursorPos(event->pos().x(),event->pos().y()); event->accept(); } void CLogViewPage::DragPlots(qreal DragValue) { mMouseMoved = true; qreal Drag = DragValue; //qreal Drag = 50; if(Drag != 0) { qreal TickValue = (qreal)GRAPH_ZONE_WIDTH/(qreal)mCurTimeSpan; qreal temp = TickValue/Drag; //quint64 usecsDrag = 1/(mCurPixelTickValue/Drag); qint64 usecsDrag = 1/temp; ScrollGraphs(usecsDrag); } } bool CLogViewPage::eventFilter(QObject *obj, QEvent *event) { if(isVisible()) //Check if event is coming from us { if(event->type() == QEvent::KeyPress) { QKeyEvent *KeyEvent = static_cast(event); if(KeyEvent->key() == Qt::Key_Left) { AdjustMouseCursorPos(mVCursor->GetPixelPos() - 1,mHCursor->GetPixelPos()); return true; //keep the keystroke } if(KeyEvent->key() == Qt::Key_Right) { AdjustMouseCursorPos(mVCursor->GetPixelPos() + 1,mHCursor->GetPixelPos()); return true; //keep the keystroke } if(KeyEvent->key() == Qt::Key_Control) { mCtrlKeyDown = true; return true; } if(KeyEvent->key() == Qt::Key_Shift) { mShiftKeyDown = true; return true; } } else if(event->type() == QEvent::KeyRelease) { QKeyEvent *KeyEvent = static_cast(event); if(KeyEvent->key() == Qt::Key_Control) { mCtrlKeyDown = false; return true; } if(KeyEvent->key() == Qt::Key_Shift) { mShiftKeyDown = false; return true; } } } return QObject::eventFilter(obj,event); } void CLogViewPage::wheelEvent(QGraphicsSceneWheelEvent *event) { //Zoom must be higher than 100 (100%) //That is full scale. //int Zoom; if(event-> delta() < 0) { ZoomOut(); // Zoom = mZoomValue - ZOOM_TICK; // if(Zoom < 100) // Zoom = 100; } else { ZoomIn(); // Zoom = mZoomValue + ZOOM_TICK; } // mZoomValue = Zoom; // SetZoom(Zoom); event->accept(); } void CLogViewPage::ScrollGraphs(qint64 Delta) { quint64 CurTimeSpan = mStopTime - mStartTime; if(Delta > 0) { if(mStopTime + Delta >= mMaxTime) { mStopTime = mMaxTime; } else { mStopTime += Delta; } mStartTime = mStopTime - CurTimeSpan; } else { // if(mStartTime == mMinTime) // return; //Delta is negative !! qint64 start = mStartTime + Delta; if(start <= (qint64)mMinTime) { mStartTime = mMinTime; } else { mStartTime += Delta; } mStopTime = mStartTime + CurTimeSpan; } // qDebug() << "StartTime = " << mStartTime << "StopTime = " << mStopTime << "delta= " << Delta; if(mScrollRefreshTimer.elapsed() > 33) //limit the scroll redraw to 30FPS { ShowSpan(mStartTime,mStopTime); mScrollRefreshTimer.start(); } // for(int param = 0; param < DISCREET_PLOTTABLE_NB_PARAM; param++) // { // mZT1DiscreetPlots[param].mPlotGaph->DisplayData(mStartTime,mStopTime); // } } void CLogViewPage::hoverMoveEvent(QGraphicsSceneHoverEvent *event) { AdjustMouseCursorPos(event->pos().x(),event->pos().y()); if(mShiftKeyDown) { qreal Drag = event->lastPos().x() - event->pos().x(); DragPlots(Drag); AdjustMouseCursorPos(event->pos().x(),event->pos().y()); } else if(mCtrlKeyDown) { qreal Drag = event->lastPos().y() - event->pos().y(); if(Drag != 0) { if(Drag > 0) { ZoomIn(); } else { ZoomOut(); } } } // mCursorPos = event->pos().x(); // if(mCursorPos < GRAPH_ZONE_X_OFFSET) // mCursorPos = GRAPH_ZONE_X_OFFSET; // else if(mCursorPos > GRAPH_ZONE_WIDTH + GRAPH_ZONE_X_OFFSET) // mCursorPos = GRAPH_ZONE_WIDTH + GRAPH_ZONE_X_OFFSET; // mCursor->setPos(mCursorPos,0); // int CursorTime = GetTimeForPixel(mCursorPos)/1000000; // mCursorPosTxt->setPlainText(QString().sprintf("%d ms",CursorTime)); } qreal CLogViewPage::GetPixelForTime(quint64 Time) { quint64 AbsoluteTime = Time - mStartTime; qreal PixelsPernSecs = (qreal)GRAPH_ZONE_WIDTH/(mStopTime - mStartTime); qreal Pixel = AbsoluteTime * PixelsPernSecs; return Pixel+GRAPH_ZONE_X_OFFSET; } quint64 CLogViewPage::GetTimeForPixel(qreal PixelPos) { PixelPos -= GRAPH_ZONE_X_OFFSET; qreal nSecsPerPixels = (mStopTime - mStartTime)/GRAPH_ZONE_WIDTH; quint64 AbsoluteTimeForPixel = PixelPos*nSecsPerPixels; quint64 Time = mStartTime + AbsoluteTimeForPixel; return Time; } unsigned int CLogViewPage::ShowSpan(qreal PixelPos1, qreal PixelPos2) { return ShowSpan(GetTimeForPixel(PixelPos1),GetTimeForPixel(PixelPos2)); } unsigned int CLogViewPage::ShowSpan(quint64 TimePos1, quint64 TimePos2) { if(TimePos1 > TimePos2) { mStartTime = TimePos2; mStopTime = TimePos1; } else { mStartTime = TimePos1; mStopTime = TimePos2; } mCurTimeSpan = mStopTime - mStartTime; mCurPixelTickValue = (qreal)GRAPH_ZONE_WIDTH/(qreal)mCurTimeSpan; //pixels per microsecs if(mViewType == ZT1_LOG_TYPE) { for(int param = 0; param < ZT1_DISCREET_PLOTTABLE_NB_PARAM; param++) { mZT1DiscreetPlots[param].mPlotGaph->DisplayData(mStartTime,mStopTime); } for(int param = 0; param < ZT1_ANALOG_PLOTTABLE_NB_PARAM; param++) { mZT1AnalogPlots[param].mPlotGaph->DisplayData(mStartTime,mStopTime); } } else if(mViewType == ZT2_LOG_TYPE) { for(int param = 0; param < ZT2_DISCREET_PLOTTABLE_NB_PARAM; param++) { mZT2DiscreetPlots[param].mPlotGaph->DisplayData(mStartTime,mStopTime); } for(int param = 0; param < ZT2_ANALOG_PLOTTABLE_NB_PARAM; param++) { // mZT2AnalogPlots[param].mPlotGaph->DisplayData(mStartTime,mStopTime); } } else return RET_ERROR; AdjustStaticCursorsPos(); mRuler->SetRange(mStartTime,mStopTime); mRankRuler->SetRange(mStartTime,mStopTime); mEventRuler->SetRange(mStartTime,mStopTime); return RET_OK; } unsigned int CLogViewPage::AdjustStaticCursorsPos() { if(mStaticCursor1->IsCursorSet()) { quint64 CursorTime = mStaticCursor1->GetTime(); if(CursorTime < mStartTime || CursorTime > mStopTime) { mStaticCursor1->hide(); } else { qreal newpos = GetPixelForTime(CursorTime); mStaticCursor1->setPos(newpos,0); mStaticCursor1->show(); } } if(mStaticCursor2->IsCursorSet()) { quint64 CursorTime = mStaticCursor2->GetTime(); if(CursorTime < mStartTime || CursorTime > mStopTime) { mStaticCursor2->hide(); } else { qreal newpos = GetPixelForTime(CursorTime); mStaticCursor2->setPos(newpos,0); mStaticCursor2->show(); } } return RET_OK; } unsigned int CLogViewPage::AdjustMouseCursorPos(qreal PosX, qreal PosY) { mCursorPos = PosX; if(mCursorPos < GRAPH_ZONE_X_OFFSET) mCursorPos = GRAPH_ZONE_X_OFFSET; else if(mCursorPos > GRAPH_ZONE_WIDTH + GRAPH_ZONE_X_OFFSET) mCursorPos = GRAPH_ZONE_WIDTH + GRAPH_ZONE_X_OFFSET; qreal HCursorPos = PosY; if(HCursorPos > GRAPH_ZONE_HEIGHT) HCursorPos = GRAPH_ZONE_HEIGHT; mVCursor->setPos(mCursorPos,0); mHCursor->setPos(GRAPH_ZONE_X_OFFSET,HCursorPos); // mCursor->update(); int CursorTime = GetTimeForPixel(mCursorPos)/1000000; mPassageStats1Txt->setPlainText(QString().sprintf("Date & heure: %s\nStation : %s\nPosition : %d ms",mPassageDateTime.toUtf8().data(),mPassageStation.toUtf8().data(),CursorTime)); // mCursorPosTxt->setPlainText(QString().sprintf("%d ms",CursorTime)); for(int i = 0; i < ZT1_ANALOG_PLOTTABLE_NB_PARAM; i++) mZT1AnalogPlots[i].mPlotGaph->GetValueForTime(GetTimeForPixel(mCursorPos)); update(mVCursor->boundingRect()); update(mHCursor->boundingRect()); return RET_OK; } unsigned int CLogViewPage::UpdateStaticCursorsDeltaTime() { if(mStaticCursor1->IsCursorSet() == true && mStaticCursor2->IsCursorSet() == true) { QString Temp; quint64 Cur1,Cur2; qint64 Diff; Cur1 = mStaticCursor1->GetTime(); Cur2 = mStaticCursor2->GetTime(); Diff = Cur1 - Cur2; //qreal Delta = (qreal)(mStaticCursor1->GetTime() - mStaticCursor2->GetTime()); qreal Delta = Diff; if(Delta < 0) Delta *= -1; if(Delta/1000000000 > 1) { QTextStream(&Temp) << "Delta: " << Delta/1000000000 << " s"; } else if(Delta/1000000 > 1) { QTextStream(&Temp) << "Delta: " << Delta/1000000 << " ms"; } else if(Delta/1000 > 1) { QTextStream(&Temp) << "Delta: " << Delta/1000 << " us"; } else { QTextStream(&Temp) << "Delta: " << Delta << " ns"; } mStaticCursorDeltaTimeTxt->setPlainText(Temp); } return RET_OK; }