VirtualBox

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

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

FE/Qt: bugref:6899: VM settings: Replacing what's this tags with tool-tips.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 68.4 KB
Line 
1/* $Id: UIMachineSettingsNetwork.cpp 93829 2022-02-17 13:30:31Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIMachineSettingsNetwork class implementation.
4 */
5
6/*
7 * Copyright (C) 2008-2022 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->setToolTip(tr("When checked, plugs this virtual network adapter into the virtual machine."));
658 m_pCheckBoxAdapter->setText(tr("&Enable Network Adapter"));
659 m_pLabelAttachmentType->setText(tr("&Attached to:"));
660 iFirstColumnWidth = qMax(iFirstColumnWidth, m_pLabelAttachmentType->minimumSizeHint().width());
661 m_pEditorAttachmentType->setToolTip(tr("Selects how this virtual adapter is attached to the real network of the Host OS."));
662 m_pLabelNetworkName->setText(tr("&Name:"));
663 iFirstColumnWidth = qMax(iFirstColumnWidth, m_pLabelNetworkName->minimumSizeHint().width());
664 m_pButtonAdvanced->setText(tr("A&dvanced"));
665 m_pButtonAdvanced->setToolTip(tr("Shows additional network adapter options."));
666 m_pLabelAdapterType->setText(tr("Adapter &Type:"));
667 iFirstColumnWidth = qMax(iFirstColumnWidth, m_pLabelAdapterType->minimumSizeHint().width());
668 m_pComboAdapterType->setToolTip(tr("Selects the type of the virtual network adapter. Depending on this value, VirtualBox "
669 "will provide different network hardware to the virtual machine."));
670 m_pLabelPromiscuousMode->setText(tr("&Promiscuous Mode:"));
671 iFirstColumnWidth = qMax(iFirstColumnWidth, m_pLabelPromiscuousMode->minimumSizeHint().width());
672 m_pComboPromiscuousMode->setToolTip(tr("Selects the promiscuous mode policy of the network adapter when attached to an "
673 "internal network, host only network or a bridge."));
674 m_pLabelMAC->setText(tr("&MAC Address:"));
675 iFirstColumnWidth = qMax(iFirstColumnWidth, m_pLabelMAC->minimumSizeHint().width());
676 m_pEditorMAC->setToolTip(tr("Holds the MAC address of this adapter. It contains exactly 12 characters chosen from {0-9,A-F}. "
677 "Note that the second character must be an even digit."));
678 m_pButtonMAC->setToolTip(tr("Generates a new random MAC address."));
679 m_pLabelGenericProperties->setText(tr("Generic Properties:"));
680 m_pEditorGenericProperties->setToolTip(tr("Holds the configuration settings for the network attachment driver. The settings "
681 "should be of the form <b>name=value</b> and will depend on the driver. "
682 "Use <b>shift-enter</b> to add a new entry."));
683 m_pCheckBoxCableConnected->setToolTip(tr("When checked, the virtual network cable is plugged in."));
684 m_pCheckBoxCableConnected->setText(tr("&Cable Connected"));
685 m_pButtonPortForwarding->setToolTip(tr("Displays a window to configure port forwarding rules."));
686 m_pButtonPortForwarding->setText(tr("&Port Forwarding"));
687
688 /* Translate combo-boxes content: */
689 populateComboboxes();
690
691 /* Translate attachment info: */
692 sltHandleAttachmentTypeChange();
693 /* Set the minimum width of the 1st column to size longest label to align all labels: */
694 m_pLayoutAdapterSettings->setColumnMinimumWidth(0, iFirstColumnWidth);
695}
696
697void UIMachineSettingsNetwork::sltHandleAdapterActivityChange()
698{
699 /* Update availability: */
700 m_pWidgetAdapterSettings->setEnabled(m_pCheckBoxAdapter->isChecked());
701
702 /* Generate a new MAC address in case this adapter was never enabled before: */
703 if ( m_pCheckBoxAdapter->isChecked()
704 && m_pEditorMAC->text().isEmpty())
705 sltGenerateMac();
706
707 /* Revalidate: */
708 m_pParent->revalidate();
709}
710
711void UIMachineSettingsNetwork::sltHandleAttachmentTypeChange()
712{
713 /* Update alternative-name combo-box availability: */
714 m_pLabelNetworkName->setEnabled(attachmentType() != KNetworkAttachmentType_Null &&
715 attachmentType() != KNetworkAttachmentType_NAT);
716 /* Update promiscuous-mode combo-box availability: */
717 m_pLabelPromiscuousMode->setEnabled(attachmentType() != KNetworkAttachmentType_Null &&
718 attachmentType() != KNetworkAttachmentType_Generic &&
719 attachmentType() != KNetworkAttachmentType_NAT);
720 m_pComboPromiscuousMode->setEnabled(attachmentType() != KNetworkAttachmentType_Null &&
721 attachmentType() != KNetworkAttachmentType_Generic &&
722 attachmentType() != KNetworkAttachmentType_NAT);
723 /* Update generic-properties editor visibility: */
724 m_pLabelGenericProperties->setVisible(attachmentType() == KNetworkAttachmentType_Generic &&
725 m_pButtonAdvanced->isExpanded());
726 m_pEditorGenericProperties->setVisible(attachmentType() == KNetworkAttachmentType_Generic &&
727 m_pButtonAdvanced->isExpanded());
728 /* Update forwarding rules button availability: */
729 m_pButtonPortForwarding->setEnabled(attachmentType() == KNetworkAttachmentType_NAT);
730
731 /* Revalidate: */
732 m_pParent->revalidate();
733}
734
735void UIMachineSettingsNetwork::sltHandleAlternativeNameChange()
736{
737 /* Remember new name if its changed,
738 * Call for other pages update, if necessary: */
739 switch (attachmentType())
740 {
741 case KNetworkAttachmentType_Internal:
742 {
743 if (!m_pEditorAttachmentType->valueName(KNetworkAttachmentType_Internal).isNull())
744 emit sigTabUpdated();
745 break;
746 }
747 case KNetworkAttachmentType_Generic:
748 {
749 if (!m_pEditorAttachmentType->valueName(KNetworkAttachmentType_Generic).isNull())
750 emit sigTabUpdated();
751 break;
752 }
753 default:
754 break;
755 }
756
757 /* Revalidate: */
758 m_pParent->revalidate();
759}
760
761void UIMachineSettingsNetwork::sltHandleAdvancedButtonStateChange()
762{
763 /* Handle the button state change: */
764 handleAdvancedButtonStateChange();
765
766 /* Notify listeners about the button state change: */
767 emit sigNotifyAdvancedButtonStateChange(m_pButtonAdvanced->isExpanded());
768}
769
770void UIMachineSettingsNetwork::sltGenerateMac()
771{
772 m_pEditorMAC->setText(uiCommon().host().GenerateMACAddress());
773}
774
775void UIMachineSettingsNetwork::sltOpenPortForwardingDlg()
776{
777 UIMachineSettingsPortForwardingDlg dlg(this, m_portForwardingRules);
778 if (dlg.exec() == QDialog::Accepted)
779 m_portForwardingRules = dlg.rules();
780}
781
782void UIMachineSettingsNetwork::prepare()
783{
784 /* Prepare everything: */
785 prepareWidgets();
786 prepareConnections();
787
788 /* Apply language settings: */
789 retranslateUi();
790}
791
792void UIMachineSettingsNetwork::prepareWidgets()
793{
794 /* Prepare main layout: */
795 QGridLayout *pLayoutMain = new QGridLayout(this);
796 if (pLayoutMain)
797 {
798 pLayoutMain->setRowStretch(2, 1);
799
800 /* Prepare adapter check-box: */
801 m_pCheckBoxAdapter = new QCheckBox(this);
802 if (m_pCheckBoxAdapter)
803 pLayoutMain->addWidget(m_pCheckBoxAdapter, 0, 0, 1, 2);
804
805 /* Prepare 20-px shifting spacer: */
806 QSpacerItem *pSpacerItem = new QSpacerItem(20, 0, QSizePolicy::Fixed, QSizePolicy::Minimum);
807 if (pSpacerItem)
808 pLayoutMain->addItem(pSpacerItem, 1, 0);
809
810 /* Prepare adapter settings widget: */
811 m_pWidgetAdapterSettings = new QWidget(this);
812 if (m_pWidgetAdapterSettings)
813 {
814 /* Prepare adapter settings widget layout: */
815 m_pLayoutAdapterSettings = new QGridLayout(m_pWidgetAdapterSettings);
816 if (m_pLayoutAdapterSettings)
817 {
818 m_pLayoutAdapterSettings->setContentsMargins(0, 0, 0, 0);
819 m_pLayoutAdapterSettings->setColumnStretch(2, 1);
820
821 /* Prepare attachment type label: */
822 m_pLabelAttachmentType = new QLabel(m_pWidgetAdapterSettings);
823 if (m_pLabelAttachmentType)
824 {
825 m_pLabelAttachmentType->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
826 m_pLayoutAdapterSettings->addWidget(m_pLabelAttachmentType, 0, 0);
827 }
828 /* Prepare adapter name label: */
829 m_pLabelNetworkName = new QLabel(m_pWidgetAdapterSettings);
830 if (m_pLabelNetworkName)
831 {
832 m_pLabelNetworkName->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
833 m_pLayoutAdapterSettings->addWidget(m_pLabelNetworkName, 1, 0);
834 }
835 /* Prepare attachment type editor: */
836 m_pEditorAttachmentType = new UINetworkAttachmentEditor(m_pWidgetAdapterSettings);
837 if (m_pEditorAttachmentType)
838 {
839 if (m_pLabelAttachmentType)
840 m_pLabelAttachmentType->setBuddy(m_pEditorAttachmentType->focusProxy1());
841 if (m_pLabelNetworkName)
842 m_pLabelNetworkName->setBuddy(m_pEditorAttachmentType->focusProxy2());
843
844 m_pLayoutAdapterSettings->addWidget(m_pEditorAttachmentType, 0, 1, 2, 3);
845 }
846
847 /* Prepare advanced arrow button: */
848 m_pButtonAdvanced = new QIArrowButtonSwitch(m_pWidgetAdapterSettings);
849 if (m_pButtonAdvanced)
850 {
851 const QStyle *pStyle = QApplication::style();
852 const int iIconMetric = (int)(pStyle->pixelMetric(QStyle::PM_SmallIconSize) * .625);
853 m_pButtonAdvanced->setIconSize(QSize(iIconMetric, iIconMetric));
854 m_pButtonAdvanced->setIcons(UIIconPool::iconSet(":/arrow_right_10px.png"),
855 UIIconPool::iconSet(":/arrow_down_10px.png"));
856
857 m_pLayoutAdapterSettings->addWidget(m_pButtonAdvanced, 2, 0);
858 }
859
860 /* Create the container widget for advanced settings related widgets: */
861 m_pWidgetAdvancedSettings = new QWidget;
862 m_pLayoutAdapterSettings->addWidget(m_pWidgetAdvancedSettings, 3, 0, 4, 3, Qt::AlignLeft);
863 QGridLayout *pLayoutAdvancedSettings = new QGridLayout(m_pWidgetAdvancedSettings);
864 pLayoutAdvancedSettings->setContentsMargins(0, 0, 0, 0);
865 prepareAdvancedSettingsWidgets(pLayoutAdvancedSettings);
866 }
867
868 pLayoutMain->addWidget(m_pWidgetAdapterSettings, 1, 1);
869 }
870 }
871}
872
873void UIMachineSettingsNetwork::prepareConnections()
874{
875 connect(m_pCheckBoxAdapter, &QCheckBox::toggled, this, &UIMachineSettingsNetwork::sltHandleAdapterActivityChange);
876 connect(m_pEditorAttachmentType, &UINetworkAttachmentEditor::sigValueTypeChanged,
877 this, &UIMachineSettingsNetwork::sltHandleAttachmentTypeChange);
878 connect(m_pEditorAttachmentType, &UINetworkAttachmentEditor::sigValueNameChanged,
879 this, &UIMachineSettingsNetwork::sltHandleAlternativeNameChange);
880 connect(m_pButtonAdvanced, &QIArrowButtonSwitch::sigClicked, this, &UIMachineSettingsNetwork::sltHandleAdvancedButtonStateChange);
881 connect(m_pEditorMAC, &QILineEdit::textChanged, m_pParent, &UIMachineSettingsNetworkPage::revalidate);
882 connect(m_pButtonMAC, &QIToolButton::clicked, this, &UIMachineSettingsNetwork::sltGenerateMac);
883 connect(m_pButtonPortForwarding, &QPushButton::clicked, this, &UIMachineSettingsNetwork::sltOpenPortForwardingDlg);
884 connect(this, &UIMachineSettingsNetwork::sigTabUpdated, m_pParent, &UIMachineSettingsNetworkPage::sltHandleTabUpdate);
885}
886
887void UIMachineSettingsNetwork::prepareAdvancedSettingsWidgets(QGridLayout *pLayout)
888{
889 AssertPtrReturnVoid(pLayout);
890
891 /* Prepare adapter type label: */
892 m_pLabelAdapterType = new QLabel(m_pWidgetAdapterSettings);
893 if (m_pLabelAdapterType)
894 {
895 m_pLabelAdapterType->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
896 pLayout->addWidget(m_pLabelAdapterType, 0, 0);
897 }
898 /* Prepare adapter type combo: */
899 m_pComboAdapterType = new QComboBox(m_pWidgetAdapterSettings);
900 if (m_pComboAdapterType)
901 {
902 if (m_pLabelAdapterType)
903 m_pLabelAdapterType->setBuddy(m_pComboAdapterType);
904 pLayout->addWidget(m_pComboAdapterType, 0, 1, 1, 3);
905 }
906
907 /* Prepare promiscuous mode label: */
908 m_pLabelPromiscuousMode = new QLabel(m_pWidgetAdapterSettings);
909 if (m_pLabelPromiscuousMode)
910 {
911 m_pLabelPromiscuousMode->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
912 pLayout->addWidget(m_pLabelPromiscuousMode, 1, 0);
913 }
914 /* Prepare promiscuous mode combo: */
915 m_pComboPromiscuousMode = new QComboBox(m_pWidgetAdapterSettings);
916 if (m_pComboPromiscuousMode)
917 {
918 if (m_pLabelPromiscuousMode)
919 m_pLabelPromiscuousMode->setBuddy(m_pComboPromiscuousMode);
920 pLayout->addWidget(m_pComboPromiscuousMode, 1, 1, 1, 3);
921 }
922
923 /* Prepare MAC label: */
924 m_pLabelMAC = new QLabel(m_pWidgetAdapterSettings);
925 if (m_pLabelMAC)
926 {
927 m_pLabelMAC->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
928 pLayout->addWidget(m_pLabelMAC, 2, 0);
929 }
930 /* Prepare MAC editor: */
931 m_pEditorMAC = new QILineEdit(m_pWidgetAdapterSettings);
932 if (m_pEditorMAC)
933 {
934 if (m_pLabelMAC)
935 m_pLabelMAC->setBuddy(m_pEditorMAC);
936 m_pEditorMAC->setAllowToCopyContentsWhenDisabled(true);
937 m_pEditorMAC->setValidator(new QRegExpValidator(QRegExp("[0-9A-Fa-f]{12}"), this));
938 m_pEditorMAC->setMinimumWidthByText(QString().fill('0', 12));
939
940 pLayout->addWidget(m_pEditorMAC, 2, 1, 1, 2);
941 }
942 /* Prepare MAC button: */
943 m_pButtonMAC = new QIToolButton(m_pWidgetAdapterSettings);
944 if (m_pButtonMAC)
945 {
946 m_pButtonMAC->setIcon(UIIconPool::iconSet(":/refresh_16px.png"));
947 pLayout->addWidget(m_pButtonMAC, 2, 3);
948 }
949
950 /* Prepare MAC label: */
951 m_pLabelGenericProperties = new QLabel(m_pWidgetAdapterSettings);
952 if (m_pLabelGenericProperties)
953 {
954 m_pLabelGenericProperties->setAlignment(Qt::AlignRight | Qt::AlignTop);
955 pLayout->addWidget(m_pLabelGenericProperties, 3, 0);
956 }
957 /* Prepare MAC editor: */
958 m_pEditorGenericProperties = new QTextEdit(m_pWidgetAdapterSettings);
959 if (m_pEditorGenericProperties)
960 pLayout->addWidget(m_pEditorGenericProperties, 3, 1, 1, 3);
961
962 /* Prepare cable connected check-box: */
963 m_pCheckBoxCableConnected = new QCheckBox(m_pWidgetAdapterSettings);
964 if (m_pCheckBoxCableConnected)
965 pLayout->addWidget(m_pCheckBoxCableConnected, 4, 1, 1, 2);
966
967 /* Prepare port forwarding button: */
968 m_pButtonPortForwarding = new QPushButton(m_pWidgetAdapterSettings);
969 if (m_pButtonPortForwarding)
970 pLayout->addWidget(m_pButtonPortForwarding, 5, 1);
971}
972
973void UIMachineSettingsNetwork::populateComboboxes()
974{
975 /* Adapter names: */
976 {
977 reloadAlternatives();
978 }
979
980 /* Adapter type: */
981 {
982 /* Clear the adapter type combo-box: */
983 m_pComboAdapterType->clear();
984
985 /* Load currently supported network adapter types: */
986 CSystemProperties comProperties = uiCommon().virtualBox().GetSystemProperties();
987 QVector<KNetworkAdapterType> supportedTypes = comProperties.GetSupportedNetworkAdapterTypes();
988 /* Take currently requested type into account if it's sane: */
989 if (!supportedTypes.contains(m_enmAdapterType) && m_enmAdapterType != KNetworkAdapterType_Null)
990 supportedTypes.prepend(m_enmAdapterType);
991
992 /* Populate adapter types: */
993 int iAdapterTypeIndex = 0;
994 foreach (const KNetworkAdapterType &enmType, supportedTypes)
995 {
996 m_pComboAdapterType->insertItem(iAdapterTypeIndex, gpConverter->toString(enmType));
997 m_pComboAdapterType->setItemData(iAdapterTypeIndex, QVariant::fromValue(enmType));
998 m_pComboAdapterType->setItemData(iAdapterTypeIndex, m_pComboAdapterType->itemText(iAdapterTypeIndex), Qt::ToolTipRole);
999 ++iAdapterTypeIndex;
1000 }
1001
1002 /* Choose requested adapter type: */
1003 const int iIndex = m_pComboAdapterType->findData(m_enmAdapterType);
1004 m_pComboAdapterType->setCurrentIndex(iIndex != -1 ? iIndex : 0);
1005 }
1006
1007 /* Promiscuous Mode type: */
1008 {
1009 /* Remember the currently selected promiscuous mode type: */
1010 int iCurrentPromiscuousMode = m_pComboPromiscuousMode->currentIndex();
1011
1012 /* Clear the promiscuous mode combo-box: */
1013 m_pComboPromiscuousMode->clear();
1014
1015 /* Populate promiscuous modes: */
1016 int iPromiscuousModeIndex = 0;
1017 m_pComboPromiscuousMode->insertItem(iPromiscuousModeIndex, gpConverter->toString(KNetworkAdapterPromiscModePolicy_Deny));
1018 m_pComboPromiscuousMode->setItemData(iPromiscuousModeIndex, KNetworkAdapterPromiscModePolicy_Deny);
1019 m_pComboPromiscuousMode->setItemData(iPromiscuousModeIndex, m_pComboPromiscuousMode->itemText(iPromiscuousModeIndex), Qt::ToolTipRole);
1020 ++iPromiscuousModeIndex;
1021 m_pComboPromiscuousMode->insertItem(iPromiscuousModeIndex, gpConverter->toString(KNetworkAdapterPromiscModePolicy_AllowNetwork));
1022 m_pComboPromiscuousMode->setItemData(iPromiscuousModeIndex, KNetworkAdapterPromiscModePolicy_AllowNetwork);
1023 m_pComboPromiscuousMode->setItemData(iPromiscuousModeIndex, m_pComboPromiscuousMode->itemText(iPromiscuousModeIndex), Qt::ToolTipRole);
1024 ++iPromiscuousModeIndex;
1025 m_pComboPromiscuousMode->insertItem(iPromiscuousModeIndex, gpConverter->toString(KNetworkAdapterPromiscModePolicy_AllowAll));
1026 m_pComboPromiscuousMode->setItemData(iPromiscuousModeIndex, KNetworkAdapterPromiscModePolicy_AllowAll);
1027 m_pComboPromiscuousMode->setItemData(iPromiscuousModeIndex, m_pComboPromiscuousMode->itemText(iPromiscuousModeIndex), Qt::ToolTipRole);
1028 ++iPromiscuousModeIndex;
1029
1030 /* Restore the previously selected promiscuous mode type: */
1031 m_pComboPromiscuousMode->setCurrentIndex(iCurrentPromiscuousMode == -1 ? 0 : iCurrentPromiscuousMode);
1032 }
1033}
1034
1035void UIMachineSettingsNetwork::handleAdvancedButtonStateChange()
1036{
1037 /* Update visibility of advanced options: */
1038 m_pWidgetAdvancedSettings->setVisible(m_pButtonAdvanced->isExpanded());
1039}
1040
1041/* static */
1042int UIMachineSettingsNetwork::position(QComboBox *pComboBox, int iData)
1043{
1044 const int iPosition = pComboBox->findData(iData);
1045 return iPosition == -1 ? 0 : iPosition;
1046}
1047
1048/* static */
1049int UIMachineSettingsNetwork::position(QComboBox *pComboBox, const QString &strText)
1050{
1051 const int iPosition = pComboBox->findText(strText);
1052 return iPosition == -1 ? 0 : iPosition;
1053}
1054
1055
1056/*********************************************************************************************************************************
1057* Class UIMachineSettingsNetworkPage implementation. *
1058*********************************************************************************************************************************/
1059
1060UIMachineSettingsNetworkPage::UIMachineSettingsNetworkPage()
1061 : m_pTabWidget(0)
1062 , m_pCache(0)
1063{
1064 /* Prepare: */
1065 prepare();
1066}
1067
1068UIMachineSettingsNetworkPage::~UIMachineSettingsNetworkPage()
1069{
1070 /* Cleanup: */
1071 cleanup();
1072}
1073
1074bool UIMachineSettingsNetworkPage::changed() const
1075{
1076 return m_pCache->wasChanged();
1077}
1078
1079void UIMachineSettingsNetworkPage::loadToCacheFrom(QVariant &data)
1080{
1081 /* Fetch data to machine: */
1082 UISettingsPageMachine::fetchData(data);
1083
1084 /* Clear cache initially: */
1085 m_pCache->clear();
1086
1087 /* Cache name lists: */
1088 refreshBridgedAdapterList();
1089 refreshInternalNetworkList(true);
1090 refreshHostInterfaceList();
1091 refreshGenericDriverList(true);
1092 refreshNATNetworkList();
1093#ifdef VBOX_WITH_CLOUD_NET
1094 refreshCloudNetworkList();
1095#endif
1096#ifdef VBOX_WITH_VMNET
1097 refreshHostOnlyNetworkList();
1098#endif
1099
1100 /* Prepare old network data: */
1101 UIDataSettingsMachineNetwork oldNetworkData;
1102
1103 /* For each network adapter: */
1104 for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot)
1105 {
1106 /* Prepare old adapter data: */
1107 UIDataSettingsMachineNetworkAdapter oldAdapterData;
1108
1109 /* Check whether adapter is valid: */
1110 const CNetworkAdapter &comAdapter = m_machine.GetNetworkAdapter(iSlot);
1111 if (!comAdapter.isNull())
1112 {
1113 /* Gather old adapter data: */
1114 oldAdapterData.m_iSlot = iSlot;
1115 oldAdapterData.m_fAdapterEnabled = comAdapter.GetEnabled();
1116 oldAdapterData.m_attachmentType = comAdapter.GetAttachmentType();
1117 oldAdapterData.m_strBridgedAdapterName = wipedOutString(comAdapter.GetBridgedInterface());
1118 oldAdapterData.m_strInternalNetworkName = wipedOutString(comAdapter.GetInternalNetwork());
1119 oldAdapterData.m_strHostInterfaceName = wipedOutString(comAdapter.GetHostOnlyInterface());
1120 oldAdapterData.m_strGenericDriverName = wipedOutString(comAdapter.GetGenericDriver());
1121 oldAdapterData.m_strNATNetworkName = wipedOutString(comAdapter.GetNATNetwork());
1122#ifdef VBOX_WITH_CLOUD_NET
1123 oldAdapterData.m_strCloudNetworkName = wipedOutString(comAdapter.GetCloudNetwork());
1124#endif
1125#ifdef VBOX_WITH_VMNET
1126 oldAdapterData.m_strHostOnlyNetworkName = wipedOutString(comAdapter.GetHostOnlyNetwork());
1127#endif
1128 oldAdapterData.m_adapterType = comAdapter.GetAdapterType();
1129 oldAdapterData.m_promiscuousMode = comAdapter.GetPromiscModePolicy();
1130 oldAdapterData.m_strMACAddress = comAdapter.GetMACAddress();
1131 oldAdapterData.m_strGenericProperties = loadGenericProperties(comAdapter);
1132 oldAdapterData.m_fCableConnected = comAdapter.GetCableConnected();
1133 foreach (const QString &strRedirect, comAdapter.GetNATEngine().GetRedirects())
1134 {
1135 /* Gather old forwarding data & cache key: */
1136 const QStringList &forwardingData = strRedirect.split(',');
1137 AssertMsg(forwardingData.size() == 6, ("Redirect rule should be composed of 6 parts!\n"));
1138 const UIDataPortForwardingRule oldForwardingData(forwardingData.at(0),
1139 (KNATProtocol)forwardingData.at(1).toUInt(),
1140 forwardingData.at(2),
1141 forwardingData.at(3).toUInt(),
1142 forwardingData.at(4),
1143 forwardingData.at(5).toUInt());
1144
1145 const QString &strForwardingKey = forwardingData.at(0);
1146 /* Cache old forwarding data: */
1147 m_pCache->child(iSlot).child(strForwardingKey).cacheInitialData(oldForwardingData);
1148 }
1149 }
1150
1151 /* Cache old adapter data: */
1152 m_pCache->child(iSlot).cacheInitialData(oldAdapterData);
1153 }
1154
1155 /* Cache old network data: */
1156 m_pCache->cacheInitialData(oldNetworkData);
1157
1158 /* Upload machine to data: */
1159 UISettingsPageMachine::uploadData(data);
1160}
1161
1162void UIMachineSettingsNetworkPage::getFromCache()
1163{
1164 /* Setup tab order: */
1165 AssertPtrReturnVoid(firstWidget());
1166 setTabOrder(firstWidget(), m_pTabWidget->focusProxy());
1167 QWidget *pLastFocusWidget = m_pTabWidget->focusProxy();
1168
1169 /* For each adapter: */
1170 for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot)
1171 {
1172 /* Get adapter page: */
1173 UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTabWidget->widget(iSlot));
1174
1175 /* Load old adapter data from the cache: */
1176 pTab->getAdapterDataFromCache(m_pCache->child(iSlot));
1177
1178 /* Setup tab order: */
1179 pLastFocusWidget = pTab->setOrderAfter(pLastFocusWidget);
1180 }
1181
1182 /* Apply language settings: */
1183 retranslateUi();
1184
1185 /* Polish page finally: */
1186 polishPage();
1187
1188 /* Revalidate: */
1189 revalidate();
1190}
1191
1192void UIMachineSettingsNetworkPage::putToCache()
1193{
1194 /* Prepare new network data: */
1195 UIDataSettingsMachineNetwork newNetworkData;
1196
1197 /* For each adapter: */
1198 for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot)
1199 {
1200 /* Get adapter page: */
1201 UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTabWidget->widget(iSlot));
1202
1203 /* Gather new adapter data: */
1204 pTab->putAdapterDataToCache(m_pCache->child(iSlot));
1205 }
1206
1207 /* Cache new network data: */
1208 m_pCache->cacheCurrentData(newNetworkData);
1209}
1210
1211void UIMachineSettingsNetworkPage::saveFromCacheTo(QVariant &data)
1212{
1213 /* Fetch data to machine: */
1214 UISettingsPageMachine::fetchData(data);
1215
1216 /* Update network data and failing state: */
1217 setFailed(!saveNetworkData());
1218
1219 /* Upload machine to data: */
1220 UISettingsPageMachine::uploadData(data);
1221}
1222
1223bool UIMachineSettingsNetworkPage::validate(QList<UIValidationMessage> &messages)
1224{
1225 /* Pass by default: */
1226 bool fValid = true;
1227
1228 /* Delegate validation to adapter tabs: */
1229 for (int i = 0; i < m_pTabWidget->count(); ++i)
1230 {
1231 UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTabWidget->widget(i));
1232 AssertMsg(pTab, ("Can't get adapter tab!\n"));
1233 if (!pTab->validate(messages))
1234 fValid = false;
1235 }
1236
1237 /* Return result: */
1238 return fValid;
1239}
1240
1241void UIMachineSettingsNetworkPage::retranslateUi()
1242{
1243 for (int i = 0; i < m_pTabWidget->count(); ++i)
1244 {
1245 UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTabWidget->widget(i));
1246 Assert(pTab);
1247 m_pTabWidget->setTabText(i, pTab->tabTitle());
1248 }
1249}
1250
1251void UIMachineSettingsNetworkPage::polishPage()
1252{
1253 /* Get the count of network adapter tabs: */
1254 for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot)
1255 {
1256 m_pTabWidget->setTabEnabled(iSlot,
1257 isMachineOffline() ||
1258 (isMachineInValidMode() &&
1259 m_pCache->childCount() > iSlot &&
1260 m_pCache->child(iSlot).base().m_fAdapterEnabled));
1261 UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTabWidget->widget(iSlot));
1262 pTab->polishTab();
1263 }
1264}
1265
1266void UIMachineSettingsNetworkPage::sltHandleTabUpdate()
1267{
1268 /* Determine the sender: */
1269 UIMachineSettingsNetwork *pSender = qobject_cast<UIMachineSettingsNetwork*>(sender());
1270 AssertMsg(pSender, ("This slot should be called only through signal<->slot mechanism from one of UIMachineSettingsNetwork tabs!\n"));
1271
1272 /* Determine sender's attachment type: */
1273 const KNetworkAttachmentType enmSenderAttachmentType = pSender->attachmentType();
1274 switch (enmSenderAttachmentType)
1275 {
1276 case KNetworkAttachmentType_Internal:
1277 {
1278 refreshInternalNetworkList();
1279 break;
1280 }
1281 case KNetworkAttachmentType_Generic:
1282 {
1283 refreshGenericDriverList();
1284 break;
1285 }
1286 default:
1287 break;
1288 }
1289
1290 /* Update all the tabs except the sender: */
1291 for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot)
1292 {
1293 /* Get the iterated tab: */
1294 UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTabWidget->widget(iSlot));
1295 AssertMsg(pTab, ("All the tabs of m_pTabWidget should be of the UIMachineSettingsNetwork type!\n"));
1296
1297 /* Update all the tabs (except sender): */
1298 if (pTab != pSender)
1299 pTab->reloadAlternatives();
1300 }
1301}
1302
1303void UIMachineSettingsNetworkPage::sltHandleAdvancedButtonStateChange(bool fExpanded)
1304{
1305 /* Update the advanced button states for all the pages: */
1306 for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot)
1307 {
1308 UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTabWidget->widget(iSlot));
1309 pTab->setAdvancedButtonState(fExpanded);
1310 }
1311}
1312
1313void UIMachineSettingsNetworkPage::prepare()
1314{
1315 /* Prepare cache: */
1316 m_pCache = new UISettingsCacheMachineNetwork;
1317 AssertPtrReturnVoid(m_pCache);
1318
1319 /* Create main layout: */
1320 QVBoxLayout *pLayoutMain = new QVBoxLayout(this);
1321 AssertPtrReturnVoid(pLayoutMain);
1322 {
1323 /* Creating tab-widget: */
1324 m_pTabWidget = new QITabWidget;
1325 AssertPtrReturnVoid(m_pTabWidget);
1326 {
1327 /* How many adapters to display: */
1328 /** @todo r=klaus this needs to be done based on the actual chipset type of the VM,
1329 * but in this place the m_machine field isn't set yet. My observation (on Linux)
1330 * is that the limitation to 4 isn't necessary any more, but this needs to be checked
1331 * on all platforms to be certain that it's usable everywhere. */
1332 const ulong uCount = qMin((ULONG)4, uiCommon().virtualBox().GetSystemProperties().GetMaxNetworkAdapters(KChipsetType_PIIX3));
1333
1334 /* Create corresponding adapter tabs: */
1335 for (ulong uSlot = 0; uSlot < uCount; ++uSlot)
1336 {
1337 /* Create adapter tab: */
1338 UIMachineSettingsNetwork *pTab = new UIMachineSettingsNetwork(this);
1339 AssertPtrReturnVoid(pTab);
1340 {
1341 /* Configure tab: */
1342 connect(pTab, &UIMachineSettingsNetwork::sigNotifyAdvancedButtonStateChange,
1343 this, &UIMachineSettingsNetworkPage::sltHandleAdvancedButtonStateChange);
1344
1345 /* Add tab into tab-widget: */
1346 m_pTabWidget->addTab(pTab, pTab->tabTitle());
1347 }
1348 }
1349
1350 /* Add tab-widget into layout: */
1351 pLayoutMain->addWidget(m_pTabWidget);
1352 }
1353 }
1354}
1355
1356void UIMachineSettingsNetworkPage::cleanup()
1357{
1358 /* Cleanup cache: */
1359 delete m_pCache;
1360 m_pCache = 0;
1361}
1362
1363void UIMachineSettingsNetworkPage::refreshBridgedAdapterList()
1364{
1365 /* Reload bridged adapters: */
1366 m_bridgedAdapterList = UINetworkAttachmentEditor::bridgedAdapters();
1367}
1368
1369void UIMachineSettingsNetworkPage::refreshInternalNetworkList(bool fFullRefresh /* = false */)
1370{
1371 /* Reload internal network list: */
1372 m_internalNetworkList.clear();
1373 /* Get internal network names from other VMs: */
1374 if (fFullRefresh)
1375 m_internalNetworkListSaved = UINetworkAttachmentEditor::internalNetworks();
1376 m_internalNetworkList << m_internalNetworkListSaved;
1377 /* Append internal network list with names from all the tabs: */
1378 for (int iTab = 0; iTab < m_pTabWidget->count(); ++iTab)
1379 {
1380 UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTabWidget->widget(iTab));
1381 if (pTab)
1382 {
1383 const QString strName = pTab->alternativeName(KNetworkAttachmentType_Internal);
1384 if (!strName.isEmpty() && !m_internalNetworkList.contains(strName))
1385 m_internalNetworkList << strName;
1386 }
1387 }
1388}
1389
1390#ifdef VBOX_WITH_CLOUD_NET
1391void UIMachineSettingsNetworkPage::refreshCloudNetworkList()
1392{
1393 /* Reload cloud network list: */
1394 m_cloudNetworkList = UINetworkAttachmentEditor::cloudNetworks();
1395}
1396#endif /* VBOX_WITH_CLOUD_NET */
1397
1398#ifdef VBOX_WITH_VMNET
1399void UIMachineSettingsNetworkPage::refreshHostOnlyNetworkList()
1400{
1401 /* Reload host-only network list: */
1402 m_hostOnlyNetworkList = UINetworkAttachmentEditor::hostOnlyNetworks();
1403}
1404#endif /* VBOX_WITH_VMNET */
1405
1406void UIMachineSettingsNetworkPage::refreshHostInterfaceList()
1407{
1408 /* Reload host interfaces: */
1409 m_hostInterfaceList = UINetworkAttachmentEditor::hostInterfaces();
1410}
1411
1412void UIMachineSettingsNetworkPage::refreshGenericDriverList(bool fFullRefresh /* = false */)
1413{
1414 /* Load generic driver list: */
1415 m_genericDriverList.clear();
1416 /* Get generic driver names from other VMs: */
1417 if (fFullRefresh)
1418 m_genericDriverListSaved = UINetworkAttachmentEditor::genericDrivers();
1419 m_genericDriverList << m_genericDriverListSaved;
1420 /* Append generic driver list with names from all the tabs: */
1421 for (int iTab = 0; iTab < m_pTabWidget->count(); ++iTab)
1422 {
1423 UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTabWidget->widget(iTab));
1424 if (pTab)
1425 {
1426 const QString strName = pTab->alternativeName(KNetworkAttachmentType_Generic);
1427 if (!strName.isEmpty() && !m_genericDriverList.contains(strName))
1428 m_genericDriverList << strName;
1429 }
1430 }
1431}
1432
1433void UIMachineSettingsNetworkPage::refreshNATNetworkList()
1434{
1435 /* Reload nat networks: */
1436 m_natNetworkList = UINetworkAttachmentEditor::natNetworks();
1437}
1438
1439/* static */
1440QString UIMachineSettingsNetworkPage::loadGenericProperties(const CNetworkAdapter &adapter)
1441{
1442 /* Prepare formatted string: */
1443 QVector<QString> names;
1444 QVector<QString> props;
1445 props = adapter.GetProperties(QString(), names);
1446 QString strResult;
1447 /* Load generic properties: */
1448 for (int i = 0; i < names.size(); ++i)
1449 {
1450 strResult += names[i] + "=" + props[i];
1451 if (i < names.size() - 1)
1452 strResult += "\n";
1453 }
1454 /* Return formatted string: */
1455 return strResult;
1456}
1457
1458/* static */
1459bool UIMachineSettingsNetworkPage::saveGenericProperties(CNetworkAdapter &comAdapter, const QString &strProperties)
1460{
1461 /* Prepare result: */
1462 bool fSuccess = true;
1463 /* Save generic properties: */
1464 if (fSuccess)
1465 {
1466 /* Acquire 'added' properties: */
1467 const QStringList newProps = strProperties.split("\n");
1468
1469 /* Insert 'added' properties: */
1470 QHash<QString, QString> hash;
1471 for (int i = 0; fSuccess && i < newProps.size(); ++i)
1472 {
1473 /* Parse property line: */
1474 const QString strLine = newProps.at(i);
1475 const QString strKey = strLine.section('=', 0, 0);
1476 const QString strVal = strLine.section('=', 1, -1);
1477 if (strKey.isEmpty() || strVal.isEmpty())
1478 continue;
1479 /* Save property in the adapter and the hash: */
1480 comAdapter.SetProperty(strKey, strVal);
1481 fSuccess = comAdapter.isOk();
1482 hash[strKey] = strVal;
1483 }
1484
1485 /* Acquire actual properties ('added' and 'removed'): */
1486 QVector<QString> names;
1487 QVector<QString> props;
1488 if (fSuccess)
1489 {
1490 props = comAdapter.GetProperties(QString(), names);
1491 fSuccess = comAdapter.isOk();
1492 }
1493
1494 /* Exclude 'removed' properties: */
1495 for (int i = 0; fSuccess && i < names.size(); ++i)
1496 {
1497 /* Get property name and value: */
1498 const QString strKey = names.at(i);
1499 const QString strVal = props.at(i);
1500 if (strVal == hash.value(strKey))
1501 continue;
1502 /* Remove property from the adapter: */
1503 // Actually we are _replacing_ property value,
1504 // not _removing_ it at all, but we are replacing it
1505 // with default constructed value, which is QString().
1506 comAdapter.SetProperty(strKey, hash.value(strKey));
1507 fSuccess = comAdapter.isOk();
1508 }
1509 }
1510 /* Return result: */
1511 return fSuccess;
1512}
1513
1514bool UIMachineSettingsNetworkPage::saveNetworkData()
1515{
1516 /* Prepare result: */
1517 bool fSuccess = true;
1518 /* Save network settings from the cache: */
1519 if (fSuccess && isMachineInValidMode() && m_pCache->wasChanged())
1520 {
1521 /* For each adapter: */
1522 for (int iSlot = 0; fSuccess && iSlot < m_pTabWidget->count(); ++iSlot)
1523 fSuccess = saveAdapterData(iSlot);
1524 }
1525 /* Return result: */
1526 return fSuccess;
1527}
1528
1529bool UIMachineSettingsNetworkPage::saveAdapterData(int iSlot)
1530{
1531 /* Prepare result: */
1532 bool fSuccess = true;
1533 /* Save adapter settings from the cache: */
1534 if (fSuccess && m_pCache->child(iSlot).wasChanged())
1535 {
1536 /* Get old network data from the cache: */
1537 const UIDataSettingsMachineNetworkAdapter &oldAdapterData = m_pCache->child(iSlot).base();
1538 /* Get new network data from the cache: */
1539 const UIDataSettingsMachineNetworkAdapter &newAdapterData = m_pCache->child(iSlot).data();
1540
1541 /* Get network adapter for further activities: */
1542 CNetworkAdapter comAdapter = m_machine.GetNetworkAdapter(iSlot);
1543 fSuccess = m_machine.isOk() && comAdapter.isNotNull();
1544
1545 /* Show error message if necessary: */
1546 if (!fSuccess)
1547 notifyOperationProgressError(UIErrorString::formatErrorInfo(m_machine));
1548 else
1549 {
1550 /* Save whether the adapter is enabled: */
1551 if (fSuccess && isMachineOffline() && newAdapterData.m_fAdapterEnabled != oldAdapterData.m_fAdapterEnabled)
1552 {
1553 comAdapter.SetEnabled(newAdapterData.m_fAdapterEnabled);
1554 fSuccess = comAdapter.isOk();
1555 }
1556 /* Save adapter type: */
1557 if (fSuccess && isMachineOffline() && newAdapterData.m_adapterType != oldAdapterData.m_adapterType)
1558 {
1559 comAdapter.SetAdapterType(newAdapterData.m_adapterType);
1560 fSuccess = comAdapter.isOk();
1561 }
1562 /* Save adapter MAC address: */
1563 if (fSuccess && isMachineOffline() && newAdapterData.m_strMACAddress != oldAdapterData.m_strMACAddress)
1564 {
1565 comAdapter.SetMACAddress(newAdapterData.m_strMACAddress);
1566 fSuccess = comAdapter.isOk();
1567 }
1568 /* Save adapter attachment type: */
1569 switch (newAdapterData.m_attachmentType)
1570 {
1571 case KNetworkAttachmentType_Bridged:
1572 {
1573 if (fSuccess && newAdapterData.m_strBridgedAdapterName != oldAdapterData.m_strBridgedAdapterName)
1574 {
1575 comAdapter.SetBridgedInterface(newAdapterData.m_strBridgedAdapterName);
1576 fSuccess = comAdapter.isOk();
1577 }
1578 break;
1579 }
1580 case KNetworkAttachmentType_Internal:
1581 {
1582 if (fSuccess && newAdapterData.m_strInternalNetworkName != oldAdapterData.m_strInternalNetworkName)
1583 {
1584 comAdapter.SetInternalNetwork(newAdapterData.m_strInternalNetworkName);
1585 fSuccess = comAdapter.isOk();
1586 }
1587 break;
1588 }
1589 case KNetworkAttachmentType_HostOnly:
1590 {
1591 if (fSuccess && newAdapterData.m_strHostInterfaceName != oldAdapterData.m_strHostInterfaceName)
1592 {
1593 comAdapter.SetHostOnlyInterface(newAdapterData.m_strHostInterfaceName);
1594 fSuccess = comAdapter.isOk();
1595 }
1596 break;
1597 }
1598 case KNetworkAttachmentType_Generic:
1599 {
1600 if (fSuccess && newAdapterData.m_strGenericDriverName != oldAdapterData.m_strGenericDriverName)
1601 {
1602 comAdapter.SetGenericDriver(newAdapterData.m_strGenericDriverName);
1603 fSuccess = comAdapter.isOk();
1604 }
1605 if (fSuccess && newAdapterData.m_strGenericProperties != oldAdapterData.m_strGenericProperties)
1606 fSuccess = saveGenericProperties(comAdapter, newAdapterData.m_strGenericProperties);
1607 break;
1608 }
1609 case KNetworkAttachmentType_NATNetwork:
1610 {
1611 if (fSuccess && newAdapterData.m_strNATNetworkName != oldAdapterData.m_strNATNetworkName)
1612 {
1613 comAdapter.SetNATNetwork(newAdapterData.m_strNATNetworkName);
1614 fSuccess = comAdapter.isOk();
1615 }
1616 break;
1617 }
1618#ifdef VBOX_WITH_CLOUD_NET
1619 case KNetworkAttachmentType_Cloud:
1620 {
1621 if (fSuccess && newAdapterData.m_strCloudNetworkName != oldAdapterData.m_strCloudNetworkName)
1622 {
1623 comAdapter.SetCloudNetwork(newAdapterData.m_strCloudNetworkName);
1624 fSuccess = comAdapter.isOk();
1625 }
1626 break;
1627 }
1628#endif /* VBOX_WITH_CLOUD_NET */
1629#ifdef VBOX_WITH_VMNET
1630 case KNetworkAttachmentType_HostOnlyNetwork:
1631 {
1632 if (fSuccess && newAdapterData.m_strHostOnlyNetworkName != oldAdapterData.m_strHostOnlyNetworkName)
1633 {
1634 comAdapter.SetHostOnlyNetwork(newAdapterData.m_strHostOnlyNetworkName);
1635 fSuccess = comAdapter.isOk();
1636 }
1637 break;
1638 }
1639#endif /* VBOX_WITH_VMNET */
1640 default:
1641 break;
1642 }
1643 if (fSuccess && newAdapterData.m_attachmentType != oldAdapterData.m_attachmentType)
1644 {
1645 comAdapter.SetAttachmentType(newAdapterData.m_attachmentType);
1646 fSuccess = comAdapter.isOk();
1647 }
1648 /* Save adapter promiscuous mode: */
1649 if (fSuccess && newAdapterData.m_promiscuousMode != oldAdapterData.m_promiscuousMode)
1650 {
1651 comAdapter.SetPromiscModePolicy(newAdapterData.m_promiscuousMode);
1652 fSuccess = comAdapter.isOk();
1653 }
1654 /* Save whether the adapter cable connected: */
1655 if (fSuccess && newAdapterData.m_fCableConnected != oldAdapterData.m_fCableConnected)
1656 {
1657 comAdapter.SetCableConnected(newAdapterData.m_fCableConnected);
1658 fSuccess = comAdapter.isOk();
1659 }
1660
1661 /* Get NAT engine for further activities: */
1662 CNATEngine comEngine;
1663 if (fSuccess)
1664 {
1665 comEngine = comAdapter.GetNATEngine();
1666 fSuccess = comAdapter.isOk() && comEngine.isNotNull();
1667 }
1668
1669 /* Show error message if necessary: */
1670 if (!fSuccess)
1671 notifyOperationProgressError(UIErrorString::formatErrorInfo(comAdapter));
1672 else
1673 {
1674 /* Save adapter port forwarding rules: */
1675 if ( oldAdapterData.m_attachmentType == KNetworkAttachmentType_NAT
1676 || newAdapterData.m_attachmentType == KNetworkAttachmentType_NAT)
1677 {
1678 /* For each rule: */
1679 for (int iRule = 0; fSuccess && iRule < m_pCache->child(iSlot).childCount(); ++iRule)
1680 {
1681 /* Get rule cache: */
1682 const UISettingsCachePortForwardingRule &ruleCache = m_pCache->child(iSlot).child(iRule);
1683
1684 /* Remove rule marked for 'remove' or 'update': */
1685 if (ruleCache.wasRemoved() || ruleCache.wasUpdated())
1686 {
1687 comEngine.RemoveRedirect(ruleCache.base().name);
1688 fSuccess = comEngine.isOk();
1689 }
1690 }
1691 for (int iRule = 0; fSuccess && iRule < m_pCache->child(iSlot).childCount(); ++iRule)
1692 {
1693 /* Get rule cache: */
1694 const UISettingsCachePortForwardingRule &ruleCache = m_pCache->child(iSlot).child(iRule);
1695
1696 /* Create rule marked for 'create' or 'update': */
1697 if (ruleCache.wasCreated() || ruleCache.wasUpdated())
1698 {
1699 comEngine.AddRedirect(ruleCache.data().name, ruleCache.data().protocol,
1700 ruleCache.data().hostIp, ruleCache.data().hostPort.value(),
1701 ruleCache.data().guestIp, ruleCache.data().guestPort.value());
1702 fSuccess = comEngine.isOk();
1703 }
1704 }
1705
1706 /* Show error message if necessary: */
1707 if (!fSuccess)
1708 notifyOperationProgressError(UIErrorString::formatErrorInfo(comEngine));
1709 }
1710 }
1711 }
1712 }
1713 /* Return result: */
1714 return fSuccess;
1715}
1716
1717# include "UIMachineSettingsNetwork.moc"
Note: See TracBrowser for help on using the repository browser.

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