VirtualBox

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

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

FE/Qt: Machine settings: Network page: Nitpicks (s.a. r114495).

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