dRonin  adbada4
dRonin GCS
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Groups Pages
seppukuconfiguration.cpp
Go to the documentation of this file.
1 
11 /*
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 3 of the License, or
15  * (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful, but
18  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20  * for more details.
21  *
22  * You should have received a copy of the GNU General Public License along
23  * with this program; if not, see <http://www.gnu.org/licenses/>
24  *
25  * Additional note on redistribution: The copyright and license notices above
26  * must be maintained in each individual source file that is a derivative work
27  * of this source file; otherwise redistribution is prohibited.
28  */
29 
30 #include "seppukuconfiguration.h"
31 
32 #include <QDebug>
33 
35  : ConfigTaskWidget(parent)
36  , ui(new Ui::Seppuku)
37  , m_background(nullptr)
38 {
39  ui->setupUi(this);
40 
41  setupGraphicsScene();
42 
43  connect(ui->cbMag, &QComboBox::currentTextChanged, this, &SeppukuConfiguration::magChanged);
44  connect(ui->cbOutputs, &QComboBox::currentTextChanged, this,
45  &SeppukuConfiguration::outputsChanged);
46  connect(ui->cbRcvrPort, &QComboBox::currentTextChanged, this, &SeppukuConfiguration::checkRcvr);
47  connect(ui->cbUart1, &QComboBox::currentTextChanged, this, &SeppukuConfiguration::checkDsm);
48  connect(ui->cbUart3, &QComboBox::currentTextChanged, this, &SeppukuConfiguration::checkUart3);
49  connect(ui->cbUart4, &QComboBox::currentTextChanged, this, &SeppukuConfiguration::checkDsm);
50  connect(ui->cbUart6, &QComboBox::currentTextChanged, this, &SeppukuConfiguration::checkDsm);
51  connect(ui->cbDsmMode, &QComboBox::currentTextChanged, this, &SeppukuConfiguration::checkDsm);
52 
56 }
57 
59 {
60  delete ui;
61 }
62 
63 void SeppukuConfiguration::setupGraphicsScene()
64 {
65  const QString diagram = ":/dronin/images/seppuku-config.svg";
66  m_renderer = new QSvgRenderer();
67  if (!m_renderer)
68  return;
69  if (QFile::exists(diagram) && m_renderer->load(diagram) && m_renderer->isValid()) {
70  m_scene = new QGraphicsScene(this);
71  if (!m_scene)
72  return;
73  ui->boardDiagram->setScene(m_scene);
74 
75  m_background = new QGraphicsSvgItem();
76  if (!m_background)
77  return;
78  m_background->setSharedRenderer(m_renderer);
79  m_background->setElementId("seppuku");
80  m_background->setOpacity(1.0);
81  m_background->setZValue(0);
82  m_scene->addItem(m_background);
83 
84  m_uart3 = addGraphicsElement("uart3");
85  if (!m_uart3)
86  return;
87 
88  m_uart4 = addGraphicsElement("esc78");
89  if (!m_uart4)
90  return;
91 
92  const QRectF bound = m_background->boundingRect();
93  ui->boardDiagram->setSceneRect(bound);
94  ui->boardDiagram->setRenderHints(QPainter::SmoothPixmapTransform);
95  ui->boardDiagram->fitInView(m_background, Qt::KeepAspectRatio);
96  } else {
97  qWarning() << "failed to setup seppuku board diagram!";
98  }
99 }
100 
101 QGraphicsSvgItem *SeppukuConfiguration::addGraphicsElement(const QString &elementId)
102 {
103  QGraphicsSvgItem *item = new QGraphicsSvgItem();
104  if (!item)
105  return nullptr;
106  item->setSharedRenderer(m_renderer);
107  item->setElementId(elementId);
108  item->setOpacity(1.0);
109  static int zval = 1;
110  item->setZValue(zval++);
111  QMatrix matrix = m_renderer->matrixForElement(elementId);
112  QRectF orig = matrix.mapRect(m_renderer->boundsOnElement(elementId));
113  item->setPos(orig.x(), orig.y());
114  m_scene->addItem(item);
115  return item;
116 }
117 
118 void SeppukuConfiguration::showEvent(QShowEvent *event)
119 {
120  Q_UNUSED(event)
121  if (m_background)
122  ui->boardDiagram->fitInView(m_background, Qt::KeepAspectRatio);
123 }
124 
125 void SeppukuConfiguration::resizeEvent(QResizeEvent *event)
126 {
127  Q_UNUSED(event)
128  if (m_background)
129  ui->boardDiagram->fitInView(m_background, Qt::KeepAspectRatio);
130 }
131 
132 void SeppukuConfiguration::magChanged(const QString &newVal)
133 {
134  bool ext = newVal.contains("External");
135  setWidgetEnabled(ui->lblExtMagOrientation, ext);
136  setWidgetEnabled(ui->cbExtMagOrientation, ext);
137  checkExtMag();
138 }
139 
140 void SeppukuConfiguration::outputsChanged(const QString &newVal)
141 {
142  bool uart = newVal.contains("UART");
143  if (m_uart4)
144  m_uart4->setElementId(uart ? "uart4" : "esc78");
145  setWidgetEnabled(ui->lblUart4, uart);
146  setWidgetEnabled(ui->cbUart4, uart);
147 }
148 
149 void SeppukuConfiguration::checkExtMag()
150 {
151  bool extMag = ui->cbMag->currentText().contains("External");
152  bool uartExt = ui->cbUart3->currentText() == "I2C";
153 
154  if (extMag && !uartExt)
155  setMessage("ExtMag", tr("External magnetometer selected but UART3 not configured as I2C!"),
156  "error");
157  else if (uartExt && !extMag)
158  setMessage("ExtMag", tr("UART3 configured as I2C but external magnetometer not selected."));
159  else
160  setMessage("ExtMag");
161 }
162 
163 void SeppukuConfiguration::checkDsm()
164 {
165  bool dsm = false;
166  dsm |= ui->cbRcvrPort->currentText().contains("DSM");
167  dsm |= ui->cbUart1->currentText().contains("DSM");
168  dsm |= ui->cbUart3->currentText().contains("DSM");
169  dsm |= ui->cbUart4->currentText().contains("DSM");
170  dsm |= ui->cbUart6->currentText().contains("DSM");
171 
172  setWidgetEnabled(ui->lblDsmMode, dsm);
173  setWidgetEnabled(ui->cbDsmMode, dsm);
174 }
175 
176 void SeppukuConfiguration::checkUart3(const QString &newVal)
177 {
178  checkDsm();
179  checkExtMag();
180 
181  bool i2c = newVal.contains("I2C");
182  if (m_uart3)
183  m_uart3->setElementId(i2c ? "i2c" : "uart3");
184 }
185 
186 void SeppukuConfiguration::checkRcvr(const QString &newVal)
187 {
188  checkDsm();
189 
190  bool dsm = newVal.contains("DSM");
191  bool enabled = newVal != "Disabled";
192  if (dsm)
193  setMessage(
194  "RxPower",
195  tr("Please remember to solder ONLY the 3V3 receiver voltage jumper under the board."),
196  "info");
197  else if (enabled)
198  setMessage(
199  "RxPower",
200  tr("Please remember to solder ONE of the receiver voltage jumpers under the board."),
201  "info");
202  else
203  setMessage("RxPower");
204 }
205 
206 void SeppukuConfiguration::setMessage(const QString &name, const QString &msg,
207  const QString &severity)
208 {
209  QLabel *lbl = ui->gbMessages->findChild<QLabel *>(name);
210  if (msg.length()) {
211  if (!lbl) {
212  lbl = new QLabel();
213  lbl->setObjectName(name);
214  ui->gbMessages->layout()->addWidget(lbl);
215  ui->gbMessages->layout()->setAlignment(lbl, Qt::AlignTop);
216  }
217  lbl->setText(msg);
218  setWidgetProperty(lbl, "severity", severity);
219  } else if (lbl) {
220  delete lbl;
221  }
222 }
223 
SeppukuConfiguration(QWidget *parent=nullptr)
void setWidgetProperty(QWidget *widget, const char *prop, const QVariant &value)
setWidgetProperty Sets a dynamic property on a widget and forces a re-evaluation of it's stylesheet N...
virtual void populateWidgets()
virtual void refreshWidgetsValues(UAVObject *obj=NULL)
void setWidgetEnabled(QWidget *widget, bool enabled=true)
setWidgetEnabled Enable/disable a widget controlled by a UAVO relation