Merged in f5soh/librepilot/update_credits (pull request #529)
[librepilot.git] / ground / gcs / src / plugins / logging / logginggadgetwidget.cpp
blobb559ef652b83d1c0a245d1635927e2afc8fc37b0
1 /**
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
8 * @{
9 * @addtogroup LoggingGadgetPlugin Logging Gadget Plugin
10 * @{
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
22 * for more details.
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>
34 #include <QWidget>
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>();
45 disableWidgets();
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()
56 // Do nothing
59 void LoggingGadgetWidget::setPlugin(LoggingPlugin *p)
61 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) {
115 emit pauseReplay();
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)
140 QString status;
141 bool enabled = false;
143 switch (state) {
144 case LoggingPlugin::IDLE:
145 status = tr("Idle");
146 setPlaybackPosition(0);
147 break;
148 case LoggingPlugin::LOGGING:
149 status = tr("Logging");
150 break;
151 case LoggingPlugin::REPLAY:
152 status = tr("Replaying");
153 enabled = true;
154 break;
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);
163 if (playing) {
164 m_logging->playButton->setVisible(false);
165 m_logging->pauseButton->setVisible(true);
166 } else {
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) {
216 case STOPPED:
217 m_logging->stopButton->setEnabled(false);
218 m_logging->playButton->setVisible(true);
219 m_logging->pauseButton->setVisible(false);
220 break;
222 case PLAYING:
223 m_logging->stopButton->setEnabled(true);
224 m_logging->playButton->setVisible(false);
225 m_logging->pauseButton->setVisible(true);
226 break;
228 case PAUSED:
229 m_logging->stopButton->setEnabled(true);
230 m_logging->playButton->setVisible(true);
231 m_logging->pauseButton->setVisible(false);
232 break;
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
265 emit pauseReplay();
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());
280 * @}
281 * @}