VirtualBox

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

Last change on this file since 66624 was 66624, checked in by vboxsync, 8 years ago

FE/Qt: Machine settings: Network page: Fix port forwarding saving collision (s.a. r114593).

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