VirtualBox

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

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

FE/Qt: Settings: Syncing comments and minor pieces of code.

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