diff --git a/src/GAudioOutput.cc b/src/GAudioOutput.cc
index 7a3b90e4cfa66e6fb8de95a9f79f193f22c96341..50ef1ecbc630cd59e59f644ff39337d188aefa95 100644
--- a/src/GAudioOutput.cc
+++ b/src/GAudioOutput.cc
@@ -151,10 +151,14 @@ GAudioOutput::~GAudioOutput()
void GAudioOutput::mute(bool mute)
{
- this->muted = mute;
- QSettings settings;
- settings.setValue(QGC_GAUDIOOUTPUT_KEY+"muted", this->muted);
- settings.sync();
+ if (mute != muted)
+ {
+ this->muted = mute;
+ QSettings settings;
+ settings.setValue(QGC_GAUDIOOUTPUT_KEY+"muted", this->muted);
+ settings.sync();
+ emit mutedChanged(muted);
+ }
}
bool GAudioOutput::isMuted()
diff --git a/src/GAudioOutput.h b/src/GAudioOutput.h
index a4889829d3ddcb14c8964b8ca616bc930fccf396..316e34d05850b2549e2a6b9608cebdea9eba14b6 100644
--- a/src/GAudioOutput.h
+++ b/src/GAudioOutput.h
@@ -80,6 +80,9 @@ public:
VOICE_FEMALE
} QGVoice;
+ /** @brief Get the mute state */
+ bool isMuted();
+
public slots:
/** @brief Say this text if current output priority matches */
bool say(QString text, int severity=1);
@@ -101,8 +104,9 @@ public slots:
void notifyNegative();
/** @brief Mute/unmute sound */
void mute(bool mute);
- /** @brief Get the mute state */
- bool isMuted();
+
+signals:
+ void mutedChanged(bool);
protected:
#ifdef Q_OS_MAC
diff --git a/src/comm/MAVLinkProtocol.cc b/src/comm/MAVLinkProtocol.cc
index 5e4e73c48705855a39259421ec22a0a6102e497a..d1d45497fe80651c76e749130832a91140a1ca1f 100644
--- a/src/comm/MAVLinkProtocol.cc
+++ b/src/comm/MAVLinkProtocol.cc
@@ -44,6 +44,9 @@ MAVLinkProtocol::MAVLinkProtocol() :
m_loggingEnabled(false),
m_logfile(NULL),
m_enable_version_check(true),
+ m_paramRetransmissionTimeout(350),
+ m_paramRewriteTimeout(500),
+ m_paramGuardEnabled(true),
versionMismatchIgnore(false),
systemId(QGC::defaultSystemId)
{
@@ -95,6 +98,14 @@ void MAVLinkProtocol::loadSettings()
{
systemId = temp;
}
+
+ // Parameter interface settings
+ bool ok;
+ temp = settings.value("PARAMETER_RETRANSMISSION_TIMEOUT", m_paramRetransmissionTimeout).toInt(&ok);
+ if (ok) m_paramRetransmissionTimeout = temp;
+ temp = settings.value("PARAMETER_REWRITE_TIMEOUT", m_paramRewriteTimeout).toInt(&ok);
+ if (ok) m_paramRewriteTimeout = temp;
+ m_paramGuardEnabled = settings.value("PARAMETER_TRANSMISSION_GUARD_ENABLED", m_paramGuardEnabled).toBool();
settings.endGroup();
}
@@ -113,6 +124,10 @@ void MAVLinkProtocol::storeSettings()
// Logfile exists, store the name
settings.setValue("LOGFILE_NAME", m_logfile->fileName());
}
+ // Parameter interface settings
+ settings.setValue("PARAMETER_RETRANSMISSION_TIMEOUT", m_paramRetransmissionTimeout);
+ settings.setValue("PARAMETER_REWRITE_TIMEOUT", m_paramRewriteTimeout);
+ settings.setValue("PARAMETER_TRANSMISSION_GUARD_ENABLED", m_paramGuardEnabled);
settings.endGroup();
settings.sync();
//qDebug() << "Storing settings!";
@@ -418,6 +433,33 @@ void MAVLinkProtocol::enableMultiplexing(bool enabled)
if (changed) emit multiplexingChanged(m_multiplexingEnabled);
}
+void MAVLinkProtocol::enableParamGuard(bool enabled)
+{
+ if (enabled != m_paramGuardEnabled)
+ {
+ m_paramGuardEnabled = enabled;
+ emit paramGuardChanged(m_paramGuardEnabled);
+ }
+}
+
+void MAVLinkProtocol::setParamRetransmissionTimeout(int ms)
+{
+ if (ms != m_paramRetransmissionTimeout)
+ {
+ m_paramRetransmissionTimeout = ms;
+ emit paramRetransmissionTimeoutChanged(m_paramRetransmissionTimeout);
+ }
+}
+
+void MAVLinkProtocol::setParamRewriteTimeout(int ms)
+{
+ if (ms != m_paramRewriteTimeout)
+ {
+ m_paramRewriteTimeout = ms;
+ emit paramRewriteTimeoutChanged(m_paramRewriteTimeout);
+ }
+}
+
void MAVLinkProtocol::enableLogging(bool enabled)
{
bool changed = false;
diff --git a/src/comm/MAVLinkProtocol.h b/src/comm/MAVLinkProtocol.h
index eaa8c10c9d2d918a3bb51db3b0735621ce2eb5f2..fc6e1d923169b5bf60428e67910c8abc4fdb8646 100644
--- a/src/comm/MAVLinkProtocol.h
+++ b/src/comm/MAVLinkProtocol.h
@@ -77,6 +77,12 @@ public:
int getVersion() { return MAVLINK_VERSION; }
/** @brief Get the name of the packet log file */
QString getLogfileName();
+ /** @brief Enable / disable parameter retransmission */
+ bool paramGuardEnabled() { return m_paramGuardEnabled; }
+ /** @brief Set parameter read timeout */
+ int getParamRetransmissionTimeout() { return m_paramRetransmissionTimeout; }
+ /** @brief Set parameter wrtie timeout */
+ int getParamRewriteTimeout() { return m_paramRewriteTimeout; }
public slots:
/** @brief Receive bytes from a communication interface */
@@ -99,6 +105,15 @@ public slots:
/** @brief Enabled/disable packet multiplexing */
void enableMultiplexing(bool enabled);
+ /** @brief Enable / disable parameter retransmission */
+ void enableParamGuard(bool enabled);
+
+ /** @brief Set parameter read timeout */
+ void setParamRetransmissionTimeout(int ms);
+
+ /** @brief Set parameter write timeout */
+ void setParamRewriteTimeout(int ms);
+
/** @brief Set log file name */
void setLogfileName(const QString& filename);
@@ -121,6 +136,9 @@ protected:
bool m_multiplexingEnabled; ///< Enable/disable packet multiplexing
QFile* m_logfile; ///< Logfile
bool m_enable_version_check; ///< Enable checking of version match of MAV and QGC
+ int m_paramRetransmissionTimeout; ///< Timeout for parameter retransmission
+ int m_paramRewriteTimeout; ///< Timeout for sending re-write request
+ bool m_paramGuardEnabled; ///< Retransmission/rewrite enabled
QMutex receiveMutex; ///< Mutex to protect receiveBytes function
int lastIndex[256][256];
int totalReceiveCounter;
@@ -143,6 +161,14 @@ signals:
void versionCheckChanged(bool enabled);
/** @brief Emitted if a message from the protocol should reach the user */
void protocolStatusMessage(const QString& title, const QString& message);
+ /** @brief Emitted if a new system ID was set */
+ void systemIdChanged(int systemId);
+ /** @brief Emitted if param guard status changed */
+ void paramGuardChanged(bool enabled);
+ /** @brief Emitted if param read timeout changed */
+ void paramRetransmissionTimeoutChanged(int ms);
+ /** @brief Emitted if param write timeout changed */
+ void paramRewriteTimeoutChanged(int ms);
};
#endif // MAVLINKPROTOCOL_H_
diff --git a/src/ui/MAVLinkSettingsWidget.cc b/src/ui/MAVLinkSettingsWidget.cc
index a96dc023ed4f0c26dc4db267cbabee7e8207ab4e..ebea16af042fec91ed44a6b0dbbf8aad5d6811ac 100644
--- a/src/ui/MAVLinkSettingsWidget.cc
+++ b/src/ui/MAVLinkSettingsWidget.cc
@@ -50,17 +50,35 @@ MAVLinkSettingsWidget::MAVLinkSettingsWidget(MAVLinkProtocol* protocol, QWidget
m_ui->versionCheckBox->setChecked(protocol->versionCheckEnabled());
m_ui->multiplexingCheckBox->setChecked(protocol->multiplexingEnabled());
m_ui->systemIdSpinBox->setValue(protocol->getSystemId());
+ m_ui->paramGuardCheckBox->setChecked(protocol->paramGuardEnabled());
+ m_ui->paramRetransmissionSpinBox->setValue(protocol->getParamRetransmissionTimeout());
+ m_ui->paramRewriteSpinBox->setValue(protocol->getParamRewriteTimeout());
// Connect actions
+ // Heartbeat
connect(protocol, SIGNAL(heartbeatChanged(bool)), m_ui->heartbeatCheckBox, SLOT(setChecked(bool)));
connect(m_ui->heartbeatCheckBox, SIGNAL(toggled(bool)), protocol, SLOT(enableHeartbeats(bool)));
+ // Logging
connect(protocol, SIGNAL(loggingChanged(bool)), m_ui->loggingCheckBox, SLOT(setChecked(bool)));
connect(m_ui->loggingCheckBox, SIGNAL(toggled(bool)), protocol, SLOT(enableLogging(bool)));
+ // Version check
connect(protocol, SIGNAL(versionCheckChanged(bool)), m_ui->versionCheckBox, SLOT(setChecked(bool)));
connect(m_ui->versionCheckBox, SIGNAL(toggled(bool)), protocol, SLOT(enableVersionCheck(bool)));
+ // Logfile
connect(m_ui->logFileButton, SIGNAL(clicked()), this, SLOT(chooseLogfileName()));
+ // System ID
+ connect(protocol, SIGNAL(systemIdChanged(int)), m_ui->systemIdSpinBox, SLOT(setValue(int)));
connect(m_ui->systemIdSpinBox, SIGNAL(valueChanged(int)), protocol, SLOT(setSystemId(int)));
+ // Multiplexing
+ connect(protocol, SIGNAL(multiplexingChanged(bool)), m_ui->multiplexingCheckBox, SLOT(setChecked(bool)));
connect(m_ui->multiplexingCheckBox, SIGNAL(toggled(bool)), protocol, SLOT(enableMultiplexing(bool)));
+ // Parameter guard
+ connect(protocol, SIGNAL(paramGuardChanged(bool)), m_ui->paramGuardCheckBox, SLOT(setChecked(bool)));
+ connect(m_ui->paramGuardCheckBox, SIGNAL(toggled(bool)), protocol, SLOT(enableParamGuard(bool)));
+ connect(protocol, SIGNAL(paramRetransmissionTimeoutChanged(int)), m_ui->paramRetransmissionSpinBox, SLOT(setValue(int)));
+ connect(m_ui->paramRetransmissionSpinBox, SIGNAL(valueChanged(int)), protocol, SLOT(setParamRetransmissionTimeout(int)));
+ connect(protocol, SIGNAL(paramRewriteTimeoutChanged(int)), m_ui->paramRewriteSpinBox, SLOT(setValue(int)));
+ connect(m_ui->paramRewriteSpinBox, SIGNAL(valueChanged(int)), protocol, SLOT(setParamRewriteTimeout(int)));
// Update values
m_ui->versionLabel->setText(tr("MAVLINK_VERSION: %1").arg(protocol->getVersion()));
@@ -71,24 +89,35 @@ MAVLinkSettingsWidget::MAVLinkSettingsWidget(MAVLinkProtocol* protocol, QWidget
m_ui->versionLabel->setVisible(protocol->versionCheckEnabled());
//connect(m_ui->versionCheckBox, SIGNAL(toggled(bool)), m_ui->versionSpacer, SLOT(setVisible(bool)));
//connect(m_ui->loggingCheckBox, SIGNAL(toggled(bool)), m_ui->logFileSpacer, SLOT(setVisible(bool)));
+ // Logging visibility
connect(protocol, SIGNAL(loggingChanged(bool)), m_ui->logFileLabel, SLOT(setVisible(bool)));
m_ui->logFileLabel->setVisible(protocol->loggingEnabled());
connect(protocol, SIGNAL(loggingChanged(bool)), m_ui->logFileButton, SLOT(setVisible(bool)));
m_ui->logFileButton->setVisible(protocol->loggingEnabled());
- connect(protocol, SIGNAL(multiplexingChanged(bool)), m_ui->multiplexingFilterCheckBox, SLOT(setVisible(bool)));
- m_ui->multiplexingFilterCheckBox->setVisible(protocol->multiplexingEnabled());
- connect(protocol, SIGNAL(multiplexingChanged(bool)), m_ui->multiplexingFilterLineEdit, SLOT(setVisible(bool)));
- m_ui->multiplexingFilterLineEdit->setVisible(protocol->multiplexingEnabled());
+// // Multiplexing visibility
+// connect(protocol, SIGNAL(multiplexingChanged(bool)), m_ui->multiplexingFilterCheckBox, SLOT(setVisible(bool)));
+// m_ui->multiplexingFilterCheckBox->setVisible(protocol->multiplexingEnabled());
+// connect(protocol, SIGNAL(multiplexingChanged(bool)), m_ui->multiplexingFilterLineEdit, SLOT(setVisible(bool)));
+// m_ui->multiplexingFilterLineEdit->setVisible(protocol->multiplexingEnabled());
+ // Param guard visibility
+ connect(protocol, SIGNAL(paramGuardChanged(bool)), m_ui->paramRetransmissionSpinBox, SLOT(setVisible(bool)));
+ m_ui->paramRetransmissionSpinBox->setVisible(protocol->paramGuardEnabled());
+ connect(protocol, SIGNAL(paramGuardChanged(bool)), m_ui->paramRetransmissionLabel, SLOT(setVisible(bool)));
+ m_ui->paramRetransmissionLabel->setVisible(protocol->paramGuardEnabled());
+ connect(protocol, SIGNAL(paramGuardChanged(bool)), m_ui->paramRewriteSpinBox, SLOT(setVisible(bool)));
+ m_ui->paramRewriteSpinBox->setVisible(protocol->paramGuardEnabled());
+ connect(protocol, SIGNAL(paramGuardChanged(bool)), m_ui->paramRewriteLabel, SLOT(setVisible(bool)));
+ m_ui->paramRewriteLabel->setVisible(protocol->paramGuardEnabled());
// TODO implement filtering
// and then remove these two lines
m_ui->multiplexingFilterCheckBox->setVisible(false);
m_ui->multiplexingFilterLineEdit->setVisible(false);
- // Update settings
- m_ui->loggingCheckBox->setChecked(protocol->loggingEnabled());
- m_ui->heartbeatCheckBox->setChecked(protocol->heartbeatsEnabled());
- m_ui->versionCheckBox->setChecked(protocol->versionCheckEnabled());
+// // Update settings
+// m_ui->loggingCheckBox->setChecked(protocol->loggingEnabled());
+// m_ui->heartbeatCheckBox->setChecked(protocol->heartbeatsEnabled());
+// m_ui->versionCheckBox->setChecked(protocol->versionCheckEnabled());
}
void MAVLinkSettingsWidget::updateLogfileName(const QString& fileName)
@@ -132,7 +161,8 @@ MAVLinkSettingsWidget::~MAVLinkSettingsWidget()
void MAVLinkSettingsWidget::changeEvent(QEvent *e)
{
QWidget::changeEvent(e);
- switch (e->type()) {
+ switch (e->type())
+ {
case QEvent::LanguageChange:
m_ui->retranslateUi(this);
break;
@@ -140,3 +170,9 @@ void MAVLinkSettingsWidget::changeEvent(QEvent *e)
break;
}
}
+
+void MAVLinkSettingsWidget::hideEvent(QHideEvent* event)
+{
+ Q_UNUSED(event);
+ protocol->storeSettings();
+}
diff --git a/src/ui/MAVLinkSettingsWidget.h b/src/ui/MAVLinkSettingsWidget.h
index c6f28c7b913abd76dd5a5bc44c2244282591d3e3..c1d99eb72ac2f0cfdc648121c39ef9eb97818c1f 100644
--- a/src/ui/MAVLinkSettingsWidget.h
+++ b/src/ui/MAVLinkSettingsWidget.h
@@ -24,6 +24,7 @@ public slots:
protected:
MAVLinkProtocol* protocol;
void changeEvent(QEvent *e);
+ void hideEvent(QHideEvent* event);
private:
Ui::MAVLinkSettingsWidget *m_ui;
diff --git a/src/ui/MAVLinkSettingsWidget.ui b/src/ui/MAVLinkSettingsWidget.ui
index 8b1db6f6c1e2ca59d40b7e1d7d6356639825966b..665a21575099ec72bed9419f5bc0a2f93c7b1b7a 100644
--- a/src/ui/MAVLinkSettingsWidget.ui
+++ b/src/ui/MAVLinkSettingsWidget.ui
@@ -7,7 +7,7 @@
0
0
431
- 256
+ 349
@@ -151,6 +151,100 @@
+ -
+
+
+ Enable retransmission of parameter read/write requests
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 8
+ 0
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 8
+ 0
+
+
+
+
+ -
+
+
+ Read request retransmission timeout
+
+
+
+ -
+
+
+ Write request retransmission timeout
+
+
+
+ -
+
+
+ Time in milliseconds after which a not acknowledged read request is sent again.
+
+
+ Time in milliseconds after which a not acknowledged read request is sent again.
+
+
+ ms
+
+
+ 50
+
+
+ 60000
+
+
+ 50
+
+
+ 50
+
+
+
+ -
+
+
+ Time in milliseconds after which a not acknowledged write request is sent again.
+
+
+ Time in milliseconds after which a not acknowledged write request is sent again.
+
+
+ ms
+
+
+ 50
+
+
+ 60000
+
+
+ 50
+
+
+
diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc
index 9fdbf365e493f3fe986ccbfe7ae044d6afc293f5..ee32126b678784d994a122442fbd527c6db70b20 100644
--- a/src/ui/MainWindow.cc
+++ b/src/ui/MainWindow.cc
@@ -1339,6 +1339,7 @@ void MainWindow::connectCommonActions()
// Audio output
ui.actionMuteAudioOutput->setChecked(GAudioOutput::instance()->isMuted());
+ connect(GAudioOutput::instance(), SIGNAL(mutedChanged(bool)), ui.actionMuteAudioOutput, SLOT(setChecked(bool)));
connect(ui.actionMuteAudioOutput, SIGNAL(triggered(bool)), GAudioOutput::instance(), SLOT(mute(bool)));
// User interaction
diff --git a/src/ui/QGCParamWidget.cc b/src/ui/QGCParamWidget.cc
index a8f8ff713a167e136e86389f87b268f2c9c12657..d826b9cf3d04ad34516189f52fc1a50b731bef66 100644
--- a/src/ui/QGCParamWidget.cc
+++ b/src/ui/QGCParamWidget.cc
@@ -31,6 +31,7 @@ This file is part of the QGROUNDCONTROL project
#include
#include
#include
+#include
#include "QGCParamWidget.h"
#include "UASInterface.h"
@@ -51,8 +52,13 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) :
parameters(),
transmissionListMode(false),
transmissionActive(false),
- transmissionStarted(0)
+ transmissionStarted(0),
+ retransmissionTimeout(350),
+ rewriteTimeout(500)
{
+ // Load settings
+ loadSettings();
+
// Create tree widget
tree = new QTreeWidget(this);
statusLabel = new QLabel();
@@ -134,6 +140,18 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) :
connect(&retransmissionTimer, SIGNAL(timeout()), this, SLOT(retransmissionGuardTick()));
}
+void QGCParamWidget::loadSettings()
+{
+ QSettings settings;
+ settings.beginGroup("QGC_MAVLINK_PROTOCOL");
+ bool ok;
+ int temp = settings.value("PARAMETER_RETRANSMISSION_TIMEOUT", retransmissionTimeout).toInt(&ok);
+ if (ok) retransmissionTimeout = temp;
+ temp = settings.value("PARAMETER_REWRITE_TIMEOUT", rewriteTimeout).toInt(&ok);
+ if (ok) rewriteTimeout = temp;
+ settings.endGroup();
+}
+
/**
* @return The MAV of this widget. Unless the MAV object has been destroyed, this
* pointer is never zero.
@@ -380,6 +398,13 @@ void QGCParamWidget::addParameter(int uas, int component, QString parameterName,
*/
void QGCParamWidget::requestParameterList()
{
+ // FIXME This call does not belong here
+ // Once the comm handling is moved to a new
+ // Param manager class the settings can be directly
+ // loaded from MAVLink protocol
+ loadSettings();
+ // End of FIXME
+
// Clear view and request param list
clear();
parameters.clear();
diff --git a/src/ui/QGCParamWidget.h b/src/ui/QGCParamWidget.h
index db7bc25597b16d86bb6221fb114202e59731936d..2a427855cdaae4769fcb39a1ece6d1f5d5835e02 100644
--- a/src/ui/QGCParamWidget.h
+++ b/src/ui/QGCParamWidget.h
@@ -94,15 +94,19 @@ protected:
QMap* > parameters; ///< All parameters
QVector received; ///< Successfully received parameters
QMap* > transmissionMissingPackets; ///< Missing packets
+ QMap* > transmissionMissingWriteAckPackets; ///< Missing write ACK packets
bool transmissionListMode; ///< Currently requesting list
QMap transmissionListSizeKnown; ///< List size initialized?
bool transmissionActive; ///< Missing packets, working on list?
quint64 transmissionStarted; ///< Timeout
QTimer retransmissionTimer; ///< Timer handling parameter retransmission
- const static int retransmissionTimeout = 250; ///< Retransmission request timeout, in milliseconds
+ int retransmissionTimeout; ///< Retransmission request timeout, in milliseconds
+ int rewriteTimeout; ///< Write request timeout, in milliseconds
/** @brief Activate / deactivate parameter retransmission */
void setRetransmissionGuardEnabled(bool enabled);
+ /** @brief Load settings */
+ void loadSettings();
};
#endif // QGCPARAMWIDGET_H
diff --git a/src/ui/QGCSettingsWidget.cc b/src/ui/QGCSettingsWidget.cc
index 78ddf8c5ea6fa4c1ad91363ec50b67a3281f8b42..706ff207a57f1d83dfe539df68479d185321b43f 100644
--- a/src/ui/QGCSettingsWidget.cc
+++ b/src/ui/QGCSettingsWidget.cc
@@ -4,6 +4,7 @@
#include "LinkManager.h"
#include "MAVLinkProtocol.h"
#include "MAVLinkSettingsWidget.h"
+#include "GAudioOutput.h"
//, Qt::WindowFlags flags
@@ -27,8 +28,16 @@ QGCSettingsWidget::QGCSettingsWidget(QWidget *parent, Qt::WindowFlags flags) :
this->window()->setWindowTitle(tr("QGroundControl Settings"));
+ // Audio preferences
+ ui->audioMuteCheckBox->setChecked(GAudioOutput::instance()->isMuted());
+ connect(ui->audioMuteCheckBox, SIGNAL(toggled(bool)), GAudioOutput::instance(), SLOT(mute(bool)));
+ connect(GAudioOutput::instance(), SIGNAL(mutedChanged(bool)), ui->audioMuteCheckBox, SLOT(setChecked(bool)));
+
// Close / destroy
connect(ui->buttonBox, SIGNAL(accepted()), this, SLOT(deleteLater()));
+
+ // Set layout options
+ ui->generalPaneGridLayout->setAlignment(Qt::AlignTop);
}
QGCSettingsWidget::~QGCSettingsWidget()
diff --git a/src/ui/QGCSettingsWidget.ui b/src/ui/QGCSettingsWidget.ui
index 8b0bef6fffc28894572cad6ac07a3a9cfe6c0042..f389c943a45c0e982c36cd363dfb5bbd38f046df 100644
--- a/src/ui/QGCSettingsWidget.ui
+++ b/src/ui/QGCSettingsWidget.ui
@@ -15,7 +15,29 @@
-
-
+
+
+
+ General
+
+
+ General Settings
+
+
+
-
+
+
+ Mute all audio output
+
+
+
+ :/images/status/audio-volume-muted.svg:/images/status/audio-volume-muted.svg
+
+
+
+
+
+
-
@@ -29,7 +51,9 @@
-
+
+
+
buttonBox