VirtualBox

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

Last change on this file since 91416 was 91416, checked in by vboxsync, 3 years ago

Devices: bugref:9932 DrvVMNet and host-only network initial implementation

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 70.6 KB
Line 
1/* $Id: UIMachineSettingsNetwork.cpp 91416 2021-09-28 06:15:49Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIMachineSettingsNetwork class implementation.
4 */
5
6/*
7 * Copyright (C) 2008-2020 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18/* Qt includes: */
19#include <QCheckBox>
20#include <QComboBox>
21#include <QGridLayout>
22#include <QLabel>
23#include <QPushButton>
24#include <QTextEdit>
25
26/* GUI includes: */
27#include "QIArrowButtonSwitch.h"
28#include "QILineEdit.h"
29#include "QITabWidget.h"
30#include "QIToolButton.h"
31#include "QIWidgetValidator.h"
32#include "UICommon.h"
33#include "UIConverter.h"
34#include "UIErrorString.h"
35#include "UIExtraDataManager.h"
36#include "UIIconPool.h"
37#include "UIMachineSettingsNetwork.h"
38#include "UINetworkAttachmentEditor.h"
39#include "UITranslator.h"
40
41/* COM includes: */
42#include "CNATEngine.h"
43#include "CNetworkAdapter.h"
44
45/* Other VBox includes: */
46#ifdef VBOX_WITH_VDE
47# include <iprt/ldr.h>
48# include <VBox/VDEPlug.h>
49#endif
50
51
52QString wipedOutString(const QString &strInputString)
53{
54 return strInputString.isEmpty() ? QString() : strInputString;
55}
56
57
58/** Machine settings: Network Adapter data structure. */
59struct UIDataSettingsMachineNetworkAdapter
60{
61 /** Constructs data. */
62 UIDataSettingsMachineNetworkAdapter()
63 : m_iSlot(0)
64 , m_fAdapterEnabled(false)
65 , m_adapterType(KNetworkAdapterType_Null)
66 , m_attachmentType(KNetworkAttachmentType_Null)
67 , m_promiscuousMode(KNetworkAdapterPromiscModePolicy_Deny)
68 , m_strBridgedAdapterName(QString())
69 , m_strInternalNetworkName(QString())
70 , m_strHostInterfaceName(QString())
71 , m_strGenericDriverName(QString())
72 , m_strGenericProperties(QString())
73 , m_strNATNetworkName(QString())
74#ifdef VBOX_WITH_CLOUD_NET
75 , m_strCloudNetworkName(QString())
76#endif /* VBOX_WITH_CLOUD_NET */
77#ifdef VBOX_WITH_VMNET
78 , m_strHostOnlyNetworkName(QString())
79#endif /* VBOX_WITH_VMNET */
80 , m_strMACAddress(QString())
81 , m_fCableConnected(false)
82 {}
83
84 /** Returns whether the @a other passed data is equal to this one. */
85 bool equal(const UIDataSettingsMachineNetworkAdapter &other) const
86 {
87 return true
88 && (m_iSlot == other.m_iSlot)
89 && (m_fAdapterEnabled == other.m_fAdapterEnabled)
90 && (m_adapterType == other.m_adapterType)
91 && (m_attachmentType == other.m_attachmentType)
92 && (m_promiscuousMode == other.m_promiscuousMode)
93 && (m_strBridgedAdapterName == other.m_strBridgedAdapterName)
94 && (m_strInternalNetworkName == other.m_strInternalNetworkName)
95 && (m_strHostInterfaceName == other.m_strHostInterfaceName)
96 && (m_strGenericDriverName == other.m_strGenericDriverName)
97 && (m_strGenericProperties == other.m_strGenericProperties)
98 && (m_strNATNetworkName == other.m_strNATNetworkName)
99#ifdef VBOX_WITH_CLOUD_NET
100 && (m_strCloudNetworkName == other.m_strCloudNetworkName)
101#endif /* VBOX_WITH_CLOUD_NET */
102#ifdef VBOX_WITH_VMNET
103 && (m_strHostOnlyNetworkName == other.m_strHostOnlyNetworkName)
104#endif /* VBOX_WITH_VMNET */
105 && (m_strMACAddress == other.m_strMACAddress)
106 && (m_fCableConnected == other.m_fCableConnected)
107 ;
108 }
109
110 /** Returns whether the @a other passed data is equal to this one. */
111 bool operator==(const UIDataSettingsMachineNetworkAdapter &other) const { return equal(other); }
112 /** Returns whether the @a other passed data is different from this one. */
113 bool operator!=(const UIDataSettingsMachineNetworkAdapter &other) const { return !equal(other); }
114
115 /** Holds the network adapter slot number. */
116 int m_iSlot;
117 /** Holds whether the network adapter is enabled. */
118 bool m_fAdapterEnabled;
119 /** Holds the network adapter type. */
120 KNetworkAdapterType m_adapterType;
121 /** Holds the network attachment type. */
122 KNetworkAttachmentType m_attachmentType;
123 /** Holds the network promiscuous mode policy. */
124 KNetworkAdapterPromiscModePolicy m_promiscuousMode;
125 /** Holds the bridged adapter name. */
126 QString m_strBridgedAdapterName;
127 /** Holds the internal network name. */
128 QString m_strInternalNetworkName;
129 /** Holds the host interface name. */
130 QString m_strHostInterfaceName;
131 /** Holds the generic driver name. */
132 QString m_strGenericDriverName;
133 /** Holds the generic driver properties. */
134 QString m_strGenericProperties;
135 /** Holds the NAT network name. */
136 QString m_strNATNetworkName;
137#ifdef VBOX_WITH_CLOUD_NET
138 /** Holds the cloud network name. */
139 QString m_strCloudNetworkName;
140#endif /* VBOX_WITH_CLOUD_NET */
141#ifdef VBOX_WITH_VMNET
142 /** Holds the host-only network name. */
143 QString m_strHostOnlyNetworkName;
144#endif /* VBOX_WITH_VMNET */
145 /** Holds the network adapter MAC address. */
146 QString m_strMACAddress;
147 /** Holds whether the network adapter is connected. */
148 bool m_fCableConnected;
149};
150
151
152/** Machine settings: Network page data structure. */
153struct UIDataSettingsMachineNetwork
154{
155 /** Constructs data. */
156 UIDataSettingsMachineNetwork() {}
157
158 /** Returns whether the @a other passed data is equal to this one. */
159 bool operator==(const UIDataSettingsMachineNetwork & /* other */) const { return true; }
160 /** Returns whether the @a other passed data is different from this one. */
161 bool operator!=(const UIDataSettingsMachineNetwork & /* other */) const { return false; }
162};
163
164
165/** Machine settings: Network Adapter tab. */
166class UIMachineSettingsNetwork : public QIWithRetranslateUI<QWidget>
167{
168 Q_OBJECT;
169
170public:
171
172 /* Constructor: */
173 UIMachineSettingsNetwork(UIMachineSettingsNetworkPage *pParent);
174
175 /* Load / Save API: */
176 void getAdapterDataFromCache(const UISettingsCacheMachineNetworkAdapter &adapterCache);
177 void putAdapterDataToCache(UISettingsCacheMachineNetworkAdapter &adapterCache);
178
179 /** Performs validation, updates @a messages list if something is wrong. */
180 bool validate(QList<UIValidationMessage> &messages);
181
182 /* Navigation stuff: */
183 QWidget *setOrderAfter(QWidget *pAfter);
184
185 /* Other public stuff: */
186 QString tabTitle() const;
187 KNetworkAttachmentType attachmentType() const;
188 QString alternativeName(KNetworkAttachmentType enmType = KNetworkAttachmentType_Null) const;
189 void polishTab();
190 void reloadAlternatives();
191
192 /** Defines whether the advanced button is @a fExpanded. */
193 void setAdvancedButtonState(bool fExpanded);
194
195signals:
196
197 /* Signal to notify listeners about tab content changed: */
198 void sigTabUpdated();
199
200 /** Notifies about the advanced button has @a fExpanded. */
201 void sigNotifyAdvancedButtonStateChange(bool fExpanded);
202
203protected:
204
205 /** Handles translation event. */
206 void retranslateUi();
207
208private slots:
209
210 /* Different handlers: */
211 void sltHandleAdapterActivityChange();
212 void sltHandleAttachmentTypeChange();
213 void sltHandleAlternativeNameChange();
214 void sltHandleAdvancedButtonStateChange();
215 void sltGenerateMac();
216 void sltOpenPortForwardingDlg();
217
218private:
219
220 /** Prepares all. */
221 void prepare();
222 /** Prepares widgets. */
223 void prepareWidgets();
224 /** Prepares connections. */
225 void prepareConnections();
226
227 /* Helping stuff: */
228 void populateComboboxes();
229
230 /** Handles advanced button state change. */
231 void handleAdvancedButtonStateChange();
232
233 /* Various static stuff: */
234 static int position(QComboBox *pComboBox, int iData);
235 static int position(QComboBox *pComboBox, const QString &strText);
236
237 /* Parent page: */
238 UIMachineSettingsNetworkPage *m_pParent;
239
240 /* Other variables: */
241 int m_iSlot;
242 KNetworkAdapterType m_enmAdapterType;
243 UIPortForwardingDataList m_portForwardingRules;
244
245 /** @name Widgets
246 * @{ */
247 /** Holds the adapter check-box instance. */
248 QCheckBox *m_pCheckBoxAdapter;
249 /** Holds the adapter settings widget instance. */
250 QWidget *m_pWidgetAdapterSettings;
251 /** Holds the attachment type label instance. */
252 QLabel *m_pLabelAttachmentType;
253 /** Holds the adapter name label instance. */
254 QLabel *m_pLabelAdapterName;
255 /** Holds the attachment type editor instance. */
256 UINetworkAttachmentEditor *m_pEditorAttachmentType;
257 /** Holds the advanced button instance. */
258 QIArrowButtonSwitch *m_pButtonAdvanced;
259 /** Holds the adapter type label instance. */
260 QLabel *m_pLabelAdapterType;
261 /** Holds the adapter type editor instance. */
262 QComboBox *m_pComboAdapterType;
263 /** Holds the promiscuous mode label instance. */
264 QLabel *m_pLabelPromiscuousMode;
265 /** Holds the promiscuous mode combo instance. */
266 QComboBox *m_pComboPromiscuousMode;
267 /** Holds the MAC label instance. */
268 QLabel *m_pLabelMAC;
269 /** Holds the MAC editor instance. */
270 QILineEdit *m_pEditorMAC;
271 /** Holds the MAC button instance. */
272 QIToolButton *m_pButtonMAC;
273 /** Holds the generic properties label instance. */
274 QLabel *m_pLabelGenericProperties;
275 /** Holds the generic properties editor instance. */
276 QTextEdit *m_pEditorGenericProperties;
277 /** Holds the cable connected check-box instance. */
278 QCheckBox *m_pCheckBoxCableConnected;
279 /** Holds the port forwarding button instance. */
280 QPushButton *m_pButtonPortForwarding;
281 /** @} */
282};
283
284
285/*********************************************************************************************************************************
286* Class UIMachineSettingsNetwork implementation. *
287*********************************************************************************************************************************/
288
289UIMachineSettingsNetwork::UIMachineSettingsNetwork(UIMachineSettingsNetworkPage *pParent)
290 : QIWithRetranslateUI<QWidget>(0)
291 , m_pParent(pParent)
292 , m_iSlot(-1)
293 , m_enmAdapterType(KNetworkAdapterType_Null)
294 , m_pCheckBoxAdapter(0)
295 , m_pWidgetAdapterSettings(0)
296 , m_pLabelAttachmentType(0)
297 , m_pLabelAdapterName(0)
298 , m_pEditorAttachmentType(0)
299 , m_pButtonAdvanced(0)
300 , m_pLabelAdapterType(0)
301 , m_pComboAdapterType(0)
302 , m_pLabelPromiscuousMode(0)
303 , m_pComboPromiscuousMode(0)
304 , m_pLabelMAC(0)
305 , m_pEditorMAC(0)
306 , m_pButtonMAC(0)
307 , m_pLabelGenericProperties(0)
308 , m_pEditorGenericProperties(0)
309 , m_pCheckBoxCableConnected(0)
310 , m_pButtonPortForwarding(0)
311{
312 prepare();
313}
314
315void UIMachineSettingsNetwork::getAdapterDataFromCache(const UISettingsCacheMachineNetworkAdapter &adapterCache)
316{
317 /* Get old adapter data: */
318 const UIDataSettingsMachineNetworkAdapter &oldAdapterData = adapterCache.base();
319
320 /* Load slot number: */
321 m_iSlot = oldAdapterData.m_iSlot;
322
323 /* Load adapter activity state: */
324 m_pCheckBoxAdapter->setChecked(oldAdapterData.m_fAdapterEnabled);
325 /* Handle adapter activity change: */
326 sltHandleAdapterActivityChange();
327
328 /* Load attachment type: */
329 m_pEditorAttachmentType->setValueType(oldAdapterData.m_attachmentType);
330 /* Load alternative names: */
331 m_pEditorAttachmentType->setValueName(KNetworkAttachmentType_Bridged, wipedOutString(oldAdapterData.m_strBridgedAdapterName));
332 m_pEditorAttachmentType->setValueName(KNetworkAttachmentType_Internal, wipedOutString(oldAdapterData.m_strInternalNetworkName));
333 m_pEditorAttachmentType->setValueName(KNetworkAttachmentType_HostOnly, wipedOutString(oldAdapterData.m_strHostInterfaceName));
334 m_pEditorAttachmentType->setValueName(KNetworkAttachmentType_Generic, wipedOutString(oldAdapterData.m_strGenericDriverName));
335 m_pEditorAttachmentType->setValueName(KNetworkAttachmentType_NATNetwork, wipedOutString(oldAdapterData.m_strNATNetworkName));
336#ifdef VBOX_WITH_CLOUD_NET
337 m_pEditorAttachmentType->setValueName(KNetworkAttachmentType_Cloud, wipedOutString(oldAdapterData.m_strCloudNetworkName));
338#endif /* VBOX_WITH_CLOUD_NET */
339#ifdef VBOX_WITH_VMNET
340 m_pEditorAttachmentType->setValueName(KNetworkAttachmentType_HostOnlyNetwork, wipedOutString(oldAdapterData.m_strHostOnlyNetworkName));
341#endif /* VBOX_WITH_VMNET */
342 /* Handle attachment type change: */
343 sltHandleAttachmentTypeChange();
344
345 /* Load adapter type: */
346 m_enmAdapterType = oldAdapterData.m_adapterType;
347
348 /* Load promiscuous mode type: */
349 m_pComboPromiscuousMode->setCurrentIndex(position(m_pComboPromiscuousMode, oldAdapterData.m_promiscuousMode));
350
351 /* Other options: */
352 m_pEditorMAC->setText(oldAdapterData.m_strMACAddress);
353 m_pEditorGenericProperties->setText(oldAdapterData.m_strGenericProperties);
354 m_pCheckBoxCableConnected->setChecked(oldAdapterData.m_fCableConnected);
355
356 /* Load port forwarding rules: */
357 m_portForwardingRules.clear();
358 for (int i = 0; i < adapterCache.childCount(); ++i)
359 m_portForwardingRules << adapterCache.child(i).base();
360
361 /* Repopulate combo-boxes content: */
362 populateComboboxes();
363 /* Reapply attachment info: */
364 sltHandleAttachmentTypeChange();
365}
366
367void UIMachineSettingsNetwork::putAdapterDataToCache(UISettingsCacheMachineNetworkAdapter &adapterCache)
368{
369 /* Prepare new adapter data: */
370 UIDataSettingsMachineNetworkAdapter newAdapterData;
371
372 /* Save adapter activity state: */
373 newAdapterData.m_fAdapterEnabled = m_pCheckBoxAdapter->isChecked();
374
375 /* Save attachment type & alternative name: */
376 newAdapterData.m_attachmentType = attachmentType();
377 switch (newAdapterData.m_attachmentType)
378 {
379 case KNetworkAttachmentType_Null:
380 break;
381 case KNetworkAttachmentType_NAT:
382 break;
383 case KNetworkAttachmentType_Bridged:
384 newAdapterData.m_strBridgedAdapterName = alternativeName();
385 break;
386 case KNetworkAttachmentType_Internal:
387 newAdapterData.m_strInternalNetworkName = m_pEditorAttachmentType->valueName(KNetworkAttachmentType_Internal);
388 break;
389 case KNetworkAttachmentType_HostOnly:
390 newAdapterData.m_strHostInterfaceName = m_pEditorAttachmentType->valueName(KNetworkAttachmentType_HostOnly);
391 break;
392 case KNetworkAttachmentType_Generic:
393 newAdapterData.m_strGenericDriverName = m_pEditorAttachmentType->valueName(KNetworkAttachmentType_Generic);
394 newAdapterData.m_strGenericProperties = m_pEditorGenericProperties->toPlainText();
395 break;
396 case KNetworkAttachmentType_NATNetwork:
397 newAdapterData.m_strNATNetworkName = m_pEditorAttachmentType->valueName(KNetworkAttachmentType_NATNetwork);
398 break;
399#ifdef VBOX_WITH_CLOUD_NET
400 case KNetworkAttachmentType_Cloud:
401 newAdapterData.m_strCloudNetworkName = m_pEditorAttachmentType->valueName(KNetworkAttachmentType_Cloud);
402 break;
403#endif /* VBOX_WITH_CLOUD_NET */
404#ifdef VBOX_WITH_VMNET
405 case KNetworkAttachmentType_HostOnlyNetwork:
406 newAdapterData.m_strHostOnlyNetworkName = m_pEditorAttachmentType->valueName(KNetworkAttachmentType_HostOnlyNetwork);
407 break;
408#endif /* VBOX_WITH_VMNET */
409 default:
410 break;
411 }
412
413 /* Save adapter type: */
414 newAdapterData.m_adapterType = m_pComboAdapterType->currentData().value<KNetworkAdapterType>();
415
416 /* Save promiscuous mode type: */
417 newAdapterData.m_promiscuousMode = (KNetworkAdapterPromiscModePolicy)m_pComboPromiscuousMode->itemData(m_pComboPromiscuousMode->currentIndex()).toInt();
418
419 /* Other options: */
420 newAdapterData.m_strMACAddress = m_pEditorMAC->text().isEmpty() ? QString() : m_pEditorMAC->text();
421 newAdapterData.m_fCableConnected = m_pCheckBoxCableConnected->isChecked();
422
423 /* Save port forwarding rules: */
424 foreach (const UIDataPortForwardingRule &rule, m_portForwardingRules)
425 adapterCache.child(rule.name).cacheCurrentData(rule);
426
427 /* Cache new adapter data: */
428 adapterCache.cacheCurrentData(newAdapterData);
429}
430
431bool UIMachineSettingsNetwork::validate(QList<UIValidationMessage> &messages)
432{
433 /* Pass if adapter is disabled: */
434 if (!m_pCheckBoxAdapter->isChecked())
435 return true;
436
437 /* Pass by default: */
438 bool fPass = true;
439
440 /* Prepare message: */
441 UIValidationMessage message;
442 message.first = UITranslator::removeAccelMark(tabTitle());
443
444 /* Validate alternatives: */
445 switch (attachmentType())
446 {
447 case KNetworkAttachmentType_Bridged:
448 {
449 if (alternativeName().isNull())
450 {
451 message.second << tr("No bridged network adapter is currently selected.");
452 fPass = false;
453 }
454 break;
455 }
456 case KNetworkAttachmentType_Internal:
457 {
458 if (alternativeName().isNull())
459 {
460 message.second << tr("No internal network name is currently specified.");
461 fPass = false;
462 }
463 break;
464 }
465#ifndef VBOX_WITH_VMNET
466 case KNetworkAttachmentType_HostOnly:
467 {
468 if (alternativeName().isNull())
469 {
470 message.second << tr("No host-only network adapter is currently selected.");
471 fPass = false;
472 }
473 break;
474 }
475#else /* VBOX_WITH_VMNET */
476 case KNetworkAttachmentType_HostOnly:
477 {
478 message.second << tr("Host-only adapters are no longer supported, use host-only networks instead.");
479 fPass = false;
480 break;
481 }
482#endif /* VBOX_WITH_VMNET */
483 case KNetworkAttachmentType_Generic:
484 {
485 if (alternativeName().isNull())
486 {
487 message.second << tr("No generic driver is currently selected.");
488 fPass = false;
489 }
490 break;
491 }
492 case KNetworkAttachmentType_NATNetwork:
493 {
494 if (alternativeName().isNull())
495 {
496 message.second << tr("No NAT network name is currently specified.");
497 fPass = false;
498 }
499 break;
500 }
501#ifdef VBOX_WITH_CLOUD_NET
502 case KNetworkAttachmentType_Cloud:
503 {
504 if (alternativeName().isNull())
505 {
506 message.second << tr("No cloud network name is currently specified.");
507 fPass = false;
508 }
509 break;
510 }
511#endif /* VBOX_WITH_CLOUD_NET */
512#ifdef VBOX_WITH_VMNET
513 case KNetworkAttachmentType_HostOnlyNetwork:
514 {
515 if (alternativeName().isNull())
516 {
517 message.second << tr("No host-only network name is currently specified.");
518 fPass = false;
519 }
520 break;
521 }
522#endif /* VBOX_WITH_VMNET */
523 default:
524 break;
525 }
526
527 /* Validate MAC-address length: */
528 if (m_pEditorMAC->text().size() < 12)
529 {
530 message.second << tr("The MAC address must be 12 hexadecimal digits long.");
531 fPass = false;
532 }
533
534 /* Make sure MAC-address is unicast: */
535 if (m_pEditorMAC->text().size() >= 2)
536 {
537 QRegExp validator("^[0-9A-Fa-f][02468ACEace]");
538 if (validator.indexIn(m_pEditorMAC->text()) != 0)
539 {
540 message.second << tr("The second digit in the MAC address may not be odd as only unicast addresses are allowed.");
541 fPass = false;
542 }
543 }
544
545 /* Serialize message: */
546 if (!message.second.isEmpty())
547 messages << message;
548
549 /* Return result: */
550 return fPass;
551}
552
553QWidget *UIMachineSettingsNetwork::setOrderAfter(QWidget *pAfter)
554{
555 setTabOrder(pAfter, m_pCheckBoxAdapter);
556 setTabOrder(m_pCheckBoxAdapter, m_pEditorAttachmentType);
557 setTabOrder(m_pEditorAttachmentType, m_pButtonAdvanced);
558 setTabOrder(m_pButtonAdvanced, m_pComboAdapterType);
559 setTabOrder(m_pComboAdapterType, m_pComboPromiscuousMode);
560 setTabOrder(m_pComboPromiscuousMode, m_pEditorMAC);
561 setTabOrder(m_pEditorMAC, m_pButtonMAC);
562 setTabOrder(m_pButtonMAC, m_pEditorGenericProperties);
563 setTabOrder(m_pEditorGenericProperties, m_pCheckBoxCableConnected);
564 setTabOrder(m_pCheckBoxCableConnected, m_pButtonPortForwarding);
565 return m_pButtonPortForwarding;
566}
567
568QString UIMachineSettingsNetwork::tabTitle() const
569{
570 return UICommon::tr("Adapter %1").arg(QString("&%1").arg(m_iSlot + 1));
571}
572
573KNetworkAttachmentType UIMachineSettingsNetwork::attachmentType() const
574{
575 return m_pEditorAttachmentType->valueType();
576}
577
578QString UIMachineSettingsNetwork::alternativeName(KNetworkAttachmentType enmType /* = KNetworkAttachmentType_Null */) const
579{
580 if (enmType == KNetworkAttachmentType_Null)
581 enmType = attachmentType();
582 return m_pEditorAttachmentType->valueName(enmType);
583}
584
585void UIMachineSettingsNetwork::polishTab()
586{
587 /* Basic attributes: */
588 m_pCheckBoxAdapter->setEnabled(m_pParent->isMachineOffline());
589 m_pLabelAttachmentType->setEnabled(m_pParent->isMachineInValidMode());
590 m_pEditorAttachmentType->setEnabled(m_pParent->isMachineInValidMode());
591 m_pLabelAdapterName->setEnabled(m_pParent->isMachineInValidMode() &&
592 attachmentType() != KNetworkAttachmentType_Null &&
593 attachmentType() != KNetworkAttachmentType_NAT);
594 m_pButtonAdvanced->setEnabled(m_pParent->isMachineInValidMode());
595
596 /* Advanced attributes: */
597 m_pLabelAdapterType->setEnabled(m_pParent->isMachineOffline());
598 m_pComboAdapterType->setEnabled(m_pParent->isMachineOffline());
599 m_pLabelPromiscuousMode->setEnabled(m_pParent->isMachineInValidMode() &&
600 attachmentType() != KNetworkAttachmentType_Null &&
601 attachmentType() != KNetworkAttachmentType_Generic &&
602 attachmentType() != KNetworkAttachmentType_NAT);
603 m_pComboPromiscuousMode->setEnabled(m_pParent->isMachineInValidMode() &&
604 attachmentType() != KNetworkAttachmentType_Null &&
605 attachmentType() != KNetworkAttachmentType_Generic &&
606 attachmentType() != KNetworkAttachmentType_NAT);
607 m_pLabelMAC->setEnabled(m_pParent->isMachineOffline());
608 m_pEditorMAC->setEnabled(m_pParent->isMachineOffline());
609 m_pButtonMAC->setEnabled(m_pParent->isMachineOffline());
610 m_pLabelGenericProperties->setEnabled(m_pParent->isMachineInValidMode());
611 m_pEditorGenericProperties->setEnabled(m_pParent->isMachineInValidMode());
612 m_pCheckBoxCableConnected->setEnabled(m_pParent->isMachineInValidMode());
613 m_pButtonPortForwarding->setEnabled(m_pParent->isMachineInValidMode() &&
614 attachmentType() == KNetworkAttachmentType_NAT);
615
616 /* Postprocessing: */
617 handleAdvancedButtonStateChange();
618}
619
620void UIMachineSettingsNetwork::reloadAlternatives()
621{
622 m_pEditorAttachmentType->setValueNames(KNetworkAttachmentType_Bridged, m_pParent->bridgedAdapterList());
623 m_pEditorAttachmentType->setValueNames(KNetworkAttachmentType_Internal, m_pParent->internalNetworkList());
624 m_pEditorAttachmentType->setValueNames(KNetworkAttachmentType_HostOnly, m_pParent->hostInterfaceList());
625 m_pEditorAttachmentType->setValueNames(KNetworkAttachmentType_Generic, m_pParent->genericDriverList());
626 m_pEditorAttachmentType->setValueNames(KNetworkAttachmentType_NATNetwork, m_pParent->natNetworkList());
627#ifdef VBOX_WITH_CLOUD_NET
628 m_pEditorAttachmentType->setValueNames(KNetworkAttachmentType_Cloud, m_pParent->cloudNetworkList());
629#endif /* VBOX_WITH_CLOUD_NET */
630#ifdef VBOX_WITH_VMNET
631 m_pEditorAttachmentType->setValueNames(KNetworkAttachmentType_HostOnlyNetwork, m_pParent->hostOnlyNetworkList());
632#endif /* VBOX_WITH_VMNET */
633}
634
635void UIMachineSettingsNetwork::setAdvancedButtonState(bool fExpanded)
636{
637 /* Check whether the button state really changed: */
638 if (m_pButtonAdvanced->isExpanded() == fExpanded)
639 return;
640
641 /* Push the state to button and handle the state change: */
642 m_pButtonAdvanced->setExpanded(fExpanded);
643 handleAdvancedButtonStateChange();
644}
645
646void UIMachineSettingsNetwork::retranslateUi()
647{
648 m_pCheckBoxAdapter->setWhatsThis(QApplication::translate("UIMachineSettingsNetwork", "When checked, plugs this virtual "
649 "network adapter into the virtual machine."));
650 m_pCheckBoxAdapter->setText(QApplication::translate("UIMachineSettingsNetwork", "&Enable Network Adapter"));
651 m_pLabelAttachmentType->setText(QApplication::translate("UIMachineSettingsNetwork", "&Attached to:"));
652 m_pEditorAttachmentType->setWhatsThis(QApplication::translate("UIMachineSettingsNetwork", "Selects how this virtual adapter "
653 "is attached to the real network of the Host OS."));
654 m_pLabelAdapterName->setText(QApplication::translate("UIMachineSettingsNetwork", "&Name:"));
655 m_pButtonAdvanced->setText(QApplication::translate("UIMachineSettingsNetwork", "A&dvanced"));
656 m_pButtonAdvanced->setWhatsThis(QApplication::translate("UIMachineSettingsNetwork", "Shows additional network adapter options."));
657 m_pLabelAdapterType->setText(QApplication::translate("UIMachineSettingsNetwork", "Adapter &Type:"));
658 m_pComboAdapterType->setWhatsThis(QApplication::translate("UIMachineSettingsNetwork", "Selects the type of the virtual network "
659 "adapter. Depending on this value, VirtualBox will provide different "
660 "network hardware to the virtual machine."));
661 m_pLabelPromiscuousMode->setText(QApplication::translate("UIMachineSettingsNetwork", "&Promiscuous Mode:"));
662 m_pComboPromiscuousMode->setWhatsThis(QApplication::translate("UIMachineSettingsNetwork", "Selects the promiscuous mode policy "
663 "of the network adapter when attached to an internal network, "
664 "host only network or a bridge."));
665 m_pLabelMAC->setText(QApplication::translate("UIMachineSettingsNetwork", "&MAC Address:"));
666 m_pEditorMAC->setWhatsThis(QApplication::translate("UIMachineSettingsNetwork", "Holds the MAC address of this adapter. It contains "
667 "exactly 12 characters chosen from {0-9,A-F}. Note that the second character "
668 "must be an even digit."));
669 m_pButtonMAC->setWhatsThis(QApplication::translate("UIMachineSettingsNetwork", "Generates a new random MAC address."));
670 m_pLabelGenericProperties->setText(QApplication::translate("UIMachineSettingsNetwork", "Generic Properties:"));
671 m_pEditorGenericProperties->setWhatsThis(QApplication::translate("UIMachineSettingsNetwork", "Holds the configuration settings "
672 "for the network attachment driver. The settings should be of "
673 "the form <b>name=value</b> and will depend on the driver. "
674 "Use <b>shift-enter</b> to add a new entry."));
675 m_pCheckBoxCableConnected->setWhatsThis(QApplication::translate("UIMachineSettingsNetwork", "When checked, the virtual network "
676 "cable is plugged in."));
677 m_pCheckBoxCableConnected->setText(QApplication::translate("UIMachineSettingsNetwork", "&Cable Connected"));
678 m_pButtonPortForwarding->setWhatsThis(QApplication::translate("UIMachineSettingsNetwork", "Displays a window to configure port "
679 "forwarding rules."));
680 m_pButtonPortForwarding->setText(QApplication::translate("UIMachineSettingsNetwork", "&Port Forwarding"));
681
682 /* Translate combo-boxes content: */
683 populateComboboxes();
684
685 /* Translate attachment info: */
686 sltHandleAttachmentTypeChange();
687}
688
689void UIMachineSettingsNetwork::sltHandleAdapterActivityChange()
690{
691 /* Update availability: */
692 m_pWidgetAdapterSettings->setEnabled(m_pCheckBoxAdapter->isChecked());
693
694 /* Generate a new MAC address in case this adapter was never enabled before: */
695 if ( m_pCheckBoxAdapter->isChecked()
696 && m_pEditorMAC->text().isEmpty())
697 sltGenerateMac();
698
699 /* Revalidate: */
700 m_pParent->revalidate();
701}
702
703void UIMachineSettingsNetwork::sltHandleAttachmentTypeChange()
704{
705 /* Update alternative-name combo-box availability: */
706 m_pLabelAdapterName->setEnabled(attachmentType() != KNetworkAttachmentType_Null &&
707 attachmentType() != KNetworkAttachmentType_NAT);
708 /* Update promiscuous-mode combo-box availability: */
709 m_pLabelPromiscuousMode->setEnabled(attachmentType() != KNetworkAttachmentType_Null &&
710 attachmentType() != KNetworkAttachmentType_Generic &&
711 attachmentType() != KNetworkAttachmentType_NAT);
712 m_pComboPromiscuousMode->setEnabled(attachmentType() != KNetworkAttachmentType_Null &&
713 attachmentType() != KNetworkAttachmentType_Generic &&
714 attachmentType() != KNetworkAttachmentType_NAT);
715 /* Update generic-properties editor visibility: */
716 m_pLabelGenericProperties->setVisible(attachmentType() == KNetworkAttachmentType_Generic &&
717 m_pButtonAdvanced->isExpanded());
718 m_pEditorGenericProperties->setVisible(attachmentType() == KNetworkAttachmentType_Generic &&
719 m_pButtonAdvanced->isExpanded());
720 /* Update forwarding rules button availability: */
721 m_pButtonPortForwarding->setEnabled(attachmentType() == KNetworkAttachmentType_NAT);
722
723 /* Revalidate: */
724 m_pParent->revalidate();
725}
726
727void UIMachineSettingsNetwork::sltHandleAlternativeNameChange()
728{
729 /* Remember new name if its changed,
730 * Call for other pages update, if necessary: */
731 switch (attachmentType())
732 {
733 case KNetworkAttachmentType_Internal:
734 {
735 if (!m_pEditorAttachmentType->valueName(KNetworkAttachmentType_Internal).isNull())
736 emit sigTabUpdated();
737 break;
738 }
739 case KNetworkAttachmentType_Generic:
740 {
741 if (!m_pEditorAttachmentType->valueName(KNetworkAttachmentType_Generic).isNull())
742 emit sigTabUpdated();
743 break;
744 }
745 default:
746 break;
747 }
748
749 /* Revalidate: */
750 m_pParent->revalidate();
751}
752
753void UIMachineSettingsNetwork::sltHandleAdvancedButtonStateChange()
754{
755 /* Handle the button state change: */
756 handleAdvancedButtonStateChange();
757
758 /* Notify listeners about the button state change: */
759 emit sigNotifyAdvancedButtonStateChange(m_pButtonAdvanced->isExpanded());
760}
761
762void UIMachineSettingsNetwork::sltGenerateMac()
763{
764 m_pEditorMAC->setText(uiCommon().host().GenerateMACAddress());
765}
766
767void UIMachineSettingsNetwork::sltOpenPortForwardingDlg()
768{
769 UIMachineSettingsPortForwardingDlg dlg(this, m_portForwardingRules);
770 if (dlg.exec() == QDialog::Accepted)
771 m_portForwardingRules = dlg.rules();
772}
773
774void UIMachineSettingsNetwork::prepare()
775{
776 /* Prepare everything: */
777 prepareWidgets();
778 prepareConnections();
779
780 /* Apply language settings: */
781 retranslateUi();
782}
783
784void UIMachineSettingsNetwork::prepareWidgets()
785{
786 /* Prepare main layout: */
787 QGridLayout *pLayoutMain = new QGridLayout(this);
788 if (pLayoutMain)
789 {
790 pLayoutMain->setRowStretch(2, 1);
791
792 /* Prepare adapter check-box: */
793 m_pCheckBoxAdapter = new QCheckBox(this);
794 if (m_pCheckBoxAdapter)
795 pLayoutMain->addWidget(m_pCheckBoxAdapter, 0, 0, 1, 2);
796
797 /* Prepare 20-px shifting spacer: */
798 QSpacerItem *pSpacerItem = new QSpacerItem(20, 0, QSizePolicy::Fixed, QSizePolicy::Minimum);
799 if (pSpacerItem)
800 pLayoutMain->addItem(pSpacerItem, 1, 0);
801
802 /* Prepare adapter settings widget: */
803 m_pWidgetAdapterSettings = new QWidget(this);
804 if (m_pWidgetAdapterSettings)
805 {
806 /* Prepare adapter settings widget layout: */
807 QGridLayout *pLayoutAdapterSettings = new QGridLayout(m_pWidgetAdapterSettings);
808 if (pLayoutAdapterSettings)
809 {
810 pLayoutAdapterSettings->setContentsMargins(0, 0, 0, 0);
811 pLayoutAdapterSettings->setColumnStretch(2, 1);
812
813 /* Prepare attachment type label: */
814 m_pLabelAttachmentType = new QLabel(m_pWidgetAdapterSettings);
815 if (m_pLabelAttachmentType)
816 {
817 m_pLabelAttachmentType->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
818 pLayoutAdapterSettings->addWidget(m_pLabelAttachmentType, 0, 0);
819 }
820 /* Prepare adapter name label: */
821 m_pLabelAdapterName = new QLabel(m_pWidgetAdapterSettings);
822 if (m_pLabelAdapterName)
823 {
824 m_pLabelAdapterName->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
825 pLayoutAdapterSettings->addWidget(m_pLabelAdapterName, 1, 0);
826 }
827 /* Prepare attachment type editor: */
828 m_pEditorAttachmentType = new UINetworkAttachmentEditor(m_pWidgetAdapterSettings);
829 if (m_pEditorAttachmentType)
830 {
831 if (m_pLabelAttachmentType)
832 m_pLabelAttachmentType->setBuddy(m_pEditorAttachmentType->focusProxy1());
833 if (m_pLabelAdapterName)
834 m_pLabelAdapterName->setBuddy(m_pEditorAttachmentType->focusProxy2());
835
836 pLayoutAdapterSettings->addWidget(m_pEditorAttachmentType, 0, 1, 2, 3);
837 }
838
839 /* Prepare advanced arrow button: */
840 m_pButtonAdvanced = new QIArrowButtonSwitch(m_pWidgetAdapterSettings);
841 if (m_pButtonAdvanced)
842 {
843 const QStyle *pStyle = QApplication::style();
844 const int iIconMetric = (int)(pStyle->pixelMetric(QStyle::PM_SmallIconSize) * .625);
845 m_pButtonAdvanced->setIconSize(QSize(iIconMetric, iIconMetric));
846 m_pButtonAdvanced->setIcons(UIIconPool::iconSet(":/arrow_right_10px.png"),
847 UIIconPool::iconSet(":/arrow_down_10px.png"));
848
849 pLayoutAdapterSettings->addWidget(m_pButtonAdvanced, 2, 0);
850 }
851
852 /* Prepare adapter type label: */
853 m_pLabelAdapterType = new QLabel(m_pWidgetAdapterSettings);
854 if (m_pLabelAdapterType)
855 {
856 m_pLabelAdapterType->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
857 pLayoutAdapterSettings->addWidget(m_pLabelAdapterType, 3, 0);
858 }
859 /* Prepare adapter type combo: */
860 m_pComboAdapterType = new QComboBox(m_pWidgetAdapterSettings);
861 if (m_pComboAdapterType)
862 {
863 if (m_pLabelAdapterType)
864 m_pLabelAdapterType->setBuddy(m_pComboAdapterType);
865 pLayoutAdapterSettings->addWidget(m_pComboAdapterType, 3, 1, 1, 3);
866 }
867
868 /* Prepare promiscuous mode label: */
869 m_pLabelPromiscuousMode = new QLabel(m_pWidgetAdapterSettings);
870 if (m_pLabelPromiscuousMode)
871 {
872 m_pLabelPromiscuousMode->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
873 pLayoutAdapterSettings->addWidget(m_pLabelPromiscuousMode, 4, 0);
874 }
875 /* Prepare promiscuous mode combo: */
876 m_pComboPromiscuousMode = new QComboBox(m_pWidgetAdapterSettings);
877 if (m_pComboPromiscuousMode)
878 {
879 if (m_pLabelPromiscuousMode)
880 m_pLabelPromiscuousMode->setBuddy(m_pComboPromiscuousMode);
881 pLayoutAdapterSettings->addWidget(m_pComboPromiscuousMode, 4, 1, 1, 3);
882 }
883
884 /* Prepare MAC label: */
885 m_pLabelMAC = new QLabel(m_pWidgetAdapterSettings);
886 if (m_pLabelMAC)
887 {
888 m_pLabelMAC->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
889 pLayoutAdapterSettings->addWidget(m_pLabelMAC, 5, 0);
890 }
891 /* Prepare MAC editor: */
892 m_pEditorMAC = new QILineEdit(m_pWidgetAdapterSettings);
893 if (m_pEditorMAC)
894 {
895 if (m_pLabelMAC)
896 m_pLabelMAC->setBuddy(m_pEditorMAC);
897 m_pEditorMAC->setAllowToCopyContentsWhenDisabled(true);
898 m_pEditorMAC->setValidator(new QRegExpValidator(QRegExp("[0-9A-Fa-f]{12}"), this));
899 m_pEditorMAC->setMinimumWidthByText(QString().fill('0', 12));
900
901 pLayoutAdapterSettings->addWidget(m_pEditorMAC, 5, 1, 1, 2);
902 }
903 /* Prepare MAC button: */
904 m_pButtonMAC = new QIToolButton(m_pWidgetAdapterSettings);
905 if (m_pButtonMAC)
906 {
907 m_pButtonMAC->setIcon(UIIconPool::iconSet(":/refresh_16px.png"));
908 pLayoutAdapterSettings->addWidget(m_pButtonMAC, 5, 3);
909 }
910
911 /* Prepare MAC label: */
912 m_pLabelGenericProperties = new QLabel(m_pWidgetAdapterSettings);
913 if (m_pLabelGenericProperties)
914 {
915 m_pLabelGenericProperties->setAlignment(Qt::AlignRight | Qt::AlignTop);
916 pLayoutAdapterSettings->addWidget(m_pLabelGenericProperties, 6, 0);
917 }
918 /* Prepare MAC editor: */
919 m_pEditorGenericProperties = new QTextEdit(m_pWidgetAdapterSettings);
920 if (m_pEditorGenericProperties)
921 pLayoutAdapterSettings->addWidget(m_pEditorGenericProperties, 6, 1, 1, 3);
922
923 /* Prepare cable connected check-box: */
924 m_pCheckBoxCableConnected = new QCheckBox(m_pWidgetAdapterSettings);
925 if (m_pCheckBoxCableConnected)
926 pLayoutAdapterSettings->addWidget(m_pCheckBoxCableConnected, 7, 1, 1, 2);
927
928 /* Prepare port forwarding button: */
929 m_pButtonPortForwarding = new QPushButton(m_pWidgetAdapterSettings);
930 if (m_pButtonPortForwarding)
931 pLayoutAdapterSettings->addWidget(m_pButtonPortForwarding, 8, 1);
932 }
933
934 pLayoutMain->addWidget(m_pWidgetAdapterSettings, 1, 1);
935 }
936 }
937}
938
939void UIMachineSettingsNetwork::prepareConnections()
940{
941 connect(m_pCheckBoxAdapter, &QCheckBox::toggled, this, &UIMachineSettingsNetwork::sltHandleAdapterActivityChange);
942 connect(m_pEditorAttachmentType, &UINetworkAttachmentEditor::sigValueTypeChanged,
943 this, &UIMachineSettingsNetwork::sltHandleAttachmentTypeChange);
944 connect(m_pEditorAttachmentType, &UINetworkAttachmentEditor::sigValueNameChanged,
945 this, &UIMachineSettingsNetwork::sltHandleAlternativeNameChange);
946 connect(m_pButtonAdvanced, &QIArrowButtonSwitch::sigClicked, this, &UIMachineSettingsNetwork::sltHandleAdvancedButtonStateChange);
947 connect(m_pEditorMAC, &QILineEdit::textChanged, m_pParent, &UIMachineSettingsNetworkPage::revalidate);
948 connect(m_pButtonMAC, &QIToolButton::clicked, this, &UIMachineSettingsNetwork::sltGenerateMac);
949 connect(m_pButtonPortForwarding, &QPushButton::clicked, this, &UIMachineSettingsNetwork::sltOpenPortForwardingDlg);
950 connect(this, &UIMachineSettingsNetwork::sigTabUpdated, m_pParent, &UIMachineSettingsNetworkPage::sltHandleTabUpdate);
951}
952
953void UIMachineSettingsNetwork::populateComboboxes()
954{
955 /* Adapter names: */
956 {
957 reloadAlternatives();
958 }
959
960 /* Adapter type: */
961 {
962 /* Clear the adapter type combo-box: */
963 m_pComboAdapterType->clear();
964
965 /* Load currently supported network adapter types: */
966 CSystemProperties comProperties = uiCommon().virtualBox().GetSystemProperties();
967 QVector<KNetworkAdapterType> supportedTypes = comProperties.GetSupportedNetworkAdapterTypes();
968 /* Take currently requested type into account if it's sane: */
969 if (!supportedTypes.contains(m_enmAdapterType) && m_enmAdapterType != KNetworkAdapterType_Null)
970 supportedTypes.prepend(m_enmAdapterType);
971
972 /* Populate adapter types: */
973 int iAdapterTypeIndex = 0;
974 foreach (const KNetworkAdapterType &enmType, supportedTypes)
975 {
976 m_pComboAdapterType->insertItem(iAdapterTypeIndex, gpConverter->toString(enmType));
977 m_pComboAdapterType->setItemData(iAdapterTypeIndex, QVariant::fromValue(enmType));
978 m_pComboAdapterType->setItemData(iAdapterTypeIndex, m_pComboAdapterType->itemText(iAdapterTypeIndex), Qt::ToolTipRole);
979 ++iAdapterTypeIndex;
980 }
981
982 /* Choose requested adapter type: */
983 const int iIndex = m_pComboAdapterType->findData(m_enmAdapterType);
984 m_pComboAdapterType->setCurrentIndex(iIndex != -1 ? iIndex : 0);
985 }
986
987 /* Promiscuous Mode type: */
988 {
989 /* Remember the currently selected promiscuous mode type: */
990 int iCurrentPromiscuousMode = m_pComboPromiscuousMode->currentIndex();
991
992 /* Clear the promiscuous mode combo-box: */
993 m_pComboPromiscuousMode->clear();
994
995 /* Populate promiscuous modes: */
996 int iPromiscuousModeIndex = 0;
997 m_pComboPromiscuousMode->insertItem(iPromiscuousModeIndex, gpConverter->toString(KNetworkAdapterPromiscModePolicy_Deny));
998 m_pComboPromiscuousMode->setItemData(iPromiscuousModeIndex, KNetworkAdapterPromiscModePolicy_Deny);
999 m_pComboPromiscuousMode->setItemData(iPromiscuousModeIndex, m_pComboPromiscuousMode->itemText(iPromiscuousModeIndex), Qt::ToolTipRole);
1000 ++iPromiscuousModeIndex;
1001 m_pComboPromiscuousMode->insertItem(iPromiscuousModeIndex, gpConverter->toString(KNetworkAdapterPromiscModePolicy_AllowNetwork));
1002 m_pComboPromiscuousMode->setItemData(iPromiscuousModeIndex, KNetworkAdapterPromiscModePolicy_AllowNetwork);
1003 m_pComboPromiscuousMode->setItemData(iPromiscuousModeIndex, m_pComboPromiscuousMode->itemText(iPromiscuousModeIndex), Qt::ToolTipRole);
1004 ++iPromiscuousModeIndex;
1005 m_pComboPromiscuousMode->insertItem(iPromiscuousModeIndex, gpConverter->toString(KNetworkAdapterPromiscModePolicy_AllowAll));
1006 m_pComboPromiscuousMode->setItemData(iPromiscuousModeIndex, KNetworkAdapterPromiscModePolicy_AllowAll);
1007 m_pComboPromiscuousMode->setItemData(iPromiscuousModeIndex, m_pComboPromiscuousMode->itemText(iPromiscuousModeIndex), Qt::ToolTipRole);
1008 ++iPromiscuousModeIndex;
1009
1010 /* Restore the previously selected promiscuous mode type: */
1011 m_pComboPromiscuousMode->setCurrentIndex(iCurrentPromiscuousMode == -1 ? 0 : iCurrentPromiscuousMode);
1012 }
1013}
1014
1015void UIMachineSettingsNetwork::handleAdvancedButtonStateChange()
1016{
1017 /* Update visibility of advanced options: */
1018 m_pLabelAdapterType->setVisible(m_pButtonAdvanced->isExpanded());
1019 m_pComboAdapterType->setVisible(m_pButtonAdvanced->isExpanded());
1020 m_pLabelPromiscuousMode->setVisible(m_pButtonAdvanced->isExpanded());
1021 m_pComboPromiscuousMode->setVisible(m_pButtonAdvanced->isExpanded());
1022 m_pLabelGenericProperties->setVisible(attachmentType() == KNetworkAttachmentType_Generic &&
1023 m_pButtonAdvanced->isExpanded());
1024 m_pEditorGenericProperties->setVisible(attachmentType() == KNetworkAttachmentType_Generic &&
1025 m_pButtonAdvanced->isExpanded());
1026 m_pLabelMAC->setVisible(m_pButtonAdvanced->isExpanded());
1027 m_pEditorMAC->setVisible(m_pButtonAdvanced->isExpanded());
1028 m_pButtonMAC->setVisible(m_pButtonAdvanced->isExpanded());
1029 m_pCheckBoxCableConnected->setVisible(m_pButtonAdvanced->isExpanded());
1030 m_pButtonPortForwarding->setVisible(m_pButtonAdvanced->isExpanded());
1031}
1032
1033/* static */
1034int UIMachineSettingsNetwork::position(QComboBox *pComboBox, int iData)
1035{
1036 const int iPosition = pComboBox->findData(iData);
1037 return iPosition == -1 ? 0 : iPosition;
1038}
1039
1040/* static */
1041int UIMachineSettingsNetwork::position(QComboBox *pComboBox, const QString &strText)
1042{
1043 const int iPosition = pComboBox->findText(strText);
1044 return iPosition == -1 ? 0 : iPosition;
1045}
1046
1047
1048/*********************************************************************************************************************************
1049* Class UIMachineSettingsNetworkPage implementation. *
1050*********************************************************************************************************************************/
1051
1052UIMachineSettingsNetworkPage::UIMachineSettingsNetworkPage()
1053 : m_pTabWidget(0)
1054 , m_pCache(0)
1055{
1056 /* Prepare: */
1057 prepare();
1058}
1059
1060UIMachineSettingsNetworkPage::~UIMachineSettingsNetworkPage()
1061{
1062 /* Cleanup: */
1063 cleanup();
1064}
1065
1066bool UIMachineSettingsNetworkPage::changed() const
1067{
1068 return m_pCache->wasChanged();
1069}
1070
1071void UIMachineSettingsNetworkPage::loadToCacheFrom(QVariant &data)
1072{
1073 /* Fetch data to machine: */
1074 UISettingsPageMachine::fetchData(data);
1075
1076 /* Clear cache initially: */
1077 m_pCache->clear();
1078
1079 /* Cache name lists: */
1080 refreshBridgedAdapterList();
1081 refreshInternalNetworkList(true);
1082 refreshHostInterfaceList();
1083 refreshGenericDriverList(true);
1084 refreshNATNetworkList();
1085#ifdef VBOX_WITH_CLOUD_NET
1086 refreshCloudNetworkList();
1087#endif /* VBOX_WITH_CLOUD_NET */
1088#ifdef VBOX_WITH_VMNET
1089 refreshHostOnlyNetworkList();
1090#endif /* VBOX_WITH_VMNET */
1091
1092 /* Prepare old network data: */
1093 UIDataSettingsMachineNetwork oldNetworkData;
1094
1095 /* For each network adapter: */
1096 for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot)
1097 {
1098 /* Prepare old adapter data: */
1099 UIDataSettingsMachineNetworkAdapter oldAdapterData;
1100
1101 /* Check whether adapter is valid: */
1102 const CNetworkAdapter &comAdapter = m_machine.GetNetworkAdapter(iSlot);
1103 if (!comAdapter.isNull())
1104 {
1105 /* Gather old adapter data: */
1106 oldAdapterData.m_iSlot = iSlot;
1107 oldAdapterData.m_fAdapterEnabled = comAdapter.GetEnabled();
1108 oldAdapterData.m_attachmentType = comAdapter.GetAttachmentType();
1109 oldAdapterData.m_strBridgedAdapterName = wipedOutString(comAdapter.GetBridgedInterface());
1110 oldAdapterData.m_strInternalNetworkName = wipedOutString(comAdapter.GetInternalNetwork());
1111 oldAdapterData.m_strHostInterfaceName = wipedOutString(comAdapter.GetHostOnlyInterface());
1112 oldAdapterData.m_strGenericDriverName = wipedOutString(comAdapter.GetGenericDriver());
1113 oldAdapterData.m_strNATNetworkName = wipedOutString(comAdapter.GetNATNetwork());
1114#ifdef VBOX_WITH_CLOUD_NET
1115 oldAdapterData.m_strCloudNetworkName = wipedOutString(comAdapter.GetCloudNetwork());
1116#endif /* VBOX_WITH_CLOUD_NET */
1117#ifdef VBOX_WITH_VMNET
1118 oldAdapterData.m_strHostOnlyNetworkName = wipedOutString(comAdapter.GetHostOnlyNetwork());
1119#endif /* VBOX_WITH_VMNET */
1120 oldAdapterData.m_adapterType = comAdapter.GetAdapterType();
1121 oldAdapterData.m_promiscuousMode = comAdapter.GetPromiscModePolicy();
1122 oldAdapterData.m_strMACAddress = comAdapter.GetMACAddress();
1123 oldAdapterData.m_strGenericProperties = loadGenericProperties(comAdapter);
1124 oldAdapterData.m_fCableConnected = comAdapter.GetCableConnected();
1125 foreach (const QString &strRedirect, comAdapter.GetNATEngine().GetRedirects())
1126 {
1127 /* Gather old forwarding data & cache key: */
1128 const QStringList &forwardingData = strRedirect.split(',');
1129 AssertMsg(forwardingData.size() == 6, ("Redirect rule should be composed of 6 parts!\n"));
1130 const UIDataPortForwardingRule oldForwardingData(forwardingData.at(0),
1131 (KNATProtocol)forwardingData.at(1).toUInt(),
1132 forwardingData.at(2),
1133 forwardingData.at(3).toUInt(),
1134 forwardingData.at(4),
1135 forwardingData.at(5).toUInt());
1136
1137 const QString &strForwardingKey = forwardingData.at(0);
1138 /* Cache old forwarding data: */
1139 m_pCache->child(iSlot).child(strForwardingKey).cacheInitialData(oldForwardingData);
1140 }
1141 }
1142
1143 /* Cache old adapter data: */
1144 m_pCache->child(iSlot).cacheInitialData(oldAdapterData);
1145 }
1146
1147 /* Cache old network data: */
1148 m_pCache->cacheInitialData(oldNetworkData);
1149
1150 /* Upload machine to data: */
1151 UISettingsPageMachine::uploadData(data);
1152}
1153
1154void UIMachineSettingsNetworkPage::getFromCache()
1155{
1156 /* Setup tab order: */
1157 AssertPtrReturnVoid(firstWidget());
1158 setTabOrder(firstWidget(), m_pTabWidget->focusProxy());
1159 QWidget *pLastFocusWidget = m_pTabWidget->focusProxy();
1160
1161 /* For each adapter: */
1162 for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot)
1163 {
1164 /* Get adapter page: */
1165 UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTabWidget->widget(iSlot));
1166
1167 /* Load old adapter data from the cache: */
1168 pTab->getAdapterDataFromCache(m_pCache->child(iSlot));
1169
1170 /* Setup tab order: */
1171 pLastFocusWidget = pTab->setOrderAfter(pLastFocusWidget);
1172 }
1173
1174 /* Apply language settings: */
1175 retranslateUi();
1176
1177 /* Polish page finally: */
1178 polishPage();
1179
1180 /* Revalidate: */
1181 revalidate();
1182}
1183
1184void UIMachineSettingsNetworkPage::putToCache()
1185{
1186 /* Prepare new network data: */
1187 UIDataSettingsMachineNetwork newNetworkData;
1188
1189 /* For each adapter: */
1190 for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot)
1191 {
1192 /* Get adapter page: */
1193 UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTabWidget->widget(iSlot));
1194
1195 /* Gather new adapter data: */
1196 pTab->putAdapterDataToCache(m_pCache->child(iSlot));
1197 }
1198
1199 /* Cache new network data: */
1200 m_pCache->cacheCurrentData(newNetworkData);
1201}
1202
1203void UIMachineSettingsNetworkPage::saveFromCacheTo(QVariant &data)
1204{
1205 /* Fetch data to machine: */
1206 UISettingsPageMachine::fetchData(data);
1207
1208 /* Update network data and failing state: */
1209 setFailed(!saveNetworkData());
1210
1211 /* Upload machine to data: */
1212 UISettingsPageMachine::uploadData(data);
1213}
1214
1215bool UIMachineSettingsNetworkPage::validate(QList<UIValidationMessage> &messages)
1216{
1217 /* Pass by default: */
1218 bool fValid = true;
1219
1220 /* Delegate validation to adapter tabs: */
1221 for (int i = 0; i < m_pTabWidget->count(); ++i)
1222 {
1223 UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTabWidget->widget(i));
1224 AssertMsg(pTab, ("Can't get adapter tab!\n"));
1225 if (!pTab->validate(messages))
1226 fValid = false;
1227 }
1228
1229 /* Return result: */
1230 return fValid;
1231}
1232
1233void UIMachineSettingsNetworkPage::retranslateUi()
1234{
1235 for (int i = 0; i < m_pTabWidget->count(); ++i)
1236 {
1237 UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTabWidget->widget(i));
1238 Assert(pTab);
1239 m_pTabWidget->setTabText(i, pTab->tabTitle());
1240 }
1241}
1242
1243void UIMachineSettingsNetworkPage::polishPage()
1244{
1245 /* Get the count of network adapter tabs: */
1246 for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot)
1247 {
1248 m_pTabWidget->setTabEnabled(iSlot,
1249 isMachineOffline() ||
1250 (isMachineInValidMode() &&
1251 m_pCache->childCount() > iSlot &&
1252 m_pCache->child(iSlot).base().m_fAdapterEnabled));
1253 UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTabWidget->widget(iSlot));
1254 pTab->polishTab();
1255 }
1256}
1257
1258void UIMachineSettingsNetworkPage::sltHandleTabUpdate()
1259{
1260 /* Determine the sender: */
1261 UIMachineSettingsNetwork *pSender = qobject_cast<UIMachineSettingsNetwork*>(sender());
1262 AssertMsg(pSender, ("This slot should be called only through signal<->slot mechanism from one of UIMachineSettingsNetwork tabs!\n"));
1263
1264 /* Determine sender's attachment type: */
1265 const KNetworkAttachmentType enmSenderAttachmentType = pSender->attachmentType();
1266 switch (enmSenderAttachmentType)
1267 {
1268 case KNetworkAttachmentType_Internal:
1269 {
1270 refreshInternalNetworkList();
1271 break;
1272 }
1273 case KNetworkAttachmentType_Generic:
1274 {
1275 refreshGenericDriverList();
1276 break;
1277 }
1278 default:
1279 break;
1280 }
1281
1282 /* Update all the tabs except the sender: */
1283 for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot)
1284 {
1285 /* Get the iterated tab: */
1286 UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTabWidget->widget(iSlot));
1287 AssertMsg(pTab, ("All the tabs of m_pTabWidget should be of the UIMachineSettingsNetwork type!\n"));
1288
1289 /* Update all the tabs (except sender): */
1290 if (pTab != pSender)
1291 pTab->reloadAlternatives();
1292 }
1293}
1294
1295void UIMachineSettingsNetworkPage::sltHandleAdvancedButtonStateChange(bool fExpanded)
1296{
1297 /* Update the advanced button states for all the pages: */
1298 for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot)
1299 {
1300 UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTabWidget->widget(iSlot));
1301 pTab->setAdvancedButtonState(fExpanded);
1302 }
1303}
1304
1305void UIMachineSettingsNetworkPage::prepare()
1306{
1307 /* Prepare cache: */
1308 m_pCache = new UISettingsCacheMachineNetwork;
1309 AssertPtrReturnVoid(m_pCache);
1310
1311 /* Create main layout: */
1312 QVBoxLayout *pLayoutMain = new QVBoxLayout(this);
1313 AssertPtrReturnVoid(pLayoutMain);
1314 {
1315 /* Creating tab-widget: */
1316 m_pTabWidget = new QITabWidget;
1317 AssertPtrReturnVoid(m_pTabWidget);
1318 {
1319 /* How many adapters to display: */
1320 /** @todo r=klaus this needs to be done based on the actual chipset type of the VM,
1321 * but in this place the m_machine field isn't set yet. My observation (on Linux)
1322 * is that the limitation to 4 isn't necessary any more, but this needs to be checked
1323 * on all platforms to be certain that it's usable everywhere. */
1324 const ulong uCount = qMin((ULONG)4, uiCommon().virtualBox().GetSystemProperties().GetMaxNetworkAdapters(KChipsetType_PIIX3));
1325
1326 /* Create corresponding adapter tabs: */
1327 for (ulong uSlot = 0; uSlot < uCount; ++uSlot)
1328 {
1329 /* Create adapter tab: */
1330 UIMachineSettingsNetwork *pTab = new UIMachineSettingsNetwork(this);
1331 AssertPtrReturnVoid(pTab);
1332 {
1333 /* Configure tab: */
1334 connect(pTab, &UIMachineSettingsNetwork::sigNotifyAdvancedButtonStateChange,
1335 this, &UIMachineSettingsNetworkPage::sltHandleAdvancedButtonStateChange);
1336
1337 /* Add tab into tab-widget: */
1338 m_pTabWidget->addTab(pTab, pTab->tabTitle());
1339 }
1340 }
1341
1342 /* Add tab-widget into layout: */
1343 pLayoutMain->addWidget(m_pTabWidget);
1344 }
1345 }
1346}
1347
1348void UIMachineSettingsNetworkPage::cleanup()
1349{
1350 /* Cleanup cache: */
1351 delete m_pCache;
1352 m_pCache = 0;
1353}
1354
1355void UIMachineSettingsNetworkPage::refreshBridgedAdapterList()
1356{
1357 /* Reload bridged adapters: */
1358 m_bridgedAdapterList = UINetworkAttachmentEditor::bridgedAdapters();
1359}
1360
1361void UIMachineSettingsNetworkPage::refreshInternalNetworkList(bool fFullRefresh /* = false */)
1362{
1363 /* Reload internal network list: */
1364 m_internalNetworkList.clear();
1365 /* Get internal network names from other VMs: */
1366 if (fFullRefresh)
1367 m_internalNetworkListSaved = UINetworkAttachmentEditor::internalNetworks();
1368 m_internalNetworkList << m_internalNetworkListSaved;
1369 /* Append internal network list with names from all the tabs: */
1370 for (int iTab = 0; iTab < m_pTabWidget->count(); ++iTab)
1371 {
1372 UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTabWidget->widget(iTab));
1373 if (pTab)
1374 {
1375 const QString strName = pTab->alternativeName(KNetworkAttachmentType_Internal);
1376 if (!strName.isEmpty() && !m_internalNetworkList.contains(strName))
1377 m_internalNetworkList << strName;
1378 }
1379 }
1380}
1381
1382#ifdef VBOX_WITH_CLOUD_NET
1383void UIMachineSettingsNetworkPage::refreshCloudNetworkList()
1384{
1385 /* Reload cloud network list: */
1386 m_cloudNetworkList = UINetworkAttachmentEditor::cloudNetworks();
1387}
1388#endif /* VBOX_WITH_CLOUD_NET */
1389
1390#ifdef VBOX_WITH_VMNET
1391void UIMachineSettingsNetworkPage::refreshHostOnlyNetworkList()
1392{
1393 /* Reload host-only network list: */
1394 m_hostOnlyNetworkList = UINetworkAttachmentEditor::hostOnlyNetworks();
1395}
1396#endif /* VBOX_WITH_VMNET */
1397
1398void UIMachineSettingsNetworkPage::refreshHostInterfaceList()
1399{
1400 /* Reload host interfaces: */
1401 m_hostInterfaceList = UINetworkAttachmentEditor::hostInterfaces();
1402}
1403
1404void UIMachineSettingsNetworkPage::refreshGenericDriverList(bool fFullRefresh /* = false */)
1405{
1406 /* Load generic driver list: */
1407 m_genericDriverList.clear();
1408 /* Get generic driver names from other VMs: */
1409 if (fFullRefresh)
1410 m_genericDriverListSaved = UINetworkAttachmentEditor::genericDrivers();
1411 m_genericDriverList << m_genericDriverListSaved;
1412 /* Append generic driver list with names from all the tabs: */
1413 for (int iTab = 0; iTab < m_pTabWidget->count(); ++iTab)
1414 {
1415 UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTabWidget->widget(iTab));
1416 if (pTab)
1417 {
1418 const QString strName = pTab->alternativeName(KNetworkAttachmentType_Generic);
1419 if (!strName.isEmpty() && !m_genericDriverList.contains(strName))
1420 m_genericDriverList << strName;
1421 }
1422 }
1423}
1424
1425void UIMachineSettingsNetworkPage::refreshNATNetworkList()
1426{
1427 /* Reload nat networks: */
1428 m_natNetworkList = UINetworkAttachmentEditor::natNetworks();
1429}
1430
1431/* static */
1432QString UIMachineSettingsNetworkPage::loadGenericProperties(const CNetworkAdapter &adapter)
1433{
1434 /* Prepare formatted string: */
1435 QVector<QString> names;
1436 QVector<QString> props;
1437 props = adapter.GetProperties(QString(), names);
1438 QString strResult;
1439 /* Load generic properties: */
1440 for (int i = 0; i < names.size(); ++i)
1441 {
1442 strResult += names[i] + "=" + props[i];
1443 if (i < names.size() - 1)
1444 strResult += "\n";
1445 }
1446 /* Return formatted string: */
1447 return strResult;
1448}
1449
1450/* static */
1451bool UIMachineSettingsNetworkPage::saveGenericProperties(CNetworkAdapter &comAdapter, const QString &strProperties)
1452{
1453 /* Prepare result: */
1454 bool fSuccess = true;
1455 /* Save generic properties: */
1456 if (fSuccess)
1457 {
1458 /* Acquire 'added' properties: */
1459 const QStringList newProps = strProperties.split("\n");
1460
1461 /* Insert 'added' properties: */
1462 QHash<QString, QString> hash;
1463 for (int i = 0; fSuccess && i < newProps.size(); ++i)
1464 {
1465 /* Parse property line: */
1466 const QString strLine = newProps.at(i);
1467 const QString strKey = strLine.section('=', 0, 0);
1468 const QString strVal = strLine.section('=', 1, -1);
1469 if (strKey.isEmpty() || strVal.isEmpty())
1470 continue;
1471 /* Save property in the adapter and the hash: */
1472 comAdapter.SetProperty(strKey, strVal);
1473 fSuccess = comAdapter.isOk();
1474 hash[strKey] = strVal;
1475 }
1476
1477 /* Acquire actual properties ('added' and 'removed'): */
1478 QVector<QString> names;
1479 QVector<QString> props;
1480 if (fSuccess)
1481 {
1482 props = comAdapter.GetProperties(QString(), names);
1483 fSuccess = comAdapter.isOk();
1484 }
1485
1486 /* Exclude 'removed' properties: */
1487 for (int i = 0; fSuccess && i < names.size(); ++i)
1488 {
1489 /* Get property name and value: */
1490 const QString strKey = names.at(i);
1491 const QString strVal = props.at(i);
1492 if (strVal == hash.value(strKey))
1493 continue;
1494 /* Remove property from the adapter: */
1495 // Actually we are _replacing_ property value,
1496 // not _removing_ it at all, but we are replacing it
1497 // with default constructed value, which is QString().
1498 comAdapter.SetProperty(strKey, hash.value(strKey));
1499 fSuccess = comAdapter.isOk();
1500 }
1501 }
1502 /* Return result: */
1503 return fSuccess;
1504}
1505
1506bool UIMachineSettingsNetworkPage::saveNetworkData()
1507{
1508 /* Prepare result: */
1509 bool fSuccess = true;
1510 /* Save network settings from the cache: */
1511 if (fSuccess && isMachineInValidMode() && m_pCache->wasChanged())
1512 {
1513 /* For each adapter: */
1514 for (int iSlot = 0; fSuccess && iSlot < m_pTabWidget->count(); ++iSlot)
1515 fSuccess = saveAdapterData(iSlot);
1516 }
1517 /* Return result: */
1518 return fSuccess;
1519}
1520
1521bool UIMachineSettingsNetworkPage::saveAdapterData(int iSlot)
1522{
1523 /* Prepare result: */
1524 bool fSuccess = true;
1525 /* Save adapter settings from the cache: */
1526 if (fSuccess && m_pCache->child(iSlot).wasChanged())
1527 {
1528 /* Get old network data from the cache: */
1529 const UIDataSettingsMachineNetworkAdapter &oldAdapterData = m_pCache->child(iSlot).base();
1530 /* Get new network data from the cache: */
1531 const UIDataSettingsMachineNetworkAdapter &newAdapterData = m_pCache->child(iSlot).data();
1532
1533 /* Get network adapter for further activities: */
1534 CNetworkAdapter comAdapter = m_machine.GetNetworkAdapter(iSlot);
1535 fSuccess = m_machine.isOk() && comAdapter.isNotNull();
1536
1537 /* Show error message if necessary: */
1538 if (!fSuccess)
1539 notifyOperationProgressError(UIErrorString::formatErrorInfo(m_machine));
1540 else
1541 {
1542 /* Save whether the adapter is enabled: */
1543 if (fSuccess && isMachineOffline() && newAdapterData.m_fAdapterEnabled != oldAdapterData.m_fAdapterEnabled)
1544 {
1545 comAdapter.SetEnabled(newAdapterData.m_fAdapterEnabled);
1546 fSuccess = comAdapter.isOk();
1547 }
1548 /* Save adapter type: */
1549 if (fSuccess && isMachineOffline() && newAdapterData.m_adapterType != oldAdapterData.m_adapterType)
1550 {
1551 comAdapter.SetAdapterType(newAdapterData.m_adapterType);
1552 fSuccess = comAdapter.isOk();
1553 }
1554 /* Save adapter MAC address: */
1555 if (fSuccess && isMachineOffline() && newAdapterData.m_strMACAddress != oldAdapterData.m_strMACAddress)
1556 {
1557 comAdapter.SetMACAddress(newAdapterData.m_strMACAddress);
1558 fSuccess = comAdapter.isOk();
1559 }
1560 /* Save adapter attachment type: */
1561 switch (newAdapterData.m_attachmentType)
1562 {
1563 case KNetworkAttachmentType_Bridged:
1564 {
1565 if (fSuccess && newAdapterData.m_strBridgedAdapterName != oldAdapterData.m_strBridgedAdapterName)
1566 {
1567 comAdapter.SetBridgedInterface(newAdapterData.m_strBridgedAdapterName);
1568 fSuccess = comAdapter.isOk();
1569 }
1570 break;
1571 }
1572 case KNetworkAttachmentType_Internal:
1573 {
1574 if (fSuccess && newAdapterData.m_strInternalNetworkName != oldAdapterData.m_strInternalNetworkName)
1575 {
1576 comAdapter.SetInternalNetwork(newAdapterData.m_strInternalNetworkName);
1577 fSuccess = comAdapter.isOk();
1578 }
1579 break;
1580 }
1581 case KNetworkAttachmentType_HostOnly:
1582 {
1583 if (fSuccess && newAdapterData.m_strHostInterfaceName != oldAdapterData.m_strHostInterfaceName)
1584 {
1585 comAdapter.SetHostOnlyInterface(newAdapterData.m_strHostInterfaceName);
1586 fSuccess = comAdapter.isOk();
1587 }
1588 break;
1589 }
1590 case KNetworkAttachmentType_Generic:
1591 {
1592 if (fSuccess && newAdapterData.m_strGenericDriverName != oldAdapterData.m_strGenericDriverName)
1593 {
1594 comAdapter.SetGenericDriver(newAdapterData.m_strGenericDriverName);
1595 fSuccess = comAdapter.isOk();
1596 }
1597 if (fSuccess && newAdapterData.m_strGenericProperties != oldAdapterData.m_strGenericProperties)
1598 fSuccess = saveGenericProperties(comAdapter, newAdapterData.m_strGenericProperties);
1599 break;
1600 }
1601 case KNetworkAttachmentType_NATNetwork:
1602 {
1603 if (fSuccess && newAdapterData.m_strNATNetworkName != oldAdapterData.m_strNATNetworkName)
1604 {
1605 comAdapter.SetNATNetwork(newAdapterData.m_strNATNetworkName);
1606 fSuccess = comAdapter.isOk();
1607 }
1608 break;
1609 }
1610#ifdef VBOX_WITH_CLOUD_NET
1611 case KNetworkAttachmentType_Cloud:
1612 {
1613 if (fSuccess && newAdapterData.m_strCloudNetworkName != oldAdapterData.m_strCloudNetworkName)
1614 {
1615 comAdapter.SetCloudNetwork(newAdapterData.m_strCloudNetworkName);
1616 fSuccess = comAdapter.isOk();
1617 }
1618 break;
1619 }
1620#endif /* VBOX_WITH_CLOUD_NET */
1621#ifdef VBOX_WITH_VMNET
1622 case KNetworkAttachmentType_HostOnlyNetwork:
1623 {
1624 if (fSuccess && newAdapterData.m_strHostOnlyNetworkName != oldAdapterData.m_strHostOnlyNetworkName)
1625 {
1626 comAdapter.SetHostOnlyNetwork(newAdapterData.m_strHostOnlyNetworkName);
1627 fSuccess = comAdapter.isOk();
1628 }
1629 break;
1630 }
1631#endif /* VBOX_WITH_VMNET */
1632 default:
1633 break;
1634 }
1635 if (fSuccess && newAdapterData.m_attachmentType != oldAdapterData.m_attachmentType)
1636 {
1637 comAdapter.SetAttachmentType(newAdapterData.m_attachmentType);
1638 fSuccess = comAdapter.isOk();
1639 }
1640 /* Save adapter promiscuous mode: */
1641 if (fSuccess && newAdapterData.m_promiscuousMode != oldAdapterData.m_promiscuousMode)
1642 {
1643 comAdapter.SetPromiscModePolicy(newAdapterData.m_promiscuousMode);
1644 fSuccess = comAdapter.isOk();
1645 }
1646 /* Save whether the adapter cable connected: */
1647 if (fSuccess && newAdapterData.m_fCableConnected != oldAdapterData.m_fCableConnected)
1648 {
1649 comAdapter.SetCableConnected(newAdapterData.m_fCableConnected);
1650 fSuccess = comAdapter.isOk();
1651 }
1652
1653 /* Get NAT engine for further activities: */
1654 CNATEngine comEngine;
1655 if (fSuccess)
1656 {
1657 comEngine = comAdapter.GetNATEngine();
1658 fSuccess = comAdapter.isOk() && comEngine.isNotNull();
1659 }
1660
1661 /* Show error message if necessary: */
1662 if (!fSuccess)
1663 notifyOperationProgressError(UIErrorString::formatErrorInfo(comAdapter));
1664 else
1665 {
1666 /* Save adapter port forwarding rules: */
1667 if ( oldAdapterData.m_attachmentType == KNetworkAttachmentType_NAT
1668 || newAdapterData.m_attachmentType == KNetworkAttachmentType_NAT)
1669 {
1670 /* For each rule: */
1671 for (int iRule = 0; fSuccess && iRule < m_pCache->child(iSlot).childCount(); ++iRule)
1672 {
1673 /* Get rule cache: */
1674 const UISettingsCachePortForwardingRule &ruleCache = m_pCache->child(iSlot).child(iRule);
1675
1676 /* Remove rule marked for 'remove' or 'update': */
1677 if (ruleCache.wasRemoved() || ruleCache.wasUpdated())
1678 {
1679 comEngine.RemoveRedirect(ruleCache.base().name);
1680 fSuccess = comEngine.isOk();
1681 }
1682 }
1683 for (int iRule = 0; fSuccess && iRule < m_pCache->child(iSlot).childCount(); ++iRule)
1684 {
1685 /* Get rule cache: */
1686 const UISettingsCachePortForwardingRule &ruleCache = m_pCache->child(iSlot).child(iRule);
1687
1688 /* Create rule marked for 'create' or 'update': */
1689 if (ruleCache.wasCreated() || ruleCache.wasUpdated())
1690 {
1691 comEngine.AddRedirect(ruleCache.data().name, ruleCache.data().protocol,
1692 ruleCache.data().hostIp, ruleCache.data().hostPort.value(),
1693 ruleCache.data().guestIp, ruleCache.data().guestPort.value());
1694 fSuccess = comEngine.isOk();
1695 }
1696 }
1697
1698 /* Show error message if necessary: */
1699 if (!fSuccess)
1700 notifyOperationProgressError(UIErrorString::formatErrorInfo(comEngine));
1701 }
1702 }
1703 }
1704 }
1705 /* Return result: */
1706 return fSuccess;
1707}
1708
1709# 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