VirtualBox

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

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

FE/Qt: bugref:10100. Some variable renaming.

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