VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsNetwork.cpp@ 98103

Last change on this file since 98103 was 98103, checked in by vboxsync, 2 years ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 48.9 KB
Line 
1/* $Id: UIMachineSettingsNetwork.cpp 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIMachineSettingsNetwork class implementation.
4 */
5
6/*
7 * Copyright (C) 2008-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28/* Qt includes: */
29#include <QRegularExpression>
30#include <QVBoxLayout>
31
32/* GUI includes: */
33#include "QITabWidget.h"
34#include "UICommon.h"
35#include "UIErrorString.h"
36#include "UIMachineSettingsNetwork.h"
37#include "UINetworkAttachmentEditor.h"
38#include "UINetworkSettingsEditor.h"
39#include "UITranslator.h"
40
41/* COM includes: */
42#include "CNATEngine.h"
43#include "CNetworkAdapter.h"
44
45
46QString wipedOutString(const QString &strInputString)
47{
48 return strInputString.isEmpty() ? QString() : strInputString;
49}
50
51
52/** Machine settings: Network Adapter data structure. */
53struct UIDataSettingsMachineNetworkAdapter
54{
55 /** Constructs data. */
56 UIDataSettingsMachineNetworkAdapter()
57 : m_iSlot(0)
58 , m_fAdapterEnabled(false)
59 , m_adapterType(KNetworkAdapterType_Null)
60 , m_attachmentType(KNetworkAttachmentType_Null)
61 , m_promiscuousMode(KNetworkAdapterPromiscModePolicy_Deny)
62 , m_strBridgedAdapterName(QString())
63 , m_strInternalNetworkName(QString())
64 , m_strHostInterfaceName(QString())
65 , m_strGenericDriverName(QString())
66 , m_strGenericProperties(QString())
67 , m_strNATNetworkName(QString())
68#ifdef VBOX_WITH_CLOUD_NET
69 , m_strCloudNetworkName(QString())
70#endif
71#ifdef VBOX_WITH_VMNET
72 , m_strHostOnlyNetworkName(QString())
73#endif
74 , m_strMACAddress(QString())
75 , m_fCableConnected(false)
76 {}
77
78 /** Returns whether the @a other passed data is equal to this one. */
79 bool equal(const UIDataSettingsMachineNetworkAdapter &other) const
80 {
81 return true
82 && (m_iSlot == other.m_iSlot)
83 && (m_fAdapterEnabled == other.m_fAdapterEnabled)
84 && (m_adapterType == other.m_adapterType)
85 && (m_attachmentType == other.m_attachmentType)
86 && (m_promiscuousMode == other.m_promiscuousMode)
87 && (m_strBridgedAdapterName == other.m_strBridgedAdapterName)
88 && (m_strInternalNetworkName == other.m_strInternalNetworkName)
89 && (m_strHostInterfaceName == other.m_strHostInterfaceName)
90 && (m_strGenericDriverName == other.m_strGenericDriverName)
91 && (m_strGenericProperties == other.m_strGenericProperties)
92 && (m_strNATNetworkName == other.m_strNATNetworkName)
93#ifdef VBOX_WITH_CLOUD_NET
94 && (m_strCloudNetworkName == other.m_strCloudNetworkName)
95#endif
96#ifdef VBOX_WITH_VMNET
97 && (m_strHostOnlyNetworkName == other.m_strHostOnlyNetworkName)
98#endif
99 && (m_strMACAddress == other.m_strMACAddress)
100 && (m_fCableConnected == other.m_fCableConnected)
101 ;
102 }
103
104 /** Returns whether the @a other passed data is equal to this one. */
105 bool operator==(const UIDataSettingsMachineNetworkAdapter &other) const { return equal(other); }
106 /** Returns whether the @a other passed data is different from this one. */
107 bool operator!=(const UIDataSettingsMachineNetworkAdapter &other) const { return !equal(other); }
108
109 /** Holds the network adapter slot number. */
110 int m_iSlot;
111 /** Holds whether the network adapter is enabled. */
112 bool m_fAdapterEnabled;
113 /** Holds the network adapter type. */
114 KNetworkAdapterType m_adapterType;
115 /** Holds the network attachment type. */
116 KNetworkAttachmentType m_attachmentType;
117 /** Holds the network promiscuous mode policy. */
118 KNetworkAdapterPromiscModePolicy m_promiscuousMode;
119 /** Holds the bridged adapter name. */
120 QString m_strBridgedAdapterName;
121 /** Holds the internal network name. */
122 QString m_strInternalNetworkName;
123 /** Holds the host interface name. */
124 QString m_strHostInterfaceName;
125 /** Holds the generic driver name. */
126 QString m_strGenericDriverName;
127 /** Holds the generic driver properties. */
128 QString m_strGenericProperties;
129 /** Holds the NAT network name. */
130 QString m_strNATNetworkName;
131#ifdef VBOX_WITH_CLOUD_NET
132 /** Holds the cloud network name. */
133 QString m_strCloudNetworkName;
134#endif
135#ifdef VBOX_WITH_VMNET
136 /** Holds the host-only network name. */
137 QString m_strHostOnlyNetworkName;
138#endif
139 /** Holds the network adapter MAC address. */
140 QString m_strMACAddress;
141 /** Holds whether the network adapter is connected. */
142 bool m_fCableConnected;
143};
144
145
146/** Machine settings: Network page data structure. */
147struct UIDataSettingsMachineNetwork
148{
149 /** Constructs data. */
150 UIDataSettingsMachineNetwork() {}
151
152 /** Returns whether the @a other passed data is equal to this one. */
153 bool operator==(const UIDataSettingsMachineNetwork & /* other */) const { return true; }
154 /** Returns whether the @a other passed data is different from this one. */
155 bool operator!=(const UIDataSettingsMachineNetwork & /* other */) const { return false; }
156};
157
158
159/** Machine settings: Network Adapter tab. */
160class UIMachineSettingsNetwork : public QIWithRetranslateUI<QWidget>
161{
162 Q_OBJECT;
163
164signals:
165
166 /** Notifies about alternative name was changed. */
167 void sigAlternativeNameChanged();
168
169 /** Notifies about advanced button state change to @a fExpanded. */
170 void sigAdvancedButtonStateChange(bool fExpanded);
171
172 /** Notifies about validity changed. */
173 void sigValidityChanged();
174
175public:
176
177 /** Constructs tab passing @a pParent to the base-class. */
178 UIMachineSettingsNetwork(UIMachineSettingsNetworkPage *pParent);
179
180 /** Loads adapter data from @a adapterCache. */
181 void getAdapterDataFromCache(const UISettingsCacheMachineNetworkAdapter &adapterCache);
182 /** Saves adapter data to @a adapterCache. */
183 void putAdapterDataToCache(UISettingsCacheMachineNetworkAdapter &adapterCache);
184
185 /** Performs validation, updates @a messages list if something is wrong. */
186 bool validate(QList<UIValidationMessage> &messages);
187
188 /** Configures tab order according to passed @a pWidget. */
189 QWidget *setOrderAfter(QWidget *pWidget);
190
191 /** Returns tab title. */
192 QString tabTitle() const;
193 /** Returns tab attachment type. */
194 KNetworkAttachmentType attachmentType() const;
195 /** Returne tab alternative name for @a enmType specified. */
196 QString alternativeName(KNetworkAttachmentType enmType = KNetworkAttachmentType_Null) const;
197
198 /** Performs tab polishing. */
199 void polishTab();
200 /** Reloads tab alternatives. */
201 void reloadAlternatives();
202
203 /** Defines whether the advanced button is @a fExpanded. */
204 void setAdvancedButtonExpanded(bool fExpanded);
205
206protected:
207
208 /** Handles translation event. */
209 void retranslateUi();
210
211private slots:
212
213 /** Handles adapter alternative name change. */
214 void sltHandleAlternativeNameChange();
215
216private:
217
218 /** Prepares all. */
219 void prepare();
220 /** Prepares widgets. */
221 void prepareWidgets();
222 /** Prepares connections. */
223 void prepareConnections();
224
225 /** Holds parent page reference. */
226 UIMachineSettingsNetworkPage *m_pParent;
227
228 /** Holds tab slot number. */
229 int m_iSlot;
230
231 /** Holds the network settings editor instance. */
232 UINetworkSettingsEditor *m_pEditorNetworkSettings;
233};
234
235
236/*********************************************************************************************************************************
237* Class UIMachineSettingsNetwork implementation. *
238*********************************************************************************************************************************/
239
240UIMachineSettingsNetwork::UIMachineSettingsNetwork(UIMachineSettingsNetworkPage *pParent)
241 : QIWithRetranslateUI<QWidget>(0)
242 , m_pParent(pParent)
243 , m_iSlot(-1)
244 , m_pEditorNetworkSettings(0)
245{
246 prepare();
247}
248
249void UIMachineSettingsNetwork::getAdapterDataFromCache(const UISettingsCacheMachineNetworkAdapter &adapterCache)
250{
251 /* Get old data: */
252 const UIDataSettingsMachineNetworkAdapter &oldAdapterData = adapterCache.base();
253
254 /* Load slot number: */
255 m_iSlot = oldAdapterData.m_iSlot;
256
257 if (m_pEditorNetworkSettings)
258 {
259 /* Load adapter activity state: */
260 m_pEditorNetworkSettings->setFeatureEnabled(oldAdapterData.m_fAdapterEnabled);
261
262 /* Load attachment type: */
263 m_pEditorNetworkSettings->setValueType(oldAdapterData.m_attachmentType);
264 /* Load alternative names: */
265 m_pEditorNetworkSettings->setValueName(KNetworkAttachmentType_Bridged, wipedOutString(oldAdapterData.m_strBridgedAdapterName));
266 m_pEditorNetworkSettings->setValueName(KNetworkAttachmentType_Internal, wipedOutString(oldAdapterData.m_strInternalNetworkName));
267 m_pEditorNetworkSettings->setValueName(KNetworkAttachmentType_HostOnly, wipedOutString(oldAdapterData.m_strHostInterfaceName));
268 m_pEditorNetworkSettings->setValueName(KNetworkAttachmentType_Generic, wipedOutString(oldAdapterData.m_strGenericDriverName));
269 m_pEditorNetworkSettings->setValueName(KNetworkAttachmentType_NATNetwork, wipedOutString(oldAdapterData.m_strNATNetworkName));
270#ifdef VBOX_WITH_CLOUD_NET
271 m_pEditorNetworkSettings->setValueName(KNetworkAttachmentType_Cloud, wipedOutString(oldAdapterData.m_strCloudNetworkName));
272#endif
273#ifdef VBOX_WITH_VMNET
274 m_pEditorNetworkSettings->setValueName(KNetworkAttachmentType_HostOnlyNetwork, wipedOutString(oldAdapterData.m_strHostOnlyNetworkName));
275#endif
276
277 /* Load settings: */
278 m_pEditorNetworkSettings->setAdapterType(oldAdapterData.m_adapterType);
279 m_pEditorNetworkSettings->setPromiscuousMode(oldAdapterData.m_promiscuousMode);
280 m_pEditorNetworkSettings->setMACAddress(oldAdapterData.m_strMACAddress);
281 m_pEditorNetworkSettings->setGenericProperties(oldAdapterData.m_strGenericProperties);
282 m_pEditorNetworkSettings->setCableConnected(oldAdapterData.m_fCableConnected);
283
284 /* Load port forwarding rules: */
285 UIPortForwardingDataList portForwardingRules;
286 for (int i = 0; i < adapterCache.childCount(); ++i)
287 portForwardingRules << adapterCache.child(i).base();
288 m_pEditorNetworkSettings->setPortForwardingRules(portForwardingRules);
289 }
290
291 /* Reload alternatives: */
292 reloadAlternatives();
293}
294
295void UIMachineSettingsNetwork::putAdapterDataToCache(UISettingsCacheMachineNetworkAdapter &adapterCache)
296{
297 /* Prepare new data: */
298 UIDataSettingsMachineNetworkAdapter newAdapterData;
299
300 /* Save slot number: */
301 newAdapterData.m_iSlot = m_iSlot;
302
303 if (m_pEditorNetworkSettings)
304 {
305 /* Save adapter activity state: */
306 newAdapterData.m_fAdapterEnabled = m_pEditorNetworkSettings->isFeatureEnabled();
307
308 /* Save attachment type & alternative name: */
309 newAdapterData.m_attachmentType = attachmentType();
310 newAdapterData.m_strBridgedAdapterName = m_pEditorNetworkSettings->valueName(KNetworkAttachmentType_Bridged);
311 newAdapterData.m_strInternalNetworkName = m_pEditorNetworkSettings->valueName(KNetworkAttachmentType_Internal);
312 newAdapterData.m_strHostInterfaceName = m_pEditorNetworkSettings->valueName(KNetworkAttachmentType_HostOnly);
313 newAdapterData.m_strGenericDriverName = m_pEditorNetworkSettings->valueName(KNetworkAttachmentType_Generic);
314 newAdapterData.m_strNATNetworkName = m_pEditorNetworkSettings->valueName(KNetworkAttachmentType_NATNetwork);
315#ifdef VBOX_WITH_CLOUD_NET
316 newAdapterData.m_strCloudNetworkName = m_pEditorNetworkSettings->valueName(KNetworkAttachmentType_Cloud);
317#endif
318#ifdef VBOX_WITH_VMNET
319 newAdapterData.m_strHostOnlyNetworkName = m_pEditorNetworkSettings->valueName(KNetworkAttachmentType_HostOnlyNetwork);
320#endif
321
322 /* Save settings: */
323 newAdapterData.m_adapterType = m_pEditorNetworkSettings->adapterType();
324 newAdapterData.m_promiscuousMode = m_pEditorNetworkSettings->promiscuousMode();
325 newAdapterData.m_strMACAddress = m_pEditorNetworkSettings->macAddress();
326 newAdapterData.m_strGenericProperties = m_pEditorNetworkSettings->genericProperties();
327 newAdapterData.m_fCableConnected = m_pEditorNetworkSettings->cableConnected();
328
329 /* Save port forwarding rules: */
330 foreach (const UIDataPortForwardingRule &rule, m_pEditorNetworkSettings->portForwardingRules())
331 adapterCache.child(rule.name).cacheCurrentData(rule);
332 }
333
334 /* Cache new data: */
335 adapterCache.cacheCurrentData(newAdapterData);
336}
337
338bool UIMachineSettingsNetwork::validate(QList<UIValidationMessage> &messages)
339{
340 /* Pass by default: */
341 bool fPass = true;
342
343 /* Prepare message: */
344 UIValidationMessage message;
345 message.first = UITranslator::removeAccelMark(tabTitle());
346
347 /* Validate enabled adapter only: */
348 if ( m_pEditorNetworkSettings
349 && m_pEditorNetworkSettings->isFeatureEnabled())
350 {
351 /* Validate alternatives: */
352 switch (attachmentType())
353 {
354 case KNetworkAttachmentType_Bridged:
355 {
356 if (alternativeName().isNull())
357 {
358 message.second << tr("No bridged network adapter is currently selected.");
359 fPass = false;
360 }
361 break;
362 }
363 case KNetworkAttachmentType_Internal:
364 {
365 if (alternativeName().isNull())
366 {
367 message.second << tr("No internal network name is currently specified.");
368 fPass = false;
369 }
370 break;
371 }
372#ifndef VBOX_WITH_VMNET
373 case KNetworkAttachmentType_HostOnly:
374 {
375 if (alternativeName().isNull())
376 {
377 message.second << tr("No host-only network adapter is currently selected.");
378 fPass = false;
379 }
380 break;
381 }
382#else /* VBOX_WITH_VMNET */
383 case KNetworkAttachmentType_HostOnly:
384 {
385 message.second << tr("Host-only adapters are no longer supported, use host-only networks instead.");
386 fPass = false;
387 break;
388 }
389#endif /* VBOX_WITH_VMNET */
390 case KNetworkAttachmentType_Generic:
391 {
392 if (alternativeName().isNull())
393 {
394 message.second << tr("No generic driver is currently selected.");
395 fPass = false;
396 }
397 break;
398 }
399 case KNetworkAttachmentType_NATNetwork:
400 {
401 if (alternativeName().isNull())
402 {
403 message.second << tr("No NAT network name is currently specified.");
404 fPass = false;
405 }
406 break;
407 }
408#ifdef VBOX_WITH_CLOUD_NET
409 case KNetworkAttachmentType_Cloud:
410 {
411 if (alternativeName().isNull())
412 {
413 message.second << tr("No cloud network name is currently specified.");
414 fPass = false;
415 }
416 break;
417 }
418#endif /* VBOX_WITH_CLOUD_NET */
419#ifdef VBOX_WITH_VMNET
420 case KNetworkAttachmentType_HostOnlyNetwork:
421 {
422 if (alternativeName().isNull())
423 {
424 message.second << tr("No host-only network name is currently specified.");
425 fPass = false;
426 }
427 break;
428 }
429#endif /* VBOX_WITH_VMNET */
430 default:
431 break;
432 }
433
434 /* Validate MAC-address length: */
435 if (m_pEditorNetworkSettings->macAddress().size() < 12)
436 {
437 message.second << tr("The MAC address must be 12 hexadecimal digits long.");
438 fPass = false;
439 }
440
441 /* Make sure MAC-address is unicast: */
442 if (m_pEditorNetworkSettings->macAddress().size() >= 2)
443 {
444 if (m_pEditorNetworkSettings->macAddress().indexOf(QRegularExpression("^[0-9A-Fa-f][02468ACEace]")) != 0)
445 {
446 message.second << tr("The second digit in the MAC address may not be odd as only unicast addresses are allowed.");
447 fPass = false;
448 }
449 }
450 }
451
452 /* Serialize message: */
453 if (!message.second.isEmpty())
454 messages << message;
455
456 /* Return result: */
457 return fPass;
458}
459
460QWidget *UIMachineSettingsNetwork::setOrderAfter(QWidget *pWidget)
461{
462 setTabOrder(pWidget, m_pEditorNetworkSettings);
463 return m_pEditorNetworkSettings;
464}
465
466QString UIMachineSettingsNetwork::tabTitle() const
467{
468 return UICommon::tr("Adapter %1").arg(QString("&%1").arg(m_iSlot + 1));
469}
470
471KNetworkAttachmentType UIMachineSettingsNetwork::attachmentType() const
472{
473 return m_pEditorNetworkSettings ? m_pEditorNetworkSettings->valueType() : KNetworkAttachmentType_Null;
474}
475
476QString UIMachineSettingsNetwork::alternativeName(KNetworkAttachmentType enmType /* = KNetworkAttachmentType_Null */) const
477{
478 if (enmType == KNetworkAttachmentType_Null)
479 enmType = attachmentType();
480 return m_pEditorNetworkSettings ? m_pEditorNetworkSettings->valueName(enmType) : QString();
481}
482
483void UIMachineSettingsNetwork::polishTab()
484{
485 if ( m_pEditorNetworkSettings
486 && m_pParent)
487 {
488 /* General stuff: */
489 m_pEditorNetworkSettings->setFeatureAvailable(m_pParent->isMachineOffline());
490
491 /* Attachment stuff: */
492 m_pEditorNetworkSettings->setAttachmentOptionsAvailable(m_pParent->isMachineInValidMode());
493
494 /* Advanced stuff: */
495 m_pEditorNetworkSettings->setAdvancedOptionsAvailable(m_pParent->isMachineInValidMode());
496 m_pEditorNetworkSettings->setAdapterOptionsAvailable(m_pParent->isMachineOffline());
497 m_pEditorNetworkSettings->setPromiscuousOptionsAvailable( attachmentType() != KNetworkAttachmentType_Null
498 && attachmentType() != KNetworkAttachmentType_Generic
499 && attachmentType() != KNetworkAttachmentType_NAT);
500 m_pEditorNetworkSettings->setMACOptionsAvailable(m_pParent->isMachineOffline());
501 m_pEditorNetworkSettings->setGenericPropertiesAvailable(attachmentType() == KNetworkAttachmentType_Generic);
502 m_pEditorNetworkSettings->setCableOptionsAvailable(m_pParent->isMachineInValidMode());
503 m_pEditorNetworkSettings->setForwardingOptionsAvailable(attachmentType() == KNetworkAttachmentType_NAT);
504 }
505}
506
507void UIMachineSettingsNetwork::reloadAlternatives()
508{
509 if ( m_pEditorNetworkSettings
510 && m_pParent)
511 {
512 m_pEditorNetworkSettings->setValueNames(KNetworkAttachmentType_Bridged, m_pParent->bridgedAdapterList());
513 m_pEditorNetworkSettings->setValueNames(KNetworkAttachmentType_Internal, m_pParent->internalNetworkList());
514 m_pEditorNetworkSettings->setValueNames(KNetworkAttachmentType_HostOnly, m_pParent->hostInterfaceList());
515 m_pEditorNetworkSettings->setValueNames(KNetworkAttachmentType_Generic, m_pParent->genericDriverList());
516 m_pEditorNetworkSettings->setValueNames(KNetworkAttachmentType_NATNetwork, m_pParent->natNetworkList());
517#ifdef VBOX_WITH_CLOUD_NET
518 m_pEditorNetworkSettings->setValueNames(KNetworkAttachmentType_Cloud, m_pParent->cloudNetworkList());
519#endif
520#ifdef VBOX_WITH_VMNET
521 m_pEditorNetworkSettings->setValueNames(KNetworkAttachmentType_HostOnlyNetwork, m_pParent->hostOnlyNetworkList());
522#endif
523 }
524}
525
526void UIMachineSettingsNetwork::setAdvancedButtonExpanded(bool fExpanded)
527{
528 if (m_pEditorNetworkSettings)
529 m_pEditorNetworkSettings->setAdvancedButtonExpanded(fExpanded);
530}
531
532void UIMachineSettingsNetwork::retranslateUi()
533{
534 /* Reload alternatives: */
535 reloadAlternatives();
536}
537
538void UIMachineSettingsNetwork::sltHandleAlternativeNameChange()
539{
540 if (m_pEditorNetworkSettings)
541 {
542 /* Notify other adapter tabs if alternative name for certain type is changed: */
543 switch (attachmentType())
544 {
545 case KNetworkAttachmentType_Internal:
546 case KNetworkAttachmentType_Generic:
547 {
548 if (!m_pEditorNetworkSettings->valueName(attachmentType()).isNull())
549 emit sigAlternativeNameChanged();
550 break;
551 }
552 default:
553 break;
554 }
555 }
556
557 /* Notify validity changed: */
558 emit sigValidityChanged();
559}
560
561void UIMachineSettingsNetwork::prepare()
562{
563 /* Prepare everything: */
564 prepareWidgets();
565 prepareConnections();
566
567 /* Apply language settings: */
568 retranslateUi();
569}
570
571void UIMachineSettingsNetwork::prepareWidgets()
572{
573 /* Prepare main layout: */
574 QVBoxLayout *pLayout = new QVBoxLayout(this);
575 if (pLayout)
576 {
577 /* Prepare settings editor: */
578 m_pEditorNetworkSettings = new UINetworkSettingsEditor(this);
579 if (m_pEditorNetworkSettings)
580 pLayout->addWidget(m_pEditorNetworkSettings);
581
582 pLayout->addStretch();
583 }
584}
585
586void UIMachineSettingsNetwork::prepareConnections()
587{
588 if (m_pEditorNetworkSettings)
589 {
590 /* Attachment connections: */
591 connect(m_pEditorNetworkSettings, &UINetworkSettingsEditor::sigFeatureStateChanged,
592 this, &UIMachineSettingsNetwork::sigValidityChanged);
593 connect(m_pEditorNetworkSettings, &UINetworkSettingsEditor::sigAttachmentTypeChanged,
594 this, &UIMachineSettingsNetwork::sigValidityChanged);
595 connect(m_pEditorNetworkSettings, &UINetworkSettingsEditor::sigAlternativeNameChanged,
596 this, &UIMachineSettingsNetwork::sltHandleAlternativeNameChange);
597
598 /* Advanced connections: */
599 connect(m_pEditorNetworkSettings, &UINetworkSettingsEditor::sigAdvancedButtonStateChange,
600 this, &UIMachineSettingsNetwork::sigAdvancedButtonStateChange);
601 connect(m_pEditorNetworkSettings, &UINetworkSettingsEditor::sigMACAddressChanged,
602 this, &UIMachineSettingsNetwork::sigValidityChanged);
603 }
604}
605
606
607/*********************************************************************************************************************************
608* Class UIMachineSettingsNetworkPage implementation. *
609*********************************************************************************************************************************/
610
611UIMachineSettingsNetworkPage::UIMachineSettingsNetworkPage()
612 : m_pCache(0)
613 , m_pTabWidget(0)
614{
615 prepare();
616}
617
618UIMachineSettingsNetworkPage::~UIMachineSettingsNetworkPage()
619{
620 cleanup();
621}
622
623bool UIMachineSettingsNetworkPage::changed() const
624{
625 return m_pCache ? m_pCache->wasChanged() : false;
626}
627
628void UIMachineSettingsNetworkPage::loadToCacheFrom(QVariant &data)
629{
630 /* Sanity check: */
631 if ( !m_pCache
632 || !m_pTabWidget)
633 return;
634
635 /* Fetch data to machine: */
636 UISettingsPageMachine::fetchData(data);
637
638 /* Clear cache initially: */
639 m_pCache->clear();
640
641 /* Cache name lists: */
642 refreshBridgedAdapterList();
643 refreshInternalNetworkList(true);
644 refreshHostInterfaceList();
645 refreshGenericDriverList(true);
646 refreshNATNetworkList();
647#ifdef VBOX_WITH_CLOUD_NET
648 refreshCloudNetworkList();
649#endif
650#ifdef VBOX_WITH_VMNET
651 refreshHostOnlyNetworkList();
652#endif
653
654 /* Prepare old data: */
655 UIDataSettingsMachineNetwork oldNetworkData;
656
657 /* For each network adapter: */
658 for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot)
659 {
660 /* Prepare old data: */
661 UIDataSettingsMachineNetworkAdapter oldAdapterData;
662
663 /* Check whether adapter is valid: */
664 const CNetworkAdapter &comAdapter = m_machine.GetNetworkAdapter(iSlot);
665 if (!comAdapter.isNull())
666 {
667 /* Gather old data: */
668 oldAdapterData.m_iSlot = iSlot;
669 oldAdapterData.m_fAdapterEnabled = comAdapter.GetEnabled();
670 oldAdapterData.m_attachmentType = comAdapter.GetAttachmentType();
671 oldAdapterData.m_strBridgedAdapterName = wipedOutString(comAdapter.GetBridgedInterface());
672 oldAdapterData.m_strInternalNetworkName = wipedOutString(comAdapter.GetInternalNetwork());
673 oldAdapterData.m_strHostInterfaceName = wipedOutString(comAdapter.GetHostOnlyInterface());
674 oldAdapterData.m_strGenericDriverName = wipedOutString(comAdapter.GetGenericDriver());
675 oldAdapterData.m_strNATNetworkName = wipedOutString(comAdapter.GetNATNetwork());
676#ifdef VBOX_WITH_CLOUD_NET
677 oldAdapterData.m_strCloudNetworkName = wipedOutString(comAdapter.GetCloudNetwork());
678#endif
679#ifdef VBOX_WITH_VMNET
680 oldAdapterData.m_strHostOnlyNetworkName = wipedOutString(comAdapter.GetHostOnlyNetwork());
681#endif
682 oldAdapterData.m_adapterType = comAdapter.GetAdapterType();
683 oldAdapterData.m_promiscuousMode = comAdapter.GetPromiscModePolicy();
684 oldAdapterData.m_strMACAddress = comAdapter.GetMACAddress();
685 oldAdapterData.m_strGenericProperties = loadGenericProperties(comAdapter);
686 oldAdapterData.m_fCableConnected = comAdapter.GetCableConnected();
687 foreach (const QString &strRedirect, comAdapter.GetNATEngine().GetRedirects())
688 {
689 /* Gather old data & cache key: */
690 const QStringList &forwardingData = strRedirect.split(',');
691 AssertMsg(forwardingData.size() == 6, ("Redirect rule should be composed of 6 parts!\n"));
692 const UIDataPortForwardingRule oldForwardingData(forwardingData.at(0),
693 (KNATProtocol)forwardingData.at(1).toUInt(),
694 forwardingData.at(2),
695 forwardingData.at(3).toUInt(),
696 forwardingData.at(4),
697 forwardingData.at(5).toUInt());
698 const QString &strForwardingKey = forwardingData.at(0);
699 /* Cache old data: */
700 m_pCache->child(iSlot).child(strForwardingKey).cacheInitialData(oldForwardingData);
701 }
702 }
703
704 /* Cache old data: */
705 m_pCache->child(iSlot).cacheInitialData(oldAdapterData);
706 }
707
708 /* Cache old data: */
709 m_pCache->cacheInitialData(oldNetworkData);
710
711 /* Upload machine to data: */
712 UISettingsPageMachine::uploadData(data);
713}
714
715void UIMachineSettingsNetworkPage::getFromCache()
716{
717 /* Sanity check: */
718 if ( !m_pCache
719 || !m_pTabWidget)
720 return;
721
722 /* Setup tab order: */
723 AssertPtrReturnVoid(firstWidget());
724 setTabOrder(firstWidget(), m_pTabWidget->focusProxy());
725 QWidget *pLastFocusWidget = m_pTabWidget->focusProxy();
726
727 /* For each adapter: */
728 for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot)
729 {
730 /* Get adapter page: */
731 UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTabWidget->widget(iSlot));
732 AssertPtrReturnVoid(pTab);
733
734 /* Load old data from cache: */
735 pTab->getAdapterDataFromCache(m_pCache->child(iSlot));
736
737 /* Setup tab order: */
738 pLastFocusWidget = pTab->setOrderAfter(pLastFocusWidget);
739 }
740
741 /* Apply language settings: */
742 retranslateUi();
743
744 /* Polish page finally: */
745 polishPage();
746
747 /* Revalidate: */
748 revalidate();
749}
750
751void UIMachineSettingsNetworkPage::putToCache()
752{
753 /* Sanity check: */
754 if ( !m_pCache
755 || !m_pTabWidget)
756 return;
757
758 /* Prepare new data: */
759 UIDataSettingsMachineNetwork newNetworkData;
760
761 /* For each adapter: */
762 for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot)
763 {
764 /* Get adapter page: */
765 UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTabWidget->widget(iSlot));
766 AssertPtrReturnVoid(pTab);
767
768 /* Gather new data: */
769 pTab->putAdapterDataToCache(m_pCache->child(iSlot));
770 }
771
772 /* Cache new data: */
773 m_pCache->cacheCurrentData(newNetworkData);
774}
775
776void UIMachineSettingsNetworkPage::saveFromCacheTo(QVariant &data)
777{
778 /* Fetch data to machine: */
779 UISettingsPageMachine::fetchData(data);
780
781 /* Update data and failing state: */
782 setFailed(!saveData());
783
784 /* Upload machine to data: */
785 UISettingsPageMachine::uploadData(data);
786}
787
788bool UIMachineSettingsNetworkPage::validate(QList<UIValidationMessage> &messages)
789{
790 /* Sanity check: */
791 if (!m_pTabWidget)
792 return false;
793
794 /* Pass by default: */
795 bool fValid = true;
796
797 /* Delegate validation to adapter tabs: */
798 for (int iIndex = 0; iIndex < m_pTabWidget->count(); ++iIndex)
799 {
800 UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTabWidget->widget(iIndex));
801 AssertPtrReturn(pTab, false);
802 if (!pTab->validate(messages))
803 fValid = false;
804 }
805
806 /* Return result: */
807 return fValid;
808}
809
810void UIMachineSettingsNetworkPage::retranslateUi()
811{
812 /* Sanity check: */
813 if (!m_pTabWidget)
814 return;
815
816 for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot)
817 {
818 UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTabWidget->widget(iSlot));
819 AssertPtrReturnVoid(pTab);
820 m_pTabWidget->setTabText(iSlot, pTab->tabTitle());
821 }
822}
823
824void UIMachineSettingsNetworkPage::polishPage()
825{
826 /* Sanity check: */
827 if ( !m_pCache
828 || !m_pTabWidget)
829 return;
830
831 for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot)
832 {
833 m_pTabWidget->setTabEnabled(iSlot,
834 isMachineOffline() ||
835 (isMachineInValidMode() &&
836 m_pCache->childCount() > iSlot &&
837 m_pCache->child(iSlot).base().m_fAdapterEnabled));
838 UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTabWidget->widget(iSlot));
839 AssertPtrReturnVoid(pTab);
840 pTab->polishTab();
841 }
842}
843
844void UIMachineSettingsNetworkPage::sltHandleAlternativeNameChange()
845{
846 /* Sanity check: */
847 if (!m_pTabWidget)
848 return;
849
850 /* Determine the sender tab: */
851 UIMachineSettingsNetwork *pSender = qobject_cast<UIMachineSettingsNetwork*>(sender());
852 AssertPtrReturnVoid(pSender);
853
854 /* Enumerate alternatives for certain types: */
855 switch (pSender->attachmentType())
856 {
857 case KNetworkAttachmentType_Internal: refreshInternalNetworkList(); break;
858 case KNetworkAttachmentType_Generic: refreshGenericDriverList(); break;
859 default: break;
860 }
861
862 /* Update alternatives for all the tabs besides the sender: */
863 for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot)
864 {
865 /* Get the iterated tab: */
866 UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTabWidget->widget(iSlot));
867 AssertPtrReturnVoid(pTab);
868
869 /* Update all the tabs (except sender): */
870 if (pTab != pSender)
871 pTab->reloadAlternatives();
872 }
873}
874
875void UIMachineSettingsNetworkPage::sltHandleAdvancedButtonStateChange(bool fExpanded)
876{
877 /* Sanity check: */
878 if (!m_pTabWidget)
879 return;
880
881 /* Update the advanced button states for all the pages: */
882 for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot)
883 {
884 UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTabWidget->widget(iSlot));
885 AssertPtrReturnVoid(pTab);
886 pTab->setAdvancedButtonExpanded(fExpanded);
887 }
888}
889
890void UIMachineSettingsNetworkPage::prepare()
891{
892 /* Prepare cache: */
893 m_pCache = new UISettingsCacheMachineNetwork;
894 AssertPtrReturnVoid(m_pCache);
895
896 /* Create main layout: */
897 QVBoxLayout *pLayoutMain = new QVBoxLayout(this);
898 if (pLayoutMain)
899 {
900 /* Creating tab-widget: */
901 m_pTabWidget = new QITabWidget;
902 if (m_pTabWidget)
903 {
904 /* How many adapters to display: */
905 /** @todo r=klaus this needs to be done based on the actual chipset type of the VM,
906 * but in this place the m_machine field isn't set yet. My observation (on Linux)
907 * is that the limitation to 4 isn't necessary any more, but this needs to be checked
908 * on all platforms to be certain that it's usable everywhere. */
909 const ulong uCount = qMin((ULONG)4, uiCommon().virtualBox().GetSystemProperties().GetMaxNetworkAdapters(KChipsetType_PIIX3));
910
911 /* Create corresponding adapter tabs: */
912 for (ulong uSlot = 0; uSlot < uCount; ++uSlot)
913 {
914 /* Create adapter tab: */
915 UIMachineSettingsNetwork *pTab = new UIMachineSettingsNetwork(this);
916 if (pTab)
917 {
918 /* Tab connections: */
919 connect(pTab, &UIMachineSettingsNetwork::sigAlternativeNameChanged,
920 this, &UIMachineSettingsNetworkPage::sltHandleAlternativeNameChange);
921 connect(pTab, &UIMachineSettingsNetwork::sigAdvancedButtonStateChange,
922 this, &UIMachineSettingsNetworkPage::sltHandleAdvancedButtonStateChange);
923 connect(pTab, &UIMachineSettingsNetwork::sigValidityChanged,
924 this, &UIMachineSettingsNetworkPage::revalidate);
925
926 /* Add tab into tab-widget: */
927 m_pTabWidget->addTab(pTab, pTab->tabTitle());
928 }
929 }
930
931 /* Add tab-widget into layout: */
932 pLayoutMain->addWidget(m_pTabWidget);
933 }
934 }
935}
936
937void UIMachineSettingsNetworkPage::cleanup()
938{
939 /* Cleanup cache: */
940 delete m_pCache;
941 m_pCache = 0;
942}
943
944void UIMachineSettingsNetworkPage::refreshBridgedAdapterList()
945{
946 /* Reload bridged adapters: */
947 m_bridgedAdapterList = UINetworkAttachmentEditor::bridgedAdapters();
948}
949
950void UIMachineSettingsNetworkPage::refreshInternalNetworkList(bool fFullRefresh /* = false */)
951{
952 /* Sanity check: */
953 if (!m_pTabWidget)
954 return;
955
956 /* Reload internal network list: */
957 m_internalNetworkList.clear();
958 /* Get internal network names from other VMs: */
959 if (fFullRefresh)
960 m_internalNetworkListSaved = UINetworkAttachmentEditor::internalNetworks();
961 m_internalNetworkList << m_internalNetworkListSaved;
962 /* Append internal network list with names from all the tabs: */
963 for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot)
964 {
965 UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTabWidget->widget(iSlot));
966 AssertPtrReturnVoid(pTab);
967 const QString strName = pTab->alternativeName(KNetworkAttachmentType_Internal);
968 if (!strName.isEmpty() && !m_internalNetworkList.contains(strName))
969 m_internalNetworkList << strName;
970 }
971}
972
973#ifdef VBOX_WITH_CLOUD_NET
974void UIMachineSettingsNetworkPage::refreshCloudNetworkList()
975{
976 /* Reload cloud network list: */
977 m_cloudNetworkList = UINetworkAttachmentEditor::cloudNetworks();
978}
979#endif /* VBOX_WITH_CLOUD_NET */
980
981#ifdef VBOX_WITH_VMNET
982void UIMachineSettingsNetworkPage::refreshHostOnlyNetworkList()
983{
984 /* Reload host-only network list: */
985 m_hostOnlyNetworkList = UINetworkAttachmentEditor::hostOnlyNetworks();
986}
987#endif /* VBOX_WITH_VMNET */
988
989void UIMachineSettingsNetworkPage::refreshHostInterfaceList()
990{
991 /* Reload host interfaces: */
992 m_hostInterfaceList = UINetworkAttachmentEditor::hostInterfaces();
993}
994
995void UIMachineSettingsNetworkPage::refreshGenericDriverList(bool fFullRefresh /* = false */)
996{
997 /* Sanity check: */
998 if (!m_pTabWidget)
999 return;
1000
1001 /* Load generic driver list: */
1002 m_genericDriverList.clear();
1003 /* Get generic driver names from other VMs: */
1004 if (fFullRefresh)
1005 m_genericDriverListSaved = UINetworkAttachmentEditor::genericDrivers();
1006 m_genericDriverList << m_genericDriverListSaved;
1007 /* Append generic driver list with names from all the tabs: */
1008 for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot)
1009 {
1010 UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTabWidget->widget(iSlot));
1011 AssertPtrReturnVoid(pTab);
1012 const QString strName = pTab->alternativeName(KNetworkAttachmentType_Generic);
1013 if (!strName.isEmpty() && !m_genericDriverList.contains(strName))
1014 m_genericDriverList << strName;
1015 }
1016}
1017
1018void UIMachineSettingsNetworkPage::refreshNATNetworkList()
1019{
1020 /* Reload nat networks: */
1021 m_natNetworkList = UINetworkAttachmentEditor::natNetworks();
1022}
1023
1024/* static */
1025QString UIMachineSettingsNetworkPage::loadGenericProperties(const CNetworkAdapter &adapter)
1026{
1027 /* Prepare formatted string: */
1028 QVector<QString> names;
1029 QVector<QString> props;
1030 props = adapter.GetProperties(QString(), names);
1031 QString strResult;
1032 /* Load generic properties: */
1033 for (int i = 0; i < names.size(); ++i)
1034 {
1035 strResult += names[i] + "=" + props[i];
1036 if (i < names.size() - 1)
1037 strResult += "\n";
1038 }
1039 /* Return formatted string: */
1040 return strResult;
1041}
1042
1043/* static */
1044bool UIMachineSettingsNetworkPage::saveGenericProperties(CNetworkAdapter &comAdapter, const QString &strProperties)
1045{
1046 /* Prepare result: */
1047 bool fSuccess = true;
1048 /* Save generic properties: */
1049 if (fSuccess)
1050 {
1051 /* Acquire 'added' properties: */
1052 const QStringList newProps = strProperties.split("\n");
1053
1054 /* Insert 'added' properties: */
1055 QHash<QString, QString> hash;
1056 for (int i = 0; fSuccess && i < newProps.size(); ++i)
1057 {
1058 /* Parse property line: */
1059 const QString strLine = newProps.at(i);
1060 const QString strKey = strLine.section('=', 0, 0);
1061 const QString strVal = strLine.section('=', 1, -1);
1062 if (strKey.isEmpty() || strVal.isEmpty())
1063 continue;
1064 /* Save property in the adapter and the hash: */
1065 comAdapter.SetProperty(strKey, strVal);
1066 fSuccess = comAdapter.isOk();
1067 hash[strKey] = strVal;
1068 }
1069
1070 /* Acquire actual properties ('added' and 'removed'): */
1071 QVector<QString> names;
1072 QVector<QString> props;
1073 if (fSuccess)
1074 {
1075 props = comAdapter.GetProperties(QString(), names);
1076 fSuccess = comAdapter.isOk();
1077 }
1078
1079 /* Exclude 'removed' properties: */
1080 for (int i = 0; fSuccess && i < names.size(); ++i)
1081 {
1082 /* Get property name and value: */
1083 const QString strKey = names.at(i);
1084 const QString strVal = props.at(i);
1085 if (strVal == hash.value(strKey))
1086 continue;
1087 /* Remove property from the adapter: */
1088 // Actually we are _replacing_ property value,
1089 // not _removing_ it at all, but we are replacing it
1090 // with default constructed value, which is QString().
1091 comAdapter.SetProperty(strKey, hash.value(strKey));
1092 fSuccess = comAdapter.isOk();
1093 }
1094 }
1095 /* Return result: */
1096 return fSuccess;
1097}
1098
1099bool UIMachineSettingsNetworkPage::saveData()
1100{
1101 /* Sanity check: */
1102 if ( !m_pCache
1103 || !m_pTabWidget)
1104 return false;
1105
1106 /* Prepare result: */
1107 bool fSuccess = true;
1108 /* Save network settings from cache: */
1109 if (fSuccess && isMachineInValidMode() && m_pCache->wasChanged())
1110 {
1111 /* For each adapter: */
1112 for (int iSlot = 0; fSuccess && iSlot < m_pTabWidget->count(); ++iSlot)
1113 fSuccess = saveAdapterData(iSlot);
1114 }
1115 /* Return result: */
1116 return fSuccess;
1117}
1118
1119bool UIMachineSettingsNetworkPage::saveAdapterData(int iSlot)
1120{
1121 /* Sanity check: */
1122 if (!m_pCache)
1123 return false;
1124
1125 /* Prepare result: */
1126 bool fSuccess = true;
1127 /* Save adapter settings from cache: */
1128 if (fSuccess && m_pCache->child(iSlot).wasChanged())
1129 {
1130 /* Get old data from cache: */
1131 const UIDataSettingsMachineNetworkAdapter &oldAdapterData = m_pCache->child(iSlot).base();
1132 /* Get new data from cache: */
1133 const UIDataSettingsMachineNetworkAdapter &newAdapterData = m_pCache->child(iSlot).data();
1134
1135 /* Get network adapter for further activities: */
1136 CNetworkAdapter comAdapter = m_machine.GetNetworkAdapter(iSlot);
1137 fSuccess = m_machine.isOk() && comAdapter.isNotNull();
1138
1139 /* Show error message if necessary: */
1140 if (!fSuccess)
1141 notifyOperationProgressError(UIErrorString::formatErrorInfo(m_machine));
1142 else
1143 {
1144 /* Save whether the adapter is enabled: */
1145 if (fSuccess && isMachineOffline() && newAdapterData.m_fAdapterEnabled != oldAdapterData.m_fAdapterEnabled)
1146 {
1147 comAdapter.SetEnabled(newAdapterData.m_fAdapterEnabled);
1148 fSuccess = comAdapter.isOk();
1149 }
1150 /* Save adapter type: */
1151 if (fSuccess && isMachineOffline() && newAdapterData.m_adapterType != oldAdapterData.m_adapterType)
1152 {
1153 comAdapter.SetAdapterType(newAdapterData.m_adapterType);
1154 fSuccess = comAdapter.isOk();
1155 }
1156 /* Save adapter MAC address: */
1157 if (fSuccess && isMachineOffline() && newAdapterData.m_strMACAddress != oldAdapterData.m_strMACAddress)
1158 {
1159 comAdapter.SetMACAddress(newAdapterData.m_strMACAddress);
1160 fSuccess = comAdapter.isOk();
1161 }
1162 /* Save adapter attachment type: */
1163 switch (newAdapterData.m_attachmentType)
1164 {
1165 case KNetworkAttachmentType_Bridged:
1166 {
1167 if (fSuccess && newAdapterData.m_strBridgedAdapterName != oldAdapterData.m_strBridgedAdapterName)
1168 {
1169 comAdapter.SetBridgedInterface(newAdapterData.m_strBridgedAdapterName);
1170 fSuccess = comAdapter.isOk();
1171 }
1172 break;
1173 }
1174 case KNetworkAttachmentType_Internal:
1175 {
1176 if (fSuccess && newAdapterData.m_strInternalNetworkName != oldAdapterData.m_strInternalNetworkName)
1177 {
1178 comAdapter.SetInternalNetwork(newAdapterData.m_strInternalNetworkName);
1179 fSuccess = comAdapter.isOk();
1180 }
1181 break;
1182 }
1183 case KNetworkAttachmentType_HostOnly:
1184 {
1185 if (fSuccess && newAdapterData.m_strHostInterfaceName != oldAdapterData.m_strHostInterfaceName)
1186 {
1187 comAdapter.SetHostOnlyInterface(newAdapterData.m_strHostInterfaceName);
1188 fSuccess = comAdapter.isOk();
1189 }
1190 break;
1191 }
1192 case KNetworkAttachmentType_Generic:
1193 {
1194 if (fSuccess && newAdapterData.m_strGenericDriverName != oldAdapterData.m_strGenericDriverName)
1195 {
1196 comAdapter.SetGenericDriver(newAdapterData.m_strGenericDriverName);
1197 fSuccess = comAdapter.isOk();
1198 }
1199 if (fSuccess && newAdapterData.m_strGenericProperties != oldAdapterData.m_strGenericProperties)
1200 fSuccess = saveGenericProperties(comAdapter, newAdapterData.m_strGenericProperties);
1201 break;
1202 }
1203 case KNetworkAttachmentType_NATNetwork:
1204 {
1205 if (fSuccess && newAdapterData.m_strNATNetworkName != oldAdapterData.m_strNATNetworkName)
1206 {
1207 comAdapter.SetNATNetwork(newAdapterData.m_strNATNetworkName);
1208 fSuccess = comAdapter.isOk();
1209 }
1210 break;
1211 }
1212#ifdef VBOX_WITH_CLOUD_NET
1213 case KNetworkAttachmentType_Cloud:
1214 {
1215 if (fSuccess && newAdapterData.m_strCloudNetworkName != oldAdapterData.m_strCloudNetworkName)
1216 {
1217 comAdapter.SetCloudNetwork(newAdapterData.m_strCloudNetworkName);
1218 fSuccess = comAdapter.isOk();
1219 }
1220 break;
1221 }
1222#endif /* VBOX_WITH_CLOUD_NET */
1223#ifdef VBOX_WITH_VMNET
1224 case KNetworkAttachmentType_HostOnlyNetwork:
1225 {
1226 if (fSuccess && newAdapterData.m_strHostOnlyNetworkName != oldAdapterData.m_strHostOnlyNetworkName)
1227 {
1228 comAdapter.SetHostOnlyNetwork(newAdapterData.m_strHostOnlyNetworkName);
1229 fSuccess = comAdapter.isOk();
1230 }
1231 break;
1232 }
1233#endif /* VBOX_WITH_VMNET */
1234 default:
1235 break;
1236 }
1237 if (fSuccess && newAdapterData.m_attachmentType != oldAdapterData.m_attachmentType)
1238 {
1239 comAdapter.SetAttachmentType(newAdapterData.m_attachmentType);
1240 fSuccess = comAdapter.isOk();
1241 }
1242 /* Save adapter promiscuous mode: */
1243 if (fSuccess && newAdapterData.m_promiscuousMode != oldAdapterData.m_promiscuousMode)
1244 {
1245 comAdapter.SetPromiscModePolicy(newAdapterData.m_promiscuousMode);
1246 fSuccess = comAdapter.isOk();
1247 }
1248 /* Save whether the adapter cable connected: */
1249 if (fSuccess && newAdapterData.m_fCableConnected != oldAdapterData.m_fCableConnected)
1250 {
1251 comAdapter.SetCableConnected(newAdapterData.m_fCableConnected);
1252 fSuccess = comAdapter.isOk();
1253 }
1254
1255 /* Get NAT engine for further activities: */
1256 CNATEngine comEngine;
1257 if (fSuccess)
1258 {
1259 comEngine = comAdapter.GetNATEngine();
1260 fSuccess = comAdapter.isOk() && comEngine.isNotNull();
1261 }
1262
1263 /* Show error message if necessary: */
1264 if (!fSuccess)
1265 notifyOperationProgressError(UIErrorString::formatErrorInfo(comAdapter));
1266 else
1267 {
1268 /* Save adapter port forwarding rules: */
1269 if ( oldAdapterData.m_attachmentType == KNetworkAttachmentType_NAT
1270 || newAdapterData.m_attachmentType == KNetworkAttachmentType_NAT)
1271 {
1272 /* For each rule: */
1273 for (int iRule = 0; fSuccess && iRule < m_pCache->child(iSlot).childCount(); ++iRule)
1274 {
1275 /* Get rule cache: */
1276 const UISettingsCachePortForwardingRule &ruleCache = m_pCache->child(iSlot).child(iRule);
1277
1278 /* Remove rule marked for 'remove' or 'update': */
1279 if (ruleCache.wasRemoved() || ruleCache.wasUpdated())
1280 {
1281 comEngine.RemoveRedirect(ruleCache.base().name);
1282 fSuccess = comEngine.isOk();
1283 }
1284 }
1285 for (int iRule = 0; fSuccess && iRule < m_pCache->child(iSlot).childCount(); ++iRule)
1286 {
1287 /* Get rule cache: */
1288 const UISettingsCachePortForwardingRule &ruleCache = m_pCache->child(iSlot).child(iRule);
1289
1290 /* Create rule marked for 'create' or 'update': */
1291 if (ruleCache.wasCreated() || ruleCache.wasUpdated())
1292 {
1293 comEngine.AddRedirect(ruleCache.data().name, ruleCache.data().protocol,
1294 ruleCache.data().hostIp, ruleCache.data().hostPort.value(),
1295 ruleCache.data().guestIp, ruleCache.data().guestPort.value());
1296 fSuccess = comEngine.isOk();
1297 }
1298 }
1299
1300 /* Show error message if necessary: */
1301 if (!fSuccess)
1302 notifyOperationProgressError(UIErrorString::formatErrorInfo(comEngine));
1303 }
1304 }
1305 }
1306 }
1307 /* Return result: */
1308 return fSuccess;
1309}
1310
1311# include "UIMachineSettingsNetwork.moc"
Note: See TracBrowser for help on using the repository browser.

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