VirtualBox

Changeset 101327 in vbox for trunk/src


Ignore:
Timestamp:
Oct 2, 2023 11:48:39 AM (17 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
159327
Message:

FE/Qt: bugref:10513: Large rework for UIMachineSettingsSerial page; All the widgets are now unified into one UISerialSettingsEditor encapsulating functionality similarly to other pages/editors do.

Location:
trunk/src/VBox/Frontends/VirtualBox
Files:
2 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk

    r101278 r101327  
    925925        src/settings/editors/UIRecordingSettingsEditor.h \
    926926        src/settings/editors/UIScaleFactorEditor.h \
     927        src/settings/editors/UISerialSettingsEditor.h \
    927928        src/settings/editors/UISharedClipboardEditor.h \
    928929        src/settings/editors/UISharedFolderDetailsEditor.h \
     
    15131514        src/settings/editors/UIRecordingSettingsEditor.cpp \
    15141515        src/settings/editors/UIScaleFactorEditor.cpp \
     1516        src/settings/editors/UISerialSettingsEditor.cpp \
    15151517        src/settings/editors/UISharedClipboardEditor.cpp \
    15161518        src/settings/editors/UISharedFolderDetailsEditor.cpp \
  • trunk/src/VBox/Frontends/VirtualBox/src/settings/editors/UISerialSettingsEditor.cpp

    r101325 r101327  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UIMachineSettingsSerial class implementation.
     3 * VBox Qt GUI - UISerialSettingsEditor class implementation.
    44 */
    55
     
    3333#include <QLabel>
    3434#include <QLineEdit>
    35 #include <QRegularExpressionValidator>
    3635
    3736/* GUI includes: */
    38 #include "QITabWidget.h"
    3937#include "QIWidgetValidator.h"
    4038#include "UICommon.h"
    4139#include "UIConverter.h"
    42 #include "UIErrorString.h"
    43 #include "UIMachineSettingsSerial.h"
    44 #include "UITranslator.h"
     40#include "UISerialSettingsEditor.h"
    4541
    4642/* COM includes: */
    47 #include "CPlatformProperties.h"
    48 #include "CSerialPort.h"
    49 
    50 
    51 /** Machine settings: Serial Port tab data structure. */
    52 struct UIDataSettingsMachineSerialPort
    53 {
    54     /** Constructs data. */
    55     UIDataSettingsMachineSerialPort()
    56         : m_iSlot(-1)
    57         , m_fPortEnabled(false)
    58         , m_uIRQ(0)
    59         , m_uIOAddress(0)
    60         , m_hostMode(KPortMode_Disconnected)
    61         , m_fServer(false)
    62         , m_strPath(QString())
    63     {}
    64 
    65     /** Returns whether the @a other passed data is equal to this one. */
    66     bool equal(const UIDataSettingsMachineSerialPort &other) const
    67     {
    68         return true
    69                && (m_iSlot == other.m_iSlot)
    70                && (m_fPortEnabled == other.m_fPortEnabled)
    71                && (m_uIRQ == other.m_uIRQ)
    72                && (m_uIOAddress == other.m_uIOAddress)
    73                && (m_hostMode == other.m_hostMode)
    74                && (m_fServer == other.m_fServer)
    75                && (m_strPath == other.m_strPath)
    76                ;
    77     }
    78 
    79     /** Returns whether the @a other passed data is equal to this one. */
    80     bool operator==(const UIDataSettingsMachineSerialPort &other) const { return equal(other); }
    81     /** Returns whether the @a other passed data is different from this one. */
    82     bool operator!=(const UIDataSettingsMachineSerialPort &other) const { return !equal(other); }
    83 
    84     /** Holds the serial port slot number. */
    85     int        m_iSlot;
    86     /** Holds whether the serial port is enabled. */
    87     bool       m_fPortEnabled;
    88     /** Holds the serial port IRQ. */
    89     ulong      m_uIRQ;
    90     /** Holds the serial port IO address. */
    91     ulong      m_uIOAddress;
    92     /** Holds the serial port host mode. */
    93     KPortMode  m_hostMode;
    94     /** Holds whether the serial port is server. */
    95     bool       m_fServer;
    96     /** Holds the serial port path. */
    97     QString    m_strPath;
    98 };
    99 
    100 
    101 /** Machine settings: Serial page data structure. */
    102 struct UIDataSettingsMachineSerial
    103 {
    104     /** Constructs data. */
    105     UIDataSettingsMachineSerial() {}
    106 
    107     /** Returns whether the @a other passed data is equal to this one. */
    108     bool operator==(const UIDataSettingsMachineSerial & /* other */) const { return true; }
    109     /** Returns whether the @a other passed data is different from this one. */
    110     bool operator!=(const UIDataSettingsMachineSerial & /* other */) const { return false; }
    111 };
    112 
    113 
    114 /** Machine settings: Serial Port tab. */
    115 class UIMachineSettingsSerial : public QIWithRetranslateUI<QWidget>
    116 {
    117     Q_OBJECT;
    118 
    119 signals:
    120 
    121     /** Notifies about port changed. */
    122     void sigPortChanged();
    123     /** Notifies about path changed. */
    124     void sigPathChanged();
    125     /** Notifies about validity changed. */
    126     void sigValidityChanged();
    127 
    128 public:
    129 
    130     /** Constructs tab passing @a pParent to the base-class. */
    131     UIMachineSettingsSerial(UIMachineSettingsSerialPage *pParent);
    132 
    133     /** Loads port data from @a portCache. */
    134     void getPortDataFromCache(const UISettingsCacheMachineSerialPort &portCache);
    135     /** Saves port data to @a portCache. */
    136     void putPortDataToCache(UISettingsCacheMachineSerialPort &portCache);
    137 
    138     /** Performs validation, updates @a messages list if something is wrong. */
    139     bool validate(QList<UIValidationMessage> &messages);
    140 
    141     /** Configures tab order according to passed @a pWidget. */
    142     QWidget *setOrderAfter(QWidget *pWidget);
    143 
    144     /** Returns tab title. */
    145     QString tabTitle() const;
    146     /** Returns whether port is enabled. */
    147     bool isPortEnabled() const;
    148     /** Returns IRQ. */
    149     QString irq() const;
    150     /** Returns IO address. */
    151     QString ioAddress() const;
    152     /** Returns path. */
    153     QString path() const;
    154 
    155     /** Performs tab polishing. */
    156     void polishTab();
    157 
    158 protected:
    159 
    160     /** Handles translation event. */
    161     void retranslateUi();
    162 
    163 private slots:
    164 
    165     /** Handles port availability being toggled to @a fOn. */
    166     void sltHandlePortAvailabilityToggled(bool fOn);
    167     /** Handles port standard @a strOption being activated. */
    168     void sltHandlePortStandardOptionActivated(const QString &strOption);
    169     /** Handles port mode change to item with certain @a iIndex. */
    170     void sltHandlePortModeChange(int iIndex);
    171 
    172 private:
    173 
    174     /** Prepares all. */
    175     void prepare();
    176     /** Prepares widgets. */
    177     void prepareWidgets();
    178     /** Prepares connections. */
    179     void prepareConnections();
    180 
    181     /** Populates combo-boxes. */
    182     void populateComboboxes();
    183 
    184     /** Holds the parent page reference. */
    185     UIMachineSettingsSerialPage *m_pParent;
    186 
    187     /** Holds the port slot number. */
    188     int        m_iSlot;
    189     /** Holds the port mode. */
    190     KPortMode  m_enmPortMode;
    191 
    192     /** @name Widgets
    193      * @{ */
    194         /** Holds the port check-box instance. */
    195         QCheckBox *m_pCheckBoxPort;
    196         /** Holds the port settings widget instance. */
    197         QWidget   *m_pWidgetPortSettings;
    198         /** Holds the number label instance. */
    199         QLabel    *m_pLabelNumber;
    200         /** Holds the number combo instance. */
    201         QComboBox *m_pComboNumber;
    202         /** Holds the IRQ label instance. */
    203         QLabel    *m_pLabelIRQ;
    204         /** Holds the IRQ editor instance. */
    205         QLineEdit *m_pLineEditIRQ;
    206         /** Holds the IO address label instance. */
    207         QLabel    *m_pLabelIOAddress;
    208         /** Holds the IO address editor instance. */
    209         QLineEdit *m_pLineEditIOAddress;
    210         /** Holds the mode label instance. */
    211         QLabel    *m_pLabelMode;
    212         /** Holds the mode combo instance. */
    213         QComboBox *m_pComboMode;
    214         /** Holds the pipe check-box instance. */
    215         QCheckBox *m_pCheckBoxPipe;
    216         /** Holds the path label instance. */
    217         QLabel    *m_pLabelPath;
    218         /** Holds the path editor instance. */
    219         QLineEdit *m_pEditorPath;
    220     /** @} */
    221 };
    222 
    223 
    224 /*********************************************************************************************************************************
    225 *   Class UIMachineSettingsSerial implementation.                                                                                *
    226 *********************************************************************************************************************************/
    227 
    228 UIMachineSettingsSerial::UIMachineSettingsSerial(UIMachineSettingsSerialPage *pParent)
    229     : QIWithRetranslateUI<QWidget>(0)
    230     , m_pParent(pParent)
    231     , m_iSlot(-1)
    232     , m_enmPortMode(KPortMode_Max)
     43#include "CSystemProperties.h"
     44
     45
     46UISerialSettingsEditor::UISerialSettingsEditor(QWidget *pParent /* = 0 */)
     47    : UIEditor(pParent)
     48    , m_enmPortMode(KPortMode_Disconnected)
    23349    , m_pCheckBoxPort(0)
    23450    , m_pWidgetPortSettings(0)
     
    24864}
    24965
    250 void UIMachineSettingsSerial::getPortDataFromCache(const UISettingsCacheMachineSerialPort &portCache)
    251 {
    252     /* Get old data: */
    253     const UIDataSettingsMachineSerialPort &oldPortData = portCache.base();
    254 
    255     /* Load port number: */
    256     m_iSlot = oldPortData.m_iSlot;
    257 
    258     /* Load port data: */
     66void UISerialSettingsEditor::setPortOptionsAvailable(bool fAvailable)
     67{
    25968    if (m_pCheckBoxPort)
    260         m_pCheckBoxPort->setChecked(oldPortData.m_fPortEnabled);
     69        m_pCheckBoxPort->setEnabled(fAvailable);
     70    if (m_pLabelNumber)
     71        m_pLabelNumber->setEnabled(fAvailable);
    26172    if (m_pComboNumber)
    262         m_pComboNumber->setCurrentIndex(m_pComboNumber->findText(UITranslator::toCOMPortName(oldPortData.m_uIRQ, oldPortData.m_uIOAddress)));
     73        m_pComboNumber->setEnabled(fAvailable);
     74}
     75
     76void UISerialSettingsEditor::setPortEnabled(bool fEnabled)
     77{
     78    if (m_pCheckBoxPort)
     79    {
     80        const bool fIssueUpdateAnyway = m_pCheckBoxPort->isChecked() == fEnabled;
     81        m_pCheckBoxPort->setChecked(fEnabled);
     82        if (fIssueUpdateAnyway)
     83            sltHandlePortAvailabilityToggled(m_pCheckBoxPort->isChecked());
     84    }
     85}
     86
     87bool UISerialSettingsEditor::isPortEnabled() const
     88{
     89    return m_pCheckBoxPort ? m_pCheckBoxPort->isChecked() : false;
     90}
     91
     92void UISerialSettingsEditor::setIRQAndIOAddressOptionsAvailable(bool fAvailable)
     93{
     94    if (m_pLabelIRQ)
     95        m_pLabelIRQ->setEnabled(fAvailable);
    26396    if (m_pLineEditIRQ)
    264         m_pLineEditIRQ->setText(QString::number(oldPortData.m_uIRQ));
     97        m_pLineEditIRQ->setEnabled(fAvailable);
     98    if (m_pLabelIOAddress)
     99        m_pLabelIOAddress->setEnabled(fAvailable);
    265100    if (m_pLineEditIOAddress)
    266         m_pLineEditIOAddress->setText("0x" + QString::number(oldPortData.m_uIOAddress, 16).toUpper());
    267     m_enmPortMode = oldPortData.m_hostMode;
     101        m_pLineEditIOAddress->setEnabled(fAvailable);
     102}
     103
     104void UISerialSettingsEditor::setPortByIRQAndIOAddress(ulong uIRQ, ulong uIOAddress)
     105{
     106    if (m_pComboNumber)
     107        m_pComboNumber->setCurrentIndex(m_pComboNumber->findText(UITranslator::toCOMPortName(uIRQ, uIOAddress)));
     108}
     109
     110bool UISerialSettingsEditor::isPortStandardOne() const
     111{
     112    ulong uIRQ, uIOAddress;
     113    return m_pComboNumber ? UITranslator::toCOMPortNumbers(m_pComboNumber->currentText(), uIRQ, uIOAddress) : false;
     114}
     115
     116void UISerialSettingsEditor::setIRQ(ulong uIRQ)
     117{
     118    if (m_pLineEditIRQ)
     119        m_pLineEditIRQ->setText(QString::number(uIRQ));
     120}
     121
     122ulong UISerialSettingsEditor::irq() const
     123{
     124    return m_pLineEditIRQ ? m_pLineEditIRQ->text().toULong(NULL, 0) : 0;
     125}
     126
     127void UISerialSettingsEditor::setIOAddress(ulong uIOAddress)
     128{
     129    if (m_pLineEditIOAddress)
     130        m_pLineEditIOAddress->setText("0x" + QString::number(uIOAddress, 16).toUpper());
     131}
     132
     133ulong UISerialSettingsEditor::ioAddress() const
     134{
     135    return m_pLineEditIOAddress ? m_pLineEditIOAddress->text().toULong(NULL, 0) : 0;
     136}
     137
     138void UISerialSettingsEditor::setHostModeOptionsAvailable(bool fAvailable)
     139{
     140    if (m_pLabelMode)
     141        m_pLabelMode->setEnabled(fAvailable);
     142    if (m_pComboMode)
     143        m_pComboMode->setEnabled(fAvailable);
     144}
     145
     146void UISerialSettingsEditor::setHostMode(KPortMode enmMode)
     147{
     148    m_enmPortMode = enmMode;
     149    populateCombo();
     150}
     151
     152KPortMode UISerialSettingsEditor::hostMode() const
     153{
     154    return m_pComboMode ? m_pComboMode->currentData().value<KPortMode>() : m_enmPortMode;
     155}
     156
     157void UISerialSettingsEditor::setPipeOptionsAvailable(bool fAvailable)
     158{
    268159    if (m_pCheckBoxPipe)
    269         m_pCheckBoxPipe->setChecked(!oldPortData.m_fServer);
     160        m_pCheckBoxPipe->setEnabled(fAvailable);
     161}
     162
     163void UISerialSettingsEditor::setServerEnabled(bool fEnabled)
     164{
     165    if (m_pCheckBoxPipe)
     166        m_pCheckBoxPipe->setChecked(!fEnabled);
     167}
     168
     169bool UISerialSettingsEditor::isServerEnabled() const
     170{
     171    return m_pCheckBoxPipe ? !m_pCheckBoxPipe->isChecked() : true;
     172}
     173
     174void UISerialSettingsEditor::setPathOptionsAvailable(bool fAvailable)
     175{
     176    if (m_pLabelPath)
     177        m_pLabelPath->setEnabled(fAvailable);
    270178    if (m_pEditorPath)
    271         m_pEditorPath->setText(oldPortData.m_strPath);
    272 
    273     /* Repopulate combo-boxes content: */
    274     populateComboboxes();
    275     /* Ensure everything is up-to-date */
    276     if (m_pCheckBoxPort)
    277         sltHandlePortAvailabilityToggled(m_pCheckBoxPort->isChecked());
    278 }
    279 
    280 void UIMachineSettingsSerial::putPortDataToCache(UISettingsCacheMachineSerialPort &portCache)
    281 {
    282     /* Prepare new data: */
    283     UIDataSettingsMachineSerialPort newPortData;
    284 
    285     /* Save port number: */
    286     newPortData.m_iSlot = m_iSlot;
    287 
    288     /* Save port data: */
    289     if (m_pCheckBoxPort)
    290         newPortData.m_fPortEnabled = m_pCheckBoxPort->isChecked();
    291     if (m_pLineEditIRQ)
    292         newPortData.m_uIRQ = m_pLineEditIRQ->text().toULong(NULL, 0);
    293     if (m_pLineEditIOAddress)
    294         newPortData.m_uIOAddress = m_pLineEditIOAddress->text().toULong(NULL, 0);
    295     if (m_pCheckBoxPipe)
    296         newPortData.m_fServer = !m_pCheckBoxPipe->isChecked();
    297     if (m_pComboMode)
    298         newPortData.m_hostMode = m_pComboMode->currentData().value<KPortMode>();
     179        m_pEditorPath->setEnabled(fAvailable);
     180}
     181
     182void UISerialSettingsEditor::setPath(const QString &strPath)
     183{
    299184    if (m_pEditorPath)
    300         newPortData.m_strPath = QDir::toNativeSeparators(m_pEditorPath->text());
    301 
    302     /* Cache new data: */
    303     portCache.cacheCurrentData(newPortData);
    304 }
    305 
    306 bool UIMachineSettingsSerial::validate(QList<UIValidationMessage> &messages)
    307 {
    308     /* Pass by default: */
    309     bool fPass = true;
    310 
    311     /* Prepare message: */
    312     UIValidationMessage message;
    313     message.first = UITranslator::removeAccelMark(tabTitle());
    314 
    315     if (   m_pCheckBoxPort
    316         && m_pCheckBoxPort->isChecked())
    317     {
    318         /* Check the port attribute emptiness & uniqueness: */
    319         const QString strIRQ = m_pLineEditIRQ ? m_pLineEditIRQ->text() : QString();
    320         const QString strIOAddress = m_pLineEditIOAddress ? m_pLineEditIOAddress->text() : QString();
    321         const QPair<QString, QString> port = qMakePair(strIRQ, strIOAddress);
    322 
    323         if (strIRQ.isEmpty())
    324         {
    325             message.second << UIMachineSettingsSerial::tr("No IRQ is currently specified.");
    326             fPass = false;
    327         }
    328         if (strIOAddress.isEmpty())
    329         {
    330             message.second << UIMachineSettingsSerial::tr("No I/O port is currently specified.");
    331             fPass = false;
    332         }
    333         if (   !strIRQ.isEmpty()
    334             && !strIOAddress.isEmpty())
    335         {
    336             QVector<QPair<QString, QString> > ports;
    337             if (m_pParent)
    338             {
    339                 ports = m_pParent->ports();
    340                 ports.removeAt(m_iSlot);
    341             }
    342             if (ports.contains(port))
    343             {
    344                 message.second << UIMachineSettingsSerial::tr("Two or more ports have the same settings.");
    345                 fPass = false;
    346             }
    347         }
    348 
    349         const KPortMode enmMode = m_pComboMode->currentData().value<KPortMode>();
    350         if (enmMode != KPortMode_Disconnected)
    351         {
    352             const QString strPath(m_pEditorPath->text());
    353 
    354             if (strPath.isEmpty())
    355             {
    356                 message.second << UIMachineSettingsSerial::tr("No port path is currently specified.");
    357                 fPass = false;
    358             }
    359             else
    360             {
    361                 QVector<QString> paths;
    362                 if (m_pParent)
    363                 {
    364                     paths = m_pParent->paths();
    365                     paths.removeAt(m_iSlot);
    366                 }
    367                 if (paths.contains(strPath))
    368                 {
    369                     message.second << UIMachineSettingsSerial::tr("There are currently duplicate port paths specified.");
    370                     fPass = false;
    371                 }
    372             }
    373         }
    374     }
    375 
    376     /* Serialize message: */
    377     if (!message.second.isEmpty())
    378         messages << message;
    379 
    380     /* Return result: */
    381     return fPass;
    382 }
    383 
    384 QWidget *UIMachineSettingsSerial::setOrderAfter(QWidget *pWidget)
    385 {
    386     setTabOrder(pWidget, m_pCheckBoxPort);
    387     setTabOrder(m_pCheckBoxPort, m_pComboNumber);
    388     setTabOrder(m_pComboNumber, m_pLineEditIRQ);
    389     setTabOrder(m_pLineEditIRQ, m_pLineEditIOAddress);
    390     setTabOrder(m_pLineEditIOAddress, m_pComboMode);
    391     setTabOrder(m_pComboMode, m_pCheckBoxPipe);
    392     setTabOrder(m_pCheckBoxPipe, m_pEditorPath);
    393     return m_pEditorPath;
    394 }
    395 
    396 QString UIMachineSettingsSerial::tabTitle() const
    397 {
    398     return QString(tr("Port %1", "serial ports")).arg(QString("&%1").arg(m_iSlot + 1));
    399 }
    400 
    401 bool UIMachineSettingsSerial::isPortEnabled() const
    402 {
    403     return m_pCheckBoxPort->isChecked();
    404 }
    405 
    406 QString UIMachineSettingsSerial::irq() const
    407 {
    408     return m_pLineEditIRQ->text();
    409 }
    410 
    411 QString UIMachineSettingsSerial::ioAddress() const
    412 {
    413     return m_pLineEditIOAddress->text();
    414 }
    415 
    416 QString UIMachineSettingsSerial::path() const
    417 {
    418     return m_pEditorPath->text();
    419 }
    420 
    421 void UIMachineSettingsSerial::polishTab()
    422 {
    423     /* Sanity check: */
    424     if (!m_pParent)
    425         return;
    426 
    427     /* Polish port page: */
    428     ulong uIRQ, uIOAddress;
    429     const bool fStd = m_pComboNumber ? UITranslator::toCOMPortNumbers(m_pComboNumber->currentText(), uIRQ, uIOAddress) : false;
    430     const KPortMode enmMode = m_pComboMode ? m_pComboMode->currentData().value<KPortMode>() : KPortMode_Max;
    431     if (m_pCheckBoxPort)
    432         m_pCheckBoxPort->setEnabled(m_pParent->isMachineOffline());
    433     if (m_pLabelNumber)
    434         m_pLabelNumber->setEnabled(m_pParent->isMachineOffline());
    435     if (m_pComboNumber)
    436         m_pComboNumber->setEnabled(m_pParent->isMachineOffline());
    437     if (m_pLabelIRQ)
    438         m_pLabelIRQ->setEnabled(m_pParent->isMachineOffline());
    439     if (m_pLineEditIRQ)
    440         m_pLineEditIRQ->setEnabled(!fStd && m_pParent->isMachineOffline());
    441     if (m_pLabelIOAddress)
    442         m_pLabelIOAddress->setEnabled(m_pParent->isMachineOffline());
    443     if (m_pLineEditIOAddress)
    444         m_pLineEditIOAddress->setEnabled(!fStd && m_pParent->isMachineOffline());
    445     if (m_pLabelMode)
    446         m_pLabelMode->setEnabled(m_pParent->isMachineOffline());
    447     if (m_pComboMode)
    448         m_pComboMode->setEnabled(m_pParent->isMachineOffline());
    449     if (m_pCheckBoxPipe)
    450         m_pCheckBoxPipe->setEnabled(   (enmMode == KPortMode_HostPipe || enmMode == KPortMode_TCP)
    451                                     && m_pParent->isMachineOffline());
    452     if (m_pLabelPath)
    453         m_pLabelPath->setEnabled(   enmMode != KPortMode_Disconnected
    454                                  && m_pParent->isMachineOffline());
    455     if (m_pEditorPath)
    456         m_pEditorPath->setEnabled(   enmMode != KPortMode_Disconnected
    457                                   && m_pParent->isMachineOffline());
    458 }
    459 
    460 void UIMachineSettingsSerial::retranslateUi()
     185        m_pEditorPath->setText(strPath);
     186}
     187
     188QString UISerialSettingsEditor::path() const
     189{
     190    return m_pEditorPath ? QDir::toNativeSeparators(m_pEditorPath->text()) : QString();
     191}
     192
     193void UISerialSettingsEditor::retranslateUi()
    461194{
    462195    if (m_pCheckBoxPort)
     
    507240
    508241    /* Translate combo-boxes content: */
    509     populateComboboxes();
    510 }
    511 
    512 void UIMachineSettingsSerial::sltHandlePortAvailabilityToggled(bool fOn)
     242    populateCombo();
     243}
     244
     245void UISerialSettingsEditor::sltHandlePortAvailabilityToggled(bool fOn)
    513246{
    514247    /* Update availability: */
    515     m_pWidgetPortSettings->setEnabled(m_pCheckBoxPort->isChecked());
     248    if (m_pWidgetPortSettings && m_pCheckBoxPort)
     249        m_pWidgetPortSettings->setEnabled(m_pCheckBoxPort->isChecked());
    516250    if (fOn)
    517251    {
    518         sltHandlePortStandardOptionActivated(m_pComboNumber->currentText());
    519         sltHandlePortModeChange(m_pComboMode->currentIndex());
    520     }
    521 
    522     /* Notify port/path changed: */
    523     emit sigPortChanged();
    524     emit sigPathChanged();
    525 }
    526 
    527 void UIMachineSettingsSerial::sltHandlePortStandardOptionActivated(const QString &strText)
     252        if (m_pComboNumber)
     253            sltHandleStandardPortOptionActivated(m_pComboNumber->currentText());
     254        if (m_pComboMode)
     255            sltHandleModeChange(m_pComboMode->currentIndex());
     256    }
     257
     258    /* Notify about port availability changed: */
     259    emit sigPortAvailabilityChanged();
     260}
     261
     262void UISerialSettingsEditor::sltHandleStandardPortOptionActivated(const QString &strText)
    528263{
    529264    /* Update availability: */
    530265    ulong uIRQ, uIOAddress;
    531266    bool fStd = UITranslator::toCOMPortNumbers(strText, uIRQ, uIOAddress);
    532     m_pLineEditIRQ->setEnabled(!fStd);
    533     m_pLineEditIOAddress->setEnabled(!fStd);
     267    if (m_pLineEditIRQ)
     268        m_pLineEditIRQ->setEnabled(!fStd);
     269    if (m_pLineEditIOAddress)
     270        m_pLineEditIOAddress->setEnabled(!fStd);
    534271    if (fStd)
    535272    {
    536         m_pLineEditIRQ->setText(QString::number(uIRQ));
    537         m_pLineEditIOAddress->setText("0x" + QString::number(uIOAddress, 16).toUpper());
    538     }
    539 
    540     /* Notify validity changed: */
    541     emit sigValidityChanged();
    542 }
    543 
    544 void UIMachineSettingsSerial::sltHandlePortModeChange(int iIndex)
     273        if (m_pLineEditIRQ)
     274            m_pLineEditIRQ->setText(QString::number(uIRQ));
     275        if (m_pLineEditIOAddress)
     276            m_pLineEditIOAddress->setText("0x" + QString::number(uIOAddress, 16).toUpper());
     277    }
     278
     279    /* Notify about standard port option changed: */
     280    emit sigStandardPortOptionChanged();
     281}
     282
     283void UISerialSettingsEditor::sltHandleModeChange(int iIndex)
    545284{
    546285    /* Update availability: */
    547     const KPortMode enmMode = m_pComboMode->itemData(iIndex).value<KPortMode>();
    548     m_pCheckBoxPipe->setEnabled(enmMode == KPortMode_HostPipe || enmMode == KPortMode_TCP);
    549     m_pEditorPath->setEnabled(enmMode != KPortMode_Disconnected);
    550     m_pLabelPath->setEnabled(enmMode != KPortMode_Disconnected);
    551 
    552     /* Notify validity changed: */
    553     emit sigValidityChanged();
    554 }
    555 
    556 void UIMachineSettingsSerial::prepare()
     286    const KPortMode enmMode = m_pComboMode ? m_pComboMode->itemData(iIndex).value<KPortMode>() : m_enmPortMode;
     287    if (m_pCheckBoxPipe)
     288        m_pCheckBoxPipe->setEnabled(enmMode == KPortMode_HostPipe || enmMode == KPortMode_TCP);
     289    if (m_pEditorPath)
     290        m_pEditorPath->setEnabled(enmMode != KPortMode_Disconnected);
     291    if (m_pLabelPath)
     292        m_pLabelPath->setEnabled(enmMode != KPortMode_Disconnected);
     293
     294    /* Notify about mode changed: */
     295    emit sigModeChanged();
     296}
     297
     298void UISerialSettingsEditor::prepare()
    557299{
    558300    /* Prepare everything: */
     
    564306}
    565307
    566 void UIMachineSettingsSerial::prepareWidgets()
     308void UISerialSettingsEditor::prepareWidgets()
    567309{
    568310    /* Prepare main layout: */
     
    691433}
    692434
    693 void UIMachineSettingsSerial::prepareConnections()
     435void UISerialSettingsEditor::prepareConnections()
    694436{
    695437    if (m_pCheckBoxPort)
    696         connect(m_pCheckBoxPort, &QCheckBox::toggled, this, &UIMachineSettingsSerial::sltHandlePortAvailabilityToggled);
     438        connect(m_pCheckBoxPort, &QCheckBox::toggled,
     439                this, &UISerialSettingsEditor::sltHandlePortAvailabilityToggled);
    697440#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
    698441    if (m_pComboNumber)
    699442        connect(m_pComboNumber, static_cast<void(QComboBox::*)(const QString&)>(&QComboBox::textActivated),
    700                 this, &UIMachineSettingsSerial::sltHandlePortStandardOptionActivated);
     443                this, &UISerialSettingsEditor::sltHandleStandardPortOptionActivated);
    701444#else
    702445    if (m_pComboNumber)
    703446        connect(m_pComboNumber, static_cast<void(QComboBox::*)(const QString&)>(&QComboBox::activated),
    704                 this, &UIMachineSettingsSerial::sltHandlePortStandardOptionActivated);
     447                this, &UISerialSettingsEditor::sltHandleStandardPortOptionActivated);
    705448#endif
    706449    if (m_pLineEditIRQ)
    707         connect(m_pLineEditIRQ, &QLineEdit::textChanged, this, &UIMachineSettingsSerial::sigPortChanged);
     450        connect(m_pLineEditIRQ, &QLineEdit::textChanged, this, &UISerialSettingsEditor::sigPortIRQChanged);
    708451    if (m_pLineEditIOAddress)
    709         connect(m_pLineEditIOAddress, &QLineEdit::textChanged, this, &UIMachineSettingsSerial::sigPortChanged);
     452        connect(m_pLineEditIOAddress, &QLineEdit::textChanged, this, &UISerialSettingsEditor::sigPortIOAddressChanged);
    710453    if (m_pComboMode)
    711454        connect(m_pComboMode, static_cast<void(QComboBox::*)(int)>(&QComboBox::activated),
    712                 this, &UIMachineSettingsSerial::sltHandlePortModeChange);
     455                this, &UISerialSettingsEditor::sltHandleModeChange);
    713456    if (m_pEditorPath)
    714         connect(m_pEditorPath, &QLineEdit::textChanged, this, &UIMachineSettingsSerial::sigPathChanged);
    715 }
    716 
    717 void UIMachineSettingsSerial::populateComboboxes()
    718 {
    719     /* Port mode: */
    720     {
    721         /* Clear the port mode combo-box: */
     457        connect(m_pEditorPath, &QLineEdit::textChanged, this, &UISerialSettingsEditor::sigPathChanged);
     458}
     459
     460void UISerialSettingsEditor::populateCombo()
     461{
     462    if (m_pComboMode)
     463    {
     464        /* Clear the mode combo-box: */
    722465        m_pComboMode->clear();
    723466
     
    739482        }
    740483
    741         /* Choose requested port mode: */
     484        /* Choose requested mode: */
    742485        const int iIndex = m_pComboMode->findData(QVariant::fromValue(m_enmPortMode));
    743486        m_pComboMode->setCurrentIndex(iIndex != -1 ? iIndex : 0);
    744487    }
    745488}
    746 
    747 
    748 /*********************************************************************************************************************************
    749 *   Class UIMachineSettingsSerialPage implementation.                                                                            *
    750 *********************************************************************************************************************************/
    751 
    752 UIMachineSettingsSerialPage::UIMachineSettingsSerialPage()
    753     : m_pCache(0)
    754     , m_pTabWidget(0)
    755 {
    756     prepare();
    757 }
    758 
    759 UIMachineSettingsSerialPage::~UIMachineSettingsSerialPage()
    760 {
    761     cleanup();
    762 }
    763 
    764 bool UIMachineSettingsSerialPage::changed() const
    765 {
    766     return m_pCache ? m_pCache->wasChanged() : false;
    767 }
    768 
    769 void UIMachineSettingsSerialPage::loadToCacheFrom(QVariant &data)
    770 {
    771     /* Sanity check: */
    772     if (   !m_pCache
    773         || !m_pTabWidget)
    774         return;
    775 
    776     /* Fetch data to machine: */
    777     UISettingsPageMachine::fetchData(data);
    778 
    779     /* Clear cache initially: */
    780     m_pCache->clear();
    781 
    782     /* Cache lists: */
    783     refreshPorts();
    784     refreshPaths();
    785 
    786     /* Prepare old data: */
    787     UIDataSettingsMachineSerial oldSerialData;
    788 
    789     /* For each serial port: */
    790     for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot)
    791     {
    792         /* Prepare old data: */
    793         UIDataSettingsMachineSerialPort oldPortData;
    794 
    795         /* Check whether port is valid: */
    796         const CSerialPort &comPort = m_machine.GetSerialPort(iSlot);
    797         if (!comPort.isNull())
    798         {
    799             /* Gather old data: */
    800             oldPortData.m_iSlot = iSlot;
    801             oldPortData.m_fPortEnabled = comPort.GetEnabled();
    802             oldPortData.m_uIRQ = comPort.GetIRQ();
    803             oldPortData.m_uIOAddress = comPort.GetIOAddress();
    804             oldPortData.m_hostMode = comPort.GetHostMode();
    805             oldPortData.m_fServer = comPort.GetServer();
    806             oldPortData.m_strPath = comPort.GetPath();
    807         }
    808 
    809         /* Cache old data: */
    810         m_pCache->child(iSlot).cacheInitialData(oldPortData);
    811     }
    812 
    813     /* Cache old data: */
    814     m_pCache->cacheInitialData(oldSerialData);
    815 
    816     /* Upload machine to data: */
    817     UISettingsPageMachine::uploadData(data);
    818 }
    819 
    820 void UIMachineSettingsSerialPage::getFromCache()
    821 {
    822     /* Sanity check: */
    823     if (   !m_pCache
    824         || !m_pTabWidget)
    825         return;
    826 
    827     /* Setup tab order: */
    828     AssertPtrReturnVoid(firstWidget());
    829     setTabOrder(firstWidget(), m_pTabWidget->focusProxy());
    830     QWidget *pLastFocusWidget = m_pTabWidget->focusProxy();
    831 
    832     /* For each port: */
    833     for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot)
    834     {
    835         /* Get port page: */
    836         UIMachineSettingsSerial *pTab = qobject_cast<UIMachineSettingsSerial*>(m_pTabWidget->widget(iSlot));
    837         AssertPtrReturnVoid(pTab);
    838 
    839         /* Load old data from cache: */
    840         pTab->getPortDataFromCache(m_pCache->child(iSlot));
    841 
    842         /* Setup tab order: */
    843         pLastFocusWidget = pTab->setOrderAfter(pLastFocusWidget);
    844     }
    845 
    846     /* Apply language settings: */
    847     retranslateUi();
    848 
    849     /* Polish page finally: */
    850     polishPage();
    851 
    852     /* Revalidate: */
    853     revalidate();
    854 }
    855 
    856 void UIMachineSettingsSerialPage::putToCache()
    857 {
    858     /* Sanity check: */
    859     if (   !m_pCache
    860         || !m_pTabWidget)
    861         return;
    862 
    863     /* Prepare new data: */
    864     UIDataSettingsMachineSerial newSerialData;
    865 
    866     /* For each port: */
    867     for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot)
    868     {
    869         /* Getting port page: */
    870         UIMachineSettingsSerial *pTab = qobject_cast<UIMachineSettingsSerial*>(m_pTabWidget->widget(iSlot));
    871         AssertPtrReturnVoid(pTab);
    872 
    873         /* Gather new data: */
    874         pTab->putPortDataToCache(m_pCache->child(iSlot));
    875     }
    876 
    877     /* Cache new data: */
    878     m_pCache->cacheCurrentData(newSerialData);
    879 }
    880 
    881 void UIMachineSettingsSerialPage::saveFromCacheTo(QVariant &data)
    882 {
    883     /* Fetch data to machine: */
    884     UISettingsPageMachine::fetchData(data);
    885 
    886     /* Update data and failing state: */
    887     setFailed(!saveData());
    888 
    889     /* Upload machine to data: */
    890     UISettingsPageMachine::uploadData(data);
    891 }
    892 
    893 bool UIMachineSettingsSerialPage::validate(QList<UIValidationMessage> &messages)
    894 {
    895     /* Sanity check: */
    896     if (!m_pTabWidget)
    897         return false;
    898 
    899     /* Pass by default: */
    900     bool fValid = true;
    901 
    902     /* Delegate validation to adapter tabs: */
    903     for (int iIndex = 0; iIndex < m_pTabWidget->count(); ++iIndex)
    904     {
    905         UIMachineSettingsSerial *pTab = qobject_cast<UIMachineSettingsSerial*>(m_pTabWidget->widget(iIndex));
    906         AssertPtrReturn(pTab, false);
    907         if (!pTab->validate(messages))
    908             fValid = false;
    909     }
    910 
    911     /* Return result: */
    912     return fValid;
    913 }
    914 
    915 void UIMachineSettingsSerialPage::retranslateUi()
    916 {
    917     /* Sanity check: */
    918     if (!m_pTabWidget)
    919         return;
    920 
    921     for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot)
    922     {
    923         UIMachineSettingsSerial *pTab = qobject_cast<UIMachineSettingsSerial*>(m_pTabWidget->widget(iSlot));
    924         AssertPtrReturnVoid(pTab);
    925         m_pTabWidget->setTabText(iSlot, pTab->tabTitle());
    926     }
    927 }
    928 
    929 void UIMachineSettingsSerialPage::polishPage()
    930 {
    931     /* Sanity check: */
    932     if (   !m_pCache
    933         || !m_pTabWidget)
    934         return;
    935 
    936     for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot)
    937     {
    938         m_pTabWidget->setTabEnabled(iSlot,
    939                                     isMachineOffline() ||
    940                                     (isMachineInValidMode() &&
    941                                      m_pCache->childCount() > iSlot &&
    942                                      m_pCache->child(iSlot).base().m_fPortEnabled));
    943         UIMachineSettingsSerial *pTab = qobject_cast<UIMachineSettingsSerial*>(m_pTabWidget->widget(iSlot));
    944         AssertPtrReturnVoid(pTab);
    945         pTab->polishTab();
    946     }
    947 }
    948 
    949 void UIMachineSettingsSerialPage::sltHandlePortChange()
    950 {
    951     refreshPorts();
    952     revalidate();
    953 }
    954 
    955 void UIMachineSettingsSerialPage::sltHandlePathChange()
    956 {
    957     refreshPaths();
    958     revalidate();
    959 }
    960 
    961 void UIMachineSettingsSerialPage::prepare()
    962 {
    963     /* Prepare cache: */
    964     m_pCache = new UISettingsCacheMachineSerial;
    965     AssertPtrReturnVoid(m_pCache);
    966 
    967     /* Create main layout: */
    968     QVBoxLayout *pLayoutMain = new QVBoxLayout(this);
    969     if (pLayoutMain)
    970     {
    971         /* Creating tab-widget: */
    972         m_pTabWidget = new QITabWidget;
    973         if (m_pTabWidget)
    974         {
    975             /* How many ports to display: */
    976             const ulong uCount = uiCommon().virtualBox().GetPlatformProperties(KPlatformArchitecture_x86).GetSerialPortCount();
    977 
    978             /* Create corresponding port tabs: */
    979             for (ulong uSlot = 0; uSlot < uCount; ++uSlot)
    980             {
    981                 /* Create port tab: */
    982                 UIMachineSettingsSerial *pTab = new UIMachineSettingsSerial(this);
    983                 if (pTab)
    984                 {
    985                     /* Tab connections: */
    986                     connect(pTab, &UIMachineSettingsSerial::sigPortChanged,
    987                             this, &UIMachineSettingsSerialPage::sltHandlePortChange);
    988                     connect(pTab, &UIMachineSettingsSerial::sigPathChanged,
    989                             this, &UIMachineSettingsSerialPage::sltHandlePathChange);
    990                     connect(pTab, &UIMachineSettingsSerial::sigValidityChanged,
    991                             this, &UIMachineSettingsSerialPage::revalidate);
    992 
    993                     /* Add tab into tab-widget: */
    994                     m_pTabWidget->addTab(pTab, pTab->tabTitle());
    995                 }
    996             }
    997 
    998             /* Add tab-widget into layout: */
    999             pLayoutMain->addWidget(m_pTabWidget);
    1000         }
    1001     }
    1002 }
    1003 
    1004 void UIMachineSettingsSerialPage::cleanup()
    1005 {
    1006     /* Cleanup cache: */
    1007     delete m_pCache;
    1008     m_pCache = 0;
    1009 }
    1010 
    1011 void UIMachineSettingsSerialPage::refreshPorts()
    1012 {
    1013     /* Sanity check: */
    1014     if (!m_pTabWidget)
    1015         return;
    1016 
    1017     /* Reload port list: */
    1018     m_ports.clear();
    1019     m_ports.resize(m_pTabWidget->count());
    1020     /* Append port list with data from all the tabs: */
    1021     for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot)
    1022     {
    1023         UIMachineSettingsSerial *pTab = qobject_cast<UIMachineSettingsSerial*>(m_pTabWidget->widget(iSlot));
    1024         AssertPtrReturnVoid(pTab);
    1025         m_ports[iSlot] = pTab->isPortEnabled() ? qMakePair(pTab->irq(), pTab->ioAddress()) : qMakePair(QString(), QString());
    1026     }
    1027 }
    1028 
    1029 void UIMachineSettingsSerialPage::refreshPaths()
    1030 {
    1031     /* Sanity check: */
    1032     if (!m_pTabWidget)
    1033         return;
    1034 
    1035     /* Reload path list: */
    1036     m_paths.clear();
    1037     m_paths.resize(m_pTabWidget->count());
    1038     /* Append path list with data from all the tabs: */
    1039     for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot)
    1040     {
    1041         UIMachineSettingsSerial *pTab = qobject_cast<UIMachineSettingsSerial*>(m_pTabWidget->widget(iSlot));
    1042         AssertPtrReturnVoid(pTab);
    1043         m_paths[iSlot] = pTab->isPortEnabled() ? pTab->path() : QString();
    1044     }
    1045 }
    1046 
    1047 bool UIMachineSettingsSerialPage::saveData()
    1048 {
    1049     /* Sanity check: */
    1050     if (   !m_pCache
    1051         || !m_pTabWidget)
    1052         return false;
    1053 
    1054     /* Prepare result: */
    1055     bool fSuccess = true;
    1056     /* Save serial settings from cache: */
    1057     if (fSuccess && isMachineInValidMode() && m_pCache->wasChanged())
    1058     {
    1059         /* For each port: */
    1060         for (int iSlot = 0; fSuccess && iSlot < m_pTabWidget->count(); ++iSlot)
    1061             fSuccess = savePortData(iSlot);
    1062     }
    1063     /* Return result: */
    1064     return fSuccess;
    1065 }
    1066 
    1067 bool UIMachineSettingsSerialPage::savePortData(int iSlot)
    1068 {
    1069     /* Sanity check: */
    1070     if (!m_pCache)
    1071         return false;
    1072 
    1073     /* Prepare result: */
    1074     bool fSuccess = true;
    1075     /* Save adapter settings from cache: */
    1076     if (fSuccess && m_pCache->child(iSlot).wasChanged())
    1077     {
    1078         /* Get old data from cache: */
    1079         const UIDataSettingsMachineSerialPort &oldPortData = m_pCache->child(iSlot).base();
    1080         /* Get new data from cache: */
    1081         const UIDataSettingsMachineSerialPort &newPortData = m_pCache->child(iSlot).data();
    1082 
    1083         /* Get serial port for further activities: */
    1084         CSerialPort comPort = m_machine.GetSerialPort(iSlot);
    1085         fSuccess = m_machine.isOk() && comPort.isNotNull();
    1086 
    1087         /* Show error message if necessary: */
    1088         if (!fSuccess)
    1089             notifyOperationProgressError(UIErrorString::formatErrorInfo(m_machine));
    1090         else
    1091         {
    1092             // This *must* be first.
    1093             // If the requested host mode is changed to disconnected we should do it first.
    1094             // That allows to automatically fulfill the requirements for some of the settings below.
    1095             /* Save port host mode: */
    1096             if (   fSuccess && isMachineOffline()
    1097                 && newPortData.m_hostMode != oldPortData.m_hostMode
    1098                 && newPortData.m_hostMode == KPortMode_Disconnected)
    1099             {
    1100                 comPort.SetHostMode(newPortData.m_hostMode);
    1101                 fSuccess = comPort.isOk();
    1102             }
    1103             /* Save whether the port is enabled: */
    1104             if (fSuccess && isMachineOffline() && newPortData.m_fPortEnabled != oldPortData.m_fPortEnabled)
    1105             {
    1106                 comPort.SetEnabled(newPortData.m_fPortEnabled);
    1107                 fSuccess = comPort.isOk();
    1108             }
    1109             /* Save port IRQ: */
    1110             if (fSuccess && isMachineOffline() && newPortData.m_uIRQ != oldPortData.m_uIRQ)
    1111             {
    1112                 comPort.SetIRQ(newPortData.m_uIRQ);
    1113                 fSuccess = comPort.isOk();
    1114             }
    1115             /* Save port IO address: */
    1116             if (fSuccess && isMachineOffline() && newPortData.m_uIOAddress != oldPortData.m_uIOAddress)
    1117             {
    1118                 comPort.SetIOAddress(newPortData.m_uIOAddress);
    1119                 fSuccess = comPort.isOk();
    1120             }
    1121             /* Save whether the port is server: */
    1122             if (fSuccess && isMachineOffline() && newPortData.m_fServer != oldPortData.m_fServer)
    1123             {
    1124                 comPort.SetServer(newPortData.m_fServer);
    1125                 fSuccess = comPort.isOk();
    1126             }
    1127             /* Save port path: */
    1128             if (fSuccess && isMachineOffline() && newPortData.m_strPath != oldPortData.m_strPath)
    1129             {
    1130                 comPort.SetPath(newPortData.m_strPath);
    1131                 fSuccess = comPort.isOk();
    1132             }
    1133             // This *must* be last.
    1134             // The host mode will be changed to disconnected if some of the necessary
    1135             // settings above will not meet the requirements for the selected mode.
    1136             /* Save port host mode: */
    1137             if (   fSuccess && isMachineOffline()
    1138                 && newPortData.m_hostMode != oldPortData.m_hostMode
    1139                 && newPortData.m_hostMode != KPortMode_Disconnected)
    1140             {
    1141                 comPort.SetHostMode(newPortData.m_hostMode);
    1142                 fSuccess = comPort.isOk();
    1143             }
    1144 
    1145             /* Show error message if necessary: */
    1146             if (!fSuccess)
    1147                 notifyOperationProgressError(UIErrorString::formatErrorInfo(comPort));
    1148         }
    1149     }
    1150     /* Return result: */
    1151     return fSuccess;
    1152 }
    1153 
    1154 # include "UIMachineSettingsSerial.moc"
  • trunk/src/VBox/Frontends/VirtualBox/src/settings/editors/UISerialSettingsEditor.h

    r101325 r101327  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UIMachineSettingsSerial class implementation.
     3 * VBox Qt GUI - UISerialSettingsEditor class declaration.
    44 */
    55
     
    2626 */
    2727
    28 /* Qt includes: */
    29 #include <QCheckBox>
    30 #include <QComboBox>
    31 #include <QDir>
    32 #include <QGridLayout>
    33 #include <QLabel>
    34 #include <QLineEdit>
    35 #include <QRegularExpressionValidator>
     28#ifndef FEQT_INCLUDED_SRC_settings_editors_UISerialSettingsEditor_h
     29#define FEQT_INCLUDED_SRC_settings_editors_UISerialSettingsEditor_h
     30#ifndef RT_WITHOUT_PRAGMA_ONCE
     31# pragma once
     32#endif
    3633
    3734/* GUI includes: */
    38 #include "QITabWidget.h"
    39 #include "QIWidgetValidator.h"
    40 #include "UICommon.h"
    41 #include "UIConverter.h"
    42 #include "UIErrorString.h"
    43 #include "UIMachineSettingsSerial.h"
    44 #include "UITranslator.h"
     35#include "UIEditor.h"
    4536
    46 /* COM includes: */
    47 #include "CPlatformProperties.h"
    48 #include "CSerialPort.h"
     37/* Forward declarations: */
     38class QCheckBox;
     39class QComboBox;
     40class QLabel;
     41class QLineEdit;
    4942
    50 
    51 /** Machine settings: Serial Port tab data structure. */
    52 struct UIDataSettingsMachineSerialPort
    53 {
    54     /** Constructs data. */
    55     UIDataSettingsMachineSerialPort()
    56         : m_iSlot(-1)
    57         , m_fPortEnabled(false)
    58         , m_uIRQ(0)
    59         , m_uIOAddress(0)
    60         , m_hostMode(KPortMode_Disconnected)
    61         , m_fServer(false)
    62         , m_strPath(QString())
    63     {}
    64 
    65     /** Returns whether the @a other passed data is equal to this one. */
    66     bool equal(const UIDataSettingsMachineSerialPort &other) const
    67     {
    68         return true
    69                && (m_iSlot == other.m_iSlot)
    70                && (m_fPortEnabled == other.m_fPortEnabled)
    71                && (m_uIRQ == other.m_uIRQ)
    72                && (m_uIOAddress == other.m_uIOAddress)
    73                && (m_hostMode == other.m_hostMode)
    74                && (m_fServer == other.m_fServer)
    75                && (m_strPath == other.m_strPath)
    76                ;
    77     }
    78 
    79     /** Returns whether the @a other passed data is equal to this one. */
    80     bool operator==(const UIDataSettingsMachineSerialPort &other) const { return equal(other); }
    81     /** Returns whether the @a other passed data is different from this one. */
    82     bool operator!=(const UIDataSettingsMachineSerialPort &other) const { return !equal(other); }
    83 
    84     /** Holds the serial port slot number. */
    85     int        m_iSlot;
    86     /** Holds whether the serial port is enabled. */
    87     bool       m_fPortEnabled;
    88     /** Holds the serial port IRQ. */
    89     ulong      m_uIRQ;
    90     /** Holds the serial port IO address. */
    91     ulong      m_uIOAddress;
    92     /** Holds the serial port host mode. */
    93     KPortMode  m_hostMode;
    94     /** Holds whether the serial port is server. */
    95     bool       m_fServer;
    96     /** Holds the serial port path. */
    97     QString    m_strPath;
    98 };
    99 
    100 
    101 /** Machine settings: Serial page data structure. */
    102 struct UIDataSettingsMachineSerial
    103 {
    104     /** Constructs data. */
    105     UIDataSettingsMachineSerial() {}
    106 
    107     /** Returns whether the @a other passed data is equal to this one. */
    108     bool operator==(const UIDataSettingsMachineSerial & /* other */) const { return true; }
    109     /** Returns whether the @a other passed data is different from this one. */
    110     bool operator!=(const UIDataSettingsMachineSerial & /* other */) const { return false; }
    111 };
    112 
    113 
    114 /** Machine settings: Serial Port tab. */
    115 class UIMachineSettingsSerial : public QIWithRetranslateUI<QWidget>
     43/** UIEditor sub-class used as a serial settings editor. */
     44class SHARED_LIBRARY_STUFF UISerialSettingsEditor : public UIEditor
    11645{
    11746    Q_OBJECT;
     
    11948signals:
    12049
    121     /** Notifies about port changed. */
    122     void sigPortChanged();
    123     /** Notifies about path changed. */
     50    /** Notifies listeners about port availability changed. */
     51    void sigPortAvailabilityChanged();
     52
     53    /** Notifies listeners about standard port option changed. */
     54    void sigStandardPortOptionChanged();
     55
     56    /** Notifies listeners about port IRQ changed. */
     57    void sigPortIRQChanged();
     58    /** Notifies listeners about port IO address changed. */
     59    void sigPortIOAddressChanged();
     60
     61    /** Notifies listeners about mode changed. */
     62    void sigModeChanged();
     63    /** Notifies listeners about path changed. */
    12464    void sigPathChanged();
    125     /** Notifies about validity changed. */
    126     void sigValidityChanged();
    12765
    12866public:
    12967
    130     /** Constructs tab passing @a pParent to the base-class. */
    131     UIMachineSettingsSerial(UIMachineSettingsSerialPage *pParent);
     68    /** Constructs editor passing @a pParent to the base-class. */
     69    UISerialSettingsEditor(QWidget *pParent = 0);
    13270
    133     /** Loads port data from @a portCache. */
    134     void getPortDataFromCache(const UISettingsCacheMachineSerialPort &portCache);
    135     /** Saves port data to @a portCache. */
    136     void putPortDataToCache(UISettingsCacheMachineSerialPort &portCache);
     71    /** Defines whether port options @a fAvailable. */
     72    void setPortOptionsAvailable(bool fAvailable);
     73    /** Defines whether port @a fEnabled. */
     74    void setPortEnabled(bool fEnabled);
     75    /** Returns whether port enabled. */
     76    bool isPortEnabled() const;
    13777
    138     /** Performs validation, updates @a messages list if something is wrong. */
    139     bool validate(QList<UIValidationMessage> &messages);
     78    /** Defines whether port IRQ and IO address options @a fAvailable. */
     79    void setIRQAndIOAddressOptionsAvailable(bool fAvailable);
     80    /** Sets standard port on the basis of passed uIRQ and uIOAddress. */
     81    void setPortByIRQAndIOAddress(ulong uIRQ, ulong uIOAddress);
     82    /** Returns whether current port is standard one. */
     83    bool isPortStandardOne() const;
     84    /** Defines port @a uIRQ. */
     85    void setIRQ(ulong uIRQ);
     86    /** Returns port IRQ. */
     87    ulong irq() const;
     88    /** Defines port @a uIOAddress. */
     89    void setIOAddress(ulong uIOAddress);
     90    /** Returns port IO address. */
     91    ulong ioAddress() const;
    14092
    141     /** Configures tab order according to passed @a pWidget. */
    142     QWidget *setOrderAfter(QWidget *pWidget);
     93    /** Defines whether host mode options @a fAvailable. */
     94    void setHostModeOptionsAvailable(bool fAvailable);
     95    /** Defines host @a enmMode. */
     96    void setHostMode(KPortMode enmMode);
     97    /** Returns host mode. */
     98    KPortMode hostMode() const;
    14399
    144     /** Returns tab title. */
    145     QString tabTitle() const;
    146     /** Returns whether port is enabled. */
    147     bool isPortEnabled() const;
    148     /** Returns IRQ. */
    149     QString irq() const;
    150     /** Returns IO address. */
    151     QString ioAddress() const;
     100    /** Defines whether pipe options @a fAvailable. */
     101    void setPipeOptionsAvailable(bool fAvailable);
     102    /** Defines whether server @a fEnabled. */
     103    void setServerEnabled(bool fEnabled);
     104    /** Returns whether server enabled. */
     105    bool isServerEnabled() const;
     106
     107    /** Defines whether path options @a fAvailable. */
     108    void setPathOptionsAvailable(bool fAvailable);
     109    /** Defines @a strPath. */
     110    void setPath(const QString &strPath);
    152111    /** Returns path. */
    153112    QString path() const;
    154 
    155     /** Performs tab polishing. */
    156     void polishTab();
    157113
    158114protected:
    159115
    160116    /** Handles translation event. */
    161     void retranslateUi();
     117    virtual void retranslateUi() RT_OVERRIDE;
    162118
    163119private slots:
     
    165121    /** Handles port availability being toggled to @a fOn. */
    166122    void sltHandlePortAvailabilityToggled(bool fOn);
    167     /** Handles port standard @a strOption being activated. */
    168     void sltHandlePortStandardOptionActivated(const QString &strOption);
    169     /** Handles port mode change to item with certain @a iIndex. */
    170     void sltHandlePortModeChange(int iIndex);
     123
     124    /** Handles standard port @a strOption being activated. */
     125    void sltHandleStandardPortOptionActivated(const QString &strOption);
     126
     127    /** Handles mode change to item with certain @a iIndex. */
     128    void sltHandleModeChange(int iIndex);
    171129
    172130private:
     
    179137    void prepareConnections();
    180138
    181     /** Populates combo-boxes. */
    182     void populateComboboxes();
     139    /** Populates combo. */
     140    void populateCombo();
    183141
    184     /** Holds the parent page reference. */
    185     UIMachineSettingsSerialPage *m_pParent;
    186 
    187     /** Holds the port slot number. */
    188     int        m_iSlot;
    189     /** Holds the port mode. */
     142    /** Holds the mode. */
    190143    KPortMode  m_enmPortMode;
    191144
     
    221174};
    222175
    223 
    224 /*********************************************************************************************************************************
    225 *   Class UIMachineSettingsSerial implementation.                                                                                *
    226 *********************************************************************************************************************************/
    227 
    228 UIMachineSettingsSerial::UIMachineSettingsSerial(UIMachineSettingsSerialPage *pParent)
    229     : QIWithRetranslateUI<QWidget>(0)
    230     , m_pParent(pParent)
    231     , m_iSlot(-1)
    232     , m_enmPortMode(KPortMode_Max)
    233     , m_pCheckBoxPort(0)
    234     , m_pWidgetPortSettings(0)
    235     , m_pLabelNumber(0)
    236     , m_pComboNumber(0)
    237     , m_pLabelIRQ(0)
    238     , m_pLineEditIRQ(0)
    239     , m_pLabelIOAddress(0)
    240     , m_pLineEditIOAddress(0)
    241     , m_pLabelMode(0)
    242     , m_pComboMode(0)
    243     , m_pCheckBoxPipe(0)
    244     , m_pLabelPath(0)
    245     , m_pEditorPath(0)
    246 {
    247     prepare();
    248 }
    249 
    250 void UIMachineSettingsSerial::getPortDataFromCache(const UISettingsCacheMachineSerialPort &portCache)
    251 {
    252     /* Get old data: */
    253     const UIDataSettingsMachineSerialPort &oldPortData = portCache.base();
    254 
    255     /* Load port number: */
    256     m_iSlot = oldPortData.m_iSlot;
    257 
    258     /* Load port data: */
    259     if (m_pCheckBoxPort)
    260         m_pCheckBoxPort->setChecked(oldPortData.m_fPortEnabled);
    261     if (m_pComboNumber)
    262         m_pComboNumber->setCurrentIndex(m_pComboNumber->findText(UITranslator::toCOMPortName(oldPortData.m_uIRQ, oldPortData.m_uIOAddress)));
    263     if (m_pLineEditIRQ)
    264         m_pLineEditIRQ->setText(QString::number(oldPortData.m_uIRQ));
    265     if (m_pLineEditIOAddress)
    266         m_pLineEditIOAddress->setText("0x" + QString::number(oldPortData.m_uIOAddress, 16).toUpper());
    267     m_enmPortMode = oldPortData.m_hostMode;
    268     if (m_pCheckBoxPipe)
    269         m_pCheckBoxPipe->setChecked(!oldPortData.m_fServer);
    270     if (m_pEditorPath)
    271         m_pEditorPath->setText(oldPortData.m_strPath);
    272 
    273     /* Repopulate combo-boxes content: */
    274     populateComboboxes();
    275     /* Ensure everything is up-to-date */
    276     if (m_pCheckBoxPort)
    277         sltHandlePortAvailabilityToggled(m_pCheckBoxPort->isChecked());
    278 }
    279 
    280 void UIMachineSettingsSerial::putPortDataToCache(UISettingsCacheMachineSerialPort &portCache)
    281 {
    282     /* Prepare new data: */
    283     UIDataSettingsMachineSerialPort newPortData;
    284 
    285     /* Save port number: */
    286     newPortData.m_iSlot = m_iSlot;
    287 
    288     /* Save port data: */
    289     if (m_pCheckBoxPort)
    290         newPortData.m_fPortEnabled = m_pCheckBoxPort->isChecked();
    291     if (m_pLineEditIRQ)
    292         newPortData.m_uIRQ = m_pLineEditIRQ->text().toULong(NULL, 0);
    293     if (m_pLineEditIOAddress)
    294         newPortData.m_uIOAddress = m_pLineEditIOAddress->text().toULong(NULL, 0);
    295     if (m_pCheckBoxPipe)
    296         newPortData.m_fServer = !m_pCheckBoxPipe->isChecked();
    297     if (m_pComboMode)
    298         newPortData.m_hostMode = m_pComboMode->currentData().value<KPortMode>();
    299     if (m_pEditorPath)
    300         newPortData.m_strPath = QDir::toNativeSeparators(m_pEditorPath->text());
    301 
    302     /* Cache new data: */
    303     portCache.cacheCurrentData(newPortData);
    304 }
    305 
    306 bool UIMachineSettingsSerial::validate(QList<UIValidationMessage> &messages)
    307 {
    308     /* Pass by default: */
    309     bool fPass = true;
    310 
    311     /* Prepare message: */
    312     UIValidationMessage message;
    313     message.first = UITranslator::removeAccelMark(tabTitle());
    314 
    315     if (   m_pCheckBoxPort
    316         && m_pCheckBoxPort->isChecked())
    317     {
    318         /* Check the port attribute emptiness & uniqueness: */
    319         const QString strIRQ = m_pLineEditIRQ ? m_pLineEditIRQ->text() : QString();
    320         const QString strIOAddress = m_pLineEditIOAddress ? m_pLineEditIOAddress->text() : QString();
    321         const QPair<QString, QString> port = qMakePair(strIRQ, strIOAddress);
    322 
    323         if (strIRQ.isEmpty())
    324         {
    325             message.second << UIMachineSettingsSerial::tr("No IRQ is currently specified.");
    326             fPass = false;
    327         }
    328         if (strIOAddress.isEmpty())
    329         {
    330             message.second << UIMachineSettingsSerial::tr("No I/O port is currently specified.");
    331             fPass = false;
    332         }
    333         if (   !strIRQ.isEmpty()
    334             && !strIOAddress.isEmpty())
    335         {
    336             QVector<QPair<QString, QString> > ports;
    337             if (m_pParent)
    338             {
    339                 ports = m_pParent->ports();
    340                 ports.removeAt(m_iSlot);
    341             }
    342             if (ports.contains(port))
    343             {
    344                 message.second << UIMachineSettingsSerial::tr("Two or more ports have the same settings.");
    345                 fPass = false;
    346             }
    347         }
    348 
    349         const KPortMode enmMode = m_pComboMode->currentData().value<KPortMode>();
    350         if (enmMode != KPortMode_Disconnected)
    351         {
    352             const QString strPath(m_pEditorPath->text());
    353 
    354             if (strPath.isEmpty())
    355             {
    356                 message.second << UIMachineSettingsSerial::tr("No port path is currently specified.");
    357                 fPass = false;
    358             }
    359             else
    360             {
    361                 QVector<QString> paths;
    362                 if (m_pParent)
    363                 {
    364                     paths = m_pParent->paths();
    365                     paths.removeAt(m_iSlot);
    366                 }
    367                 if (paths.contains(strPath))
    368                 {
    369                     message.second << UIMachineSettingsSerial::tr("There are currently duplicate port paths specified.");
    370                     fPass = false;
    371                 }
    372             }
    373         }
    374     }
    375 
    376     /* Serialize message: */
    377     if (!message.second.isEmpty())
    378         messages << message;
    379 
    380     /* Return result: */
    381     return fPass;
    382 }
    383 
    384 QWidget *UIMachineSettingsSerial::setOrderAfter(QWidget *pWidget)
    385 {
    386     setTabOrder(pWidget, m_pCheckBoxPort);
    387     setTabOrder(m_pCheckBoxPort, m_pComboNumber);
    388     setTabOrder(m_pComboNumber, m_pLineEditIRQ);
    389     setTabOrder(m_pLineEditIRQ, m_pLineEditIOAddress);
    390     setTabOrder(m_pLineEditIOAddress, m_pComboMode);
    391     setTabOrder(m_pComboMode, m_pCheckBoxPipe);
    392     setTabOrder(m_pCheckBoxPipe, m_pEditorPath);
    393     return m_pEditorPath;
    394 }
    395 
    396 QString UIMachineSettingsSerial::tabTitle() const
    397 {
    398     return QString(tr("Port %1", "serial ports")).arg(QString("&%1").arg(m_iSlot + 1));
    399 }
    400 
    401 bool UIMachineSettingsSerial::isPortEnabled() const
    402 {
    403     return m_pCheckBoxPort->isChecked();
    404 }
    405 
    406 QString UIMachineSettingsSerial::irq() const
    407 {
    408     return m_pLineEditIRQ->text();
    409 }
    410 
    411 QString UIMachineSettingsSerial::ioAddress() const
    412 {
    413     return m_pLineEditIOAddress->text();
    414 }
    415 
    416 QString UIMachineSettingsSerial::path() const
    417 {
    418     return m_pEditorPath->text();
    419 }
    420 
    421 void UIMachineSettingsSerial::polishTab()
    422 {
    423     /* Sanity check: */
    424     if (!m_pParent)
    425         return;
    426 
    427     /* Polish port page: */
    428     ulong uIRQ, uIOAddress;
    429     const bool fStd = m_pComboNumber ? UITranslator::toCOMPortNumbers(m_pComboNumber->currentText(), uIRQ, uIOAddress) : false;
    430     const KPortMode enmMode = m_pComboMode ? m_pComboMode->currentData().value<KPortMode>() : KPortMode_Max;
    431     if (m_pCheckBoxPort)
    432         m_pCheckBoxPort->setEnabled(m_pParent->isMachineOffline());
    433     if (m_pLabelNumber)
    434         m_pLabelNumber->setEnabled(m_pParent->isMachineOffline());
    435     if (m_pComboNumber)
    436         m_pComboNumber->setEnabled(m_pParent->isMachineOffline());
    437     if (m_pLabelIRQ)
    438         m_pLabelIRQ->setEnabled(m_pParent->isMachineOffline());
    439     if (m_pLineEditIRQ)
    440         m_pLineEditIRQ->setEnabled(!fStd && m_pParent->isMachineOffline());
    441     if (m_pLabelIOAddress)
    442         m_pLabelIOAddress->setEnabled(m_pParent->isMachineOffline());
    443     if (m_pLineEditIOAddress)
    444         m_pLineEditIOAddress->setEnabled(!fStd && m_pParent->isMachineOffline());
    445     if (m_pLabelMode)
    446         m_pLabelMode->setEnabled(m_pParent->isMachineOffline());
    447     if (m_pComboMode)
    448         m_pComboMode->setEnabled(m_pParent->isMachineOffline());
    449     if (m_pCheckBoxPipe)
    450         m_pCheckBoxPipe->setEnabled(   (enmMode == KPortMode_HostPipe || enmMode == KPortMode_TCP)
    451                                     && m_pParent->isMachineOffline());
    452     if (m_pLabelPath)
    453         m_pLabelPath->setEnabled(   enmMode != KPortMode_Disconnected
    454                                  && m_pParent->isMachineOffline());
    455     if (m_pEditorPath)
    456         m_pEditorPath->setEnabled(   enmMode != KPortMode_Disconnected
    457                                   && m_pParent->isMachineOffline());
    458 }
    459 
    460 void UIMachineSettingsSerial::retranslateUi()
    461 {
    462     if (m_pCheckBoxPort)
    463     {
    464         m_pCheckBoxPort->setText(tr("&Enable Serial Port"));
    465         m_pCheckBoxPort->setToolTip(tr("When checked, enables the given serial port of the virtual machine."));
    466     }
    467     if (m_pLabelNumber)
    468         m_pLabelNumber->setText(tr("Port &Number:"));
    469     if (m_pComboNumber)
    470     {
    471         m_pComboNumber->setItemText(m_pComboNumber->count() - 1, UITranslator::toCOMPortName(0, 0));
    472         m_pComboNumber->setToolTip(tr("Selects the serial port number. You can choose one of the standard serial ports or select "
    473                                       "User-defined and specify port parameters manually."));
    474     }
    475     if (m_pLabelIRQ)
    476         m_pLabelIRQ->setText(tr("&IRQ:"));
    477     if (m_pLineEditIRQ)
    478         m_pLineEditIRQ->setToolTip(tr("Holds the IRQ number of this serial port. This should be a whole number between "
    479                                       "<tt>0</tt> and <tt>255</tt>. Values greater than <tt>15</tt> may only be used if the "
    480                                       "I/O APIC setting is enabled for this virtual machine."));
    481     if (m_pLabelIOAddress)
    482         m_pLabelIOAddress->setText(tr("I/O Po&rt:"));
    483     if (m_pLineEditIOAddress)
    484         m_pLineEditIOAddress->setToolTip(tr("Holds the base I/O port address of this serial port. Valid values are integer numbers "
    485                                             "in range from <tt>0</tt> to <tt>0xFFFF</tt>."));
    486     if (m_pLabelMode)
    487         m_pLabelMode->setText(tr("Port &Mode:"));
    488     if (m_pComboMode)
    489         m_pComboMode->setToolTip(tr("Selects the working mode of this serial port. If you select Disconnected, the guest "
    490                                     "OS will detect the serial port but will not be able to operate it."));
    491     if (m_pCheckBoxPipe)
    492     {
    493         m_pCheckBoxPipe->setText(tr("&Connect to existing pipe/socket"));
    494         m_pCheckBoxPipe->setToolTip(tr("When checked, the virtual machine will assume that the pipe or socket specified in the "
    495                                        "Path/Address field exists and try to use it. Otherwise, the pipe or socket will "
    496                                        "be created by the virtual machine when it starts."));
    497     }
    498     if (m_pLabelPath)
    499         m_pLabelPath->setText(tr("&Path/Address:"));
    500     if (m_pEditorPath)
    501         m_pEditorPath->setToolTip(tr("In Host Pipe mode: Holds the path to the serial port's pipe on the host. "
    502                                      "Examples: \"\\\\.\\pipe\\myvbox\" or \"/tmp/myvbox\", for Windows and UNIX-like systems "
    503                                      "respectively. In Host Device mode: Holds the host serial device name. "
    504                                      "Examples: \"COM1\" or \"/dev/ttyS0\". In Raw File mode: Holds the file-path "
    505                                      "on the host system, where the serial output will be dumped. In TCP mode: "
    506                                      "Holds the TCP \"port\" when in server mode, or \"hostname:port\" when in client mode."));
    507 
    508     /* Translate combo-boxes content: */
    509     populateComboboxes();
    510 }
    511 
    512 void UIMachineSettingsSerial::sltHandlePortAvailabilityToggled(bool fOn)
    513 {
    514     /* Update availability: */
    515     m_pWidgetPortSettings->setEnabled(m_pCheckBoxPort->isChecked());
    516     if (fOn)
    517     {
    518         sltHandlePortStandardOptionActivated(m_pComboNumber->currentText());
    519         sltHandlePortModeChange(m_pComboMode->currentIndex());
    520     }
    521 
    522     /* Notify port/path changed: */
    523     emit sigPortChanged();
    524     emit sigPathChanged();
    525 }
    526 
    527 void UIMachineSettingsSerial::sltHandlePortStandardOptionActivated(const QString &strText)
    528 {
    529     /* Update availability: */
    530     ulong uIRQ, uIOAddress;
    531     bool fStd = UITranslator::toCOMPortNumbers(strText, uIRQ, uIOAddress);
    532     m_pLineEditIRQ->setEnabled(!fStd);
    533     m_pLineEditIOAddress->setEnabled(!fStd);
    534     if (fStd)
    535     {
    536         m_pLineEditIRQ->setText(QString::number(uIRQ));
    537         m_pLineEditIOAddress->setText("0x" + QString::number(uIOAddress, 16).toUpper());
    538     }
    539 
    540     /* Notify validity changed: */
    541     emit sigValidityChanged();
    542 }
    543 
    544 void UIMachineSettingsSerial::sltHandlePortModeChange(int iIndex)
    545 {
    546     /* Update availability: */
    547     const KPortMode enmMode = m_pComboMode->itemData(iIndex).value<KPortMode>();
    548     m_pCheckBoxPipe->setEnabled(enmMode == KPortMode_HostPipe || enmMode == KPortMode_TCP);
    549     m_pEditorPath->setEnabled(enmMode != KPortMode_Disconnected);
    550     m_pLabelPath->setEnabled(enmMode != KPortMode_Disconnected);
    551 
    552     /* Notify validity changed: */
    553     emit sigValidityChanged();
    554 }
    555 
    556 void UIMachineSettingsSerial::prepare()
    557 {
    558     /* Prepare everything: */
    559     prepareWidgets();
    560     prepareConnections();
    561 
    562     /* Apply language settings: */
    563     retranslateUi();
    564 }
    565 
    566 void UIMachineSettingsSerial::prepareWidgets()
    567 {
    568     /* Prepare main layout: */
    569     QGridLayout *pLayoutMain = new QGridLayout(this);
    570     if (pLayoutMain)
    571     {
    572         pLayoutMain->setRowStretch(2, 1);
    573 
    574         /* Prepare port check-box: */
    575         m_pCheckBoxPort = new QCheckBox(this);
    576         if (m_pCheckBoxPort)
    577             pLayoutMain->addWidget(m_pCheckBoxPort, 0, 0, 1, 2);
    578 
    579         /* Prepare 20-px shifting spacer: */
    580         QSpacerItem *pSpacerItem = new QSpacerItem(20, 0, QSizePolicy::Fixed, QSizePolicy::Minimum);
    581         if (pSpacerItem)
    582             pLayoutMain->addItem(pSpacerItem, 1, 0);
    583 
    584         /* Prepare adapter settings widget: */
    585         m_pWidgetPortSettings = new QWidget(this);
    586         if (m_pWidgetPortSettings)
    587         {
    588             /* Prepare adapter settings widget layout: */
    589             QGridLayout *pLayoutPortSettings = new QGridLayout(m_pWidgetPortSettings);
    590             if (pLayoutPortSettings)
    591             {
    592                 pLayoutPortSettings->setContentsMargins(0, 0, 0, 0);
    593                 pLayoutPortSettings->setColumnStretch(6, 1);
    594 
    595                 /* Prepare number label: */
    596                 m_pLabelNumber = new QLabel(m_pWidgetPortSettings);
    597                 if (m_pLabelNumber)
    598                 {
    599                     m_pLabelNumber->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    600                     pLayoutPortSettings->addWidget(m_pLabelNumber, 0, 0);
    601                 }
    602                 /* Prepare number combo: */
    603                 m_pComboNumber = new QComboBox(m_pWidgetPortSettings);
    604                 if (m_pComboNumber)
    605                 {
    606                     if (m_pLabelNumber)
    607                         m_pLabelNumber->setBuddy(m_pComboNumber);
    608                     m_pComboNumber->insertItem(0, UITranslator::toCOMPortName(0, 0));
    609                     m_pComboNumber->insertItems(0, UITranslator::COMPortNames());
    610                     pLayoutPortSettings->addWidget(m_pComboNumber, 0, 1);
    611                 }
    612                 /* Prepare IRQ label: */
    613                 m_pLabelIRQ = new QLabel(m_pWidgetPortSettings);
    614                 if (m_pLabelIRQ)
    615                     pLayoutPortSettings->addWidget(m_pLabelIRQ, 0, 2);
    616                 /* Prepare IRQ label: */
    617                 m_pLineEditIRQ = new QLineEdit(m_pWidgetPortSettings);
    618                 if (m_pLineEditIRQ)
    619                 {
    620                     if (m_pLabelIRQ)
    621                         m_pLabelIRQ->setBuddy(m_pLineEditIRQ);
    622 #if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
    623                     m_pLineEditIRQ->setFixedWidth(m_pLineEditIRQ->fontMetrics().horizontalAdvance("8888"));
    624 #else
    625                     m_pLineEditIRQ->setFixedWidth(m_pLineEditIRQ->fontMetrics().width("8888"));
    626 #endif
    627                     m_pLineEditIRQ->setValidator(new QIULongValidator(0, 255, this));
    628                     pLayoutPortSettings->addWidget(m_pLineEditIRQ, 0, 3);
    629                 }
    630                 /* Prepare IO address label: */
    631                 m_pLabelIOAddress = new QLabel(m_pWidgetPortSettings);
    632                 if (m_pLabelIOAddress)
    633                     pLayoutPortSettings->addWidget(m_pLabelIOAddress, 0, 4);
    634                 /* Prepare IO address label: */
    635                 m_pLineEditIOAddress = new QLineEdit(m_pWidgetPortSettings);
    636                 if (m_pLineEditIOAddress)
    637                 {
    638                     if (m_pLabelIOAddress)
    639                         m_pLabelIOAddress->setBuddy(m_pLineEditIOAddress);
    640 #if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
    641                     m_pLineEditIOAddress->setFixedWidth(m_pLineEditIOAddress->fontMetrics().horizontalAdvance("8888888"));
    642 #else
    643                     m_pLineEditIOAddress->setFixedWidth(m_pLineEditIOAddress->fontMetrics().width("8888888"));
    644 #endif
    645                     m_pLineEditIOAddress->setValidator(new QIULongValidator(0, 0xFFFF, this));
    646                     pLayoutPortSettings->addWidget(m_pLineEditIOAddress, 0, 5);
    647                 }
    648 
    649                 /* Prepare mode label: */
    650                 m_pLabelMode = new QLabel(m_pWidgetPortSettings);
    651                 if (m_pLabelMode)
    652                 {
    653                     m_pLabelMode->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    654                     pLayoutPortSettings->addWidget(m_pLabelMode, 1, 0);
    655                 }
    656                 /* Prepare mode combo: */
    657                 m_pComboMode = new QComboBox(m_pWidgetPortSettings);
    658                 if (m_pComboMode)
    659                 {
    660                     if (m_pLabelMode)
    661                         m_pLabelMode->setBuddy(m_pComboMode);
    662                     pLayoutPortSettings->addWidget(m_pComboMode, 1, 1);
    663                 }
    664 
    665                 /* Prepare pipe check-box: */
    666                 m_pCheckBoxPipe = new QCheckBox(m_pWidgetPortSettings);
    667                 if (m_pCheckBoxPipe)
    668                     pLayoutPortSettings->addWidget(m_pCheckBoxPipe, 2, 1, 1, 5);
    669 
    670                 /* Prepare path label: */
    671                 m_pLabelPath = new QLabel(m_pWidgetPortSettings);
    672                 if (m_pLabelPath)
    673                 {
    674                     m_pLabelPath->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    675                     pLayoutPortSettings->addWidget(m_pLabelPath, 3, 0);
    676                 }
    677                 /* Prepare path editor: */
    678                 m_pEditorPath = new QLineEdit(m_pWidgetPortSettings);
    679                 if (m_pEditorPath)
    680                 {
    681                     if (m_pLabelPath)
    682                         m_pLabelPath->setBuddy(m_pEditorPath);
    683                     m_pEditorPath->setValidator(new QRegularExpressionValidator(QRegularExpression(".+"), this));
    684                     pLayoutPortSettings->addWidget(m_pEditorPath, 3, 1, 1, 6);
    685                 }
    686             }
    687 
    688             pLayoutMain->addWidget(m_pWidgetPortSettings, 1, 1);
    689         }
    690     }
    691 }
    692 
    693 void UIMachineSettingsSerial::prepareConnections()
    694 {
    695     if (m_pCheckBoxPort)
    696         connect(m_pCheckBoxPort, &QCheckBox::toggled, this, &UIMachineSettingsSerial::sltHandlePortAvailabilityToggled);
    697 #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
    698     if (m_pComboNumber)
    699         connect(m_pComboNumber, static_cast<void(QComboBox::*)(const QString&)>(&QComboBox::textActivated),
    700                 this, &UIMachineSettingsSerial::sltHandlePortStandardOptionActivated);
    701 #else
    702     if (m_pComboNumber)
    703         connect(m_pComboNumber, static_cast<void(QComboBox::*)(const QString&)>(&QComboBox::activated),
    704                 this, &UIMachineSettingsSerial::sltHandlePortStandardOptionActivated);
    705 #endif
    706     if (m_pLineEditIRQ)
    707         connect(m_pLineEditIRQ, &QLineEdit::textChanged, this, &UIMachineSettingsSerial::sigPortChanged);
    708     if (m_pLineEditIOAddress)
    709         connect(m_pLineEditIOAddress, &QLineEdit::textChanged, this, &UIMachineSettingsSerial::sigPortChanged);
    710     if (m_pComboMode)
    711         connect(m_pComboMode, static_cast<void(QComboBox::*)(int)>(&QComboBox::activated),
    712                 this, &UIMachineSettingsSerial::sltHandlePortModeChange);
    713     if (m_pEditorPath)
    714         connect(m_pEditorPath, &QLineEdit::textChanged, this, &UIMachineSettingsSerial::sigPathChanged);
    715 }
    716 
    717 void UIMachineSettingsSerial::populateComboboxes()
    718 {
    719     /* Port mode: */
    720     {
    721         /* Clear the port mode combo-box: */
    722         m_pComboMode->clear();
    723 
    724         /* Load currently supported port moded: */
    725         CSystemProperties comProperties = uiCommon().virtualBox().GetSystemProperties();
    726         QVector<KPortMode> supportedModes = comProperties.GetSupportedPortModes();
    727         /* Take currently requested mode into account if it's sane: */
    728         if (!supportedModes.contains(m_enmPortMode) && m_enmPortMode != KPortMode_Max)
    729             supportedModes.prepend(m_enmPortMode);
    730 
    731         /* Populate port modes: */
    732         int iPortModeIndex = 0;
    733         foreach (const KPortMode &enmMode, supportedModes)
    734         {
    735             m_pComboMode->insertItem(iPortModeIndex, gpConverter->toString(enmMode));
    736             m_pComboMode->setItemData(iPortModeIndex, QVariant::fromValue(enmMode));
    737             m_pComboMode->setItemData(iPortModeIndex, m_pComboMode->itemText(iPortModeIndex), Qt::ToolTipRole);
    738             ++iPortModeIndex;
    739         }
    740 
    741         /* Choose requested port mode: */
    742         const int iIndex = m_pComboMode->findData(QVariant::fromValue(m_enmPortMode));
    743         m_pComboMode->setCurrentIndex(iIndex != -1 ? iIndex : 0);
    744     }
    745 }
    746 
    747 
    748 /*********************************************************************************************************************************
    749 *   Class UIMachineSettingsSerialPage implementation.                                                                            *
    750 *********************************************************************************************************************************/
    751 
    752 UIMachineSettingsSerialPage::UIMachineSettingsSerialPage()
    753     : m_pCache(0)
    754     , m_pTabWidget(0)
    755 {
    756     prepare();
    757 }
    758 
    759 UIMachineSettingsSerialPage::~UIMachineSettingsSerialPage()
    760 {
    761     cleanup();
    762 }
    763 
    764 bool UIMachineSettingsSerialPage::changed() const
    765 {
    766     return m_pCache ? m_pCache->wasChanged() : false;
    767 }
    768 
    769 void UIMachineSettingsSerialPage::loadToCacheFrom(QVariant &data)
    770 {
    771     /* Sanity check: */
    772     if (   !m_pCache
    773         || !m_pTabWidget)
    774         return;
    775 
    776     /* Fetch data to machine: */
    777     UISettingsPageMachine::fetchData(data);
    778 
    779     /* Clear cache initially: */
    780     m_pCache->clear();
    781 
    782     /* Cache lists: */
    783     refreshPorts();
    784     refreshPaths();
    785 
    786     /* Prepare old data: */
    787     UIDataSettingsMachineSerial oldSerialData;
    788 
    789     /* For each serial port: */
    790     for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot)
    791     {
    792         /* Prepare old data: */
    793         UIDataSettingsMachineSerialPort oldPortData;
    794 
    795         /* Check whether port is valid: */
    796         const CSerialPort &comPort = m_machine.GetSerialPort(iSlot);
    797         if (!comPort.isNull())
    798         {
    799             /* Gather old data: */
    800             oldPortData.m_iSlot = iSlot;
    801             oldPortData.m_fPortEnabled = comPort.GetEnabled();
    802             oldPortData.m_uIRQ = comPort.GetIRQ();
    803             oldPortData.m_uIOAddress = comPort.GetIOAddress();
    804             oldPortData.m_hostMode = comPort.GetHostMode();
    805             oldPortData.m_fServer = comPort.GetServer();
    806             oldPortData.m_strPath = comPort.GetPath();
    807         }
    808 
    809         /* Cache old data: */
    810         m_pCache->child(iSlot).cacheInitialData(oldPortData);
    811     }
    812 
    813     /* Cache old data: */
    814     m_pCache->cacheInitialData(oldSerialData);
    815 
    816     /* Upload machine to data: */
    817     UISettingsPageMachine::uploadData(data);
    818 }
    819 
    820 void UIMachineSettingsSerialPage::getFromCache()
    821 {
    822     /* Sanity check: */
    823     if (   !m_pCache
    824         || !m_pTabWidget)
    825         return;
    826 
    827     /* Setup tab order: */
    828     AssertPtrReturnVoid(firstWidget());
    829     setTabOrder(firstWidget(), m_pTabWidget->focusProxy());
    830     QWidget *pLastFocusWidget = m_pTabWidget->focusProxy();
    831 
    832     /* For each port: */
    833     for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot)
    834     {
    835         /* Get port page: */
    836         UIMachineSettingsSerial *pTab = qobject_cast<UIMachineSettingsSerial*>(m_pTabWidget->widget(iSlot));
    837         AssertPtrReturnVoid(pTab);
    838 
    839         /* Load old data from cache: */
    840         pTab->getPortDataFromCache(m_pCache->child(iSlot));
    841 
    842         /* Setup tab order: */
    843         pLastFocusWidget = pTab->setOrderAfter(pLastFocusWidget);
    844     }
    845 
    846     /* Apply language settings: */
    847     retranslateUi();
    848 
    849     /* Polish page finally: */
    850     polishPage();
    851 
    852     /* Revalidate: */
    853     revalidate();
    854 }
    855 
    856 void UIMachineSettingsSerialPage::putToCache()
    857 {
    858     /* Sanity check: */
    859     if (   !m_pCache
    860         || !m_pTabWidget)
    861         return;
    862 
    863     /* Prepare new data: */
    864     UIDataSettingsMachineSerial newSerialData;
    865 
    866     /* For each port: */
    867     for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot)
    868     {
    869         /* Getting port page: */
    870         UIMachineSettingsSerial *pTab = qobject_cast<UIMachineSettingsSerial*>(m_pTabWidget->widget(iSlot));
    871         AssertPtrReturnVoid(pTab);
    872 
    873         /* Gather new data: */
    874         pTab->putPortDataToCache(m_pCache->child(iSlot));
    875     }
    876 
    877     /* Cache new data: */
    878     m_pCache->cacheCurrentData(newSerialData);
    879 }
    880 
    881 void UIMachineSettingsSerialPage::saveFromCacheTo(QVariant &data)
    882 {
    883     /* Fetch data to machine: */
    884     UISettingsPageMachine::fetchData(data);
    885 
    886     /* Update data and failing state: */
    887     setFailed(!saveData());
    888 
    889     /* Upload machine to data: */
    890     UISettingsPageMachine::uploadData(data);
    891 }
    892 
    893 bool UIMachineSettingsSerialPage::validate(QList<UIValidationMessage> &messages)
    894 {
    895     /* Sanity check: */
    896     if (!m_pTabWidget)
    897         return false;
    898 
    899     /* Pass by default: */
    900     bool fValid = true;
    901 
    902     /* Delegate validation to adapter tabs: */
    903     for (int iIndex = 0; iIndex < m_pTabWidget->count(); ++iIndex)
    904     {
    905         UIMachineSettingsSerial *pTab = qobject_cast<UIMachineSettingsSerial*>(m_pTabWidget->widget(iIndex));
    906         AssertPtrReturn(pTab, false);
    907         if (!pTab->validate(messages))
    908             fValid = false;
    909     }
    910 
    911     /* Return result: */
    912     return fValid;
    913 }
    914 
    915 void UIMachineSettingsSerialPage::retranslateUi()
    916 {
    917     /* Sanity check: */
    918     if (!m_pTabWidget)
    919         return;
    920 
    921     for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot)
    922     {
    923         UIMachineSettingsSerial *pTab = qobject_cast<UIMachineSettingsSerial*>(m_pTabWidget->widget(iSlot));
    924         AssertPtrReturnVoid(pTab);
    925         m_pTabWidget->setTabText(iSlot, pTab->tabTitle());
    926     }
    927 }
    928 
    929 void UIMachineSettingsSerialPage::polishPage()
    930 {
    931     /* Sanity check: */
    932     if (   !m_pCache
    933         || !m_pTabWidget)
    934         return;
    935 
    936     for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot)
    937     {
    938         m_pTabWidget->setTabEnabled(iSlot,
    939                                     isMachineOffline() ||
    940                                     (isMachineInValidMode() &&
    941                                      m_pCache->childCount() > iSlot &&
    942                                      m_pCache->child(iSlot).base().m_fPortEnabled));
    943         UIMachineSettingsSerial *pTab = qobject_cast<UIMachineSettingsSerial*>(m_pTabWidget->widget(iSlot));
    944         AssertPtrReturnVoid(pTab);
    945         pTab->polishTab();
    946     }
    947 }
    948 
    949 void UIMachineSettingsSerialPage::sltHandlePortChange()
    950 {
    951     refreshPorts();
    952     revalidate();
    953 }
    954 
    955 void UIMachineSettingsSerialPage::sltHandlePathChange()
    956 {
    957     refreshPaths();
    958     revalidate();
    959 }
    960 
    961 void UIMachineSettingsSerialPage::prepare()
    962 {
    963     /* Prepare cache: */
    964     m_pCache = new UISettingsCacheMachineSerial;
    965     AssertPtrReturnVoid(m_pCache);
    966 
    967     /* Create main layout: */
    968     QVBoxLayout *pLayoutMain = new QVBoxLayout(this);
    969     if (pLayoutMain)
    970     {
    971         /* Creating tab-widget: */
    972         m_pTabWidget = new QITabWidget;
    973         if (m_pTabWidget)
    974         {
    975             /* How many ports to display: */
    976             const ulong uCount = uiCommon().virtualBox().GetPlatformProperties(KPlatformArchitecture_x86).GetSerialPortCount();
    977 
    978             /* Create corresponding port tabs: */
    979             for (ulong uSlot = 0; uSlot < uCount; ++uSlot)
    980             {
    981                 /* Create port tab: */
    982                 UIMachineSettingsSerial *pTab = new UIMachineSettingsSerial(this);
    983                 if (pTab)
    984                 {
    985                     /* Tab connections: */
    986                     connect(pTab, &UIMachineSettingsSerial::sigPortChanged,
    987                             this, &UIMachineSettingsSerialPage::sltHandlePortChange);
    988                     connect(pTab, &UIMachineSettingsSerial::sigPathChanged,
    989                             this, &UIMachineSettingsSerialPage::sltHandlePathChange);
    990                     connect(pTab, &UIMachineSettingsSerial::sigValidityChanged,
    991                             this, &UIMachineSettingsSerialPage::revalidate);
    992 
    993                     /* Add tab into tab-widget: */
    994                     m_pTabWidget->addTab(pTab, pTab->tabTitle());
    995                 }
    996             }
    997 
    998             /* Add tab-widget into layout: */
    999             pLayoutMain->addWidget(m_pTabWidget);
    1000         }
    1001     }
    1002 }
    1003 
    1004 void UIMachineSettingsSerialPage::cleanup()
    1005 {
    1006     /* Cleanup cache: */
    1007     delete m_pCache;
    1008     m_pCache = 0;
    1009 }
    1010 
    1011 void UIMachineSettingsSerialPage::refreshPorts()
    1012 {
    1013     /* Sanity check: */
    1014     if (!m_pTabWidget)
    1015         return;
    1016 
    1017     /* Reload port list: */
    1018     m_ports.clear();
    1019     m_ports.resize(m_pTabWidget->count());
    1020     /* Append port list with data from all the tabs: */
    1021     for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot)
    1022     {
    1023         UIMachineSettingsSerial *pTab = qobject_cast<UIMachineSettingsSerial*>(m_pTabWidget->widget(iSlot));
    1024         AssertPtrReturnVoid(pTab);
    1025         m_ports[iSlot] = pTab->isPortEnabled() ? qMakePair(pTab->irq(), pTab->ioAddress()) : qMakePair(QString(), QString());
    1026     }
    1027 }
    1028 
    1029 void UIMachineSettingsSerialPage::refreshPaths()
    1030 {
    1031     /* Sanity check: */
    1032     if (!m_pTabWidget)
    1033         return;
    1034 
    1035     /* Reload path list: */
    1036     m_paths.clear();
    1037     m_paths.resize(m_pTabWidget->count());
    1038     /* Append path list with data from all the tabs: */
    1039     for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot)
    1040     {
    1041         UIMachineSettingsSerial *pTab = qobject_cast<UIMachineSettingsSerial*>(m_pTabWidget->widget(iSlot));
    1042         AssertPtrReturnVoid(pTab);
    1043         m_paths[iSlot] = pTab->isPortEnabled() ? pTab->path() : QString();
    1044     }
    1045 }
    1046 
    1047 bool UIMachineSettingsSerialPage::saveData()
    1048 {
    1049     /* Sanity check: */
    1050     if (   !m_pCache
    1051         || !m_pTabWidget)
    1052         return false;
    1053 
    1054     /* Prepare result: */
    1055     bool fSuccess = true;
    1056     /* Save serial settings from cache: */
    1057     if (fSuccess && isMachineInValidMode() && m_pCache->wasChanged())
    1058     {
    1059         /* For each port: */
    1060         for (int iSlot = 0; fSuccess && iSlot < m_pTabWidget->count(); ++iSlot)
    1061             fSuccess = savePortData(iSlot);
    1062     }
    1063     /* Return result: */
    1064     return fSuccess;
    1065 }
    1066 
    1067 bool UIMachineSettingsSerialPage::savePortData(int iSlot)
    1068 {
    1069     /* Sanity check: */
    1070     if (!m_pCache)
    1071         return false;
    1072 
    1073     /* Prepare result: */
    1074     bool fSuccess = true;
    1075     /* Save adapter settings from cache: */
    1076     if (fSuccess && m_pCache->child(iSlot).wasChanged())
    1077     {
    1078         /* Get old data from cache: */
    1079         const UIDataSettingsMachineSerialPort &oldPortData = m_pCache->child(iSlot).base();
    1080         /* Get new data from cache: */
    1081         const UIDataSettingsMachineSerialPort &newPortData = m_pCache->child(iSlot).data();
    1082 
    1083         /* Get serial port for further activities: */
    1084         CSerialPort comPort = m_machine.GetSerialPort(iSlot);
    1085         fSuccess = m_machine.isOk() && comPort.isNotNull();
    1086 
    1087         /* Show error message if necessary: */
    1088         if (!fSuccess)
    1089             notifyOperationProgressError(UIErrorString::formatErrorInfo(m_machine));
    1090         else
    1091         {
    1092             // This *must* be first.
    1093             // If the requested host mode is changed to disconnected we should do it first.
    1094             // That allows to automatically fulfill the requirements for some of the settings below.
    1095             /* Save port host mode: */
    1096             if (   fSuccess && isMachineOffline()
    1097                 && newPortData.m_hostMode != oldPortData.m_hostMode
    1098                 && newPortData.m_hostMode == KPortMode_Disconnected)
    1099             {
    1100                 comPort.SetHostMode(newPortData.m_hostMode);
    1101                 fSuccess = comPort.isOk();
    1102             }
    1103             /* Save whether the port is enabled: */
    1104             if (fSuccess && isMachineOffline() && newPortData.m_fPortEnabled != oldPortData.m_fPortEnabled)
    1105             {
    1106                 comPort.SetEnabled(newPortData.m_fPortEnabled);
    1107                 fSuccess = comPort.isOk();
    1108             }
    1109             /* Save port IRQ: */
    1110             if (fSuccess && isMachineOffline() && newPortData.m_uIRQ != oldPortData.m_uIRQ)
    1111             {
    1112                 comPort.SetIRQ(newPortData.m_uIRQ);
    1113                 fSuccess = comPort.isOk();
    1114             }
    1115             /* Save port IO address: */
    1116             if (fSuccess && isMachineOffline() && newPortData.m_uIOAddress != oldPortData.m_uIOAddress)
    1117             {
    1118                 comPort.SetIOAddress(newPortData.m_uIOAddress);
    1119                 fSuccess = comPort.isOk();
    1120             }
    1121             /* Save whether the port is server: */
    1122             if (fSuccess && isMachineOffline() && newPortData.m_fServer != oldPortData.m_fServer)
    1123             {
    1124                 comPort.SetServer(newPortData.m_fServer);
    1125                 fSuccess = comPort.isOk();
    1126             }
    1127             /* Save port path: */
    1128             if (fSuccess && isMachineOffline() && newPortData.m_strPath != oldPortData.m_strPath)
    1129             {
    1130                 comPort.SetPath(newPortData.m_strPath);
    1131                 fSuccess = comPort.isOk();
    1132             }
    1133             // This *must* be last.
    1134             // The host mode will be changed to disconnected if some of the necessary
    1135             // settings above will not meet the requirements for the selected mode.
    1136             /* Save port host mode: */
    1137             if (   fSuccess && isMachineOffline()
    1138                 && newPortData.m_hostMode != oldPortData.m_hostMode
    1139                 && newPortData.m_hostMode != KPortMode_Disconnected)
    1140             {
    1141                 comPort.SetHostMode(newPortData.m_hostMode);
    1142                 fSuccess = comPort.isOk();
    1143             }
    1144 
    1145             /* Show error message if necessary: */
    1146             if (!fSuccess)
    1147                 notifyOperationProgressError(UIErrorString::formatErrorInfo(comPort));
    1148         }
    1149     }
    1150     /* Return result: */
    1151     return fSuccess;
    1152 }
    1153 
    1154 # include "UIMachineSettingsSerial.moc"
     176#endif /* !FEQT_INCLUDED_SRC_settings_editors_UISerialSettingsEditor_h */
  • trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSerial.cpp

    r101325 r101327  
    2727
    2828/* Qt includes: */
    29 #include <QCheckBox>
    30 #include <QComboBox>
    31 #include <QDir>
    32 #include <QGridLayout>
    33 #include <QLabel>
    34 #include <QLineEdit>
    35 #include <QRegularExpressionValidator>
     29#include <QVBoxLayout>
    3630
    3731/* GUI includes: */
    3832#include "QITabWidget.h"
    39 #include "QIWidgetValidator.h"
    4033#include "UICommon.h"
    41 #include "UIConverter.h"
    4234#include "UIErrorString.h"
    4335#include "UIMachineSettingsSerial.h"
     36#include "UISerialSettingsEditor.h"
    4437#include "UITranslator.h"
    4538
     
    121114    /** Notifies about port changed. */
    122115    void sigPortChanged();
     116
    123117    /** Notifies about path changed. */
    124118    void sigPathChanged();
     119
    125120    /** Notifies about validity changed. */
    126121    void sigValidityChanged();
     
    159154
    160155    /** Handles translation event. */
    161     void retranslateUi();
    162 
    163 private slots:
    164 
    165     /** Handles port availability being toggled to @a fOn. */
    166     void sltHandlePortAvailabilityToggled(bool fOn);
    167     /** Handles port standard @a strOption being activated. */
    168     void sltHandlePortStandardOptionActivated(const QString &strOption);
    169     /** Handles port mode change to item with certain @a iIndex. */
    170     void sltHandlePortModeChange(int iIndex);
     156    void retranslateUi() {}
    171157
    172158private:
     
    179165    void prepareConnections();
    180166
    181     /** Populates combo-boxes. */
    182     void populateComboboxes();
    183 
    184167    /** Holds the parent page reference. */
    185168    UIMachineSettingsSerialPage *m_pParent;
    186169
    187170    /** Holds the port slot number. */
    188     int        m_iSlot;
    189     /** Holds the port mode. */
    190     KPortMode  m_enmPortMode;
    191 
    192     /** @name Widgets
    193      * @{ */
    194         /** Holds the port check-box instance. */
    195         QCheckBox *m_pCheckBoxPort;
    196         /** Holds the port settings widget instance. */
    197         QWidget   *m_pWidgetPortSettings;
    198         /** Holds the number label instance. */
    199         QLabel    *m_pLabelNumber;
    200         /** Holds the number combo instance. */
    201         QComboBox *m_pComboNumber;
    202         /** Holds the IRQ label instance. */
    203         QLabel    *m_pLabelIRQ;
    204         /** Holds the IRQ editor instance. */
    205         QLineEdit *m_pLineEditIRQ;
    206         /** Holds the IO address label instance. */
    207         QLabel    *m_pLabelIOAddress;
    208         /** Holds the IO address editor instance. */
    209         QLineEdit *m_pLineEditIOAddress;
    210         /** Holds the mode label instance. */
    211         QLabel    *m_pLabelMode;
    212         /** Holds the mode combo instance. */
    213         QComboBox *m_pComboMode;
    214         /** Holds the pipe check-box instance. */
    215         QCheckBox *m_pCheckBoxPipe;
    216         /** Holds the path label instance. */
    217         QLabel    *m_pLabelPath;
    218         /** Holds the path editor instance. */
    219         QLineEdit *m_pEditorPath;
    220     /** @} */
     171    int  m_iSlot;
     172
     173    /** Holds the serial settings editor instance. */
     174    UISerialSettingsEditor *m_pEditorSerialSettings;
    221175};
    222176
     
    230184    , m_pParent(pParent)
    231185    , m_iSlot(-1)
    232     , m_enmPortMode(KPortMode_Max)
    233     , m_pCheckBoxPort(0)
    234     , m_pWidgetPortSettings(0)
    235     , m_pLabelNumber(0)
    236     , m_pComboNumber(0)
    237     , m_pLabelIRQ(0)
    238     , m_pLineEditIRQ(0)
    239     , m_pLabelIOAddress(0)
    240     , m_pLineEditIOAddress(0)
    241     , m_pLabelMode(0)
    242     , m_pComboMode(0)
    243     , m_pCheckBoxPipe(0)
    244     , m_pLabelPath(0)
    245     , m_pEditorPath(0)
     186    , m_pEditorSerialSettings(0)
    246187{
    247188    prepare();
     
    256197    m_iSlot = oldPortData.m_iSlot;
    257198
    258     /* Load port data: */
    259     if (m_pCheckBoxPort)
    260         m_pCheckBoxPort->setChecked(oldPortData.m_fPortEnabled);
    261     if (m_pComboNumber)
    262         m_pComboNumber->setCurrentIndex(m_pComboNumber->findText(UITranslator::toCOMPortName(oldPortData.m_uIRQ, oldPortData.m_uIOAddress)));
    263     if (m_pLineEditIRQ)
    264         m_pLineEditIRQ->setText(QString::number(oldPortData.m_uIRQ));
    265     if (m_pLineEditIOAddress)
    266         m_pLineEditIOAddress->setText("0x" + QString::number(oldPortData.m_uIOAddress, 16).toUpper());
    267     m_enmPortMode = oldPortData.m_hostMode;
    268     if (m_pCheckBoxPipe)
    269         m_pCheckBoxPipe->setChecked(!oldPortData.m_fServer);
    270     if (m_pEditorPath)
    271         m_pEditorPath->setText(oldPortData.m_strPath);
    272 
    273     /* Repopulate combo-boxes content: */
    274     populateComboboxes();
    275     /* Ensure everything is up-to-date */
    276     if (m_pCheckBoxPort)
    277         sltHandlePortAvailabilityToggled(m_pCheckBoxPort->isChecked());
     199    if (m_pEditorSerialSettings)
     200    {
     201        /* Load port data: */
     202        m_pEditorSerialSettings->setPortByIRQAndIOAddress(oldPortData.m_uIRQ, oldPortData.m_uIOAddress);
     203        m_pEditorSerialSettings->setIRQ(oldPortData.m_uIRQ);
     204        m_pEditorSerialSettings->setIOAddress(oldPortData.m_uIOAddress);
     205        m_pEditorSerialSettings->setHostMode(oldPortData.m_hostMode);
     206        m_pEditorSerialSettings->setServerEnabled(oldPortData.m_fServer);
     207        m_pEditorSerialSettings->setPath(oldPortData.m_strPath);
     208        // Should be done in th end to finalize availability:
     209        m_pEditorSerialSettings->setPortEnabled(oldPortData.m_fPortEnabled);
     210    }
    278211}
    279212
     
    286219    newPortData.m_iSlot = m_iSlot;
    287220
    288     /* Save port data: */
    289     if (m_pCheckBoxPort)
    290         newPortData.m_fPortEnabled = m_pCheckBoxPort->isChecked();
    291     if (m_pLineEditIRQ)
    292         newPortData.m_uIRQ = m_pLineEditIRQ->text().toULong(NULL, 0);
    293     if (m_pLineEditIOAddress)
    294         newPortData.m_uIOAddress = m_pLineEditIOAddress->text().toULong(NULL, 0);
    295     if (m_pCheckBoxPipe)
    296         newPortData.m_fServer = !m_pCheckBoxPipe->isChecked();
    297     if (m_pComboMode)
    298         newPortData.m_hostMode = m_pComboMode->currentData().value<KPortMode>();
    299     if (m_pEditorPath)
    300         newPortData.m_strPath = QDir::toNativeSeparators(m_pEditorPath->text());
     221    if (m_pEditorSerialSettings)
     222    {
     223        /* Save port data: */
     224        newPortData.m_fPortEnabled = m_pEditorSerialSettings->isPortEnabled();
     225        newPortData.m_uIRQ = m_pEditorSerialSettings->irq();
     226        newPortData.m_uIOAddress = m_pEditorSerialSettings->ioAddress();
     227        newPortData.m_fServer = m_pEditorSerialSettings->isServerEnabled();
     228        newPortData.m_hostMode = m_pEditorSerialSettings->hostMode();
     229        newPortData.m_strPath = m_pEditorSerialSettings->path();
     230    }
    301231
    302232    /* Cache new data: */
     
    313243    message.first = UITranslator::removeAccelMark(tabTitle());
    314244
    315     if (   m_pCheckBoxPort
    316         && m_pCheckBoxPort->isChecked())
     245    /* Validate enabled port only: */
     246    if (   m_pEditorSerialSettings
     247        && m_pEditorSerialSettings->isPortEnabled())
    317248    {
    318249        /* Check the port attribute emptiness & uniqueness: */
    319         const QString strIRQ = m_pLineEditIRQ ? m_pLineEditIRQ->text() : QString();
    320         const QString strIOAddress = m_pLineEditIOAddress ? m_pLineEditIOAddress->text() : QString();
     250        const QString strIRQ = irq();
     251        const QString strIOAddress = ioAddress();
    321252        const QPair<QString, QString> port = qMakePair(strIRQ, strIOAddress);
    322253
     
    347278        }
    348279
    349         const KPortMode enmMode = m_pComboMode->currentData().value<KPortMode>();
     280        const KPortMode enmMode = m_pEditorSerialSettings->hostMode();
    350281        if (enmMode != KPortMode_Disconnected)
    351282        {
    352             const QString strPath(m_pEditorPath->text());
     283            const QString strPath = m_pEditorSerialSettings->path();
    353284
    354285            if (strPath.isEmpty())
     
    384315QWidget *UIMachineSettingsSerial::setOrderAfter(QWidget *pWidget)
    385316{
    386     setTabOrder(pWidget, m_pCheckBoxPort);
    387     setTabOrder(m_pCheckBoxPort, m_pComboNumber);
    388     setTabOrder(m_pComboNumber, m_pLineEditIRQ);
    389     setTabOrder(m_pLineEditIRQ, m_pLineEditIOAddress);
    390     setTabOrder(m_pLineEditIOAddress, m_pComboMode);
    391     setTabOrder(m_pComboMode, m_pCheckBoxPipe);
    392     setTabOrder(m_pCheckBoxPipe, m_pEditorPath);
    393     return m_pEditorPath;
     317    setTabOrder(pWidget, m_pEditorSerialSettings);
     318    return m_pEditorSerialSettings;
    394319}
    395320
     
    401326bool UIMachineSettingsSerial::isPortEnabled() const
    402327{
    403     return m_pCheckBoxPort->isChecked();
     328    return m_pEditorSerialSettings->isPortEnabled();
    404329}
    405330
    406331QString UIMachineSettingsSerial::irq() const
    407332{
    408     return m_pLineEditIRQ->text();
     333    return QString::number(m_pEditorSerialSettings->irq());
    409334}
    410335
    411336QString UIMachineSettingsSerial::ioAddress() const
    412337{
    413     return m_pLineEditIOAddress->text();
     338    return QString::number(m_pEditorSerialSettings->ioAddress());
    414339}
    415340
    416341QString UIMachineSettingsSerial::path() const
    417342{
    418     return m_pEditorPath->text();
     343    return m_pEditorSerialSettings->path();
    419344}
    420345
    421346void UIMachineSettingsSerial::polishTab()
    422347{
    423     /* Sanity check: */
    424     if (!m_pParent)
    425         return;
    426 
    427     /* Polish port page: */
    428     ulong uIRQ, uIOAddress;
    429     const bool fStd = m_pComboNumber ? UITranslator::toCOMPortNumbers(m_pComboNumber->currentText(), uIRQ, uIOAddress) : false;
    430     const KPortMode enmMode = m_pComboMode ? m_pComboMode->currentData().value<KPortMode>() : KPortMode_Max;
    431     if (m_pCheckBoxPort)
    432         m_pCheckBoxPort->setEnabled(m_pParent->isMachineOffline());
    433     if (m_pLabelNumber)
    434         m_pLabelNumber->setEnabled(m_pParent->isMachineOffline());
    435     if (m_pComboNumber)
    436         m_pComboNumber->setEnabled(m_pParent->isMachineOffline());
    437     if (m_pLabelIRQ)
    438         m_pLabelIRQ->setEnabled(m_pParent->isMachineOffline());
    439     if (m_pLineEditIRQ)
    440         m_pLineEditIRQ->setEnabled(!fStd && m_pParent->isMachineOffline());
    441     if (m_pLabelIOAddress)
    442         m_pLabelIOAddress->setEnabled(m_pParent->isMachineOffline());
    443     if (m_pLineEditIOAddress)
    444         m_pLineEditIOAddress->setEnabled(!fStd && m_pParent->isMachineOffline());
    445     if (m_pLabelMode)
    446         m_pLabelMode->setEnabled(m_pParent->isMachineOffline());
    447     if (m_pComboMode)
    448         m_pComboMode->setEnabled(m_pParent->isMachineOffline());
    449     if (m_pCheckBoxPipe)
    450         m_pCheckBoxPipe->setEnabled(   (enmMode == KPortMode_HostPipe || enmMode == KPortMode_TCP)
    451                                     && m_pParent->isMachineOffline());
    452     if (m_pLabelPath)
    453         m_pLabelPath->setEnabled(   enmMode != KPortMode_Disconnected
    454                                  && m_pParent->isMachineOffline());
    455     if (m_pEditorPath)
    456         m_pEditorPath->setEnabled(   enmMode != KPortMode_Disconnected
    457                                   && m_pParent->isMachineOffline());
    458 }
    459 
    460 void UIMachineSettingsSerial::retranslateUi()
    461 {
    462     if (m_pCheckBoxPort)
    463     {
    464         m_pCheckBoxPort->setText(tr("&Enable Serial Port"));
    465         m_pCheckBoxPort->setToolTip(tr("When checked, enables the given serial port of the virtual machine."));
    466     }
    467     if (m_pLabelNumber)
    468         m_pLabelNumber->setText(tr("Port &Number:"));
    469     if (m_pComboNumber)
    470     {
    471         m_pComboNumber->setItemText(m_pComboNumber->count() - 1, UITranslator::toCOMPortName(0, 0));
    472         m_pComboNumber->setToolTip(tr("Selects the serial port number. You can choose one of the standard serial ports or select "
    473                                       "User-defined and specify port parameters manually."));
    474     }
    475     if (m_pLabelIRQ)
    476         m_pLabelIRQ->setText(tr("&IRQ:"));
    477     if (m_pLineEditIRQ)
    478         m_pLineEditIRQ->setToolTip(tr("Holds the IRQ number of this serial port. This should be a whole number between "
    479                                       "<tt>0</tt> and <tt>255</tt>. Values greater than <tt>15</tt> may only be used if the "
    480                                       "I/O APIC setting is enabled for this virtual machine."));
    481     if (m_pLabelIOAddress)
    482         m_pLabelIOAddress->setText(tr("I/O Po&rt:"));
    483     if (m_pLineEditIOAddress)
    484         m_pLineEditIOAddress->setToolTip(tr("Holds the base I/O port address of this serial port. Valid values are integer numbers "
    485                                             "in range from <tt>0</tt> to <tt>0xFFFF</tt>."));
    486     if (m_pLabelMode)
    487         m_pLabelMode->setText(tr("Port &Mode:"));
    488     if (m_pComboMode)
    489         m_pComboMode->setToolTip(tr("Selects the working mode of this serial port. If you select Disconnected, the guest "
    490                                     "OS will detect the serial port but will not be able to operate it."));
    491     if (m_pCheckBoxPipe)
    492     {
    493         m_pCheckBoxPipe->setText(tr("&Connect to existing pipe/socket"));
    494         m_pCheckBoxPipe->setToolTip(tr("When checked, the virtual machine will assume that the pipe or socket specified in the "
    495                                        "Path/Address field exists and try to use it. Otherwise, the pipe or socket will "
    496                                        "be created by the virtual machine when it starts."));
    497     }
    498     if (m_pLabelPath)
    499         m_pLabelPath->setText(tr("&Path/Address:"));
    500     if (m_pEditorPath)
    501         m_pEditorPath->setToolTip(tr("In Host Pipe mode: Holds the path to the serial port's pipe on the host. "
    502                                      "Examples: \"\\\\.\\pipe\\myvbox\" or \"/tmp/myvbox\", for Windows and UNIX-like systems "
    503                                      "respectively. In Host Device mode: Holds the host serial device name. "
    504                                      "Examples: \"COM1\" or \"/dev/ttyS0\". In Raw File mode: Holds the file-path "
    505                                      "on the host system, where the serial output will be dumped. In TCP mode: "
    506                                      "Holds the TCP \"port\" when in server mode, or \"hostname:port\" when in client mode."));
    507 
    508     /* Translate combo-boxes content: */
    509     populateComboboxes();
    510 }
    511 
    512 void UIMachineSettingsSerial::sltHandlePortAvailabilityToggled(bool fOn)
    513 {
    514     /* Update availability: */
    515     m_pWidgetPortSettings->setEnabled(m_pCheckBoxPort->isChecked());
    516     if (fOn)
    517     {
    518         sltHandlePortStandardOptionActivated(m_pComboNumber->currentText());
    519         sltHandlePortModeChange(m_pComboMode->currentIndex());
    520     }
    521 
    522     /* Notify port/path changed: */
    523     emit sigPortChanged();
    524     emit sigPathChanged();
    525 }
    526 
    527 void UIMachineSettingsSerial::sltHandlePortStandardOptionActivated(const QString &strText)
    528 {
    529     /* Update availability: */
    530     ulong uIRQ, uIOAddress;
    531     bool fStd = UITranslator::toCOMPortNumbers(strText, uIRQ, uIOAddress);
    532     m_pLineEditIRQ->setEnabled(!fStd);
    533     m_pLineEditIOAddress->setEnabled(!fStd);
    534     if (fStd)
    535     {
    536         m_pLineEditIRQ->setText(QString::number(uIRQ));
    537         m_pLineEditIOAddress->setText("0x" + QString::number(uIOAddress, 16).toUpper());
    538     }
    539 
    540     /* Notify validity changed: */
    541     emit sigValidityChanged();
    542 }
    543 
    544 void UIMachineSettingsSerial::sltHandlePortModeChange(int iIndex)
    545 {
    546     /* Update availability: */
    547     const KPortMode enmMode = m_pComboMode->itemData(iIndex).value<KPortMode>();
    548     m_pCheckBoxPipe->setEnabled(enmMode == KPortMode_HostPipe || enmMode == KPortMode_TCP);
    549     m_pEditorPath->setEnabled(enmMode != KPortMode_Disconnected);
    550     m_pLabelPath->setEnabled(enmMode != KPortMode_Disconnected);
    551 
    552     /* Notify validity changed: */
    553     emit sigValidityChanged();
     348    if (   m_pEditorSerialSettings
     349        && m_pParent)
     350    {
     351        /* Polish port page: */
     352        const bool fStd = m_pEditorSerialSettings->isPortStandardOne();
     353        const KPortMode enmMode = m_pEditorSerialSettings->hostMode();
     354        m_pEditorSerialSettings->setPortOptionsAvailable(m_pParent->isMachineOffline());
     355        m_pEditorSerialSettings->setIRQAndIOAddressOptionsAvailable(!fStd && m_pParent->isMachineOffline());
     356        m_pEditorSerialSettings->setHostModeOptionsAvailable(m_pParent->isMachineOffline());
     357        m_pEditorSerialSettings->setPipeOptionsAvailable(   (enmMode == KPortMode_HostPipe || enmMode == KPortMode_TCP)
     358                                                         && m_pParent->isMachineOffline());
     359        m_pEditorSerialSettings->setPathOptionsAvailable(   enmMode != KPortMode_Disconnected
     360                                                         && m_pParent->isMachineOffline());
     361    }
    554362}
    555363
     
    567375{
    568376    /* Prepare main layout: */
    569     QGridLayout *pLayoutMain = new QGridLayout(this);
    570     if (pLayoutMain)
    571     {
    572         pLayoutMain->setRowStretch(2, 1);
    573 
    574         /* Prepare port check-box: */
    575         m_pCheckBoxPort = new QCheckBox(this);
    576         if (m_pCheckBoxPort)
    577             pLayoutMain->addWidget(m_pCheckBoxPort, 0, 0, 1, 2);
    578 
    579         /* Prepare 20-px shifting spacer: */
    580         QSpacerItem *pSpacerItem = new QSpacerItem(20, 0, QSizePolicy::Fixed, QSizePolicy::Minimum);
    581         if (pSpacerItem)
    582             pLayoutMain->addItem(pSpacerItem, 1, 0);
    583 
    584         /* Prepare adapter settings widget: */
    585         m_pWidgetPortSettings = new QWidget(this);
    586         if (m_pWidgetPortSettings)
    587         {
    588             /* Prepare adapter settings widget layout: */
    589             QGridLayout *pLayoutPortSettings = new QGridLayout(m_pWidgetPortSettings);
    590             if (pLayoutPortSettings)
    591             {
    592                 pLayoutPortSettings->setContentsMargins(0, 0, 0, 0);
    593                 pLayoutPortSettings->setColumnStretch(6, 1);
    594 
    595                 /* Prepare number label: */
    596                 m_pLabelNumber = new QLabel(m_pWidgetPortSettings);
    597                 if (m_pLabelNumber)
    598                 {
    599                     m_pLabelNumber->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    600                     pLayoutPortSettings->addWidget(m_pLabelNumber, 0, 0);
    601                 }
    602                 /* Prepare number combo: */
    603                 m_pComboNumber = new QComboBox(m_pWidgetPortSettings);
    604                 if (m_pComboNumber)
    605                 {
    606                     if (m_pLabelNumber)
    607                         m_pLabelNumber->setBuddy(m_pComboNumber);
    608                     m_pComboNumber->insertItem(0, UITranslator::toCOMPortName(0, 0));
    609                     m_pComboNumber->insertItems(0, UITranslator::COMPortNames());
    610                     pLayoutPortSettings->addWidget(m_pComboNumber, 0, 1);
    611                 }
    612                 /* Prepare IRQ label: */
    613                 m_pLabelIRQ = new QLabel(m_pWidgetPortSettings);
    614                 if (m_pLabelIRQ)
    615                     pLayoutPortSettings->addWidget(m_pLabelIRQ, 0, 2);
    616                 /* Prepare IRQ label: */
    617                 m_pLineEditIRQ = new QLineEdit(m_pWidgetPortSettings);
    618                 if (m_pLineEditIRQ)
    619                 {
    620                     if (m_pLabelIRQ)
    621                         m_pLabelIRQ->setBuddy(m_pLineEditIRQ);
    622 #if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
    623                     m_pLineEditIRQ->setFixedWidth(m_pLineEditIRQ->fontMetrics().horizontalAdvance("8888"));
    624 #else
    625                     m_pLineEditIRQ->setFixedWidth(m_pLineEditIRQ->fontMetrics().width("8888"));
    626 #endif
    627                     m_pLineEditIRQ->setValidator(new QIULongValidator(0, 255, this));
    628                     pLayoutPortSettings->addWidget(m_pLineEditIRQ, 0, 3);
    629                 }
    630                 /* Prepare IO address label: */
    631                 m_pLabelIOAddress = new QLabel(m_pWidgetPortSettings);
    632                 if (m_pLabelIOAddress)
    633                     pLayoutPortSettings->addWidget(m_pLabelIOAddress, 0, 4);
    634                 /* Prepare IO address label: */
    635                 m_pLineEditIOAddress = new QLineEdit(m_pWidgetPortSettings);
    636                 if (m_pLineEditIOAddress)
    637                 {
    638                     if (m_pLabelIOAddress)
    639                         m_pLabelIOAddress->setBuddy(m_pLineEditIOAddress);
    640 #if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
    641                     m_pLineEditIOAddress->setFixedWidth(m_pLineEditIOAddress->fontMetrics().horizontalAdvance("8888888"));
    642 #else
    643                     m_pLineEditIOAddress->setFixedWidth(m_pLineEditIOAddress->fontMetrics().width("8888888"));
    644 #endif
    645                     m_pLineEditIOAddress->setValidator(new QIULongValidator(0, 0xFFFF, this));
    646                     pLayoutPortSettings->addWidget(m_pLineEditIOAddress, 0, 5);
    647                 }
    648 
    649                 /* Prepare mode label: */
    650                 m_pLabelMode = new QLabel(m_pWidgetPortSettings);
    651                 if (m_pLabelMode)
    652                 {
    653                     m_pLabelMode->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    654                     pLayoutPortSettings->addWidget(m_pLabelMode, 1, 0);
    655                 }
    656                 /* Prepare mode combo: */
    657                 m_pComboMode = new QComboBox(m_pWidgetPortSettings);
    658                 if (m_pComboMode)
    659                 {
    660                     if (m_pLabelMode)
    661                         m_pLabelMode->setBuddy(m_pComboMode);
    662                     pLayoutPortSettings->addWidget(m_pComboMode, 1, 1);
    663                 }
    664 
    665                 /* Prepare pipe check-box: */
    666                 m_pCheckBoxPipe = new QCheckBox(m_pWidgetPortSettings);
    667                 if (m_pCheckBoxPipe)
    668                     pLayoutPortSettings->addWidget(m_pCheckBoxPipe, 2, 1, 1, 5);
    669 
    670                 /* Prepare path label: */
    671                 m_pLabelPath = new QLabel(m_pWidgetPortSettings);
    672                 if (m_pLabelPath)
    673                 {
    674                     m_pLabelPath->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    675                     pLayoutPortSettings->addWidget(m_pLabelPath, 3, 0);
    676                 }
    677                 /* Prepare path editor: */
    678                 m_pEditorPath = new QLineEdit(m_pWidgetPortSettings);
    679                 if (m_pEditorPath)
    680                 {
    681                     if (m_pLabelPath)
    682                         m_pLabelPath->setBuddy(m_pEditorPath);
    683                     m_pEditorPath->setValidator(new QRegularExpressionValidator(QRegularExpression(".+"), this));
    684                     pLayoutPortSettings->addWidget(m_pEditorPath, 3, 1, 1, 6);
    685                 }
    686             }
    687 
    688             pLayoutMain->addWidget(m_pWidgetPortSettings, 1, 1);
    689         }
     377    QVBoxLayout *pLayout = new QVBoxLayout(this);
     378    if (pLayout)
     379    {
     380        /* Prepare settings editor: */
     381        m_pEditorSerialSettings = new UISerialSettingsEditor(this);
     382        if (m_pEditorSerialSettings)
     383            pLayout->addWidget(m_pEditorSerialSettings);
     384
     385        pLayout->addStretch();
    690386    }
    691387}
     
    693389void UIMachineSettingsSerial::prepareConnections()
    694390{
    695     if (m_pCheckBoxPort)
    696         connect(m_pCheckBoxPort, &QCheckBox::toggled, this, &UIMachineSettingsSerial::sltHandlePortAvailabilityToggled);
    697 #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
    698     if (m_pComboNumber)
    699         connect(m_pComboNumber, static_cast<void(QComboBox::*)(const QString&)>(&QComboBox::textActivated),
    700                 this, &UIMachineSettingsSerial::sltHandlePortStandardOptionActivated);
    701 #else
    702     if (m_pComboNumber)
    703         connect(m_pComboNumber, static_cast<void(QComboBox::*)(const QString&)>(&QComboBox::activated),
    704                 this, &UIMachineSettingsSerial::sltHandlePortStandardOptionActivated);
    705 #endif
    706     if (m_pLineEditIRQ)
    707         connect(m_pLineEditIRQ, &QLineEdit::textChanged, this, &UIMachineSettingsSerial::sigPortChanged);
    708     if (m_pLineEditIOAddress)
    709         connect(m_pLineEditIOAddress, &QLineEdit::textChanged, this, &UIMachineSettingsSerial::sigPortChanged);
    710     if (m_pComboMode)
    711         connect(m_pComboMode, static_cast<void(QComboBox::*)(int)>(&QComboBox::activated),
    712                 this, &UIMachineSettingsSerial::sltHandlePortModeChange);
    713     if (m_pEditorPath)
    714         connect(m_pEditorPath, &QLineEdit::textChanged, this, &UIMachineSettingsSerial::sigPathChanged);
    715 }
    716 
    717 void UIMachineSettingsSerial::populateComboboxes()
    718 {
    719     /* Port mode: */
    720     {
    721         /* Clear the port mode combo-box: */
    722         m_pComboMode->clear();
    723 
    724         /* Load currently supported port moded: */
    725         CSystemProperties comProperties = uiCommon().virtualBox().GetSystemProperties();
    726         QVector<KPortMode> supportedModes = comProperties.GetSupportedPortModes();
    727         /* Take currently requested mode into account if it's sane: */
    728         if (!supportedModes.contains(m_enmPortMode) && m_enmPortMode != KPortMode_Max)
    729             supportedModes.prepend(m_enmPortMode);
    730 
    731         /* Populate port modes: */
    732         int iPortModeIndex = 0;
    733         foreach (const KPortMode &enmMode, supportedModes)
    734         {
    735             m_pComboMode->insertItem(iPortModeIndex, gpConverter->toString(enmMode));
    736             m_pComboMode->setItemData(iPortModeIndex, QVariant::fromValue(enmMode));
    737             m_pComboMode->setItemData(iPortModeIndex, m_pComboMode->itemText(iPortModeIndex), Qt::ToolTipRole);
    738             ++iPortModeIndex;
    739         }
    740 
    741         /* Choose requested port mode: */
    742         const int iIndex = m_pComboMode->findData(QVariant::fromValue(m_enmPortMode));
    743         m_pComboMode->setCurrentIndex(iIndex != -1 ? iIndex : 0);
     391    if (m_pEditorSerialSettings)
     392    {
     393        connect(m_pEditorSerialSettings, &UISerialSettingsEditor::sigPortAvailabilityChanged,
     394                this, &UIMachineSettingsSerial::sigPortChanged);
     395        connect(m_pEditorSerialSettings, &UISerialSettingsEditor::sigPortAvailabilityChanged,
     396                this, &UIMachineSettingsSerial::sigPathChanged);
     397        connect(m_pEditorSerialSettings, &UISerialSettingsEditor::sigStandardPortOptionChanged,
     398                this, &UIMachineSettingsSerial::sigValidityChanged);
     399        connect(m_pEditorSerialSettings, &UISerialSettingsEditor::sigPortIRQChanged,
     400                this, &UIMachineSettingsSerial::sigPortChanged);
     401        connect(m_pEditorSerialSettings, &UISerialSettingsEditor::sigPortIOAddressChanged,
     402                this, &UIMachineSettingsSerial::sigPortChanged);
     403        connect(m_pEditorSerialSettings, &UISerialSettingsEditor::sigModeChanged,
     404                this, &UIMachineSettingsSerial::sigValidityChanged);
     405        connect(m_pEditorSerialSettings, &UISerialSettingsEditor::sigPathChanged,
     406                this, &UIMachineSettingsSerial::sigPathChanged);
    744407    }
    745408}
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette