diff options
-rw-r--r-- | src/mumble/CMakeLists.txt | 3 | ||||
-rw-r--r-- | src/mumble/MainWindow.cpp | 134 | ||||
-rw-r--r-- | src/mumble/ServerInformation.cpp | 199 | ||||
-rw-r--r-- | src/mumble/ServerInformation.h | 37 | ||||
-rw-r--r-- | src/mumble/ServerInformation.ui | 643 |
5 files changed, 885 insertions, 131 deletions
diff --git a/src/mumble/CMakeLists.txt b/src/mumble/CMakeLists.txt index 96266ee8f..e90272181 100644 --- a/src/mumble/CMakeLists.txt +++ b/src/mumble/CMakeLists.txt @@ -176,6 +176,9 @@ set(MUMBLE_SOURCES "Screen.h" "ServerHandler.cpp" "ServerHandler.h" + "ServerInformation.cpp" + "ServerInformation.h" + "ServerInformation.ui" "Settings.cpp" "Settings.h" "SharedMemory.cpp" diff --git a/src/mumble/MainWindow.cpp b/src/mumble/MainWindow.cpp index 1b7723ed4..6d955c9d6 100644 --- a/src/mumble/MainWindow.cpp +++ b/src/mumble/MainWindow.cpp @@ -39,6 +39,7 @@ #include "SSLCipherInfo.h" #include "Screen.h" #include "ServerHandler.h" +#include "ServerInformation.h" #include "Settings.h" #include "SvgIcon.h" #include "TalkingUI.h" @@ -1403,138 +1404,9 @@ void MainWindow::on_qaServerUserList_triggered() { } } -static const QString currentCodec() { - if (Global::get().bOpus) - return QLatin1String("Opus"); - - int v = Global::get().bPreferAlpha ? Global::get().iCodecAlpha : Global::get().iCodecBeta; - CELTCodec *cc = Global::get().qmCodecs.value(v); - if (cc) - return QString::fromLatin1("CELT %1").arg(cc->version()); - else - return QString::fromLatin1("CELT %1").arg(QString::number(v, 16)); -} - void MainWindow::on_qaServerInformation_triggered() { - ConnectionPtr c = Global::get().sh->cConnection; - - if (!c) - return; - - QSslCipher qsc = Global::get().sh->qscCipher; - - QString qsVersion = tr("<h2>Version</h2><p>Protocol %1</p>").arg(MumbleVersion::toString(Global::get().sh->uiVersion)); - - if (Global::get().sh->qsRelease.isEmpty() || Global::get().sh->qsOS.isEmpty() || Global::get().sh->qsOSVersion.isEmpty()) { - qsVersion.append(tr("<p>No build information or OS version available</p>")); - } else { - qsVersion.append( - tr("<p>%1 (%2)<br />%3</p>") - .arg(Global::get().sh->qsRelease.toHtmlEscaped(), Global::get().sh->qsOS.toHtmlEscaped(), Global::get().sh->qsOSVersion.toHtmlEscaped())); - } - - QString host, uname, pw; - unsigned short port; - - Global::get().sh->getConnectionInfo(host, port, uname, pw); - - const SSLCipherInfo *ci = SSLCipherInfoLookupByOpenSSLName(qsc.name().toLatin1().constData()); - - QString cipherDescription; - if (ci && ci->message_authentication && ci->encryption && ci->key_exchange_verbose && ci->rfc_name) { - if (QString::fromLatin1(ci->message_authentication) == QLatin1String("AEAD")) { - // Authenticated Encryption with Associated Data - // See https://en.wikipedia.org/wiki/Authenticated_encryption - cipherDescription = - tr("The connection is encrypted and authenticated " - "using %1 and uses %2 as the key exchange mechanism (%3)") - .arg(QString::fromLatin1(ci->encryption), QString::fromLatin1(ci->key_exchange_verbose), - QString::fromLatin1(ci->rfc_name)); - } else { - cipherDescription = - tr("The connection is encrypted using %1, with %2 " - "for message authentication and %3 as the key " - "exchange mechanism (%4)") - .arg(QString::fromLatin1(ci->encryption), QString::fromLatin1(ci->message_authentication), - QString::fromLatin1(ci->key_exchange_verbose), QString::fromLatin1(ci->rfc_name)); - } - } - if (cipherDescription.isEmpty()) { - cipherDescription = - tr("The connection is secured by the cipher suite that OpenSSL identifies as %1").arg(qsc.name()); - } - - QString cipherPFSInfo; - if (ci) { - if (ci->forward_secret) { - cipherPFSInfo = tr("<p>The connection provides perfect forward secrecy</p>"); - } else { - cipherPFSInfo = tr("<p>The connection does not provide perfect forward secrecy</p>"); - } - } - - QString qsControl = - tr("<h2>Control channel</h2>" - "<p>The connection uses %1</p>" - "%2" - "%3" - "<p>%4 ms average latency (%5 deviation)</p>" - "<p>Remote host %6 (port %7)</p>") - .arg(c->sessionProtocolString().toHtmlEscaped(), cipherDescription, cipherPFSInfo, - QString::fromLatin1("%1").arg(boost::accumulators::mean(Global::get().sh->accTCP), 0, 'f', 2), - QString::fromLatin1("%1").arg(sqrt(boost::accumulators::variance(Global::get().sh->accTCP)), 0, 'f', 2), - host.toHtmlEscaped(), QString::number(port)); - if (Global::get().uiMaxUsers) { - qsControl += tr("<p>Connected users: %1/%2</p>").arg(ModelItem::c_qhUsers.count()).arg(Global::get().uiMaxUsers); - } - - QString qsVoice, qsCrypt, qsAudio; - - if (NetworkConfig::TcpModeEnabled()) { - qsVoice = tr("Voice channel is sent over control channel"); - } else { - qsVoice = tr("<h2>Voice channel</h2><p>Encrypted with 128 bit OCB-AES128<br />%1 ms average latency (%4 " - "deviation)</p>") - .arg(boost::accumulators::mean(Global::get().sh->accUDP), 0, 'f', 2) - .arg(sqrt(boost::accumulators::variance(Global::get().sh->accUDP)), 0, 'f', 2); - qsCrypt = QString::fromLatin1("<h2>%1</h2><table><tr><th></th><th>%2</th><th>%3</th></tr>" - "<tr><th>%4</th><td>%8</td><td>%12</td></tr>" - "<tr><th>%5</th><td>%9</td><td>%13</td></tr>" - "<tr><th>%6</th><td>%10</td><td>%14</td></tr>" - "<tr><th>%7</th><td>%11</td><td>%15</td></tr>" - "</table>") - .arg(tr("UDP Statistics")) - .arg(tr("To Server")) - .arg(tr("From Server")) - .arg(tr("Good")) - .arg(tr("Late")) - .arg(tr("Lost")) - .arg(tr("Resync")) - .arg(c->csCrypt->uiRemoteGood) - .arg(c->csCrypt->uiRemoteLate) - .arg(c->csCrypt->uiRemoteLost) - .arg(c->csCrypt->uiRemoteResync) - .arg(c->csCrypt->uiGood) - .arg(c->csCrypt->uiLate) - .arg(c->csCrypt->uiLost) - .arg(c->csCrypt->uiResync); - } - qsAudio = tr("<h2>Audio bandwidth</h2><p>Maximum %1 kbit/s<br />Current %2 kbit/s<br />Codec: %3</p>") - .arg(Global::get().iMaxBandwidth / 1000.0, 0, 'f', 1) - .arg(Global::get().iAudioBandwidth / 1000.0, 0, 'f', 1) - .arg(currentCodec()); - - QMessageBox qmb(QMessageBox::Information, tr("Mumble Server Information"), - qsVersion + qsControl + qsVoice + qsCrypt + qsAudio, QMessageBox::Ok, this); - qmb.setDefaultButton(QMessageBox::Ok); - qmb.setEscapeButton(QMessageBox::Ok); - - QPushButton *qp = qmb.addButton(tr("&View Certificate"), QMessageBox::ActionRole); - int res = qmb.exec(); - if ((res == 0) && (qmb.clickedButton() == qp)) { - ViewCert vc(Global::get().sh->qscCert, this); - vc.exec(); - } + ServerInformation *infoDialog = new ServerInformation(this); + infoDialog->show(); } void MainWindow::on_qaServerTexture_triggered() { diff --git a/src/mumble/ServerInformation.cpp b/src/mumble/ServerInformation.cpp new file mode 100644 index 000000000..dd8e41278 --- /dev/null +++ b/src/mumble/ServerInformation.cpp @@ -0,0 +1,199 @@ +// Copyright 2021 The Mumble Developers. All rights reserved. +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file at the root of the +// Mumble source tree or at <https://www.mumble.info/LICENSE>. + +#include "ServerInformation.h" +#include "CELTCodec.h" +#include "Connection.h" +#include "MainWindow.h" +#include "NetworkConfig.h" +#include "SSL.h" +#include "SSLCipherInfo.h" +#include "ServerHandler.h" +#include "UserModel.h" +#include "Version.h" +#include "ViewCert.h" +#include "Global.h" + +#include <QTableWidgetItem> + +#include <boost/accumulators/accumulators.hpp> + +#include <cmath> + +QString ServerInformation::m_unknownStr = tr("Unknown"); + +ServerInformation::ServerInformation(QWidget *parent) : QDialog(parent) { + setupUi(this); + + updateFields(); +} + +void ServerInformation::updateFields() { + updateServerInformation(); + updateAudioBandwidth(); + updateConnectionDetails(); +} + +void ServerInformation::on_okButton_clicked() { + accept(); +} + +void ServerInformation::on_viewCertButton_clicked() { + hide(); + + ViewCert certViewer(Global::get().sh->qscCert, this); + certViewer.exec(); + + accept(); +} + +void ServerInformation::updateServerInformation() { + QString host, userName, password; + unsigned short port; + + Global::get().sh->getConnectionInfo(host, port, userName, password); + + const int userCount = ModelItem::c_qhUsers.count(); + const unsigned int maxUserCount = Global::get().uiMaxUsers; + + QString release = Global::get().sh->qsRelease; + if (release.isEmpty()) { + release = m_unknownStr; + } + QString os = Global::get().sh->qsOS; + if (os.isEmpty()) { + os = m_unknownStr; + } else if (!Global::get().sh->qsOSVersion.isEmpty()) { + os += QString::fromLatin1(" (%1)").arg(Global::get().sh->qsOSVersion); + } + + serverInfo_host->setText(host); + serverInfo_port->setText(QString::number(port)); + serverInfo_users->setText(QString::fromLatin1("%1 / %2").arg(userCount).arg(maxUserCount)); + serverInfo_protocol->setText(MumbleVersion::toString(Global::get().sh->uiVersion)); + serverInfo_release->setText(release); + serverInfo_os->setText(os); +} + +static const QString currentCodec() { + if (Global::get().bOpus) + return QLatin1String("Opus"); + + int v = Global::get().bPreferAlpha ? Global::get().iCodecAlpha : Global::get().iCodecBeta; + CELTCodec *cc = Global::get().qmCodecs.value(v); + if (cc) + return QString::fromLatin1("CELT %1").arg(cc->version()); + else + return QString::fromLatin1("CELT %1").arg(QString::number(v, 16)); +} + +void ServerInformation::updateAudioBandwidth() { + // The bandwidths are in bit/s, so we divide by 1000 to get kBit/s + const float maxBandwidthAllowed = Global::get().iMaxBandwidth / 1000.0f; + const float currentBandwidth = Global::get().iAudioBandwidth / 1000.0f; + + audio_current->setText(QString::fromLatin1("%1 kBit/s").arg(currentBandwidth, 0, 'f', 1)); + audio_allowed->setText(QString::fromLatin1("%1 kBit/s").arg(maxBandwidthAllowed, 0, 'f', 1)); + audio_codec->setText(currentCodec()); +} + +QString getCipherID(const QSslCipher &cipher, const SSLCipherInfo *cipherInfo) { + if (cipherInfo && cipherInfo->rfc_name) { + return QString::fromUtf8(cipherInfo->rfc_name); + } + + return cipher.name(); +} + +void ServerInformation::updateConnectionDetails() { + QString latencyString = QString::fromUtf8("%1 ms (σ = %2 ms)"); + const ConnectionPtr connection = Global::get().sh->cConnection; + + if (!connection) { + return; + } + + // UDP + if (NetworkConfig::TcpModeEnabled()) { + connection_udp_infoMessage->show(); + + connection_udp_encryption->hide(); + connection_udp_encryptionLabel->hide(); + connection_udp_latency->hide(); + connection_udp_latencyLabel->hide(); + connection_udp_statisticsGroup->hide(); + } else { + connection_udp_infoMessage->hide(); + + connection_udp_encryption->show(); + connection_udp_encryptionLabel->show(); + connection_udp_latency->show(); + connection_udp_latencyLabel->show(); + connection_udp_statisticsGroup->show(); + + // Actually fill in data + const float latency = boost::accumulators::mean(Global::get().sh->accUDP); + const float deviation = std::sqrt(boost::accumulators::variance(Global::get().sh->accUDP)); + + connection_udp_encryption->setText("128 bit OCB-AES128"); + connection_udp_latency->setText(latencyString.arg(latency, 0, 'f', 1).arg(deviation, 0, 'f', 1)); + + populateUDPStatistics(*connection); + } + + + // TCP + const float latency = boost::accumulators::mean(Global::get().sh->accTCP); + const float deviation = std::sqrt(boost::accumulators::variance(Global::get().sh->accTCP)); + + QSslCipher cipher = Global::get().sh->qscCipher; + const SSLCipherInfo *cipherInfo = SSLCipherInfoLookupByOpenSSLName(cipher.name().toLatin1().constData()); + + const QString cipherID = getCipherID(cipher, cipherInfo); + + connection_tcp_tls->setText(MumbleSSL::protocolToString(connection->sessionProtocol()).toHtmlEscaped()); + connection_tcp_latency->setText(latencyString.arg(latency, 0, 'f', 1).arg(deviation, 0, 'f', 1)); + connection_tcp_cipher->setText(cipherID.isEmpty() ? m_unknownStr : cipherID); + + if (cipherInfo) { + if (cipherInfo->forward_secret) { + connection_tcp_forwardSecrecy->setText(tr("The connection provides perfect forward secrecy.")); + } else { + connection_tcp_forwardSecrecy->setText(tr("The connection does NOT provide perfect forward secrecy.")); + } + } else { + connection_tcp_forwardSecrecy->setText(tr("No information about forward secrecy available.")); + } +} + +void ServerInformation::populateUDPStatistics(const Connection &connection) { + // statistics + constexpr int toServerCol = 0; + constexpr int fromServerCol = 1; + constexpr int goodRow = 0; + constexpr int lateRow = 1; + constexpr int lostRow = 2; + constexpr int resyncRow = 3; + + QTableWidgetItem *toGoodItem = new QTableWidgetItem(QString::number(connection.csCrypt->uiRemoteGood)); + QTableWidgetItem *fromGoodItem = new QTableWidgetItem(QString::number(connection.csCrypt->uiGood)); + QTableWidgetItem *toLateItem = new QTableWidgetItem(QString::number(connection.csCrypt->uiRemoteLate)); + QTableWidgetItem *fromLateItem = new QTableWidgetItem(QString::number(connection.csCrypt->uiLate)); + QTableWidgetItem *toLostItem = new QTableWidgetItem(QString::number(connection.csCrypt->uiRemoteLost)); + QTableWidgetItem *fromLostItem = new QTableWidgetItem(QString::number(connection.csCrypt->uiLost)); + QTableWidgetItem *toResyncItem = new QTableWidgetItem(QString::number(connection.csCrypt->uiRemoteResync)); + QTableWidgetItem *fromResyncItem = new QTableWidgetItem(QString::number(connection.csCrypt->uiResync)); + + connection_udp_statisticsTable->setItem(goodRow, toServerCol, toGoodItem); + connection_udp_statisticsTable->setItem(goodRow, fromServerCol, fromGoodItem); + connection_udp_statisticsTable->setItem(lateRow, toServerCol, toLateItem); + connection_udp_statisticsTable->setItem(lateRow, fromServerCol, fromLateItem); + connection_udp_statisticsTable->setItem(lostRow, toServerCol, toLostItem); + connection_udp_statisticsTable->setItem(lostRow, fromServerCol, fromLostItem); + connection_udp_statisticsTable->setItem(resyncRow, toServerCol, toResyncItem); + connection_udp_statisticsTable->setItem(resyncRow, fromServerCol, fromResyncItem); + + connection_udp_statisticsTable->adjustSize(); +} diff --git a/src/mumble/ServerInformation.h b/src/mumble/ServerInformation.h new file mode 100644 index 000000000..41669b5d4 --- /dev/null +++ b/src/mumble/ServerInformation.h @@ -0,0 +1,37 @@ +// Copyright 2021 The Mumble Developers. All rights reserved. +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file at the root of the +// Mumble source tree or at <https://www.mumble.info/LICENSE>. + +#ifndef MUMBLE_MUMBLE_SERVERINFORMATION_H_ +#define MUMBLE_MUMBLE_SERVERINFORMATION_H_ + +#include <QDialog> + +#include "ui_ServerInformation.h" + +class Connection; + +class ServerInformation : public QDialog, private Ui::ServerInformation { + Q_OBJECT; + Q_DISABLE_COPY(ServerInformation); + +public: + ServerInformation(QWidget *parent = nullptr); + + void updateFields(); + +public slots: + void on_okButton_clicked(); + void on_viewCertButton_clicked(); + +private: + static QString m_unknownStr; + + void updateServerInformation(); + void updateAudioBandwidth(); + void updateConnectionDetails(); + void populateUDPStatistics(const Connection &connection); +}; + +#endif // MUMBLE_MUMBLE_SERVERINFORMATION_H_ diff --git a/src/mumble/ServerInformation.ui b/src/mumble/ServerInformation.ui new file mode 100644 index 000000000..ba274deda --- /dev/null +++ b/src/mumble/ServerInformation.ui @@ -0,0 +1,643 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>ServerInformation</class> + <widget class="QDialog" name="ServerInformation"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>578</width> + <height>585</height> + </rect> + </property> + <property name="windowTitle"> + <string>Server information</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <item> + <widget class="QScrollArea" name="scrollArea"> + <property name="widgetResizable"> + <bool>true</bool> + </property> + <widget class="QWidget" name="scrollAreaWidgetContents"> + <property name="geometry"> + <rect> + <x>0</x> + <y>-203</y> + <width>541</width> + <height>731</height> + </rect> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QGroupBox" name="qgbServerInformation"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Server Information</string> + </property> + <layout class="QFormLayout" name="formLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string><b>Host:</b></string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLabel" name="serverInfo_host"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string notr="true"><host></string> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string><html><head/><body><p><span style=" font-weight:600;">Port:</span></p></body></html></string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLabel" name="serverInfo_port"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string notr="true"><port></string> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string><b>Users</b>:</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QLabel" name="serverInfo_users"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string notr="true"><users></string> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="label_9"> + <property name="text"> + <string><html><head/><body><p><span style=" font-weight:600;">Protocol:</span></p></body></html></string> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QLabel" name="serverInfo_protocol"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string notr="true"><protocol></string> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item row="4" column="0"> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string><html><head/><body><p><span style=" font-weight:600;">Release:</span></p></body></html></string> + </property> + </widget> + </item> + <item row="4" column="1"> + <widget class="QLabel" name="serverInfo_release"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string notr="true"><release></string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item row="5" column="0"> + <widget class="QLabel" name="label_5"> + <property name="text"> + <string><html><head/><body><p><span style=" font-weight:600;">OS:</span></p></body></html></string> + </property> + </widget> + </item> + <item row="5" column="1"> + <widget class="QLabel" name="serverInfo_os"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string notr="true"><os></string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="qgbAudioBandwidth"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Audio</string> + </property> + <layout class="QFormLayout" name="formLayout_4"> + <item row="1" column="0"> + <widget class="QLabel" name="label_31"> + <property name="text"> + <string><html><head/><body><p><span style=" font-weight:600;">Allowed:</span></p></body></html></string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLabel" name="audio_allowed"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string notr="true"><allowed></string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="label_32"> + <property name="text"> + <string><b>Current:</b></string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLabel" name="audio_current"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string notr="true"><current></string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_33"> + <property name="text"> + <string><b>Codec:</b></string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QLabel" name="audio_codec"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string notr="true"><codec></string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="qgbConnectionDetails"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Connection details</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QTabWidget" name="tabWidget"> + <property name="tabPosition"> + <enum>QTabWidget::North</enum> + </property> + <property name="tabShape"> + <enum>QTabWidget::Rounded</enum> + </property> + <property name="currentIndex"> + <number>0</number> + </property> + <widget class="QWidget" name="tab_2"> + <attribute name="title"> + <string>UDP (Voice)</string> + </attribute> + <layout class="QFormLayout" name="formLayout_3"> + <item row="1" column="0"> + <widget class="QLabel" name="connection_udp_encryptionLabel"> + <property name="text"> + <string><b>Encryption:</b></string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLabel" name="connection_udp_encryption"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string notr="true"><encryption></string> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="connection_udp_latencyLabel"> + <property name="text"> + <string><b>Avg. latency:</b></string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QLabel" name="connection_udp_latency"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string notr="true"><latency></string> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item row="4" column="0" colspan="2"> + <widget class="QGroupBox" name="connection_udp_statisticsGroup"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Statistics</string> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_4"> + <property name="sizeConstraint"> + <enum>QLayout::SetDefaultConstraint</enum> + </property> + <item> + <widget class="QTableWidget" name="connection_udp_statisticsTable"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="verticalScrollBarPolicy"> + <enum>Qt::ScrollBarAlwaysOff</enum> + </property> + <property name="horizontalScrollBarPolicy"> + <enum>Qt::ScrollBarAlwaysOff</enum> + </property> + <property name="sizeAdjustPolicy"> + <enum>QAbstractScrollArea::AdjustToContents</enum> + </property> + <property name="editTriggers"> + <set>QAbstractItemView::NoEditTriggers</set> + </property> + <property name="selectionMode"> + <enum>QAbstractItemView::SingleSelection</enum> + </property> + <property name="verticalScrollMode"> + <enum>QAbstractItemView::ScrollPerPixel</enum> + </property> + <property name="horizontalScrollMode"> + <enum>QAbstractItemView::ScrollPerPixel</enum> + </property> + <property name="showGrid"> + <bool>true</bool> + </property> + <property name="cornerButtonEnabled"> + <bool>false</bool> + </property> + <row> + <property name="text"> + <string>Good</string> + </property> + </row> + <row> + <property name="text"> + <string>Late</string> + </property> + </row> + <row> + <property name="text"> + <string>Lost</string> + </property> + </row> + <row> + <property name="text"> + <string>Resync</string> + </property> + </row> + <column> + <property name="text"> + <string>Outgoing</string> + </property> + </column> + <column> + <property name="text"> + <string>Incoming</string> + </property> + </column> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>0</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </item> + <item row="0" column="0" colspan="2"> + <widget class="QLabel" name="connection_udp_infoMessage"> + <property name="text"> + <string>Voice packets is currently sent over TCP.</string> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item row="3" column="1"> + <spacer name="verticalSpacer_2"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>5</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + <widget class="QWidget" name="tab"> + <attribute name="title"> + <string>TCP (Control)</string> + </attribute> + <layout class="QFormLayout" name="formLayout_2"> + <item row="0" column="0"> + <widget class="QLabel" name="label_11"> + <property name="text"> + <string><b>TLS version:</b></string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLabel" name="connection_tcp_tls"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string notr="true"><TLS></string> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_13"> + <property name="text"> + <string><b>Cipher suite:</b></string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLabel" name="connection_tcp_cipher"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string notr="true"><Cipher></string> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_15"> + <property name="text"> + <string><b>Avg. latency:</b></string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QLabel" name="connection_tcp_latency"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string notr="true"><latency></string> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item row="4" column="0" colspan="2"> + <widget class="QLabel" name="connection_tcp_forwardSecrecy"> + <property name="text"> + <string><forward secrecy></string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item row="3" column="0" colspan="2"> + <spacer name="verticalSpacer_3"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Maximum</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>5</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="viewCertButton"> + <property name="text"> + <string>&View certificate</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="okButton"> + <property name="text"> + <string>&Ok</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> |