VirtualBox

Changeset 92731 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Dec 3, 2021 11:24:28 AM (3 years ago)
Author:
vboxsync
Message:

FE/Qt: bugref:10163: UINetworkManager: Initial implementation for cloud networks tab; No subnet id stuff for now, rest is there.

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

Legend:

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

    r92647 r92731  
    626626        src/activity/overview/UIVMActivityOverviewWidget.h \
    627627        src/activity/overview/UIVMActivityToolWidget.h \
     628        src/networkmanager/UIDetailsWidgetCloudNetwork.h \
    628629        src/networkmanager/UIDetailsWidgetHostNetwork.h \
    629630        src/networkmanager/UIDetailsWidgetNATNetwork.h \
     
    11301131        src/activity/overview/UIVMActivityOverviewWidget.cpp \
    11311132        src/activity/overview/UIVMActivityToolWidget.cpp \
     1133        src/networkmanager/UIDetailsWidgetCloudNetwork.cpp \
    11321134        src/networkmanager/UIDetailsWidgetHostNetwork.cpp \
    11331135        src/networkmanager/UIDetailsWidgetNATNetwork.cpp \
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/UIMessageCenter.cpp

    r92191 r92731  
    13071307}
    13081308
     1309bool UIMessageCenter::confirmCloudNetworkRemoval(const QString &strName, QWidget *pParent /* = 0*/) const
     1310{
     1311    return questionBinary(pParent, MessageType_Question,
     1312                          tr("<p>Do you want to remove the cloud network <nobr><b>%1</b>?</nobr></p>"
     1313                             "<p>If this network is in use by one or more virtual "
     1314                             "machine network adapters these adapters will no longer be "
     1315                             "usable until you correct their settings by either choosing "
     1316                             "a different network name or a different adapter attachment "
     1317                             "type.</p>")
     1318                             .arg(strName),
     1319                          0 /* auto-confirm id */,
     1320                          tr("Remove") /* ok button text */,
     1321                          QString() /* cancel button text */,
     1322                          false /* ok button by default? */);
     1323}
     1324
    13091325bool UIMessageCenter::confirmHostOnlyInterfaceRemoval(const QString &strName, QWidget *pParent /* = 0 */) const
    13101326{
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/UIMessageCenter.h

    r92191 r92731  
    356356    /** @name VirtualBox Manager / Network Manager warnings.
    357357      * @{ */
     358        bool confirmCloudNetworkRemoval(const QString &strName, QWidget *pParent = 0) const;
    358359        bool confirmHostOnlyInterfaceRemoval(const QString &strName, QWidget *pParent = 0) const;
    359360        bool confirmNATNetworkRemoval(const QString &strName, QWidget *pParent = 0) const;
  • trunk/src/VBox/Frontends/VirtualBox/src/networkmanager/UIDetailsWidgetCloudNetwork.cpp

    r92489 r92731  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UIDetailsWidgetNATNetwork class implementation.
     3 * VBox Qt GUI - UIDetailsWidgetCloudNetwork class implementation.
    44 */
    55
     
    2828
    2929/* GUI includes: */
     30#include "QIComboBox.h"
    3031#include "QIDialogButtonBox.h"
    3132#include "QILineEdit.h"
    3233#include "QITabWidget.h"
    3334#include "UIIconPool.h"
    34 #include "UIDetailsWidgetNATNetwork.h"
     35#include "UICloudNetworkingStuff.h"
     36#include "UIDetailsWidgetCloudNetwork.h"
    3537#include "UIMessageCenter.h"
    3638#include "UINetworkManagerUtils.h"
    3739#include "UINotificationCenter.h"
    3840
    39 /* Other VBox includes: */
    40 #include "iprt/assert.h"
    41 #include "iprt/cidr.h"
    42 
    43 
    44 UIDetailsWidgetNATNetwork::UIDetailsWidgetNATNetwork(EmbedTo enmEmbedding, QWidget *pParent /* = 0 */)
     41
     42UIDetailsWidgetCloudNetwork::UIDetailsWidgetCloudNetwork(EmbedTo enmEmbedding, QWidget *pParent /* = 0 */)
    4543    : QIWithRetranslateUI<QWidget>(pParent)
    4644    , m_enmEmbedding(enmEmbedding)
    47     , m_pTabWidget(0)
    4845    , m_pLabelNetworkName(0)
    4946    , m_pEditorNetworkName(0)
    50     , m_pGroupBoxIPv4(0)
    51     , m_pLabelNetworkIPv4Prefix(0)
    52     , m_pEditorNetworkIPv4Prefix(0)
    53     , m_pCheckboxSupportsDHCP(0)
    54     , m_pGroupBoxIPv6(0)
    55     , m_pLabelNetworkIPv6Prefix(0)
    56     , m_pEditorNetworkIPv6Prefix(0)
    57     , m_pCheckboxAdvertiseDefaultIPv6Route(0)
     47    , m_pLabelProviderName(0)
     48    , m_pComboProviderName(0)
     49    , m_pLabelProfileName(0)
     50    , m_pComboProfileName(0)
    5851    , m_pButtonBoxOptions(0)
    59     , m_pTabWidgetForwarding(0)
    60     , m_pForwardingTableIPv4(0)
    61     , m_pForwardingTableIPv6(0)
    62     , m_pButtonBoxForwarding(0)
    63     , m_fHoldPosition(false)
    6452{
    6553    prepare();
    6654}
    6755
    68 void UIDetailsWidgetNATNetwork::setData(const UIDataNATNetwork &data,
    69                                         const QStringList &busyNames /* = QStringList() */,
    70                                         bool fHoldPosition /* = false */)
     56void UIDetailsWidgetCloudNetwork::setData(const UIDataCloudNetwork &data,
     57                                          const QStringList &busyNames /* = QStringList() */)
    7158{
    7259    /* Cache old/new data: */
     
    7461    m_newData = m_oldData;
    7562    m_busyNames = busyNames;
    76     m_fHoldPosition = fHoldPosition;
    77 
    78     /* Load 'Options' data: */
    79     loadDataForOptions();
    80     /* Load 'Forwarding' data: */
    81     loadDataForForwarding();
    82 }
    83 
    84 bool UIDetailsWidgetNATNetwork::revalidate() const
     63
     64    /* Load data: */
     65    loadData();
     66}
     67
     68bool UIDetailsWidgetCloudNetwork::revalidate() const
    8569{
    8670    /* Make sure network name isn't empty: */
     
    10084    }
    10185
    102     /* Make sure IPv4 prefix isn't empty: */
    103     if (m_newData.m_strPrefixIPv4.isEmpty())
    104     {
    105         UINotificationMessage::warnAboutNoIPv4PrefixSpecified(m_newData.m_strName);
    106         return false;
    107     }
    108     /* Make sure IPv6 prefix isn't empty if IPv6 is supported: */
    109     if (m_newData.m_fSupportsIPv6 && m_newData.m_strPrefixIPv6.isEmpty())
    110     {
    111         UINotificationMessage::warnAboutNoIPv6PrefixSpecified(m_newData.m_strName);
    112         return false;
    113     }
    114 
    115     /* Validate 'Forwarding' tab content: */
    116     return m_pForwardingTableIPv4->validate() && m_pForwardingTableIPv6->validate();
    117 }
    118 
    119 void UIDetailsWidgetNATNetwork::updateButtonStates()
     86    return true;
     87}
     88
     89void UIDetailsWidgetCloudNetwork::updateButtonStates()
    12090{
    12191//    if (m_oldData != m_newData)
     
    134104        m_pButtonBoxOptions->button(QDialogButtonBox::Ok)->setEnabled(m_oldData != m_newData);
    135105    }
    136     if (m_pButtonBoxForwarding)
    137     {
    138         m_pButtonBoxForwarding->button(QDialogButtonBox::Cancel)->setEnabled(m_oldData != m_newData);
    139         m_pButtonBoxForwarding->button(QDialogButtonBox::Ok)->setEnabled(m_oldData != m_newData);
    140     }
    141106
    142107    /* Notify listeners as well: */
     
    144109}
    145110
    146 void UIDetailsWidgetNATNetwork::retranslateUi()
    147 {
    148     /* Translate tab-widget: */
    149     if (m_pTabWidget)
    150     {
    151         m_pTabWidget->setTabText(0, tr("&General Options"));
    152         m_pTabWidget->setTabText(1, tr("&Port Forwarding"));
    153     }
    154 
     111void UIDetailsWidgetCloudNetwork::retranslateUi()
     112{
    155113    if (m_pLabelNetworkName)
    156114        m_pLabelNetworkName->setText(tr("N&ame:"));
    157115    if (m_pEditorNetworkName)
    158116        m_pEditorNetworkName->setToolTip(tr("Holds the name for this network."));
    159     if (m_pLabelNetworkIPv4Prefix)
    160         m_pLabelNetworkIPv4Prefix->setText(tr("Pref&ix:"));
    161     if (m_pEditorNetworkIPv4Prefix)
    162         m_pEditorNetworkIPv4Prefix->setToolTip(tr("Holds the IPv4 prefix for this network."));
    163     if (m_pLabelNetworkIPv6Prefix)
    164         m_pLabelNetworkIPv6Prefix->setText(tr("Prefi&x:"));
    165     if (m_pEditorNetworkIPv6Prefix)
    166         m_pEditorNetworkIPv6Prefix->setToolTip(tr("Holds the IPv6 prefix for this network."));
    167     if (m_pCheckboxSupportsDHCP)
    168     {
    169         m_pCheckboxSupportsDHCP->setText(tr("Enable &DHCP"));
    170         m_pCheckboxSupportsDHCP->setToolTip(tr("When checked, this network will support DHCP."));
    171     }
    172     if (m_pGroupBoxIPv4)
    173         m_pGroupBoxIPv4->setTitle(tr("IPv&4"));
    174     if (m_pGroupBoxIPv6)
    175     {
    176         m_pGroupBoxIPv6->setTitle(tr("IPv&6"));
    177         m_pGroupBoxIPv6->setToolTip(tr("When checked, this network will support IPv6."));
    178     }
    179     if (m_pCheckboxAdvertiseDefaultIPv6Route)
    180     {
    181         m_pCheckboxAdvertiseDefaultIPv6Route->setText(tr("Advertise Default IPv6 &Route"));
    182         m_pCheckboxAdvertiseDefaultIPv6Route->setToolTip(tr("When checked, this network will be advertised as the default IPv6 route."));
    183     }
     117    if (m_pLabelProviderName)
     118        m_pLabelProviderName->setText(tr("&Provider:"));
     119    if (m_pComboProviderName)
     120    {
     121        m_pComboProviderName->setToolTip(tr("Holds the cloud provider for this network."));
     122        m_pComboProviderName->setItemText(0, "--");
     123    }
     124    if (m_pLabelProfileName)
     125        m_pLabelProfileName->setText(tr("P&rofile:"));
     126    if (m_pComboProfileName)
     127        m_pComboProfileName->setToolTip(tr("Holds the cloud profile for this network."));
    184128    if (m_pButtonBoxOptions)
    185129    {
     
    195139            setToolTip(tr("Apply Changes (%1)").arg(m_pButtonBoxOptions->button(QDialogButtonBox::Ok)->shortcut().toString()));
    196140    }
    197 
    198     /* Translate 'Forwarding' tab content: */
    199     if (m_pTabWidgetForwarding)
    200     {
    201         m_pTabWidgetForwarding->setTabText(0, tr("IPv&4"));
    202         m_pTabWidgetForwarding->setTabText(1, tr("IPv&6"));
    203     }
    204     if (m_pButtonBoxForwarding)
    205     {
    206         m_pButtonBoxForwarding->button(QDialogButtonBox::Cancel)->setText(tr("Reset"));
    207         m_pButtonBoxForwarding->button(QDialogButtonBox::Ok)->setText(tr("Apply"));
    208         m_pButtonBoxForwarding->button(QDialogButtonBox::Cancel)->setShortcut(Qt::Key_Escape);
    209         m_pButtonBoxForwarding->button(QDialogButtonBox::Ok)->setShortcut(QString("Ctrl+Return"));
    210         m_pButtonBoxForwarding->button(QDialogButtonBox::Cancel)->setStatusTip(tr("Reset changes in current interface details"));
    211         m_pButtonBoxForwarding->button(QDialogButtonBox::Ok)->setStatusTip(tr("Apply changes in current interface details"));
    212         m_pButtonBoxForwarding->button(QDialogButtonBox::Cancel)->
    213             setToolTip(tr("Reset Changes (%1)").arg(m_pButtonBoxForwarding->button(QDialogButtonBox::Cancel)->shortcut().toString()));
    214         m_pButtonBoxForwarding->button(QDialogButtonBox::Ok)->
    215             setToolTip(tr("Apply Changes (%1)").arg(m_pButtonBoxForwarding->button(QDialogButtonBox::Ok)->shortcut().toString()));
    216     }
    217 
    218     // WORKAROUND:
    219     // Adjust name layout indent:
    220     int iLeft, iTop, iRight, iBottom;
    221     // We assume that IPv4 group-box has the same margin as IPv6 one:
    222     m_pGroupBoxIPv4->layout()->getContentsMargins(&iLeft, &iTop, &iRight, &iBottom);
    223     // We assume that IPv4 label has the same text as IPv6 one:
    224     QFontMetrics fm(m_pLabelNetworkIPv4Prefix->font());
    225     const int iIndent = iLeft + 1 /* group-box frame width */
    226                       + fm.width(m_pLabelNetworkIPv4Prefix->text().remove('&'));
    227     m_pLayoutName->setColumnMinimumWidth(0, iIndent);
    228 }
    229 
    230 void UIDetailsWidgetNATNetwork::sltNetworkNameChanged(const QString &strText)
     141}
     142
     143void UIDetailsWidgetCloudNetwork::sltNetworkNameChanged(const QString &strText)
    231144{
    232145    m_newData.m_strName = strText;
     
    234147}
    235148
    236 void UIDetailsWidgetNATNetwork::sltNetworkIPv4PrefixChanged(const QString &strText)
    237 {
    238     m_newData.m_strPrefixIPv4 = strText;
     149void UIDetailsWidgetCloudNetwork::sltCloudProviderNameChanged(int iIndex)
     150{
     151    /* Store provider: */
     152    m_newData.m_strProvider = m_pComboProviderName->itemData(iIndex).toString();
     153
     154    /* Update profiles: */
     155    prepareProfiles();
     156    /* And store selected profile: */
     157    sltCloudProfileNameChanged(m_pComboProfileName->currentIndex());
     158
     159    /* Update button states finally: */
    239160    updateButtonStates();
    240161}
    241162
    242 void UIDetailsWidgetNATNetwork::sltNetworkIPv6PrefixChanged(const QString &strText)
    243 {
    244     m_newData.m_strPrefixIPv6 = strText;
     163void UIDetailsWidgetCloudNetwork::sltCloudProfileNameChanged(int iIndex)
     164{
     165    /* Store profile: */
     166    m_newData.m_strProfile = m_pComboProfileName->itemData(iIndex).toString();
     167
     168    /* Update button states finally: */
    245169    updateButtonStates();
    246170}
    247171
    248 void UIDetailsWidgetNATNetwork::sltSupportsDHCPChanged(bool fChecked)
    249 {
    250     m_newData.m_fSupportsDHCP = fChecked;
    251     updateButtonStates();
    252 }
    253 
    254 void UIDetailsWidgetNATNetwork::sltSupportsIPv6Changed(bool fChecked)
    255 {
    256     m_newData.m_fSupportsIPv6 = fChecked;
    257     loadDataForOptions();
    258     updateButtonStates();
    259 }
    260 
    261 void UIDetailsWidgetNATNetwork::sltAdvertiseDefaultIPv6RouteChanged(bool fChecked)
    262 {
    263     m_newData.m_fAdvertiseDefaultIPv6Route = fChecked;
    264     updateButtonStates();
    265 }
    266 
    267 void UIDetailsWidgetNATNetwork::sltForwardingRulesIPv4Changed()
    268 {
    269     m_newData.m_rules4 = m_pForwardingTableIPv4->rules();
    270     updateButtonStates();
    271 }
    272 
    273 void UIDetailsWidgetNATNetwork::sltForwardingRulesIPv6Changed()
    274 {
    275     m_newData.m_rules6 = m_pForwardingTableIPv6->rules();
    276     updateButtonStates();
    277 }
    278 
    279 void UIDetailsWidgetNATNetwork::sltHandleButtonBoxClick(QAbstractButton *pButton)
    280 {
    281     /* Make sure button-boxes exist: */
    282     if (!m_pButtonBoxOptions || !m_pButtonBoxForwarding)
     172void UIDetailsWidgetCloudNetwork::sltHandleButtonBoxClick(QAbstractButton *pButton)
     173{
     174    /* Make sure button-box exist: */
     175    if (!m_pButtonBoxOptions)
    283176        return;
    284177
     
    286179    m_pButtonBoxOptions->button(QDialogButtonBox::Cancel)->setEnabled(false);
    287180    m_pButtonBoxOptions->button(QDialogButtonBox::Ok)->setEnabled(false);
    288     m_pButtonBoxForwarding->button(QDialogButtonBox::Cancel)->setEnabled(false);
    289     m_pButtonBoxForwarding->button(QDialogButtonBox::Ok)->setEnabled(false);
    290181
    291182    /* Compare with known buttons: */
    292     if (   pButton == m_pButtonBoxOptions->button(QDialogButtonBox::Cancel)
    293         || pButton == m_pButtonBoxForwarding->button(QDialogButtonBox::Cancel))
     183    if (pButton == m_pButtonBoxOptions->button(QDialogButtonBox::Cancel))
    294184        emit sigDataChangeRejected();
    295185    else
    296     if (   pButton == m_pButtonBoxOptions->button(QDialogButtonBox::Ok)
    297         || pButton == m_pButtonBoxForwarding->button(QDialogButtonBox::Ok))
     186    if (pButton == m_pButtonBoxOptions->button(QDialogButtonBox::Ok))
    298187        emit sigDataChangeAccepted();
    299188}
    300189
    301 void UIDetailsWidgetNATNetwork::prepare()
    302 {
    303     /* Prepare this: */
     190void UIDetailsWidgetCloudNetwork::prepare()
     191{
     192    /* Prepare everything: */
    304193    prepareThis();
     194    prepareProviders();
     195    prepareProfiles();
    305196
    306197    /* Apply language settings: */
     
    311202}
    312203
    313 void UIDetailsWidgetNATNetwork::prepareThis()
    314 {
    315     /* Create layout: */
    316     new QVBoxLayout(this);
    317     if (layout())
    318     {
    319         /* Configure layout: */
    320         layout()->setContentsMargins(0, 0, 0, 0);
    321 
    322         /* Prepare tab-widget: */
    323         prepareTabWidget();
    324     }
    325 }
    326 
    327 void UIDetailsWidgetNATNetwork::prepareTabWidget()
    328 {
    329     /* Create tab-widget: */
    330     m_pTabWidget = new QITabWidget(this);
    331     if (m_pTabWidget)
    332     {
    333         /* Prepare 'Options' tab: */
    334         prepareTabOptions();
    335         /* Prepare 'Forwarding' tab: */
    336         prepareTabForwarding();
    337 
    338         /* Add into layout: */
    339         layout()->addWidget(m_pTabWidget);
    340     }
    341 }
    342 
    343 void UIDetailsWidgetNATNetwork::prepareTabOptions()
    344 {
    345     /* Prepare 'Options' tab: */
    346     QWidget *pTabOptions = new QWidget(m_pTabWidget);
    347     if (pTabOptions)
    348     {
    349         /* Prepare 'Options' layout: */
    350         QVBoxLayout *pLayoutOptions = new QVBoxLayout(pTabOptions);
     204void UIDetailsWidgetCloudNetwork::prepareThis()
     205{
     206    /* Prepare main layout: */
     207    QVBoxLayout *pLayoutMain = new QVBoxLayout(this);
     208    if (pLayoutMain)
     209    {
     210#ifdef VBOX_WS_MAC
     211        pLayoutMain->setSpacing(10);
     212        pLayoutMain->setContentsMargins(10, 10, 10, 10);
     213#endif
     214
     215        /* Prepare options widget layout: */
     216        QGridLayout *pLayoutOptions = new QGridLayout;
    351217        if (pLayoutOptions)
    352218        {
    353 #ifdef VBOX_WS_MAC
    354             pLayoutOptions->setSpacing(10);
    355             pLayoutOptions->setContentsMargins(10, 10, 10, 10);
    356 #endif
    357 
    358             /* Prepare name widget layout: */
    359             m_pLayoutName = new QGridLayout;
    360             if (m_pLayoutName)
    361             {
    362                 /* Prepare network name label: */
    363                 m_pLabelNetworkName = new QLabel(pTabOptions);
     219            /* Prepare network name label: */
     220            m_pLabelNetworkName = new QLabel(this);
     221            if (m_pLabelNetworkName)
     222            {
     223                m_pLabelNetworkName->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
     224                pLayoutOptions->addWidget(m_pLabelNetworkName, 0, 0);
     225            }
     226            /* Prepare network name editor: */
     227            m_pEditorNetworkName = new QLineEdit(this);
     228            if (m_pEditorNetworkName)
     229            {
    364230                if (m_pLabelNetworkName)
    365                 {
    366                     m_pLabelNetworkName->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    367                     m_pLayoutName->addWidget(m_pLabelNetworkName, 0, 0);
    368                 }
    369                 /* Prepare network name editor: */
    370                 m_pEditorNetworkName = new QLineEdit(pTabOptions);
    371                 if (m_pEditorNetworkName)
    372                 {
    373                     if (m_pLabelNetworkName)
    374                         m_pLabelNetworkName->setBuddy(m_pEditorNetworkName);
    375                     connect(m_pEditorNetworkName, &QLineEdit::textEdited,
    376                             this, &UIDetailsWidgetNATNetwork::sltNetworkNameChanged);
    377 
    378                     m_pLayoutName->addWidget(m_pEditorNetworkName, 0, 1);
    379                 }
    380 
    381                 pLayoutOptions->addLayout(m_pLayoutName);
    382             }
    383 
    384             /* Prepare IPv4 group-box: */
    385             m_pGroupBoxIPv4 = new QGroupBox(pTabOptions);
    386             if (m_pGroupBoxIPv4)
    387             {
    388                 /* Prepare settings widget layout: */
    389                 QGridLayout *pLayoutSettings = new QGridLayout(m_pGroupBoxIPv4);
    390                 if (pLayoutSettings)
    391                 {
    392                     pLayoutSettings->setColumnStretch(2, 1);
    393 
    394                     /* Prepare network IPv4 prefix label: */
    395                     m_pLabelNetworkIPv4Prefix = new QLabel(pTabOptions);
    396                     if (m_pLabelNetworkIPv4Prefix)
    397                     {
    398                         m_pLabelNetworkIPv4Prefix->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    399                         pLayoutSettings->addWidget(m_pLabelNetworkIPv4Prefix, 1, 0);
    400                     }
    401                     /* Prepare network IPv4 prefix editor: */
    402                     m_pEditorNetworkIPv4Prefix = new QLineEdit(pTabOptions);
    403                     if (m_pEditorNetworkIPv4Prefix)
    404                     {
    405                         if (m_pLabelNetworkIPv4Prefix)
    406                             m_pLabelNetworkIPv4Prefix->setBuddy(m_pEditorNetworkIPv4Prefix);
    407                         connect(m_pEditorNetworkIPv4Prefix, &QLineEdit::textEdited,
    408                                 this, &UIDetailsWidgetNATNetwork::sltNetworkIPv4PrefixChanged);
    409 
    410                         pLayoutSettings->addWidget(m_pEditorNetworkIPv4Prefix, 1, 1, 1, 2);
    411                     }
    412 
    413                     /* Prepare 'supports DHCP' check-box: */
    414                     m_pCheckboxSupportsDHCP = new QCheckBox(pTabOptions);
    415                     if (m_pCheckboxSupportsDHCP)
    416                     {
    417                         connect(m_pCheckboxSupportsDHCP, &QCheckBox::toggled,
    418                                 this, &UIDetailsWidgetNATNetwork::sltSupportsDHCPChanged);
    419                         pLayoutSettings->addWidget(m_pCheckboxSupportsDHCP, 2, 1);
    420                     }
    421                 }
    422 
    423                 pLayoutOptions->addWidget(m_pGroupBoxIPv4);
    424             }
    425 
    426             /* Prepare IPv6 group-box: */
    427             m_pGroupBoxIPv6 = new QGroupBox(pTabOptions);
    428             if (m_pGroupBoxIPv6)
    429             {
    430                 m_pGroupBoxIPv6->setCheckable(true);
    431                 connect(m_pGroupBoxIPv6, &QGroupBox::toggled,
    432                         this, &UIDetailsWidgetNATNetwork::sltSupportsIPv6Changed);
    433 
    434                 /* Prepare settings widget layout: */
    435                 QGridLayout *pLayoutSettings = new QGridLayout(m_pGroupBoxIPv6);
    436                 if (pLayoutSettings)
    437                 {
    438                     pLayoutSettings->setColumnStretch(2, 1);
    439 
    440                     /* Prepare network IPv6 prefix label: */
    441                     m_pLabelNetworkIPv6Prefix = new QLabel(pTabOptions);
    442                     if (m_pLabelNetworkIPv6Prefix)
    443                     {
    444                         m_pLabelNetworkIPv6Prefix->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    445                         pLayoutSettings->addWidget(m_pLabelNetworkIPv6Prefix, 0, 0);
    446                     }
    447                     /* Prepare network IPv6 prefix editor: */
    448                     m_pEditorNetworkIPv6Prefix = new QLineEdit(pTabOptions);
    449                     if (m_pEditorNetworkIPv6Prefix)
    450                     {
    451                         if (m_pLabelNetworkIPv6Prefix)
    452                             m_pLabelNetworkIPv6Prefix->setBuddy(m_pEditorNetworkIPv6Prefix);
    453                         connect(m_pEditorNetworkIPv6Prefix, &QLineEdit::textEdited,
    454                                 this, &UIDetailsWidgetNATNetwork::sltNetworkIPv6PrefixChanged);
    455 
    456                         pLayoutSettings->addWidget(m_pEditorNetworkIPv6Prefix, 0, 1, 1, 2);
    457                     }
    458 
    459                     /* Prepare 'advertise default IPv6 route' check-box: */
    460                     m_pCheckboxAdvertiseDefaultIPv6Route = new QCheckBox(pTabOptions);
    461                     if (m_pCheckboxAdvertiseDefaultIPv6Route)
    462                     {
    463                         connect(m_pCheckboxAdvertiseDefaultIPv6Route, &QCheckBox::toggled,
    464                                 this, &UIDetailsWidgetNATNetwork::sltAdvertiseDefaultIPv6RouteChanged);
    465                         pLayoutSettings->addWidget(m_pCheckboxAdvertiseDefaultIPv6Route, 1, 1, 1, 2);
    466                     }
    467                 }
    468 
    469                 pLayoutOptions->addWidget(m_pGroupBoxIPv6);
    470             }
    471 
    472             /* If parent embedded into stack: */
    473             if (m_enmEmbedding == EmbedTo_Stack)
    474             {
    475                 /* Prepare button-box: */
    476                 m_pButtonBoxOptions = new QIDialogButtonBox(pTabOptions);
    477                 if (m_pButtonBoxOptions)
    478                 {
    479                     m_pButtonBoxOptions->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Ok);
    480                     connect(m_pButtonBoxOptions, &QIDialogButtonBox::clicked, this, &UIDetailsWidgetNATNetwork::sltHandleButtonBoxClick);
    481 
    482                     pLayoutOptions->addWidget(m_pButtonBoxOptions);
    483                 }
    484             }
     231                    m_pLabelNetworkName->setBuddy(m_pEditorNetworkName);
     232                connect(m_pEditorNetworkName, &QLineEdit::textEdited,
     233                        this, &UIDetailsWidgetCloudNetwork::sltNetworkNameChanged);
     234
     235                pLayoutOptions->addWidget(m_pEditorNetworkName, 0, 1);
     236            }
     237
     238            /* Prepare cloud provider name label: */
     239            m_pLabelProviderName = new QLabel(this);
     240            if (m_pLabelProviderName)
     241            {
     242                m_pLabelProviderName->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
     243                pLayoutOptions->addWidget(m_pLabelProviderName, 1, 0);
     244            }
     245            /* Prepare cloud provider name combo: */
     246            m_pComboProviderName = new QIComboBox(this);
     247            if (m_pComboProviderName)
     248            {
     249                if (m_pLabelProviderName)
     250                    m_pLabelProviderName->setBuddy(m_pComboProviderName);
     251                connect(m_pComboProviderName, static_cast<void(QIComboBox::*)(int)>(&QIComboBox::currentIndexChanged),
     252                        this, &UIDetailsWidgetCloudNetwork::sltCloudProviderNameChanged);
     253
     254                pLayoutOptions->addWidget(m_pComboProviderName, 1, 1);
     255            }
     256
     257            /* Prepare cloud profile name label: */
     258            m_pLabelProfileName = new QLabel(this);
     259            if (m_pLabelProfileName)
     260            {
     261                m_pLabelProfileName->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
     262                pLayoutOptions->addWidget(m_pLabelProfileName, 2, 0);
     263            }
     264            /* Prepare cloud profile name combo: */
     265            m_pComboProfileName = new QIComboBox(this);
     266            if (m_pComboProfileName)
     267            {
     268                if (m_pLabelProfileName)
     269                    m_pLabelProfileName->setBuddy(m_pComboProfileName);
     270                connect(m_pComboProfileName, static_cast<void(QIComboBox::*)(int)>(&QIComboBox::currentIndexChanged),
     271                        this, &UIDetailsWidgetCloudNetwork::sltCloudProfileNameChanged);
     272
     273                pLayoutOptions->addWidget(m_pComboProfileName, 2, 1);
     274            }
     275
     276            pLayoutMain->addLayout(pLayoutOptions);
    485277        }
    486278
    487         m_pTabWidget->addTab(pTabOptions, QString());
    488     }
    489 }
    490 
    491 void UIDetailsWidgetNATNetwork::prepareTabForwarding()
    492 {
    493     /* Prepare 'Forwarding' tab: */
    494     QWidget *pTabForwarding = new QWidget(m_pTabWidget);
    495     if (pTabForwarding)
    496     {
    497         /* Prepare 'Forwarding' layout: */
    498         QGridLayout *pLayoutForwarding = new QGridLayout(pTabForwarding);
    499         if (pLayoutForwarding)
     279        /* If parent embedded into stack: */
     280        if (m_enmEmbedding == EmbedTo_Stack)
    500281        {
    501 #ifdef VBOX_WS_MAC
    502             /* Configure layout: */
    503             pLayoutForwarding->setSpacing(10);
    504             pLayoutForwarding->setContentsMargins(10, 10, 10, 10);
    505 #endif
    506 
    507             /* Prepare forwarding tab-widget: */
    508             m_pTabWidgetForwarding = new QITabWidget(pTabForwarding);
    509             if (m_pTabWidgetForwarding)
    510             {
    511                 /* Prepare IPv4 forwarding table: */
    512                 m_pForwardingTableIPv4 = new UIPortForwardingTable(UIPortForwardingDataList(),
    513                                                                    false /* ip IPv6 protocol */,
    514                                                                    false /* allow empty guest IPs */);
    515                 if (m_pForwardingTableIPv4)
    516                 {
    517                     connect(m_pForwardingTableIPv4, &UIPortForwardingTable::sigDataChanged,
    518                             this, &UIDetailsWidgetNATNetwork::sltForwardingRulesIPv4Changed);
    519                     m_pTabWidgetForwarding->addTab(m_pForwardingTableIPv4, QString());
    520                 }
    521                 /* Prepare IPv6 forwarding table: */
    522                 m_pForwardingTableIPv6 = new UIPortForwardingTable(UIPortForwardingDataList(),
    523                                                                    true /* ip IPv6 protocol */,
    524                                                                    false /* allow empty guest IPs */);
    525                 if (m_pForwardingTableIPv6)
    526                 {
    527                     connect(m_pForwardingTableIPv4, &UIPortForwardingTable::sigDataChanged,
    528                             this, &UIDetailsWidgetNATNetwork::sltForwardingRulesIPv6Changed);
    529                     m_pTabWidgetForwarding->addTab(m_pForwardingTableIPv6, QString());
    530                 }
    531 
    532                 pLayoutForwarding->addWidget(m_pTabWidgetForwarding, 0, 0);
    533             }
    534 
    535             /* If parent embedded into stack: */
    536             if (m_enmEmbedding == EmbedTo_Stack)
    537             {
    538                 /* Prepare button-box: */
    539                 m_pButtonBoxForwarding = new QIDialogButtonBox(pTabForwarding);
    540                 if (m_pButtonBoxForwarding)
    541                 {
    542                     m_pButtonBoxForwarding->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Ok);
    543                     connect(m_pButtonBoxForwarding, &QIDialogButtonBox::clicked, this, &UIDetailsWidgetNATNetwork::sltHandleButtonBoxClick);
    544 
    545                     pLayoutForwarding->addWidget(m_pButtonBoxForwarding, 1, 0);
    546                 }
     282            /* Prepare button-box: */
     283            m_pButtonBoxOptions = new QIDialogButtonBox(this);
     284            if (m_pButtonBoxOptions)
     285            {
     286                m_pButtonBoxOptions->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Ok);
     287                connect(m_pButtonBoxOptions, &QIDialogButtonBox::clicked, this, &UIDetailsWidgetCloudNetwork::sltHandleButtonBoxClick);
     288
     289                pLayoutMain->addWidget(m_pButtonBoxOptions);
    547290            }
    548291        }
    549 
    550         m_pTabWidget->addTab(pTabForwarding, QString());
    551     }
    552 }
    553 
    554 void UIDetailsWidgetNATNetwork::loadDataForOptions()
     292    }
     293}
     294
     295void UIDetailsWidgetCloudNetwork::prepareProviders()
     296{
     297    /* Sanity check: */
     298    AssertPtrReturnVoid(m_pComboProviderName);
     299
     300    /* Remember current item data to be able to restore it: */
     301    QString strOldData;
     302    if (m_pComboProviderName->currentIndex() != -1)
     303        strOldData = m_pComboProviderName->currentData().toString();
     304
     305    /* Block signals while updating: */
     306    m_pComboProviderName->blockSignals(true);
     307
     308    /* Clear combo initially: */
     309    m_pComboProviderName->clear();
     310
     311    /* Add empty item: */
     312    m_pComboProviderName->addItem(QString());
     313
     314    /* Iterate through existing providers: */
     315    foreach (const CCloudProvider &comProvider, listCloudProviders())
     316    {
     317        /* Skip if we have nothing to populate (file missing?): */
     318        if (comProvider.isNull())
     319            continue;
     320        /* Acquire provider name: */
     321        QString strProviderName;
     322        if (!cloudProviderName(comProvider, strProviderName))
     323            continue;
     324        /* Acquire provider short name: */
     325        QString strProviderShortName;
     326        if (!cloudProviderShortName(comProvider, strProviderShortName))
     327            continue;
     328
     329        /* Compose empty item, fill the data: */
     330        m_pComboProviderName->addItem(strProviderName);
     331        m_pComboProviderName->setItemData(m_pComboProviderName->count() - 1, strProviderShortName);
     332    }
     333
     334    /* Set previous/default item if possible: */
     335    int iNewIndex = -1;
     336    if (   iNewIndex == -1
     337        && !strOldData.isNull())
     338        iNewIndex = m_pComboProviderName->findData(strOldData);
     339    if (   iNewIndex == -1
     340        && m_pComboProviderName->count() > 0)
     341        iNewIndex = 0;
     342    if (iNewIndex != -1)
     343        m_pComboProviderName->setCurrentIndex(iNewIndex);
     344
     345    /* Unblock signals after update: */
     346    m_pComboProviderName->blockSignals(false);
     347}
     348
     349void UIDetailsWidgetCloudNetwork::prepareProfiles()
     350{
     351    /* Sanity check: */
     352    AssertPtrReturnVoid(m_pComboProfileName);
     353
     354    /* Remember current item data to be able to restore it: */
     355    QString strOldData;
     356    if (m_pComboProfileName->currentIndex() != -1)
     357        strOldData = m_pComboProfileName->currentData().toString();
     358
     359    /* Block signals while updating: */
     360    m_pComboProfileName->blockSignals(true);
     361
     362    /* Clear combo initially: */
     363    m_pComboProfileName->clear();
     364
     365    /* Acquire provider short name: */
     366    const QString strProviderShortName = m_pComboProviderName->currentData().toString();
     367    if (!strProviderShortName.isEmpty())
     368    {
     369        /* Acquire provider: */
     370        CCloudProvider comProvider = cloudProviderByShortName(strProviderShortName);
     371        if (comProvider.isNotNull())
     372        {
     373            /* Iterate through existing profiles: */
     374            foreach (const CCloudProfile &comProfile, listCloudProfiles(comProvider))
     375            {
     376                /* Skip if we have nothing to populate (wtf happened?): */
     377                if (comProfile.isNull())
     378                    continue;
     379                /* Acquire current profile name: */
     380                QString strProfileName;
     381                if (!cloudProfileName(comProfile, strProfileName))
     382                    continue;
     383
     384                /* Compose item, fill the data: */
     385                m_pComboProfileName->addItem(strProfileName);
     386                m_pComboProfileName->setItemData(m_pComboProfileName->count() - 1, strProfileName);
     387            }
     388
     389            /* Set previous/default item if possible: */
     390            int iNewIndex = -1;
     391            if (   iNewIndex == -1
     392                && !strOldData.isNull())
     393                iNewIndex = m_pComboProfileName->findData(strOldData);
     394            if (   iNewIndex == -1
     395                && m_pComboProfileName->count() > 0)
     396                iNewIndex = 0;
     397            if (iNewIndex != -1)
     398                m_pComboProfileName->setCurrentIndex(iNewIndex);
     399        }
     400    }
     401
     402    /* Unblock signals after update: */
     403    m_pComboProfileName->blockSignals(false);
     404}
     405
     406void UIDetailsWidgetCloudNetwork::loadData()
    555407{
    556408    /* Check whether network exists and enabled: */
    557409    const bool fIsNetworkExists = m_newData.m_fExists;
    558     const bool fIsIPv6Supported = m_newData.m_fSupportsIPv6;
    559 
    560     /* Update 'Options' field availability: */
     410
     411    /* Update field availability: */
    561412    m_pLabelNetworkName->setEnabled(fIsNetworkExists);
    562413    m_pEditorNetworkName->setEnabled(fIsNetworkExists);
    563     m_pGroupBoxIPv4->setEnabled(fIsNetworkExists);
    564     m_pLabelNetworkIPv4Prefix->setEnabled(fIsNetworkExists);
    565     m_pEditorNetworkIPv4Prefix->setEnabled(fIsNetworkExists);
    566     m_pCheckboxSupportsDHCP->setEnabled(fIsNetworkExists);
    567     m_pGroupBoxIPv6->setEnabled(fIsNetworkExists);
    568     m_pLabelNetworkIPv6Prefix->setEnabled(fIsNetworkExists && fIsIPv6Supported);
    569     m_pEditorNetworkIPv6Prefix->setEnabled(fIsNetworkExists && fIsIPv6Supported);
    570     m_pCheckboxAdvertiseDefaultIPv6Route->setEnabled(fIsNetworkExists && fIsIPv6Supported);
    571 
    572     /* Load 'Options' fields: */
     414    m_pLabelProviderName->setEnabled(fIsNetworkExists);
     415    m_pComboProviderName->setEnabled(fIsNetworkExists);
     416    m_pLabelProfileName->setEnabled(fIsNetworkExists);
     417    m_pComboProfileName->setEnabled(fIsNetworkExists);
     418
     419    /* Load fields: */
    573420    m_pEditorNetworkName->setText(m_newData.m_strName);
    574     m_pEditorNetworkIPv4Prefix->setText(m_newData.m_strPrefixIPv4);
    575     m_pCheckboxSupportsDHCP->setChecked(m_newData.m_fSupportsDHCP);
    576     m_pGroupBoxIPv6->setChecked(m_newData.m_fSupportsIPv6);
    577     m_pEditorNetworkIPv6Prefix->setText(m_newData.m_strPrefixIPv6);
    578     m_pCheckboxAdvertiseDefaultIPv6Route->setChecked(m_newData.m_fAdvertiseDefaultIPv6Route);
    579 }
    580 
    581 void UIDetailsWidgetNATNetwork::loadDataForForwarding()
    582 {
    583     /* Check whether network exists and enabled: */
    584     const bool fIsNetworkExists = m_newData.m_fExists;
    585 
    586     /* Update 'Forwarding' field availability: */
    587     m_pForwardingTableIPv4->setEnabled(fIsNetworkExists);
    588     m_pForwardingTableIPv6->setEnabled(fIsNetworkExists);
    589 
    590     /* Calculate/load guest address hints: */
    591     char szTmpIp[16];
    592     RTNETADDRIPV4 rtNetwork4;
    593     int iPrefix4;
    594     const int rc = RTNetStrToIPv4Cidr(m_newData.m_strPrefixIPv4.toUtf8().constData(), &rtNetwork4, &iPrefix4);
    595     RTStrPrintf(szTmpIp, sizeof(szTmpIp), "%RTnaipv4", rtNetwork4);
    596     if (RT_SUCCESS(rc))
    597         m_pForwardingTableIPv4->setGuestAddressHint(QString(szTmpIp));
    598 
    599     /* Load 'Forwarding' fields: */
    600     m_pForwardingTableIPv4->setRules(m_newData.m_rules4, m_fHoldPosition);
    601     m_pForwardingTableIPv6->setRules(m_newData.m_rules6, m_fHoldPosition);
    602     m_fHoldPosition = false;
    603 }
     421    const int iProviderIndex = m_pComboProviderName->findData(m_newData.m_strProvider);
     422    m_pComboProviderName->setCurrentIndex(iProviderIndex == -1 ? 0 : iProviderIndex);
     423    const int iProfileIndex = m_pComboProfileName->findData(m_newData.m_strProfile);
     424    m_pComboProfileName->setCurrentIndex(iProfileIndex == -1 ? 0 : iProfileIndex);
     425}
  • trunk/src/VBox/Frontends/VirtualBox/src/networkmanager/UIDetailsWidgetCloudNetwork.h

    r92489 r92731  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UIDetailsWidgetNATNetwork class declaration.
     3 * VBox Qt GUI - UIDetailsWidgetCloudNetwork class declaration.
    44 */
    55
     
    1616 */
    1717
    18 #ifndef FEQT_INCLUDED_SRC_networkmanager_UIDetailsWidgetNATNetwork_h
    19 #define FEQT_INCLUDED_SRC_networkmanager_UIDetailsWidgetNATNetwork_h
     18#ifndef FEQT_INCLUDED_SRC_networkmanager_UIDetailsWidgetCloudNetwork_h
     19#define FEQT_INCLUDED_SRC_networkmanager_UIDetailsWidgetCloudNetwork_h
    2020#ifndef RT_WITHOUT_PRAGMA_ONCE
    2121# pragma once
     
    3838class QLineEdit;
    3939class QRadioButton;
     40class QIComboBox;
    4041class QIDialogButtonBox;
    4142class QILineEdit;
     
    4344
    4445
    45 /** Network Manager: NAT network data structure. */
    46 struct UIDataNATNetwork
     46/** Network Manager: Cloud network data structure. */
     47struct UIDataCloudNetwork
    4748{
    4849    /** Constructs data. */
    49     UIDataNATNetwork()
     50    UIDataCloudNetwork()
    5051        : m_fExists(false)
     52        , m_fEnabled(true)
    5153        , m_strName(QString())
    52         , m_strPrefixIPv4(QString())
    53         , m_strPrefixIPv6(QString())
    54         , m_fSupportsDHCP(false)
    55         , m_fSupportsIPv6(false)
    56         , m_fAdvertiseDefaultIPv6Route(false)
     54        , m_strProvider(QString())
     55        , m_strProfile(QString())
    5756    {}
    5857
    5958    /** Returns whether the @a other passed data is equal to this one. */
    60     bool equal(const UIDataNATNetwork &other) const
     59    bool equal(const UIDataCloudNetwork &other) const
    6160    {
    6261        return true
    6362               && (m_fExists == other.m_fExists)
     63               && (m_fEnabled == other.m_fEnabled)
    6464               && (m_strName == other.m_strName)
    65                && (m_strPrefixIPv4 == other.m_strPrefixIPv4)
    66                && (m_strPrefixIPv6 == other.m_strPrefixIPv6)
    67                && (m_fSupportsDHCP == other.m_fSupportsDHCP)
    68                && (m_fSupportsIPv6 == other.m_fSupportsIPv6)
    69                && (m_fAdvertiseDefaultIPv6Route == other.m_fAdvertiseDefaultIPv6Route)
    70                && (m_rules4 == other.m_rules4)
    71                && (m_rules6 == other.m_rules6)
     65               && (m_strProvider == other.m_strProvider)
     66               && (m_strProfile == other.m_strProfile)
    7267               ;
    7368    }
    7469
    7570    /** Returns whether the @a other passed data is equal to this one. */
    76     bool operator==(const UIDataNATNetwork &other) const { return equal(other); }
     71    bool operator==(const UIDataCloudNetwork &other) const { return equal(other); }
    7772    /** Returns whether the @a other passed data is different from this one. */
    78     bool operator!=(const UIDataNATNetwork &other) const { return !equal(other); }
     73    bool operator!=(const UIDataCloudNetwork &other) const { return !equal(other); }
    7974
    8075    /** Holds whether this network is not NULL. */
    81     bool                      m_fExists;
     76    bool     m_fExists;
     77    /** Holds whether network is enabled. */
     78    bool     m_fEnabled;
    8279    /** Holds network name. */
    83     QString                   m_strName;
    84     /** Holds network IPv4 prefix. */
    85     QString                   m_strPrefixIPv4;
    86     /** Holds network IPv6 prefix. */
    87     QString                   m_strPrefixIPv6;
    88     /** Holds whether this network supports DHCP. */
    89     bool                      m_fSupportsDHCP;
    90     /** Holds whether this network supports IPv6. */
    91     bool                      m_fSupportsIPv6;
    92     /** Holds whether this network advertised as default IPv6 route. */
    93     bool                      m_fAdvertiseDefaultIPv6Route;
    94     /** Holds IPv4 port forwarding rules. */
    95     UIPortForwardingDataList  m_rules4;
    96     /** Holds IPv6 port forwarding rules. */
    97     UIPortForwardingDataList  m_rules6;
     80    QString  m_strName;
     81    /** Holds cloud provider name. */
     82    QString  m_strProvider;
     83    /** Holds cloud profile name. */
     84    QString  m_strProfile;
    9885};
    9986
    10087
    101 /** Network Manager: NAT network details-widget. */
    102 class UIDetailsWidgetNATNetwork : public QIWithRetranslateUI<QWidget>
     88/** Network Manager: Cloud network details-widget. */
     89class UIDetailsWidgetCloudNetwork : public QIWithRetranslateUI<QWidget>
    10390{
    10491    Q_OBJECT;
     
    118105    /** Constructs medium details dialog passing @a pParent to the base-class.
    119106      * @param  enmEmbedding  Brings embedding type. */
    120     UIDetailsWidgetNATNetwork(EmbedTo enmEmbedding, QWidget *pParent = 0);
     107    UIDetailsWidgetCloudNetwork(EmbedTo enmEmbedding, QWidget *pParent = 0);
    121108
    122109    /** Returns the host network data. */
    123     const UIDataNATNetwork &data() const { return m_newData; }
     110    const UIDataCloudNetwork &data() const { return m_newData; }
    124111    /** Defines the host network @a data.
    125       * @param  busyNames      Holds the list of names busy by other
    126       *                        NAT networks.
    127       * @param  fHoldPosition  Holds whether we should try to keep
    128       *                        port forwarding rule position intact. */
    129     void setData(const UIDataNATNetwork &data,
    130                  const QStringList &busyNames = QStringList(),
    131                  bool fHoldPosition = false);
     112      * @param  busyNames  Holds the list of names busy by other
     113      *                    Cloud networks. */
     114    void setData(const UIDataCloudNetwork &data,
     115                 const QStringList &busyNames = QStringList());
    132116
    133117    /** @name Change handling stuff.
     
    151135        /** Handles network name text change. */
    152136        void sltNetworkNameChanged(const QString &strText);
    153         /** Handles network IPv4 prefix text change. */
    154         void sltNetworkIPv4PrefixChanged(const QString &strText);
    155         /** Handles network IPv6 prefix text change. */
    156         void sltNetworkIPv6PrefixChanged(const QString &strText);
    157         /** Handles network supports DHCP choice change. */
    158         void sltSupportsDHCPChanged(bool fChecked);
    159         /** Handles network supports IPv6 choice change. */
    160         void sltSupportsIPv6Changed(bool fChecked);
    161         /** Handles network advertised as default IPv6 route choice change. */
    162         void sltAdvertiseDefaultIPv6RouteChanged(bool fChecked);
    163 
    164         /** Handles IPv4 forwarding rules table change. */
    165         void sltForwardingRulesIPv4Changed();
    166         /** Handles IPv6 forwarding rules table change. */
    167         void sltForwardingRulesIPv6Changed();
     137        /** Handles cloud provider name index change. */
     138        void sltCloudProviderNameChanged(int iIndex);
     139        /** Handles cloud profile name index change. */
     140        void sltCloudProfileNameChanged(int iIndex);
    168141
    169142        /** Handles button-box button click. */
     
    179152        /** Prepares this. */
    180153        void prepareThis();
    181         /** Prepares tab-widget. */
    182         void prepareTabWidget();
    183         /** Prepares 'Options' tab. */
    184         void prepareTabOptions();
    185         /** Prepares 'Forwarding' tab. */
    186         void prepareTabForwarding();
     154        /** Prepares providers. */
     155        void prepareProviders();
     156        /** Prepares profiles. */
     157        void prepareProfiles();
    187158    /** @} */
    188159
    189160    /** @name Loading stuff.
    190161      * @{ */
    191         /** Loads 'Options' data. */
    192         void loadDataForOptions();
    193         /** Loads 'Forwarding' data. */
    194         void loadDataForForwarding();
     162        /** Loads data. */
     163        void loadData();
    195164    /** @} */
    196165
     
    201170
    202171        /** Holds the old data copy. */
    203         UIDataNATNetwork  m_oldData;
     172        UIDataCloudNetwork  m_oldData;
    204173        /** Holds the new data copy. */
    205         UIDataNATNetwork  m_newData;
    206 
    207         /** Holds the tab-widget. */
    208         QITabWidget *m_pTabWidget;
     174        UIDataCloudNetwork  m_newData;
    209175    /** @} */
    210176
    211177    /** @name Network variables.
    212178      * @{ */
    213         /** Holds the name layout instance. */
    214         QGridLayout       *m_pLayoutName;
    215179        /** Holds the network name label instance. */
    216         QLabel            *m_pLabelNetworkName;
     180        QLabel     *m_pLabelNetworkName;
    217181        /** Holds the network name editor instance. */
    218         QLineEdit         *m_pEditorNetworkName;
    219         /** Holds the IPv4 group-box instance. */
    220         QGroupBox         *m_pGroupBoxIPv4;
    221         /** Holds the network IPv4 prefix label instance. */
    222         QLabel            *m_pLabelNetworkIPv4Prefix;
    223         /** Holds the network IPv4 prefix editor instance. */
    224         QLineEdit         *m_pEditorNetworkIPv4Prefix;
    225         /** Holds the 'supports DHCP' check-box instance. */
    226         QCheckBox         *m_pCheckboxSupportsDHCP;
    227         /** Holds the IPv4 group-box instance. */
    228         QGroupBox         *m_pGroupBoxIPv6;
    229         /** Holds the network IPv6 prefix label instance. */
    230         QLabel            *m_pLabelNetworkIPv6Prefix;
    231         /** Holds the network IPv6 prefix editor instance. */
    232         QLineEdit         *m_pEditorNetworkIPv6Prefix;
    233         /** Holds the 'advertise default IPv6 route' check-box instance. */
    234         QCheckBox         *m_pCheckboxAdvertiseDefaultIPv6Route;
     182        QLineEdit  *m_pEditorNetworkName;
     183        /** Holds the cloud provider name label instance. */
     184        QLabel     *m_pLabelProviderName;
     185        /** Holds the cloud provider name combo instance. */
     186        QIComboBox *m_pComboProviderName;
     187        /** Holds the cloud profile name label instance. */
     188        QLabel     *m_pLabelProfileName;
     189        /** Holds the cloud profile name combo instance. */
     190        QIComboBox *m_pComboProfileName;
     191
    235192        /** Holds the 'Options' button-box instance. */
    236193        QIDialogButtonBox *m_pButtonBoxOptions;
    237     /** @} */
    238 
    239     /** @name Forwarding variables.
    240       * @{ */
    241         /** */
    242         QITabWidget           *m_pTabWidgetForwarding;
    243         /** */
    244         UIPortForwardingTable *m_pForwardingTableIPv4;
    245         /** */
    246         UIPortForwardingTable *m_pForwardingTableIPv6;
    247         /** Holds the 'Forwarding' button-box instance. */
    248         QIDialogButtonBox     *m_pButtonBoxForwarding;
    249194        /** Holds the list of names busy by other
    250195          * NAT networks. */
    251         QStringList            m_busyNames;
    252         /** Holds whether we should try to keep
    253           * port forwarding rule position intact. */
    254         bool                   m_fHoldPosition;
     196        QStringList        m_busyNames;
    255197    /** @} */
    256198};
    257199
    258200
    259 #endif /* !FEQT_INCLUDED_SRC_networkmanager_UIDetailsWidgetNATNetwork_h */
    260 
     201#endif /* !FEQT_INCLUDED_SRC_networkmanager_UIDetailsWidgetCloudNetwork_h */
  • trunk/src/VBox/Frontends/VirtualBox/src/networkmanager/UINetworkManager.cpp

    r92730 r92731  
    2828#include "UIActionPoolManager.h"
    2929#include "UIConverter.h"
     30#include "UIDetailsWidgetCloudNetwork.h"
    3031#include "UIDetailsWidgetHostNetwork.h"
    3132#include "UIDetailsWidgetNATNetwork.h"
     
    4344
    4445/* COM includes: */
     46#include "CCloudNetwork.h"
    4547#include "CDHCPServer.h"
    4648#include "CHost.h"
     
    5759    TabWidgetIndex_HostNetwork,
    5860    TabWidgetIndex_NATNetwork,
     61    TabWidgetIndex_CloudNetwork,
    5962};
    6063
     
    8285
    8386
     87/** Cloud network tree-widget column indexes. */
     88enum CloudNetworkColumn
     89{
     90    CloudNetworkColumn_Name,
     91    CloudNetworkColumn_Provider,
     92    CloudNetworkColumn_Profile,
     93    CloudNetworkColumn_Max,
     94};
     95
     96
    8497/** Network Manager: Host Network tree-widget item. */
    8598class UIItemHostNetwork : public QITreeWidgetItem, public UIDataHostNetwork
     
    104117/** Network Manager: NAT Network tree-widget item. */
    105118class UIItemNATNetwork : public QITreeWidgetItem, public UIDataNATNetwork
     119{
     120    Q_OBJECT;
     121
     122public:
     123
     124    /** Updates item fields from data. */
     125    void updateFields();
     126
     127    /** Returns item name. */
     128    QString name() const { return m_strName; }
     129
     130protected:
     131
     132    /** Returns default text. */
     133    virtual QString defaultText() const /* override */;
     134};
     135
     136
     137/** Network Manager: Cloud Network tree-widget item. */
     138class UIItemCloudNetwork : public QITreeWidgetItem, public UIDataCloudNetwork
    106139{
    107140    Q_OBJECT;
     
    266299
    267300/*********************************************************************************************************************************
     301*   Class UIItemCloudNetwork implementation.                                                                                     *
     302*********************************************************************************************************************************/
     303
     304void UIItemCloudNetwork::updateFields()
     305{
     306    /* Compose item fields: */
     307    setText(CloudNetworkColumn_Name, m_strName);
     308    setText(CloudNetworkColumn_Provider, m_strProvider);
     309    setText(CloudNetworkColumn_Profile, m_strProfile);
     310
     311    /* Compose item tool-tip: */
     312    const QString strTable("<table cellspacing=5>%1</table>");
     313    const QString strHeader("<tr><td><nobr>%1:&nbsp;</nobr></td><td><nobr>%2</nobr></td></tr>");
     314    QString strToolTip;
     315
     316    /* Network information: */
     317    strToolTip += strHeader.arg(tr("Network Name"), m_strName);
     318    strToolTip += strHeader.arg(tr("Provider"), m_strProvider);
     319    strToolTip += strHeader.arg(tr("Profile"), m_strProfile);
     320
     321    /* Assign tool-tip finally: */
     322    setToolTip(CloudNetworkColumn_Name, strTable.arg(strToolTip));
     323}
     324
     325QString UIItemCloudNetwork::defaultText() const
     326{
     327    return tr("%1, %2", "col.2 text, col.1 name").arg(text(1)).arg(parentTree()->headerItem()->text(0));
     328}
     329
     330
     331/*********************************************************************************************************************************
    268332*   Class UINetworkManagerWidget implementation.                                                                                 *
    269333*********************************************************************************************************************************/
     
    285349    , m_pTreeWidgetNATNetwork(0)
    286350    , m_pDetailsWidgetNATNetwork(0)
     351    , m_pTabCloudNetwork(0)
     352    , m_pLayoutCloudNetwork(0)
     353    , m_pTreeWidgetCloudNetwork(0)
     354    , m_pDetailsWidgetCloudNetwork(0)
    287355{
    288356    prepare();
     
    313381        m_pTabWidget->setTabText(0, UINetworkManager::tr("Host-only Networks"));
    314382        m_pTabWidget->setTabText(1, UINetworkManager::tr("NAT Networks"));
     383        m_pTabWidget->setTabText(2, UINetworkManager::tr("Cloud Networks"));
    315384    }
    316385
     
    336405        m_pTreeWidgetNATNetwork->setHeaderLabels(fields);
    337406    }
     407
     408    /* Translate cloud network tree-widget: */
     409    if (m_pTreeWidgetCloudNetwork)
     410    {
     411        const QStringList fields = QStringList()
     412                                   << UINetworkManager::tr("Name")
     413                                   << UINetworkManager::tr("Provider")
     414                                   << UINetworkManager::tr("Profile");
     415        m_pTreeWidgetCloudNetwork->setHeaderLabels(fields);
     416    }
    338417}
    339418
     
    366445        case TabWidgetIndex_HostNetwork: sltHandleCurrentItemChangeHostNetwork(); break;
    367446        case TabWidgetIndex_NATNetwork: sltHandleCurrentItemChangeNATNetwork(); break;
     447        case TabWidgetIndex_CloudNetwork: sltHandleCurrentItemChangeCloudNetwork(); break;
    368448        default: break;
    369449    }
     
    380460        case TabWidgetIndex_HostNetwork: sltApplyDetailsChangesHostNetwork(); break;
    381461        case TabWidgetIndex_NATNetwork: sltApplyDetailsChangesNATNetwork(); break;
     462        case TabWidgetIndex_CloudNetwork: sltApplyDetailsChangesCloudNetwork(); break;
    382463        default: break;
    383464    }
     
    668749}
    669750
     751void UINetworkManagerWidget::sltCreateCloudNetwork()
     752{
     753    /* For cloud networks only: */
     754    if (m_pTabWidget->currentIndex() != TabWidgetIndex_CloudNetwork)
     755        return;
     756
     757    /* Compose a set of busy names: */
     758    QSet<QString> names;
     759    for (int i = 0; i < m_pTreeWidgetCloudNetwork->topLevelItemCount(); ++i)
     760        names << qobject_cast<UIItemCloudNetwork*>(m_pTreeWidgetCloudNetwork->childItem(i))->name();
     761    /* Compose a map of busy indexes: */
     762    QMap<int, bool> presence;
     763    const QString strNameTemplate("CloudNetwork%1");
     764    const QRegExp regExp(strNameTemplate.arg("([\\d]*)"));
     765    foreach (const QString &strName, names)
     766        if (regExp.indexIn(strName) != -1)
     767            presence[regExp.cap(1).toInt()] = true;
     768    /* Search for a minimum index: */
     769    int iMinimumIndex = 0;
     770    for (int i = 0; !presence.isEmpty() && i <= presence.lastKey() + 1; ++i)
     771        if (!presence.contains(i))
     772        {
     773            iMinimumIndex = i;
     774            break;
     775        }
     776    /* Compose resulting index and name: */
     777    const QString strNetworkName = strNameTemplate.arg(iMinimumIndex == 0 ? QString() : QString::number(iMinimumIndex));
     778
     779    /* Compose new item data: */
     780    UIDataCloudNetwork oldData;
     781    oldData.m_fEnabled = true;
     782    oldData.m_strName = strNetworkName;
     783    oldData.m_strProvider = QString();
     784    oldData.m_strProfile = QString();
     785
     786    /* Get VirtualBox for further activities: */
     787    CVirtualBox comVBox = uiCommon().virtualBox();
     788
     789    /* Create network: */
     790    CCloudNetwork comNetwork = comVBox.CreateCloudNetwork(oldData.m_strName);
     791    CCloudNetwork comNetworkBase = comNetwork;
     792
     793    /* Show error message if necessary: */
     794    if (!comVBox.isOk())
     795        UINotificationMessage::cannotCreateCloudNetwork(comVBox);
     796    else
     797    {
     798        /* Save whether network enabled: */
     799        if (comNetwork.isOk())
     800            comNetwork.SetEnabled(oldData.m_fEnabled);
     801        /* Save cloud network name: */
     802        if (comNetwork.isOk())
     803            comNetwork.SetNetworkName(oldData.m_strName);
     804        /* Save cloud provider: */
     805        if (comNetwork.isOk())
     806            comNetwork.SetProvider(oldData.m_strProvider);
     807        /* Save cloud profile: */
     808        if (comNetwork.isOk())
     809            comNetwork.SetProfile(oldData.m_strProfile);
     810
     811        /* Show error message if necessary: */
     812        if (!comNetwork.isOk())
     813            UINotificationMessage::cannotChangeCloudNetworkParameter(comNetwork);
     814
     815        /* Add network to the tree: */
     816        UIDataCloudNetwork newData;
     817        loadCloudNetwork(comNetworkBase, newData);
     818        createItemForCloudNetwork(newData, true);
     819
     820        /* Adjust tree-widgets: */
     821        sltAdjustTreeWidgets();
     822    }
     823}
     824
     825void UINetworkManagerWidget::sltRemoveCloudNetwork()
     826{
     827    /* For cloud networks only: */
     828    if (m_pTabWidget->currentIndex() != TabWidgetIndex_CloudNetwork)
     829        return;
     830
     831    /* Check cloud network tree-widget: */
     832    AssertMsgReturnVoid(m_pTreeWidgetCloudNetwork, ("Cloud network tree-widget isn't created!\n"));
     833
     834    /* Get network item: */
     835    UIItemCloudNetwork *pItem = static_cast<UIItemCloudNetwork*>(m_pTreeWidgetCloudNetwork->currentItem());
     836    AssertMsgReturnVoid(pItem, ("Current item must not be null!\n"));
     837
     838    /* Get network name: */
     839    const QString strNetworkName(pItem->name());
     840
     841    /* Confirm host network removal: */
     842    if (!msgCenter().confirmCloudNetworkRemoval(strNetworkName, this))
     843        return;
     844
     845    /* Get VirtualBox for further activities: */
     846    CVirtualBox comVBox = uiCommon().virtualBox();
     847
     848    /* Find corresponding network: */
     849    const CCloudNetwork &comNetwork = comVBox.FindCloudNetworkByName(strNetworkName);
     850
     851    /* Show error message if necessary: */
     852    if (!comVBox.isOk() || comNetwork.isNull())
     853        UINotificationMessage::cannotFindCloudNetwork(comVBox, strNetworkName);
     854    else
     855    {
     856        /* Remove network finally: */
     857        comVBox.RemoveCloudNetwork(comNetwork);
     858
     859        /* Show error message if necessary: */
     860        if (!comVBox.isOk())
     861            UINotificationMessage::cannotRemoveCloudNetwork(comVBox, strNetworkName);
     862        else
     863        {
     864            /* Move selection to somewhere else: */
     865            if (m_pTreeWidgetCloudNetwork->itemBelow(pItem))
     866                m_pTreeWidgetCloudNetwork->setCurrentItem(m_pTreeWidgetCloudNetwork->itemBelow(pItem));
     867            else if (m_pTreeWidgetCloudNetwork->itemAbove(pItem))
     868                m_pTreeWidgetCloudNetwork->setCurrentItem(m_pTreeWidgetCloudNetwork->itemAbove(pItem));
     869            else
     870                m_pTreeWidgetCloudNetwork->setCurrentItem(0);
     871
     872            /* Remove interface from the tree: */
     873            delete pItem;
     874
     875            /* Adjust tree-widgets: */
     876            sltAdjustTreeWidgets();
     877        }
     878    }
     879}
     880
    670881void UINetworkManagerWidget::sltToggleDetailsVisibility(bool fVisible)
    671882{
     
    679890            if (m_pDetailsWidgetNATNetwork)
    680891                m_pDetailsWidgetNATNetwork->setVisible(false);
     892            if (m_pDetailsWidgetCloudNetwork)
     893                m_pDetailsWidgetCloudNetwork->setVisible(false);
    681894            if (m_pDetailsWidgetHostNetwork)
    682895                m_pDetailsWidgetHostNetwork->setVisible(fVisible);
     
    687900            if (m_pDetailsWidgetHostNetwork)
    688901                m_pDetailsWidgetHostNetwork->setVisible(false);
     902            if (m_pDetailsWidgetCloudNetwork)
     903                m_pDetailsWidgetCloudNetwork->setVisible(false);
    689904            if (m_pDetailsWidgetNATNetwork)
    690905                m_pDetailsWidgetNATNetwork->setVisible(fVisible);
    691906            break;
    692907        }
     908        case TabWidgetIndex_CloudNetwork:
     909        {
     910            if (m_pDetailsWidgetHostNetwork)
     911                m_pDetailsWidgetHostNetwork->setVisible(false);
     912            if (m_pDetailsWidgetNATNetwork)
     913                m_pDetailsWidgetNATNetwork->setVisible(false);
     914            if (m_pDetailsWidgetCloudNetwork)
     915                m_pDetailsWidgetCloudNetwork->setVisible(fVisible);
     916            break;
     917        }
    693918    }
    694919    /* Notify external listeners: */
     
    709934            if (m_pDetailsWidgetNATNetwork)
    710935                m_pDetailsWidgetNATNetwork->setVisible(false);
     936            if (m_pDetailsWidgetCloudNetwork)
     937                m_pDetailsWidgetCloudNetwork->setVisible(false);
    711938            if (m_pDetailsWidgetHostNetwork)
    712939                m_pDetailsWidgetHostNetwork->setVisible(fVisible);
     
    717944            if (m_pDetailsWidgetHostNetwork)
    718945                m_pDetailsWidgetHostNetwork->setVisible(false);
     946            if (m_pDetailsWidgetCloudNetwork)
     947                m_pDetailsWidgetCloudNetwork->setVisible(false);
    719948            if (m_pDetailsWidgetNATNetwork)
    720949                m_pDetailsWidgetNATNetwork->setVisible(fVisible);
     950            break;
     951        }
     952        case TabWidgetIndex_CloudNetwork:
     953        {
     954            if (m_pDetailsWidgetHostNetwork)
     955                m_pDetailsWidgetHostNetwork->setVisible(false);
     956            if (m_pDetailsWidgetNATNetwork)
     957                m_pDetailsWidgetNATNetwork->setVisible(false);
     958            if (m_pDetailsWidgetCloudNetwork)
     959                m_pDetailsWidgetCloudNetwork->setVisible(fVisible);
    721960            break;
    722961        }
     
    7741013        m_pTreeWidgetNATNetwork->setColumnWidth(NATNetworkColumn_DHCP, iWidth3);
    7751014        m_pTreeWidgetNATNetwork->setColumnWidth(NATNetworkColumn_Name, iTotal - iWidth1 - iWidth2 - iWidth3);
     1015    }
     1016
     1017    /* Check cloud network tree-widget: */
     1018    if (m_pTreeWidgetCloudNetwork)
     1019    {
     1020        /* Get the tree-widget abstract interface: */
     1021        QAbstractItemView *pItemView = m_pTreeWidgetCloudNetwork;
     1022        /* Get the tree-widget header-view: */
     1023        QHeaderView *pItemHeader = m_pTreeWidgetCloudNetwork->header();
     1024
     1025        /* Calculate the total tree-widget width: */
     1026        const int iTotal = m_pTreeWidgetCloudNetwork->viewport()->width();
     1027        /* Look for a minimum width hints for non-important columns: */
     1028        const int iMinWidth1 = qMax(pItemView->sizeHintForColumn(CloudNetworkColumn_Provider), pItemHeader->sectionSizeHint(CloudNetworkColumn_Provider));
     1029        const int iMinWidth2 = qMax(pItemView->sizeHintForColumn(CloudNetworkColumn_Profile), pItemHeader->sectionSizeHint(CloudNetworkColumn_Profile));
     1030        /* Propose suitable width hints for non-important columns: */
     1031        const int iWidth1 = iMinWidth1 < iTotal / CloudNetworkColumn_Max ? iMinWidth1 : iTotal / CloudNetworkColumn_Max;
     1032        const int iWidth2 = iMinWidth2 < iTotal / CloudNetworkColumn_Max ? iMinWidth2 : iTotal / CloudNetworkColumn_Max;
     1033        /* Apply the proposal: */
     1034        m_pTreeWidgetCloudNetwork->setColumnWidth(CloudNetworkColumn_Provider, iWidth1);
     1035        m_pTreeWidgetCloudNetwork->setColumnWidth(CloudNetworkColumn_Profile, iWidth2);
     1036        m_pTreeWidgetCloudNetwork->setColumnWidth(CloudNetworkColumn_Name, iTotal - iWidth1 - iWidth2);
    7761037    }
    7771038}
     
    11211382}
    11221383
     1384void UINetworkManagerWidget::sltHandleCurrentItemChangeCloudNetwork()
     1385{
     1386    /* Check cloud network tree-widget: */
     1387    AssertMsgReturnVoid(m_pTreeWidgetCloudNetwork, ("Cloud network tree-widget isn't created!\n"));
     1388
     1389    /* Get network item: */
     1390    UIItemCloudNetwork *pItem = static_cast<UIItemCloudNetwork*>(m_pTreeWidgetCloudNetwork->currentItem());
     1391
     1392    /* Update actions availability: */
     1393    m_pActionPool->action(UIActionIndexMN_M_Network_S_Remove)->setEnabled(pItem);
     1394
     1395    /* Check Cloud network details-widget: */
     1396    AssertMsgReturnVoid(m_pDetailsWidgetCloudNetwork, ("Cloud network details-widget isn't created!\n"));
     1397
     1398    /* If there is an item => update details data: */
     1399    if (pItem)
     1400    {
     1401        QStringList busyNamesForItem = busyNamesCloud();
     1402        busyNamesForItem.removeAll(pItem->name());
     1403        m_pDetailsWidgetCloudNetwork->setData(*pItem, busyNamesForItem);
     1404    }
     1405    /* Otherwise => clear details: */
     1406    else
     1407        m_pDetailsWidgetCloudNetwork->setData(UIDataCloudNetwork());
     1408}
     1409
     1410void UINetworkManagerWidget::sltHandleContextMenuRequestCloudNetwork(const QPoint &position)
     1411{
     1412    /* Check cloud network tree-widget: */
     1413    AssertMsgReturnVoid(m_pTreeWidgetCloudNetwork, ("Cloud network tree-widget isn't created!\n"));
     1414
     1415    /* Compose temporary context-menu: */
     1416    QMenu menu;
     1417    if (m_pTreeWidgetCloudNetwork->itemAt(position))
     1418    {
     1419        menu.addAction(m_pActionPool->action(UIActionIndexMN_M_Network_S_Remove));
     1420        menu.addAction(m_pActionPool->action(UIActionIndexMN_M_Network_T_Details));
     1421    }
     1422    else
     1423    {
     1424        menu.addAction(m_pActionPool->action(UIActionIndexMN_M_Network_S_Create));
     1425//        menu.addAction(m_pActionPool->action(UIActionIndexMN_M_Network_S_Refresh));
     1426    }
     1427    /* And show it: */
     1428    menu.exec(m_pTreeWidgetCloudNetwork->mapToGlobal(position));
     1429}
     1430
     1431void UINetworkManagerWidget::sltApplyDetailsChangesCloudNetwork()
     1432{
     1433    /* Check cloud network tree-widget: */
     1434    AssertMsgReturnVoid(m_pTreeWidgetCloudNetwork, ("Cloud network tree-widget isn't created!\n"));
     1435
     1436    /* Get Cloud network item: */
     1437    UIItemCloudNetwork *pItem = static_cast<UIItemCloudNetwork*>(m_pTreeWidgetCloudNetwork->currentItem());
     1438    AssertMsgReturnVoid(pItem, ("Current item must not be null!\n"));
     1439
     1440    /* Check Cloud network details-widget: */
     1441    AssertMsgReturnVoid(m_pDetailsWidgetCloudNetwork, ("Cloud network details-widget isn't created!\n"));
     1442
     1443    /* Revalidate Cloud network details: */
     1444    if (m_pDetailsWidgetCloudNetwork->revalidate())
     1445    {
     1446        /* Get item data: */
     1447        UIDataCloudNetwork oldData = *pItem;
     1448        UIDataCloudNetwork newData = m_pDetailsWidgetCloudNetwork->data();
     1449
     1450        /* Get VirtualBox for further activities: */
     1451        CVirtualBox comVBox = uiCommon().virtualBox();
     1452
     1453        /* Find corresponding network: */
     1454        CCloudNetwork comNetwork = comVBox.FindCloudNetworkByName(oldData.m_strName);
     1455        CCloudNetwork comNetworkBase = comNetwork;
     1456
     1457        /* Show error message if necessary: */
     1458        if (!comVBox.isOk() || comNetwork.isNull())
     1459            UINotificationMessage::cannotFindCloudNetwork(comVBox, oldData.m_strName);
     1460        else
     1461        {
     1462            /* Save whether cloud network enabled: */
     1463            if (comNetwork.isOk() && newData.m_fEnabled != oldData.m_fEnabled)
     1464                comNetwork.SetEnabled(newData.m_fEnabled);
     1465            /* Save cloud network name: */
     1466            if (comNetwork.isOk() && newData.m_strName != oldData.m_strName)
     1467                comNetwork.SetNetworkName(newData.m_strName);
     1468            /* Save cloud provider: */
     1469            if (comNetwork.isOk() && newData.m_strProvider != oldData.m_strProvider)
     1470                comNetwork.SetProvider(newData.m_strProvider);
     1471            /* Save cloud profile: */
     1472            if (comNetwork.isOk() && newData.m_strProfile != oldData.m_strProfile)
     1473                comNetwork.SetProfile(newData.m_strProfile);
     1474
     1475            /* Show error message if necessary: */
     1476            if (!comNetwork.isOk())
     1477                UINotificationMessage::cannotChangeCloudNetworkParameter(comNetwork);
     1478
     1479            /* Update network in the tree: */
     1480            UIDataCloudNetwork data;
     1481            loadCloudNetwork(comNetworkBase, data);
     1482            updateItemForCloudNetwork(data, true, pItem);
     1483
     1484            /* Make sure current item fetched: */
     1485            sltHandleCurrentItemChangeCloudNetwork();
     1486
     1487            /* Adjust tree-widgets: */
     1488            sltAdjustTreeWidgets();
     1489        }
     1490    }
     1491
     1492    /* Make sure button states updated: */
     1493    m_pDetailsWidgetNATNetwork->updateButtonStates();
     1494}
     1495
    11231496void UINetworkManagerWidget::prepare()
    11241497{
     
    11391512    loadHostNetworks();
    11401513    loadNATNetworks();
     1514    loadCloudNetworks();
    11411515}
    11421516
     
    11541528    connect(m_pActionPool->action(UIActionIndexMN_M_Network_S_Create), &QAction::triggered,
    11551529            this, &UINetworkManagerWidget::sltCreateNATNetwork);
     1530    connect(m_pActionPool->action(UIActionIndexMN_M_Network_S_Create), &QAction::triggered,
     1531            this, &UINetworkManagerWidget::sltCreateCloudNetwork);
    11561532    connect(m_pActionPool->action(UIActionIndexMN_M_Network_S_Remove), &QAction::triggered,
    11571533            this, &UINetworkManagerWidget::sltRemoveHostNetwork);
    11581534    connect(m_pActionPool->action(UIActionIndexMN_M_Network_S_Remove), &QAction::triggered,
    11591535            this, &UINetworkManagerWidget::sltRemoveNATNetwork);
     1536    connect(m_pActionPool->action(UIActionIndexMN_M_Network_S_Remove), &QAction::triggered,
     1537            this, &UINetworkManagerWidget::sltRemoveCloudNetwork);
    11601538    connect(m_pActionPool->action(UIActionIndexMN_M_Network_T_Details), &QAction::toggled,
    11611539            this, &UINetworkManagerWidget::sltToggleDetailsVisibility);
     
    11861564        prepareDetailsWidgetHostNetwork();
    11871565        prepareDetailsWidgetNATNetwork();
     1566        prepareDetailsWidgetCloudNetwork();
    11881567    }
    11891568}
     
    12281607        prepareTabHostNetwork();
    12291608        prepareTabNATNetwork();
     1609        prepareTabCloudNetwork();
    12301610
    12311611        /* Add into layout: */
     
    13551735        /* Add into layout: */
    13561736        layout()->addWidget(m_pDetailsWidgetNATNetwork);
     1737    }
     1738}
     1739
     1740void UINetworkManagerWidget::prepareTabCloudNetwork()
     1741{
     1742    /* Prepare cloud network tab: */
     1743    m_pTabCloudNetwork = new QWidget(m_pTabWidget);
     1744    if (m_pTabCloudNetwork)
     1745    {
     1746        /* Prepare cloud network layout: */
     1747        m_pLayoutCloudNetwork = new QVBoxLayout(m_pTabCloudNetwork);
     1748        if (m_pLayoutCloudNetwork)
     1749            prepareTreeWidgetCloudNetwork();
     1750
     1751        /* Add into tab-widget: */
     1752        m_pTabWidget->insertTab(TabWidgetIndex_CloudNetwork, m_pTabCloudNetwork, QString());
     1753    }
     1754}
     1755
     1756void UINetworkManagerWidget::prepareTreeWidgetCloudNetwork()
     1757{
     1758    /* Prepare cloud network tree-widget: */
     1759    m_pTreeWidgetCloudNetwork = new QITreeWidget(m_pTabCloudNetwork);
     1760    if (m_pTreeWidgetCloudNetwork)
     1761    {
     1762        m_pTreeWidgetCloudNetwork->setRootIsDecorated(false);
     1763        m_pTreeWidgetCloudNetwork->setAlternatingRowColors(true);
     1764        m_pTreeWidgetCloudNetwork->setContextMenuPolicy(Qt::CustomContextMenu);
     1765        m_pTreeWidgetCloudNetwork->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
     1766        m_pTreeWidgetCloudNetwork->setColumnCount(CloudNetworkColumn_Max);
     1767        m_pTreeWidgetCloudNetwork->setSortingEnabled(true);
     1768        m_pTreeWidgetCloudNetwork->sortByColumn(CloudNetworkColumn_Name, Qt::AscendingOrder);
     1769        m_pTreeWidgetCloudNetwork->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Expanding);
     1770        connect(m_pTreeWidgetCloudNetwork, &QITreeWidget::currentItemChanged,
     1771                this, &UINetworkManagerWidget::sltHandleCurrentItemChangeCloudNetwork);
     1772        connect(m_pTreeWidgetCloudNetwork, &QITreeWidget::customContextMenuRequested,
     1773                this, &UINetworkManagerWidget::sltHandleContextMenuRequestCloudNetwork);
     1774        connect(m_pTreeWidgetCloudNetwork, &QITreeWidget::itemDoubleClicked,
     1775                m_pActionPool->action(UIActionIndexMN_M_Network_T_Details), &QAction::setChecked);
     1776
     1777        /* Add into layout: */
     1778        m_pLayoutCloudNetwork->addWidget(m_pTreeWidgetCloudNetwork);
     1779    }
     1780}
     1781
     1782void UINetworkManagerWidget::prepareDetailsWidgetCloudNetwork()
     1783{
     1784    /* Prepare cloud network details-widget: */
     1785    m_pDetailsWidgetCloudNetwork = new UIDetailsWidgetCloudNetwork(m_enmEmbedding, this);
     1786    if (m_pDetailsWidgetCloudNetwork)
     1787    {
     1788        m_pDetailsWidgetCloudNetwork->setVisible(false);
     1789        m_pDetailsWidgetCloudNetwork->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
     1790        connect(m_pDetailsWidgetCloudNetwork, &UIDetailsWidgetCloudNetwork::sigDataChanged,
     1791                this, &UINetworkManagerWidget::sigDetailsDataChangedCloudNetwork);
     1792        connect(m_pDetailsWidgetCloudNetwork, &UIDetailsWidgetCloudNetwork::sigDataChangeRejected,
     1793                this, &UINetworkManagerWidget::sltHandleCurrentItemChangeCloudNetwork);
     1794        connect(m_pDetailsWidgetCloudNetwork, &UIDetailsWidgetCloudNetwork::sigDataChangeAccepted,
     1795                this, &UINetworkManagerWidget::sltApplyDetailsChangesCloudNetwork);
     1796
     1797        /* Add into layout: */
     1798        layout()->addWidget(m_pDetailsWidgetCloudNetwork);
    13571799    }
    13581800}
     
    15762018}
    15772019
     2020void UINetworkManagerWidget::loadCloudNetworks()
     2021{
     2022    /* Check cloud network tree-widget: */
     2023    if (!m_pTreeWidgetCloudNetwork)
     2024        return;
     2025
     2026    /* Clear tree first of all: */
     2027    m_pTreeWidgetCloudNetwork->clear();
     2028
     2029    /* Get VirtualBox for further activities: */
     2030    const CVirtualBox comVBox = uiCommon().virtualBox();
     2031
     2032    /* Get interfaces for further activities: */
     2033    const QVector<CCloudNetwork> networks = comVBox.GetCloudNetworks();
     2034
     2035    /* Show error message if necessary: */
     2036    if (!comVBox.isOk())
     2037        UINotificationMessage::cannotAcquireVirtualBoxParameter(comVBox);
     2038    else
     2039    {
     2040        /* For each cloud network => load it to the tree: */
     2041        foreach (const CCloudNetwork &comNetwork, networks)
     2042        {
     2043            UIDataCloudNetwork data;
     2044            loadCloudNetwork(comNetwork, data);
     2045            createItemForCloudNetwork(data, false);
     2046        }
     2047
     2048        /* Choose the 1st item as current initially: */
     2049        m_pTreeWidgetCloudNetwork->setCurrentItem(m_pTreeWidgetCloudNetwork->topLevelItem(0));
     2050        sltHandleCurrentItemChangeCloudNetwork();
     2051
     2052        /* Adjust tree-widgets: */
     2053        sltAdjustTreeWidgets();
     2054    }
     2055}
     2056
     2057void UINetworkManagerWidget::loadCloudNetwork(const CCloudNetwork &comNetwork, UIDataCloudNetwork &data)
     2058{
     2059    /* Gather network settings: */
     2060    if (comNetwork.isNotNull())
     2061        data.m_fExists = true;
     2062    if (comNetwork.isNotNull())
     2063        data.m_fEnabled = comNetwork.GetEnabled();
     2064    if (comNetwork.isOk())
     2065        data.m_strName = comNetwork.GetNetworkName();
     2066    if (comNetwork.isOk())
     2067        data.m_strProvider = comNetwork.GetProvider();
     2068    if (comNetwork.isOk())
     2069        data.m_strProfile = comNetwork.GetProfile();
     2070
     2071    /* Show error message if necessary: */
     2072    if (!comNetwork.isOk())
     2073        UINotificationMessage::cannotAcquireCloudNetworkParameter(comNetwork);
     2074}
     2075
    15782076void UINetworkManagerWidget::createItemForHostNetwork(const UIDataHostNetwork &data, bool fChooseItem)
    15792077{
     
    16392137}
    16402138
     2139void UINetworkManagerWidget::createItemForCloudNetwork(const UIDataCloudNetwork &data, bool fChooseItem)
     2140{
     2141    /* Create new item: */
     2142    UIItemCloudNetwork *pItem = new UIItemCloudNetwork;
     2143    if (pItem)
     2144    {
     2145        /* Configure item: */
     2146        pItem->UIDataCloudNetwork::operator=(data);
     2147        pItem->updateFields();
     2148        /* Add item to the tree: */
     2149        m_pTreeWidgetCloudNetwork->addTopLevelItem(pItem);
     2150        /* And choose it as current if necessary: */
     2151        if (fChooseItem)
     2152            m_pTreeWidgetCloudNetwork->setCurrentItem(pItem);
     2153    }
     2154}
     2155
     2156void UINetworkManagerWidget::updateItemForCloudNetwork(const UIDataCloudNetwork &data, bool fChooseItem, UIItemCloudNetwork *pItem)
     2157{
     2158    /* Update passed item: */
     2159    if (pItem)
     2160    {
     2161        /* Configure item: */
     2162        pItem->UIDataCloudNetwork::operator=(data);
     2163        pItem->updateFields();
     2164        /* And choose it as current if necessary: */
     2165        if (fChooseItem)
     2166            m_pTreeWidgetCloudNetwork->setCurrentItem(pItem);
     2167    }
     2168}
     2169
    16412170QStringList UINetworkManagerWidget::busyNamesNAT() const
    16422171{
     
    16452174    {
    16462175        UIItemNATNetwork *pItem = qobject_cast<UIItemNATNetwork*>(m_pTreeWidgetNATNetwork->childItem(i));
     2176        const QString strItemName(pItem->name());
     2177        if (!strItemName.isEmpty() && !names.contains(strItemName))
     2178            names << strItemName;
     2179    }
     2180    return names;
     2181}
     2182
     2183QStringList UINetworkManagerWidget::busyNamesCloud() const
     2184{
     2185    QStringList names;
     2186    for (int i = 0; i < m_pTreeWidgetCloudNetwork->topLevelItemCount(); ++i)
     2187    {
     2188        UIItemCloudNetwork *pItem = qobject_cast<UIItemCloudNetwork*>(m_pTreeWidgetCloudNetwork->childItem(i));
    16472189        const QString strItemName(pItem->name());
    16482190        if (!strItemName.isEmpty() && !names.contains(strItemName))
     
    17582300    connect(widget(), &UINetworkManagerWidget::sigDetailsDataChangedNATNetwork,
    17592301            button(ButtonType_Reset), &QPushButton::setEnabled);
     2302    connect(widget(), &UINetworkManagerWidget::sigDetailsDataChangedCloudNetwork,
     2303            button(ButtonType_Apply), &QPushButton::setEnabled);
     2304    connect(widget(), &UINetworkManagerWidget::sigDetailsDataChangedCloudNetwork,
     2305            button(ButtonType_Reset), &QPushButton::setEnabled);
    17602306    connect(buttonBox(), &QIDialogButtonBox::clicked,
    17612307            this, &UINetworkManager::sltHandleButtonBoxClick);
  • trunk/src/VBox/Frontends/VirtualBox/src/networkmanager/UINetworkManager.h

    r92730 r92731  
    3030
    3131/* Forward declarations: */
     32class CCloudNetwork;
    3233class CHostNetworkInterface;
    3334class CNATNetwork;
     
    3940class QITreeWidget;
    4041class UIActionPool;
     42class UIDetailsWidgetCloudNetwork;
    4143class UIDetailsWidgetHostNetwork;
    4244class UIDetailsWidgetNATNetwork;
     45class UIItemCloudNetwork;
    4346class UIItemHostNetwork;
    4447class UIItemNATNetwork;
    4548class QIToolBar;
     49struct UIDataCloudNetwork;
    4650struct UIDataHostNetwork;
    4751struct UIDataNATNetwork;
     
    6266    /** Notifies listeners about NAT network details data @a fDiffers. */
    6367    void sigDetailsDataChangedNATNetwork(bool fDiffers);
     68    /** Notifies listeners about cloud network details data @a fDiffers. */
     69    void sigDetailsDataChangedCloudNetwork(bool fDiffers);
    6470
    6571public:
     
    121127        /** Handles command to remove NAT network. */
    122128        void sltRemoveNATNetwork();
     129
     130        /** Handles command to create cloud network. */
     131        void sltCreateCloudNetwork();
     132        /** Handles command to remove cloud network. */
     133        void sltRemoveCloudNetwork();
    123134
    124135        /** Handles command to make details @a fVisible. */
     
    151162        /** Handles command to apply NAT network details changes. */
    152163        void sltApplyDetailsChangesNATNetwork();
     164
     165        /** Handles cloud network tree-widget current item change. */
     166        void sltHandleCurrentItemChangeCloudNetwork();
     167        /** Handles cloud network context-menu request for tree-widget @a position. */
     168        void sltHandleContextMenuRequestCloudNetwork(const QPoint &position);
     169        /** Handles command to apply cloud network details changes. */
     170        void sltApplyDetailsChangesCloudNetwork();
    153171    /** @} */
    154172
     
    179197        /** Prepares NAT network details-widget. */
    180198        void prepareDetailsWidgetNATNetwork();
     199        /** Prepares cloud network tab. */
     200        void prepareTabCloudNetwork();
     201        /** Prepares cloud network tree-widget. */
     202        void prepareTreeWidgetCloudNetwork();
     203        /** Prepares cloud network details-widget. */
     204        void prepareDetailsWidgetCloudNetwork();
    181205        /** Load settings: */
    182206        void loadSettings();
     
    194218        /** Loads NAT @a comNetwork data to passed @a data container. */
    195219        void loadNATNetwork(const CNATNetwork &comNetwork, UIDataNATNetwork &data);
     220
     221        /** Loads cloud networks. */
     222        void loadCloudNetworks();
     223        /** Loads cloud @a comNetwork data to passed @a data container. */
     224        void loadCloudNetwork(const CCloudNetwork &comNetwork, UIDataCloudNetwork &data);
    196225    /** @} */
    197226
     
    208237        void updateItemForNATNetwork(const UIDataNATNetwork &data, bool fChooseItem, UIItemNATNetwork *pItem);
    209238
     239        /** Creates a new cloud network tree-widget item on the basis of passed @a data, @a fChooseItem if requested. */
     240        void createItemForCloudNetwork(const UIDataCloudNetwork &data, bool fChooseItem);
     241        /** Updates passed cloud network tree-widget item on the basis of passed @a data, @a fChooseItem if requested. */
     242        void updateItemForCloudNetwork(const UIDataCloudNetwork &data, bool fChooseItem, UIItemCloudNetwork *pItem);
     243
    210244        /** Returns a list of busy NAT network names. */
    211245        QStringList busyNamesNAT() const;
     246        /** Returns a list of busy cloud network names. */
     247        QStringList busyNamesCloud() const;
    212248    /** @} */
    213249
     
    250286        /** Holds the NAT network details-widget instance. */
    251287        UIDetailsWidgetNATNetwork *m_pDetailsWidgetNATNetwork;
     288
     289        /** Holds the cloud network tab. */
     290        QWidget                     *m_pTabCloudNetwork;
     291        /** Holds the cloud network tab layout. */
     292        QVBoxLayout                 *m_pLayoutCloudNetwork;
     293        /** Holds the cloud network tree-widget instance. */
     294        QITreeWidget                *m_pTreeWidgetCloudNetwork;
     295        /** Holds the cloud network details-widget instance. */
     296        UIDetailsWidgetCloudNetwork *m_pDetailsWidgetCloudNetwork;
    252297    /** @} */
    253298};
  • trunk/src/VBox/Frontends/VirtualBox/src/notificationcenter/UINotificationObjects.cpp

    r92477 r92731  
    3939#include "CBooleanFormValue.h"
    4040#include "CChoiceFormValue.h"
     41#include "CCloudNetwork.h"
    4142#include "CCloudProfile.h"
    4243#include "CCloudProvider.h"
     
    669670
    670671/* static */
     672void UINotificationMessage::cannotAcquireCloudNetworkParameter(const CCloudNetwork &comNetwork)
     673{
     674    createMessage(
     675        QApplication::translate("UIMessageCenter", "Cloud network failure ..."),
     676        QApplication::translate("UIMessageCenter", "Failed to acquire cloud network parameter.") +
     677        UIErrorString::formatErrorInfo(comNetwork));
     678}
     679
     680/* static */
    671681void UINotificationMessage::cannotAcquireHostNetworkInterfaceParameter(const CHostNetworkInterface &comInterface)
    672682{
     
    804814        QApplication::translate("UIMessageCenter", "Failed to change DHCP server parameter.") +
    805815        UIErrorString::formatErrorInfo(comServer));
     816}
     817
     818/* static */
     819void UINotificationMessage::cannotChangeCloudNetworkParameter(const CCloudNetwork &comNetwork)
     820{
     821    createMessage(
     822        QApplication::translate("UIMessageCenter", "Cloud network failure ..."),
     823        QApplication::translate("UIMessageCenter", "Failed to change cloud network parameter.") +
     824        UIErrorString::formatErrorInfo(comNetwork));
    806825}
    807826
     
    10501069
    10511070/* static */
     1071void UINotificationMessage::cannotFindCloudNetwork(const CVirtualBox &comVBox, const QString &strNetworkName)
     1072{
     1073    createMessage(
     1074        QApplication::translate("UIMessageCenter", "Can't find cloud network ..."),
     1075        QApplication::translate("UIMessageCenter", "Unable to find the cloud network <b>%1</b>.")
     1076                                                   .arg(strNetworkName) +
     1077        UIErrorString::formatErrorInfo(comVBox));
     1078}
     1079
     1080/* static */
    10521081void UINotificationMessage::cannotFindHostNetworkInterface(const CHost &comHost, const QString &strInterfaceName)
    10531082{
     
    10861115        QApplication::translate("UIMessageCenter", "Failed to remove the DHCP server for the network interface <b>%1</b>.")
    10871116                                                   .arg(strInterfaceName) +
     1117        UIErrorString::formatErrorInfo(comVBox));
     1118}
     1119
     1120/* static */
     1121void UINotificationMessage::cannotCreateCloudNetwork(const CVirtualBox &comVBox)
     1122{
     1123    createMessage(
     1124        QApplication::translate("UIMessageCenter", "Can't create cloud network ..."),
     1125        QApplication::translate("UIMessageCenter", "Failed to create a cloud network.") +
     1126        UIErrorString::formatErrorInfo(comVBox));
     1127}
     1128
     1129/* static */
     1130void UINotificationMessage::cannotRemoveCloudNetwork(const CVirtualBox &comVBox, const QString &strNetworkName)
     1131{
     1132    createMessage(
     1133        QApplication::translate("UIMessageCenter", "Can't remove cloud network ..."),
     1134        QApplication::translate("UIMessageCenter", "Failed to remove the cloud network <b>%1</b>.")
     1135                                                   .arg(strNetworkName) +
    10881136        UIErrorString::formatErrorInfo(comVBox));
    10891137}
  • trunk/src/VBox/Frontends/VirtualBox/src/notificationcenter/UINotificationObjects.h

    r92730 r92731  
    285285          * @param  comServer  Brings the object parameter get acquired from. */
    286286        static void cannotAcquireDHCPServerParameter(const CDHCPServer &comServer);
     287        /** Notifies about inability to acquire ICloudNetwork parameter.
     288          * @param  comNetwork  Brings the object parameter get acquired from. */
     289        static void cannotAcquireCloudNetworkParameter(const CCloudNetwork &comNetwork);
    287290        /** Notifies about inability to acquire IHostNetworkInterface parameter.
    288291          * @param  comInterface  Brings the object parameter get acquired from. */
     
    333336          * @param  comServer  Brings the object parameter being changed for. */
    334337        static void cannotChangeDHCPServerParameter(const CDHCPServer &comServer);
     338        /** Notifies about inability to change ICloudNetwork parameter.
     339          * @param  comNetwork  Brings the object parameter being changed for. */
     340        static void cannotChangeCloudNetworkParameter(const CCloudNetwork &comNetwork);
    335341        /** Notifies about inability to change IHostNetworkInterface parameter.
    336342          * @param  comInterface  Brings the object parameter being changed for. */
     
    421427        static void cannotOpenExtPackFile(const CExtPackFile &comExtPackFile, const QString &strFilename);
    422428
     429        /** Notifies about inability to find cloud network.
     430          * @param  comVBox         Brings common VBox object being search through.
     431          * @param  strNetworkName  Brings network name. */
     432        static void cannotFindCloudNetwork(const CVirtualBox &comVBox, const QString &strNetworkName);
    423433        /** Notifies about inability to find host network interface.
    424434          * @param  comHost  Brings the host being search through.
     
    437447          * @param  strInterfaceName  Brings the interface name. */
    438448        static void cannotRemoveDHCPServer(const CVirtualBox &comVBox, const QString &strInterfaceName);
     449        /** Notifies about inability to create cloud network.
     450          * @param  comVBox  Brings common VBox object trying to create cloud network. */
     451        static void cannotCreateCloudNetwork(const CVirtualBox &comVBox);
     452        /** Notifies about inability to remove cloud network.
     453          * @param  comVBox         Brings common VBox object trying to remove cloud network.
     454          * @param  strNetworkName  Brings the network name. */
     455        static void cannotRemoveCloudNetwork(const CVirtualBox &comVBox, const QString &strNetworkName);
    439456        /** Notifies about inability to create NAT network.
    440457          * @param  comVBox  Brings common VBox object trying to create NAT network. */
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