VirtualBox

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

Last change on this file since 101522 was 101522, checked in by vboxsync, 16 months ago

FE/Qt: bugref:10513: UIMachineSettingsNetwork: Make sure adapters from 2nd for 4th invisible in Basic experience mode (are they excessive?).

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