VirtualBox

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

Last change on this file since 85764 was 85764, checked in by vboxsync, 5 years ago

FE/Qt: bugref:9812. Removing UIMachineSettingsNetwork.ui

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