2 ******************************************************************************
4 * @file logginggadgetwidget.cpp
5 * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2018.
6 * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
7 * @addtogroup GCSPlugins GCS Plugins
9 * @addtogroup LoggingGadgetPlugin Logging Gadget Plugin
11 * @brief A gadget to control playback of a GCS log.
12 *****************************************************************************/
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 3 of the License, or
17 * (at your option) any later version.
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
21 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24 * You should have received a copy of the GNU General Public License along
25 * with this program; if not, write to the Free Software Foundation, Inc.,
26 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include "logginggadgetwidget.h"
30 #include "ui_logging.h"
32 #include <loggingplugin.h>
35 #include <QPushButton>
37 LoggingGadgetWidget::LoggingGadgetWidget(QWidget
*parent
) : QWidget(parent
), loggingPlugin(NULL
)
39 m_logging
= new Ui_Logging();
40 m_logging
->setupUi(this);
42 ExtensionSystem::PluginManager
*pm
= ExtensionSystem::PluginManager::instance();
43 scpPlugin
= pm
->getObject
<ScopeGadgetFactory
>();
47 // Configure timer to delay application of slider position action for 200ms
48 sliderActionDelay
.setSingleShot(true);
49 sliderActionDelay
.setInterval(200);
51 connect(&sliderActionDelay
, SIGNAL(timeout()), this, SLOT(sliderAction()));
54 LoggingGadgetWidget::~LoggingGadgetWidget()
59 void LoggingGadgetWidget::setPlugin(LoggingPlugin
*p
)
62 LogFile
*logFile
= loggingPlugin
->getLogfile();
64 // GUI elements to gadgetwidget functions
65 connect(m_logging
->playButton
, &QPushButton::clicked
, this, &LoggingGadgetWidget::playButtonAction
);
66 connect(m_logging
->pauseButton
, &QPushButton::clicked
, this, &LoggingGadgetWidget::pauseButtonAction
);
67 connect(m_logging
->stopButton
, &QPushButton::clicked
, this, &LoggingGadgetWidget::stopButtonAction
);
68 connect(m_logging
->playbackPosition
, &QSlider::valueChanged
, this, &LoggingGadgetWidget::sliderMoved
);
70 connect(m_logging
->playbackSpeed
, static_cast<void(QDoubleSpinBox::*) (double)>(&QDoubleSpinBox::valueChanged
), logFile
, &LogFile::setReplaySpeed
);
72 // gadgetwidget functions to logfile actions
73 connect(this, &LoggingGadgetWidget::resumeReplay
, logFile
, &LogFile::resumeReplay
);
74 connect(this, &LoggingGadgetWidget::pauseReplay
, logFile
, &LogFile::pauseReplay
);
75 connect(this, &LoggingGadgetWidget::pauseReplayAndResetPosition
, logFile
, &LogFile::pauseReplayAndResetPosition
);
77 // gadgetwidget functions to scope actions
78 connect(this, &LoggingGadgetWidget::resumeReplay
, scpPlugin
, &ScopeGadgetFactory::startPlotting
);
79 connect(this, &LoggingGadgetWidget::pauseReplay
, scpPlugin
, &ScopeGadgetFactory::stopPlotting
);
80 connect(this, &LoggingGadgetWidget::pauseReplayAndResetPosition
, scpPlugin
, &ScopeGadgetFactory::stopPlotting
);
82 // Feedback from logfile to GUI
83 connect(loggingPlugin
, &LoggingPlugin::stateChanged
, this, &LoggingGadgetWidget::stateChanged
);
84 connect(logFile
, &LogFile::timesChanged
, this, &LoggingGadgetWidget::setBeginAndEndTimes
);
85 connect(logFile
, &LogFile::playbackPositionChanged
, this, &LoggingGadgetWidget::setPlaybackPosition
);
86 connect(logFile
, &LogFile::replayStarted
, this, &LoggingGadgetWidget::enableWidgets
);
87 connect(logFile
, &LogFile::replayFinished
, this, &LoggingGadgetWidget::disableWidgets
);
88 connect(logFile
, &LogFile::replayCompleted
, this, &LoggingGadgetWidget::stopButtonAction
);
90 // Feedback from logfile to scope
91 connect(logFile
, &LogFile::replayFinished
, scpPlugin
, &ScopeGadgetFactory::stopPlotting
);
93 // Perform actions as if the plugin state has been changed
94 stateChanged(loggingPlugin
->getState());
97 void LoggingGadgetWidget::playButtonAction()
99 ReplayState replayState
= loggingPlugin
->getLogfile()->getReplayState();
101 if (replayState
!= PLAYING
) {
102 emit
resumeReplay(m_logging
->playbackPosition
->value());
105 m_logging
->playButton
->setVisible(false);
106 m_logging
->pauseButton
->setVisible(true);
107 m_logging
->stopButton
->setEnabled(true);
110 void LoggingGadgetWidget::pauseButtonAction()
112 ReplayState replayState
= loggingPlugin
->getLogfile()->getReplayState();
114 if (replayState
== PLAYING
) {
118 m_logging
->playButton
->setVisible(true);
119 m_logging
->pauseButton
->setVisible(false);
120 m_logging
->stopButton
->setEnabled(true);
122 m_logging
->statusLabel
->setText(tr("Paused"));
125 void LoggingGadgetWidget::stopButtonAction()
127 emit
pauseReplayAndResetPosition();
129 m_logging
->playButton
->setVisible(true);
130 m_logging
->pauseButton
->setVisible(false);
131 m_logging
->stopButton
->setEnabled(false);
133 setPlaybackPosition(0);
135 m_logging
->statusLabel
->setText(tr("Stopped"));
138 void LoggingGadgetWidget::stateChanged(LoggingPlugin::State state
)
141 bool enabled
= false;
144 case LoggingPlugin::IDLE
:
146 setPlaybackPosition(0);
148 case LoggingPlugin::LOGGING
:
149 status
= tr("Logging");
151 case LoggingPlugin::REPLAY
:
152 status
= tr("Replaying");
156 m_logging
->statusLabel
->setText(status
);
158 bool playing
= loggingPlugin
->getLogfile()->isPlaying();
159 m_logging
->playButton
->setEnabled(enabled
);
160 m_logging
->pauseButton
->setEnabled(enabled
);
161 m_logging
->stopButton
->setEnabled(enabled
&& playing
);
164 m_logging
->playButton
->setVisible(false);
165 m_logging
->pauseButton
->setVisible(true);
167 m_logging
->playButton
->setVisible(true);
168 m_logging
->pauseButton
->setVisible(false);
172 void LoggingGadgetWidget::setBeginAndEndTimes(quint32 startTimeStamp
, quint32 endTimeStamp
)
174 int startSec
, startMin
, endSec
, endMin
;
176 startSec
= (startTimeStamp
/ 1000) % 60;
177 startMin
= startTimeStamp
/ (60 * 1000);
179 endSec
= (endTimeStamp
/ 1000) % 60;
180 endMin
= endTimeStamp
/ (60 * 1000);
182 // update start and end labels
183 m_logging
->startTimeLabel
->setText(QString("%1:%2").arg(startMin
, 2, 10, QChar('0')).arg(startSec
, 2, 10, QChar('0')));
184 m_logging
->endTimeLabel
->setText(QString("%1:%2").arg(endMin
, 2, 10, QChar('0')).arg(endSec
, 2, 10, QChar('0')));
186 // Update position bar
187 m_logging
->playbackPosition
->setMinimum(startTimeStamp
);
188 m_logging
->playbackPosition
->setMaximum(endTimeStamp
);
190 m_logging
->playbackPosition
->setSingleStep((endTimeStamp
- startTimeStamp
) / 100);
191 m_logging
->playbackPosition
->setPageStep((endTimeStamp
- startTimeStamp
) / 10);
194 void LoggingGadgetWidget::setPlaybackPosition(quint32 positionTimeStamp
)
196 // Update position bar, but only if the user is not updating the slider position
197 if (!m_logging
->playbackPosition
->isSliderDown() && !sliderActionDelay
.isActive()) {
198 // Block signals during slider position update:
199 m_logging
->playbackPosition
->blockSignals(true);
200 m_logging
->playbackPosition
->setValue(positionTimeStamp
);
201 m_logging
->playbackPosition
->blockSignals(false);
203 // update position label
204 updatePositionLabel(positionTimeStamp
);
208 void LoggingGadgetWidget::enableWidgets()
210 ReplayState replayState
= loggingPlugin
->getLogfile()->getReplayState();
212 m_logging
->playButton
->setEnabled(true);
213 m_logging
->pauseButton
->setEnabled(true);
215 switch (replayState
) {
217 m_logging
->stopButton
->setEnabled(false);
218 m_logging
->playButton
->setVisible(true);
219 m_logging
->pauseButton
->setVisible(false);
223 m_logging
->stopButton
->setEnabled(true);
224 m_logging
->playButton
->setVisible(false);
225 m_logging
->pauseButton
->setVisible(true);
229 m_logging
->stopButton
->setEnabled(true);
230 m_logging
->playButton
->setVisible(true);
231 m_logging
->pauseButton
->setVisible(false);
234 m_logging
->playbackPosition
->setEnabled(true);
237 void LoggingGadgetWidget::disableWidgets()
239 m_logging
->playButton
->setVisible(true);
240 m_logging
->pauseButton
->setVisible(false);
242 m_logging
->playButton
->setEnabled(false);
243 m_logging
->pauseButton
->setEnabled(false);
244 m_logging
->stopButton
->setEnabled(false);
246 m_logging
->playbackPosition
->setEnabled(false);
248 // reset start and end labels
249 m_logging
->startTimeLabel
->setText("");
250 m_logging
->endTimeLabel
->setText("");
253 void LoggingGadgetWidget::updatePositionLabel(quint32 positionTimeStamp
)
255 // update position label -> MM:SS
256 int sec
= (positionTimeStamp
/ 1000) % 60;
257 int min
= positionTimeStamp
/ (60 * 1000);
259 m_logging
->positionTimestampLabel
->setText(QString("%1:%2").arg(min
, 2, 10, QChar('0')).arg(sec
, 2, 10, QChar('0')));
262 void LoggingGadgetWidget::sliderMoved(int position
)
264 // pause playback while the user is dragging the slider to change position
267 updatePositionLabel(position
);
269 // Start or restarts a time-out after which replay will resume from the new position.
270 sliderActionDelay
.start();
273 void LoggingGadgetWidget::sliderAction()
275 emit
resumeReplay(m_logging
->playbackPosition
->value());