VirtualBox

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

Last change on this file since 78600 was 78600, checked in by vboxsync, 6 years ago

FE/Qt: bugref:9446: Forgotten variables initialization in r130585.

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

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