VirtualBox

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

Last change on this file since 51873 was 51873, checked in by vboxsync, 11 years ago

FE/Qt: Message Center: Heavy QIMessageBox rework for advanced details formatting support.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Revision Author Id
File size: 51.5 KB
Line 
1/* $Id: UIMachineSettingsNetwork.cpp 51873 2014-07-04 16:22:24Z vboxsync $ */
2/** @file
3 *
4 * VBox frontends: Qt4 GUI ("VirtualBox"):
5 * UIMachineSettingsNetwork class implementation
6 */
7
8/*
9 * Copyright (C) 2008-2013 Oracle Corporation
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.virtualbox.org. This file is free software;
13 * you can redistribute it and/or modify it under the terms of the GNU
14 * General Public License (GPL) as published by the Free Software
15 * Foundation, in version 2 as it comes in the "COPYING" file of the
16 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
17 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18 */
19
20/* GUI includes: */
21#include "QIWidgetValidator.h"
22#include "QIArrowButtonSwitch.h"
23#include "UIMachineSettingsNetwork.h"
24#include "QITabWidget.h"
25#include "VBoxGlobal.h"
26#include "UIConverter.h"
27#include "UIIconPool.h"
28
29/* COM includes: */
30#include "CNetworkAdapter.h"
31#include "CNATEngine.h"
32#include "CHostNetworkInterface.h"
33#include "CNATNetwork.h"
34
35/* Other VBox includes: */
36#ifdef VBOX_WITH_VDE
37# include <iprt/ldr.h>
38# include <VBox/VDEPlug.h>
39#endif /* VBOX_WITH_VDE */
40
41/* Empty item extra-code: */
42const char *pEmptyItemCode = "#empty#";
43
44QString wipedOutString(const QString &strInputString)
45{
46 return strInputString.isEmpty() ? QString() : strInputString;
47}
48
49UIMachineSettingsNetwork::UIMachineSettingsNetwork(UIMachineSettingsNetworkPage *pParent)
50 : QIWithRetranslateUI<QWidget>(0)
51 , m_pParent(pParent)
52 , m_iSlot(-1)
53{
54 /* Apply UI decorations: */
55 Ui::UIMachineSettingsNetwork::setupUi(this);
56
57 /* Setup widgets: */
58 m_pAdapterNameCombo->setInsertPolicy(QComboBox::NoInsert);
59 m_pMACEditor->setValidator(new QRegExpValidator(QRegExp("[0-9A-Fa-f]{12}"), this));
60 m_pMACEditor->setMinimumWidthByText(QString().fill('0', 12));
61 m_pMACButton->setIcon(UIIconPool::iconSet(":/refresh_16px.png"));
62 m_pAdvancedArrow->setIconSize(QSize(10, 10));
63 m_pAdvancedArrow->setIconForButtonState(QIArrowButtonSwitch::ButtonState_Collapsed,
64 UIIconPool::iconSet(":/arrow_right_10px.png"));
65 m_pAdvancedArrow->setIconForButtonState(QIArrowButtonSwitch::ButtonState_Expanded,
66 UIIconPool::iconSet(":/arrow_down_10px.png"));
67
68 /* Setup connections: */
69 connect(m_pEnableAdapterCheckBox, SIGNAL(toggled(bool)), this, SLOT(sltHandleAdapterActivityChange()));
70 connect(m_pAttachmentTypeComboBox, SIGNAL(activated(int)), this, SLOT(sltHandleAttachmentTypeChange()));
71 connect(m_pAdapterNameCombo, SIGNAL(activated(int)), this, SLOT(sltHandleAlternativeNameChange()));
72 connect(m_pAdapterNameCombo, SIGNAL(editTextChanged(const QString&)), this, SLOT(sltHandleAlternativeNameChange()));
73 connect(m_pAdvancedArrow, SIGNAL(sigClicked()), this, SLOT(sltHandleAdvancedButtonStateChange()));
74 connect(m_pMACButton, SIGNAL(clicked()), this, SLOT(sltGenerateMac()));
75 connect(m_pPortForwardingButton, SIGNAL(clicked()), this, SLOT(sltOpenPortForwardingDlg()));
76 connect(this, SIGNAL(sigTabUpdated()), m_pParent, SLOT(sltHandleUpdatedTab()));
77
78 /* Prepare validation: */
79 prepareValidation();
80
81 /* Applying language settings: */
82 retranslateUi();
83}
84
85void UIMachineSettingsNetwork::fetchAdapterCache(const UICacheSettingsMachineNetworkAdapter &adapterCache)
86{
87 /* Get adapter data: */
88 const UIDataSettingsMachineNetworkAdapter &adapterData = adapterCache.base();
89
90 /* Load slot number: */
91 m_iSlot = adapterData.m_iSlot;
92
93 /* Load adapter activity state: */
94 m_pEnableAdapterCheckBox->setChecked(adapterData.m_fAdapterEnabled);
95 /* Handle adapter activity change: */
96 sltHandleAdapterActivityChange();
97
98 /* Load attachment type: */
99 m_pAttachmentTypeComboBox->setCurrentIndex(position(m_pAttachmentTypeComboBox, adapterData.m_attachmentType));
100 /* Load alternative name: */
101 m_strBridgedAdapterName = wipedOutString(adapterData.m_strBridgedAdapterName);
102 m_strInternalNetworkName = wipedOutString(adapterData.m_strInternalNetworkName);
103 m_strHostInterfaceName = wipedOutString(adapterData.m_strHostInterfaceName);
104 m_strGenericDriverName = wipedOutString(adapterData.m_strGenericDriverName);
105 m_strNATNetworkName = wipedOutString(adapterData.m_strNATNetworkName);
106 /* Handle attachment type change: */
107 sltHandleAttachmentTypeChange();
108
109 /* Load adapter type: */
110 m_pAdapterTypeCombo->setCurrentIndex(position(m_pAdapterTypeCombo, adapterData.m_adapterType));
111
112 /* Load promiscuous mode type: */
113 m_pPromiscuousModeCombo->setCurrentIndex(position(m_pPromiscuousModeCombo, adapterData.m_promiscuousMode));
114
115 /* Other options: */
116 m_pMACEditor->setText(adapterData.m_strMACAddress);
117 m_pGenericPropertiesTextEdit->setText(adapterData.m_strGenericProperties);
118 m_pCableConnectedCheckBox->setChecked(adapterData.m_fCableConnected);
119
120 /* Load port forwarding rules: */
121 m_portForwardingRules = adapterData.m_redirects;
122}
123
124void UIMachineSettingsNetwork::uploadAdapterCache(UICacheSettingsMachineNetworkAdapter &adapterCache)
125{
126 /* Prepare adapter data: */
127 UIDataSettingsMachineNetworkAdapter adapterData = adapterCache.base();
128
129 /* Save adapter activity state: */
130 adapterData.m_fAdapterEnabled = m_pEnableAdapterCheckBox->isChecked();
131
132 /* Save attachment type & alternative name: */
133 adapterData.m_attachmentType = attachmentType();
134 switch (adapterData.m_attachmentType)
135 {
136 case KNetworkAttachmentType_Null:
137 break;
138 case KNetworkAttachmentType_NAT:
139 break;
140 case KNetworkAttachmentType_Bridged:
141 adapterData.m_strBridgedAdapterName = alternativeName();
142 break;
143 case KNetworkAttachmentType_Internal:
144 adapterData.m_strInternalNetworkName = alternativeName();
145 break;
146 case KNetworkAttachmentType_HostOnly:
147 adapterData.m_strHostInterfaceName = alternativeName();
148 break;
149 case KNetworkAttachmentType_Generic:
150 adapterData.m_strGenericDriverName = alternativeName();
151 adapterData.m_strGenericProperties = m_pGenericPropertiesTextEdit->toPlainText();
152 break;
153 case KNetworkAttachmentType_NATNetwork:
154 adapterData.m_strNATNetworkName = alternativeName();
155 break;
156 default:
157 break;
158 }
159
160 /* Save adapter type: */
161 adapterData.m_adapterType = (KNetworkAdapterType)m_pAdapterTypeCombo->itemData(m_pAdapterTypeCombo->currentIndex()).toInt();
162
163 /* Save promiscuous mode type: */
164 adapterData.m_promiscuousMode = (KNetworkAdapterPromiscModePolicy)m_pPromiscuousModeCombo->itemData(m_pPromiscuousModeCombo->currentIndex()).toInt();
165
166 /* Other options: */
167 adapterData.m_strMACAddress = m_pMACEditor->text().isEmpty() ? QString() : m_pMACEditor->text();
168 adapterData.m_fCableConnected = m_pCableConnectedCheckBox->isChecked();
169
170 /* Save port forwarding rules: */
171 adapterData.m_redirects = m_portForwardingRules;
172
173 /* Cache adapter data: */
174 adapterCache.cacheCurrentData(adapterData);
175}
176
177bool UIMachineSettingsNetwork::validate(QList<UIValidationMessage> &messages)
178{
179 /* Pass if adapter is disabled: */
180 if (!m_pEnableAdapterCheckBox->isChecked())
181 return true;
182
183 /* Pass by default: */
184 bool fPass = true;
185
186 /* Prepare message: */
187 UIValidationMessage message;
188 message.first = vboxGlobal().removeAccelMark(tabTitle());
189
190 /* Validate alternatives: */
191 switch (attachmentType())
192 {
193 case KNetworkAttachmentType_Bridged:
194 {
195 if (alternativeName().isNull())
196 {
197 message.second << tr("No bridged network adapter is currently selected.");
198 fPass = false;
199 }
200 break;
201 }
202 case KNetworkAttachmentType_Internal:
203 {
204 if (alternativeName().isNull())
205 {
206 message.second << tr("No internal network name is currently specified.");
207 fPass = false;
208 }
209 break;
210 }
211 case KNetworkAttachmentType_HostOnly:
212 {
213 if (alternativeName().isNull())
214 {
215 message.second << tr("No host-only network adapter is currently selected.");
216 fPass = false;
217 }
218 break;
219 }
220 case KNetworkAttachmentType_Generic:
221 {
222 if (alternativeName().isNull())
223 {
224 message.second << tr("No generic driver is currently selected.");
225 fPass = false;
226 }
227 break;
228 }
229 case KNetworkAttachmentType_NATNetwork:
230 {
231 if (alternativeName().isNull())
232 {
233 message.second << tr("No NAT network name is currently specified.");
234 fPass = false;
235 }
236 break;
237 }
238 default:
239 break;
240 }
241
242 /* Validate MAC-address length: */
243 if (m_pMACEditor->text().size() < 12)
244 {
245 message.second << tr("The MAC address must be 12 hexadecimal digits long.");
246 fPass = false;
247 }
248
249 /* Make sure MAC-address is unicast: */
250 if (m_pMACEditor->text().size() >= 2)
251 {
252 QRegExp validator("^[0-9A-Fa-f][02468ACEace]");
253 if (validator.indexIn(m_pMACEditor->text()) != 0)
254 {
255 message.second << tr("The second digit in the MAC address may not be odd as only unicast addresses are allowed.");
256 fPass = false;
257 }
258 }
259
260 /* Serialize message: */
261 if (!message.second.isEmpty())
262 messages << message;
263
264 /* Return result: */
265 return fPass;
266}
267
268QWidget* UIMachineSettingsNetwork::setOrderAfter(QWidget *pAfter)
269{
270 setTabOrder(pAfter, m_pEnableAdapterCheckBox);
271 setTabOrder(m_pEnableAdapterCheckBox, m_pAttachmentTypeComboBox);
272 setTabOrder(m_pAttachmentTypeComboBox, m_pAdapterNameCombo);
273 setTabOrder(m_pAdapterNameCombo, m_pAdvancedArrow);
274 setTabOrder(m_pAdvancedArrow, m_pAdapterTypeCombo);
275 setTabOrder(m_pAdapterTypeCombo, m_pPromiscuousModeCombo);
276 setTabOrder(m_pPromiscuousModeCombo, m_pMACEditor);
277 setTabOrder(m_pMACEditor, m_pMACButton);
278 setTabOrder(m_pMACButton, m_pGenericPropertiesTextEdit);
279 setTabOrder(m_pGenericPropertiesTextEdit, m_pCableConnectedCheckBox);
280 setTabOrder(m_pCableConnectedCheckBox, m_pPortForwardingButton);
281 return m_pPortForwardingButton;
282}
283
284QString UIMachineSettingsNetwork::tabTitle() const
285{
286 return VBoxGlobal::tr("Adapter %1").arg(QString("&%1").arg(m_iSlot + 1));
287}
288
289KNetworkAttachmentType UIMachineSettingsNetwork::attachmentType() const
290{
291 return (KNetworkAttachmentType)m_pAttachmentTypeComboBox->itemData(m_pAttachmentTypeComboBox->currentIndex()).toInt();
292}
293
294QString UIMachineSettingsNetwork::alternativeName(int iType) const
295{
296 if (iType == -1)
297 iType = attachmentType();
298 QString strResult;
299 switch (iType)
300 {
301 case KNetworkAttachmentType_Bridged:
302 strResult = m_strBridgedAdapterName;
303 break;
304 case KNetworkAttachmentType_Internal:
305 strResult = m_strInternalNetworkName;
306 break;
307 case KNetworkAttachmentType_HostOnly:
308 strResult = m_strHostInterfaceName;
309 break;
310 case KNetworkAttachmentType_Generic:
311 strResult = m_strGenericDriverName;
312 break;
313 case KNetworkAttachmentType_NATNetwork:
314 strResult = m_strNATNetworkName;
315 break;
316 default:
317 break;
318 }
319 Assert(strResult.isNull() || !strResult.isEmpty());
320 return strResult;
321}
322
323void UIMachineSettingsNetwork::polishTab()
324{
325 /* Basic attributes: */
326 m_pEnableAdapterCheckBox->setEnabled(m_pParent->isMachineOffline());
327 m_pAttachmentTypeLabel->setEnabled(m_pParent->isMachineInValidMode());
328 m_pAttachmentTypeComboBox->setEnabled(m_pParent->isMachineInValidMode());
329 m_pAdapterNameLabel->setEnabled(m_pParent->isMachineInValidMode() &&
330 attachmentType() != KNetworkAttachmentType_Null &&
331 attachmentType() != KNetworkAttachmentType_NAT);
332 m_pAdapterNameCombo->setEnabled(m_pParent->isMachineInValidMode() &&
333 attachmentType() != KNetworkAttachmentType_Null &&
334 attachmentType() != KNetworkAttachmentType_NAT);
335 m_pAdvancedArrow->setEnabled(m_pParent->isMachineInValidMode());
336
337 /* Advanced attributes: */
338 m_pAdapterTypeLabel->setEnabled(m_pParent->isMachineOffline());
339 m_pAdapterTypeCombo->setEnabled(m_pParent->isMachineOffline());
340 m_pPromiscuousModeLabel->setEnabled(m_pParent->isMachineInValidMode() &&
341 attachmentType() != KNetworkAttachmentType_Null &&
342 attachmentType() != KNetworkAttachmentType_Generic &&
343 attachmentType() != KNetworkAttachmentType_NAT);
344 m_pPromiscuousModeCombo->setEnabled(m_pParent->isMachineInValidMode() &&
345 attachmentType() != KNetworkAttachmentType_Null &&
346 attachmentType() != KNetworkAttachmentType_Generic &&
347 attachmentType() != KNetworkAttachmentType_NAT);
348 m_pMACLabel->setEnabled(m_pParent->isMachineOffline());
349 m_pMACEditor->setEnabled(m_pParent->isMachineOffline());
350 m_pMACButton->setEnabled(m_pParent->isMachineOffline());
351 m_pGenericPropertiesLabel->setEnabled(m_pParent->isMachineInValidMode());
352 m_pGenericPropertiesTextEdit->setEnabled(m_pParent->isMachineInValidMode());
353 m_pPortForwardingButton->setEnabled(m_pParent->isMachineInValidMode() &&
354 attachmentType() == KNetworkAttachmentType_NAT);
355
356 /* Postprocessing: */
357 if ((m_pParent->isMachineSaved() || m_pParent->isMachineOnline()) && !m_pAdvancedArrow->isExpanded())
358 m_pAdvancedArrow->animateClick();
359 sltHandleAdvancedButtonStateChange();
360}
361
362void UIMachineSettingsNetwork::reloadAlternative()
363{
364 /* Repopulate alternative-name combo-box content: */
365 updateAlternativeList();
366 /* Select previous or default alternative-name combo-box item: */
367 updateAlternativeName();
368}
369
370void UIMachineSettingsNetwork::retranslateUi()
371{
372 /* Translate uic generated strings: */
373 Ui::UIMachineSettingsNetwork::retranslateUi(this);
374
375 /* Translate combo-boxes content: */
376 populateComboboxes();
377
378 /* Translate attachment info: */
379 sltHandleAttachmentTypeChange();
380}
381
382void UIMachineSettingsNetwork::sltHandleAdapterActivityChange()
383{
384 /* Update availability: */
385 m_pAdapterOptionsContainer->setEnabled(m_pEnableAdapterCheckBox->isChecked());
386
387 /* Revalidate: */
388 m_pParent->revalidate();
389}
390
391void UIMachineSettingsNetwork::sltHandleAttachmentTypeChange()
392{
393 /* Update alternative-name combo-box availability: */
394 m_pAdapterNameLabel->setEnabled(attachmentType() != KNetworkAttachmentType_Null &&
395 attachmentType() != KNetworkAttachmentType_NAT);
396 m_pAdapterNameCombo->setEnabled(attachmentType() != KNetworkAttachmentType_Null &&
397 attachmentType() != KNetworkAttachmentType_NAT);
398 /* Update promiscuous-mode combo-box availability: */
399 m_pPromiscuousModeLabel->setEnabled(attachmentType() != KNetworkAttachmentType_Null &&
400 attachmentType() != KNetworkAttachmentType_Generic &&
401 attachmentType() != KNetworkAttachmentType_NAT);
402 m_pPromiscuousModeCombo->setEnabled(attachmentType() != KNetworkAttachmentType_Null &&
403 attachmentType() != KNetworkAttachmentType_Generic &&
404 attachmentType() != KNetworkAttachmentType_NAT);
405 /* Update generic-properties editor visibility: */
406 m_pGenericPropertiesLabel->setVisible(attachmentType() == KNetworkAttachmentType_Generic &&
407 m_pAdvancedArrow->isExpanded());
408 m_pGenericPropertiesTextEdit->setVisible(attachmentType() == KNetworkAttachmentType_Generic &&
409 m_pAdvancedArrow->isExpanded());
410 /* Update forwarding-rules button availability: */
411 m_pPortForwardingButton->setEnabled(attachmentType() == KNetworkAttachmentType_NAT);
412 /* Update alternative-name combo-box whats-this and editable state: */
413 switch (attachmentType())
414 {
415 case KNetworkAttachmentType_Bridged:
416 {
417 m_pAdapterNameCombo->setWhatsThis(tr("Selects the network adapter on the host system that traffic "
418 "to and from this network card will go through."));
419 m_pAdapterNameCombo->setEditable(false);
420 break;
421 }
422 case KNetworkAttachmentType_Internal:
423 {
424 m_pAdapterNameCombo->setWhatsThis(tr("Holds the name of the internal network that this network card "
425 "will be connected to. You can create a new internal network by "
426 "choosing a name which is not used by any other network cards "
427 "in this virtual machine or others."));
428 m_pAdapterNameCombo->setEditable(true);
429 break;
430 }
431 case KNetworkAttachmentType_HostOnly:
432 {
433 m_pAdapterNameCombo->setWhatsThis(tr("Selects the virtual network adapter on the host system that traffic "
434 "to and from this network card will go through. "
435 "You can create and remove adapters using the global network "
436 "settings in the virtual machine manager window."));
437 m_pAdapterNameCombo->setEditable(false);
438 break;
439 }
440 case KNetworkAttachmentType_Generic:
441 {
442 m_pAdapterNameCombo->setWhatsThis(tr("Selects the driver to be used with this network card."));
443 m_pAdapterNameCombo->setEditable(true);
444 break;
445 }
446 case KNetworkAttachmentType_NATNetwork:
447 {
448 m_pAdapterNameCombo->setWhatsThis(tr("Holds the name of the NAT network that this network card "
449 "will be connected to. You can create and remove networks "
450 "using the global network settings in the virtual machine "
451 "manager window."));
452 m_pAdapterNameCombo->setEditable(false);
453 break;
454 }
455 default:
456 {
457 m_pAdapterNameCombo->setWhatsThis(QString());
458 break;
459 }
460 }
461
462 /* Update alternative combo: */
463 reloadAlternative();
464
465 /* Handle alternative-name cange: */
466 sltHandleAlternativeNameChange();
467}
468
469void UIMachineSettingsNetwork::sltHandleAlternativeNameChange()
470{
471 /* Remember new name if its changed,
472 * Call for other pages update, if necessary: */
473 switch (attachmentType())
474 {
475 case KNetworkAttachmentType_Bridged:
476 {
477 QString newName(m_pAdapterNameCombo->itemData(m_pAdapterNameCombo->currentIndex()).toString() == QString(pEmptyItemCode) ||
478 m_pAdapterNameCombo->currentText().isEmpty() ? QString() : m_pAdapterNameCombo->currentText());
479 if (m_strBridgedAdapterName != newName)
480 m_strBridgedAdapterName = newName;
481 break;
482 }
483 case KNetworkAttachmentType_Internal:
484 {
485 QString newName((m_pAdapterNameCombo->itemData(m_pAdapterNameCombo->currentIndex()).toString() == QString(pEmptyItemCode) &&
486 m_pAdapterNameCombo->currentText() == m_pAdapterNameCombo->itemText(m_pAdapterNameCombo->currentIndex())) ||
487 m_pAdapterNameCombo->currentText().isEmpty() ? QString() : m_pAdapterNameCombo->currentText());
488 if (m_strInternalNetworkName != newName)
489 {
490 m_strInternalNetworkName = newName;
491 if (!m_strInternalNetworkName.isNull())
492 emit sigTabUpdated();
493 }
494 break;
495 }
496 case KNetworkAttachmentType_HostOnly:
497 {
498 QString newName(m_pAdapterNameCombo->itemData(m_pAdapterNameCombo->currentIndex()).toString() == QString(pEmptyItemCode) ||
499 m_pAdapterNameCombo->currentText().isEmpty() ? QString() : m_pAdapterNameCombo->currentText());
500 if (m_strHostInterfaceName != newName)
501 m_strHostInterfaceName = newName;
502 break;
503 }
504 case KNetworkAttachmentType_Generic:
505 {
506 QString newName((m_pAdapterNameCombo->itemData(m_pAdapterNameCombo->currentIndex()).toString() == QString(pEmptyItemCode) &&
507 m_pAdapterNameCombo->currentText() == m_pAdapterNameCombo->itemText(m_pAdapterNameCombo->currentIndex())) ||
508 m_pAdapterNameCombo->currentText().isEmpty() ? QString() : m_pAdapterNameCombo->currentText());
509 if (m_strGenericDriverName != newName)
510 {
511 m_strGenericDriverName = newName;
512 if (!m_strGenericDriverName.isNull())
513 emit sigTabUpdated();
514 }
515 break;
516 }
517 case KNetworkAttachmentType_NATNetwork:
518 {
519 QString newName(m_pAdapterNameCombo->itemData(m_pAdapterNameCombo->currentIndex()).toString() == QString(pEmptyItemCode) ||
520 m_pAdapterNameCombo->currentText().isEmpty() ? QString() : m_pAdapterNameCombo->currentText());
521 if (m_strNATNetworkName != newName)
522 m_strNATNetworkName = newName;
523 break;
524 }
525 default:
526 break;
527 }
528
529 /* Revalidate: */
530 m_pParent->revalidate();
531}
532
533void UIMachineSettingsNetwork::sltHandleAdvancedButtonStateChange()
534{
535 /* Update visibility of advanced options: */
536 m_pAdapterTypeLabel->setVisible(m_pAdvancedArrow->isExpanded());
537 m_pAdapterTypeCombo->setVisible(m_pAdvancedArrow->isExpanded());
538 m_pPromiscuousModeLabel->setVisible(m_pAdvancedArrow->isExpanded());
539 m_pPromiscuousModeCombo->setVisible(m_pAdvancedArrow->isExpanded());
540 m_pGenericPropertiesLabel->setVisible(attachmentType() == KNetworkAttachmentType_Generic &&
541 m_pAdvancedArrow->isExpanded());
542 m_pGenericPropertiesTextEdit->setVisible(attachmentType() == KNetworkAttachmentType_Generic &&
543 m_pAdvancedArrow->isExpanded());
544 m_pMACLabel->setVisible(m_pAdvancedArrow->isExpanded());
545 m_pMACEditor->setVisible(m_pAdvancedArrow->isExpanded());
546 m_pMACButton->setVisible(m_pAdvancedArrow->isExpanded());
547 m_pCableConnectedCheckBox->setVisible(m_pAdvancedArrow->isExpanded());
548 m_pPortForwardingButton->setVisible(m_pAdvancedArrow->isExpanded());
549}
550
551void UIMachineSettingsNetwork::sltGenerateMac()
552{
553 m_pMACEditor->setText(vboxGlobal().host().GenerateMACAddress());
554}
555
556void UIMachineSettingsNetwork::sltOpenPortForwardingDlg()
557{
558 UIMachineSettingsPortForwardingDlg dlg(this, m_portForwardingRules);
559 if (dlg.exec() == QDialog::Accepted)
560 m_portForwardingRules = dlg.rules();
561}
562
563void UIMachineSettingsNetwork::prepareValidation()
564{
565 /* Configure validation: */
566 connect(m_pMACEditor, SIGNAL(textEdited(const QString &)), m_pParent, SLOT(revalidate()));
567}
568
569void UIMachineSettingsNetwork::populateComboboxes()
570{
571 /* Attachment type: */
572 {
573 /* Remember the currently selected attachment type: */
574 int iCurrentAttachment = m_pAttachmentTypeComboBox->currentIndex();
575
576 /* Clear the attachments combo-box: */
577 m_pAttachmentTypeComboBox->clear();
578
579 /* Populate attachments: */
580 int iAttachmentTypeIndex = 0;
581 m_pAttachmentTypeComboBox->insertItem(iAttachmentTypeIndex, gpConverter->toString(KNetworkAttachmentType_Null));
582 m_pAttachmentTypeComboBox->setItemData(iAttachmentTypeIndex, KNetworkAttachmentType_Null);
583 m_pAttachmentTypeComboBox->setItemData(iAttachmentTypeIndex, m_pAttachmentTypeComboBox->itemText(iAttachmentTypeIndex), Qt::ToolTipRole);
584 ++iAttachmentTypeIndex;
585 m_pAttachmentTypeComboBox->insertItem(iAttachmentTypeIndex, gpConverter->toString(KNetworkAttachmentType_NAT));
586 m_pAttachmentTypeComboBox->setItemData(iAttachmentTypeIndex, KNetworkAttachmentType_NAT);
587 m_pAttachmentTypeComboBox->setItemData(iAttachmentTypeIndex, m_pAttachmentTypeComboBox->itemText(iAttachmentTypeIndex), Qt::ToolTipRole);
588 ++iAttachmentTypeIndex;
589 m_pAttachmentTypeComboBox->insertItem(iAttachmentTypeIndex, gpConverter->toString(KNetworkAttachmentType_NATNetwork));
590 m_pAttachmentTypeComboBox->setItemData(iAttachmentTypeIndex, KNetworkAttachmentType_NATNetwork);
591 m_pAttachmentTypeComboBox->setItemData(iAttachmentTypeIndex, m_pAttachmentTypeComboBox->itemText(iAttachmentTypeIndex), Qt::ToolTipRole);
592 ++iAttachmentTypeIndex;
593 m_pAttachmentTypeComboBox->insertItem(iAttachmentTypeIndex, gpConverter->toString(KNetworkAttachmentType_Bridged));
594 m_pAttachmentTypeComboBox->setItemData(iAttachmentTypeIndex, KNetworkAttachmentType_Bridged);
595 m_pAttachmentTypeComboBox->setItemData(iAttachmentTypeIndex, m_pAttachmentTypeComboBox->itemText(iAttachmentTypeIndex), Qt::ToolTipRole);
596 ++iAttachmentTypeIndex;
597 m_pAttachmentTypeComboBox->insertItem(iAttachmentTypeIndex, gpConverter->toString(KNetworkAttachmentType_Internal));
598 m_pAttachmentTypeComboBox->setItemData(iAttachmentTypeIndex, KNetworkAttachmentType_Internal);
599 m_pAttachmentTypeComboBox->setItemData(iAttachmentTypeIndex, m_pAttachmentTypeComboBox->itemText(iAttachmentTypeIndex), Qt::ToolTipRole);
600 ++iAttachmentTypeIndex;
601 m_pAttachmentTypeComboBox->insertItem(iAttachmentTypeIndex, gpConverter->toString(KNetworkAttachmentType_HostOnly));
602 m_pAttachmentTypeComboBox->setItemData(iAttachmentTypeIndex, KNetworkAttachmentType_HostOnly);
603 m_pAttachmentTypeComboBox->setItemData(iAttachmentTypeIndex, m_pAttachmentTypeComboBox->itemText(iAttachmentTypeIndex), Qt::ToolTipRole);
604 ++iAttachmentTypeIndex;
605 m_pAttachmentTypeComboBox->insertItem(iAttachmentTypeIndex, gpConverter->toString(KNetworkAttachmentType_Generic));
606 m_pAttachmentTypeComboBox->setItemData(iAttachmentTypeIndex, KNetworkAttachmentType_Generic);
607 m_pAttachmentTypeComboBox->setItemData(iAttachmentTypeIndex, m_pAttachmentTypeComboBox->itemText(iAttachmentTypeIndex), Qt::ToolTipRole);
608 ++iAttachmentTypeIndex;
609
610 /* Restore the previously selected attachment type: */
611 m_pAttachmentTypeComboBox->setCurrentIndex(iCurrentAttachment == -1 ? 0 : iCurrentAttachment);
612 }
613
614 /* Adapter type: */
615 {
616 /* Remember the currently selected adapter type: */
617 int iCurrentAdapter = m_pAdapterTypeCombo->currentIndex();
618
619 /* Clear the adapter type combo-box: */
620 m_pAdapterTypeCombo->clear();
621
622 /* Populate adapter types: */
623 int iAdapterTypeIndex = 0;
624 m_pAdapterTypeCombo->insertItem(iAdapterTypeIndex, gpConverter->toString(KNetworkAdapterType_Am79C970A));
625 m_pAdapterTypeCombo->setItemData(iAdapterTypeIndex, KNetworkAdapterType_Am79C970A);
626 m_pAdapterTypeCombo->setItemData(iAdapterTypeIndex, m_pAdapterTypeCombo->itemText(iAdapterTypeIndex), Qt::ToolTipRole);
627 ++iAdapterTypeIndex;
628 m_pAdapterTypeCombo->insertItem(iAdapterTypeIndex, gpConverter->toString(KNetworkAdapterType_Am79C973));
629 m_pAdapterTypeCombo->setItemData(iAdapterTypeIndex, KNetworkAdapterType_Am79C973);
630 m_pAdapterTypeCombo->setItemData(iAdapterTypeIndex, m_pAdapterTypeCombo->itemText(iAdapterTypeIndex), Qt::ToolTipRole);
631 ++iAdapterTypeIndex;
632#ifdef VBOX_WITH_E1000
633 m_pAdapterTypeCombo->insertItem(iAdapterTypeIndex, gpConverter->toString(KNetworkAdapterType_I82540EM));
634 m_pAdapterTypeCombo->setItemData(iAdapterTypeIndex, KNetworkAdapterType_I82540EM);
635 m_pAdapterTypeCombo->setItemData(iAdapterTypeIndex, m_pAdapterTypeCombo->itemText(iAdapterTypeIndex), Qt::ToolTipRole);
636 ++iAdapterTypeIndex;
637 m_pAdapterTypeCombo->insertItem(iAdapterTypeIndex, gpConverter->toString(KNetworkAdapterType_I82543GC));
638 m_pAdapterTypeCombo->setItemData(iAdapterTypeIndex, KNetworkAdapterType_I82543GC);
639 m_pAdapterTypeCombo->setItemData(iAdapterTypeIndex, m_pAdapterTypeCombo->itemText(iAdapterTypeIndex), Qt::ToolTipRole);
640 ++iAdapterTypeIndex;
641 m_pAdapterTypeCombo->insertItem(iAdapterTypeIndex, gpConverter->toString(KNetworkAdapterType_I82545EM));
642 m_pAdapterTypeCombo->setItemData(iAdapterTypeIndex, KNetworkAdapterType_I82545EM);
643 m_pAdapterTypeCombo->setItemData(iAdapterTypeIndex, m_pAdapterTypeCombo->itemText(iAdapterTypeIndex), Qt::ToolTipRole);
644 ++iAdapterTypeIndex;
645#endif /* VBOX_WITH_E1000 */
646#ifdef VBOX_WITH_VIRTIO
647 m_pAdapterTypeCombo->insertItem(iAdapterTypeIndex, gpConverter->toString(KNetworkAdapterType_Virtio));
648 m_pAdapterTypeCombo->setItemData(iAdapterTypeIndex, KNetworkAdapterType_Virtio);
649 m_pAdapterTypeCombo->setItemData(iAdapterTypeIndex, m_pAdapterTypeCombo->itemText(iAdapterTypeIndex), Qt::ToolTipRole);
650 ++iAdapterTypeIndex;
651#endif /* VBOX_WITH_VIRTIO */
652
653 /* Restore the previously selected adapter type: */
654 m_pAdapterTypeCombo->setCurrentIndex(iCurrentAdapter == -1 ? 0 : iCurrentAdapter);
655 }
656
657 /* Promiscuous Mode type: */
658 {
659 /* Remember the currently selected promiscuous mode type: */
660 int iCurrentPromiscuousMode = m_pPromiscuousModeCombo->currentIndex();
661
662 /* Clear the promiscuous mode combo-box: */
663 m_pPromiscuousModeCombo->clear();
664
665 /* Populate promiscuous modes: */
666 int iPromiscuousModeIndex = 0;
667 m_pPromiscuousModeCombo->insertItem(iPromiscuousModeIndex, gpConverter->toString(KNetworkAdapterPromiscModePolicy_Deny));
668 m_pPromiscuousModeCombo->setItemData(iPromiscuousModeIndex, KNetworkAdapterPromiscModePolicy_Deny);
669 m_pPromiscuousModeCombo->setItemData(iPromiscuousModeIndex, m_pPromiscuousModeCombo->itemText(iPromiscuousModeIndex), Qt::ToolTipRole);
670 ++iPromiscuousModeIndex;
671 m_pPromiscuousModeCombo->insertItem(iPromiscuousModeIndex, gpConverter->toString(KNetworkAdapterPromiscModePolicy_AllowNetwork));
672 m_pPromiscuousModeCombo->setItemData(iPromiscuousModeIndex, KNetworkAdapterPromiscModePolicy_AllowNetwork);
673 m_pPromiscuousModeCombo->setItemData(iPromiscuousModeIndex, m_pPromiscuousModeCombo->itemText(iPromiscuousModeIndex), Qt::ToolTipRole);
674 ++iPromiscuousModeIndex;
675 m_pPromiscuousModeCombo->insertItem(iPromiscuousModeIndex, gpConverter->toString(KNetworkAdapterPromiscModePolicy_AllowAll));
676 m_pPromiscuousModeCombo->setItemData(iPromiscuousModeIndex, KNetworkAdapterPromiscModePolicy_AllowAll);
677 m_pPromiscuousModeCombo->setItemData(iPromiscuousModeIndex, m_pPromiscuousModeCombo->itemText(iPromiscuousModeIndex), Qt::ToolTipRole);
678 ++iPromiscuousModeIndex;
679
680 /* Restore the previously selected promiscuous mode type: */
681 m_pPromiscuousModeCombo->setCurrentIndex(iCurrentPromiscuousMode == -1 ? 0 : iCurrentPromiscuousMode);
682 }
683}
684
685void UIMachineSettingsNetwork::updateAlternativeList()
686{
687 /* Block signals initially: */
688 m_pAdapterNameCombo->blockSignals(true);
689
690 /* Repopulate alternative-name combo: */
691 m_pAdapterNameCombo->clear();
692 switch (attachmentType())
693 {
694 case KNetworkAttachmentType_Bridged:
695 m_pAdapterNameCombo->insertItems(0, m_pParent->bridgedAdapterList());
696 break;
697 case KNetworkAttachmentType_Internal:
698 m_pAdapterNameCombo->insertItems(0, m_pParent->internalNetworkList());
699 break;
700 case KNetworkAttachmentType_HostOnly:
701 m_pAdapterNameCombo->insertItems(0, m_pParent->hostInterfaceList());
702 break;
703 case KNetworkAttachmentType_Generic:
704 m_pAdapterNameCombo->insertItems(0, m_pParent->genericDriverList());
705 break;
706 case KNetworkAttachmentType_NATNetwork:
707 m_pAdapterNameCombo->insertItems(0, m_pParent->natNetworkList());
708 break;
709 default:
710 break;
711 }
712
713 /* Prepend 'empty' or 'default' item to alternative-name combo: */
714 if (m_pAdapterNameCombo->count() == 0)
715 {
716 switch (attachmentType())
717 {
718 case KNetworkAttachmentType_Bridged:
719 case KNetworkAttachmentType_HostOnly:
720 case KNetworkAttachmentType_NATNetwork:
721 {
722 /* If adapter list is empty => add 'Not selected' item: */
723 int pos = m_pAdapterNameCombo->findData(pEmptyItemCode);
724 if (pos == -1)
725 m_pAdapterNameCombo->insertItem(0, tr("Not selected", "network adapter name"), pEmptyItemCode);
726 else
727 m_pAdapterNameCombo->setItemText(pos, tr("Not selected", "network adapter name"));
728 break;
729 }
730 case KNetworkAttachmentType_Internal:
731 {
732 /* Internal network list should have a default item: */
733 if (m_pAdapterNameCombo->findText("intnet") == -1)
734 m_pAdapterNameCombo->insertItem(0, "intnet");
735 break;
736 }
737 default:
738 break;
739 }
740 }
741
742 /* Unblock signals finally: */
743 m_pAdapterNameCombo->blockSignals(false);
744}
745
746void UIMachineSettingsNetwork::updateAlternativeName()
747{
748 /* Block signals initially: */
749 m_pAdapterNameCombo->blockSignals(true);
750
751 switch (attachmentType())
752 {
753 case KNetworkAttachmentType_Bridged:
754 case KNetworkAttachmentType_Internal:
755 case KNetworkAttachmentType_HostOnly:
756 case KNetworkAttachmentType_Generic:
757 case KNetworkAttachmentType_NATNetwork:
758 {
759 m_pAdapterNameCombo->setCurrentIndex(position(m_pAdapterNameCombo, alternativeName()));
760 break;
761 }
762 default:
763 break;
764 }
765
766 /* Unblock signals finally: */
767 m_pAdapterNameCombo->blockSignals(false);
768}
769
770/* static */
771int UIMachineSettingsNetwork::position(QComboBox *pComboBox, int iData)
772{
773 int iPosition = pComboBox->findData(iData);
774 return iPosition == -1 ? 0 : iPosition;
775}
776
777/* static */
778int UIMachineSettingsNetwork::position(QComboBox *pComboBox, const QString &strText)
779{
780 int iPosition = pComboBox->findText(strText);
781 return iPosition == -1 ? 0 : iPosition;
782}
783
784/* UIMachineSettingsNetworkPage Stuff: */
785UIMachineSettingsNetworkPage::UIMachineSettingsNetworkPage()
786 : m_pTwAdapters(0)
787{
788 /* Setup main layout: */
789 QVBoxLayout *pMainLayout = new QVBoxLayout(this);
790 pMainLayout->setContentsMargins(0, 5, 0, 5);
791
792 /* Creating tab-widget: */
793 m_pTwAdapters = new QITabWidget(this);
794 pMainLayout->addWidget(m_pTwAdapters);
795
796 /* How many adapters to display: */
797 ulong uCount = qMin((ULONG)4, vboxGlobal().virtualBox().GetSystemProperties().GetMaxNetworkAdapters(KChipsetType_PIIX3));
798 /* Add corresponding tab pages to parent tab widget: */
799 for (ulong uSlot = 0; uSlot < uCount; ++uSlot)
800 {
801 /* Creating adapter tab: */
802 UIMachineSettingsNetwork *pTab = new UIMachineSettingsNetwork(this);
803 m_pTwAdapters->addTab(pTab, pTab->tabTitle());
804 }
805}
806
807/* Load data to cache from corresponding external object(s),
808 * this task COULD be performed in other than GUI thread: */
809void UIMachineSettingsNetworkPage::loadToCacheFrom(QVariant &data)
810{
811 /* Fetch data to machine: */
812 UISettingsPageMachine::fetchData(data);
813
814 /* Clear cache initially: */
815 m_cache.clear();
816
817 /* Cache name lists: */
818 refreshBridgedAdapterList();
819 refreshInternalNetworkList(true);
820 refreshHostInterfaceList();
821 refreshGenericDriverList(true);
822 refreshNATNetworkList();
823
824 /* For each network adapter: */
825 for (int iSlot = 0; iSlot < m_pTwAdapters->count(); ++iSlot)
826 {
827 /* Prepare adapter data: */
828 UIDataSettingsMachineNetworkAdapter adapterData;
829
830 /* Check if adapter is valid: */
831 const CNetworkAdapter &adapter = m_machine.GetNetworkAdapter(iSlot);
832 if (!adapter.isNull())
833 {
834 /* Gather main options: */
835 adapterData.m_iSlot = iSlot;
836 adapterData.m_fAdapterEnabled = adapter.GetEnabled();
837 adapterData.m_attachmentType = adapter.GetAttachmentType();
838 adapterData.m_strBridgedAdapterName = wipedOutString(adapter.GetBridgedInterface());
839 adapterData.m_strInternalNetworkName = wipedOutString(adapter.GetInternalNetwork());
840 adapterData.m_strHostInterfaceName = wipedOutString(adapter.GetHostOnlyInterface());
841 adapterData.m_strGenericDriverName = wipedOutString(adapter.GetGenericDriver());
842 adapterData.m_strNATNetworkName = wipedOutString(adapter.GetNATNetwork());
843
844 /* Gather advanced options: */
845 adapterData.m_adapterType = adapter.GetAdapterType();
846 adapterData.m_promiscuousMode = adapter.GetPromiscModePolicy();
847 adapterData.m_strMACAddress = adapter.GetMACAddress();
848 adapterData.m_strGenericProperties = summarizeGenericProperties(adapter);
849 adapterData.m_fCableConnected = adapter.GetCableConnected();
850
851 /* Gather redirect options: */
852 QVector<QString> redirects = adapter.GetNATEngine().GetRedirects();
853 for (int i = 0; i < redirects.size(); ++i)
854 {
855 QStringList redirectData = redirects[i].split(',');
856 AssertMsg(redirectData.size() == 6, ("Redirect rule should be composed of 6 parts!\n"));
857 adapterData.m_redirects << UIPortForwardingData(redirectData[0],
858 (KNATProtocol)redirectData[1].toUInt(),
859 redirectData[2],
860 redirectData[3].toUInt(),
861 redirectData[4],
862 redirectData[5].toUInt());
863 }
864 }
865
866 /* Cache adapter data: */
867 m_cache.child(iSlot).cacheInitialData(adapterData);
868 }
869
870 /* Upload machine to data: */
871 UISettingsPageMachine::uploadData(data);
872}
873
874/* Load data to corresponding widgets from cache,
875 * this task SHOULD be performed in GUI thread only: */
876void UIMachineSettingsNetworkPage::getFromCache()
877{
878 /* Setup tab order: */
879 Assert(firstWidget());
880 setTabOrder(firstWidget(), m_pTwAdapters->focusProxy());
881 QWidget *pLastFocusWidget = m_pTwAdapters->focusProxy();
882
883 /* For each network adapter: */
884 for (int iSlot = 0; iSlot < m_pTwAdapters->count(); ++iSlot)
885 {
886 /* Get adapter page: */
887 UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTwAdapters->widget(iSlot));
888
889 /* Load adapter data to page: */
890 pTab->fetchAdapterCache(m_cache.child(iSlot));
891
892 /* Setup tab order: */
893 pLastFocusWidget = pTab->setOrderAfter(pLastFocusWidget);
894 }
895
896 /* Applying language settings: */
897 retranslateUi();
898
899 /* Polish page finally: */
900 polishPage();
901
902 /* Revalidate: */
903 revalidate();
904}
905
906/* Save data from corresponding widgets to cache,
907 * this task SHOULD be performed in GUI thread only: */
908void UIMachineSettingsNetworkPage::putToCache()
909{
910 /* For each network adapter: */
911 for (int iSlot = 0; iSlot < m_pTwAdapters->count(); ++iSlot)
912 {
913 /* Get adapter page: */
914 UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTwAdapters->widget(iSlot));
915
916 /* Gather & cache adapter data: */
917 pTab->uploadAdapterCache(m_cache.child(iSlot));
918 }
919}
920
921/* Save data from cache to corresponding external object(s),
922 * this task COULD be performed in other than GUI thread: */
923void UIMachineSettingsNetworkPage::saveFromCacheTo(QVariant &data)
924{
925 /* Fetch data to machine: */
926 UISettingsPageMachine::fetchData(data);
927
928 /* Check if network data was changed: */
929 if (m_cache.wasChanged())
930 {
931 /* For each network adapter: */
932 for (int iSlot = 0; iSlot < m_pTwAdapters->count(); ++iSlot)
933 {
934 /* Check if adapter data was changed: */
935 const UICacheSettingsMachineNetworkAdapter &adapterCache = m_cache.child(iSlot);
936 if (adapterCache.wasChanged())
937 {
938 /* Check if adapter still valid: */
939 CNetworkAdapter adapter = m_machine.GetNetworkAdapter(iSlot);
940 if (!adapter.isNull())
941 {
942 /* Get adapter data from cache: */
943 const UIDataSettingsMachineNetworkAdapter &adapterData = adapterCache.data();
944
945 /* Store adapter data: */
946 if (isMachineOffline())
947 {
948 /* Basic attributes: */
949 adapter.SetEnabled(adapterData.m_fAdapterEnabled);
950 adapter.SetAdapterType(adapterData.m_adapterType);
951 adapter.SetMACAddress(adapterData.m_strMACAddress);
952 }
953 if (isMachineInValidMode())
954 {
955 /* Attachment type: */
956 switch (adapterData.m_attachmentType)
957 {
958 case KNetworkAttachmentType_Bridged:
959 adapter.SetBridgedInterface(adapterData.m_strBridgedAdapterName);
960 break;
961 case KNetworkAttachmentType_Internal:
962 adapter.SetInternalNetwork(adapterData.m_strInternalNetworkName);
963 break;
964 case KNetworkAttachmentType_HostOnly:
965 adapter.SetHostOnlyInterface(adapterData.m_strHostInterfaceName);
966 break;
967 case KNetworkAttachmentType_Generic:
968 adapter.SetGenericDriver(adapterData.m_strGenericDriverName);
969 updateGenericProperties(adapter, adapterData.m_strGenericProperties);
970 break;
971 case KNetworkAttachmentType_NATNetwork:
972 adapter.SetNATNetwork(adapterData.m_strNATNetworkName);
973 break;
974 default:
975 break;
976 }
977 adapter.SetAttachmentType(adapterData.m_attachmentType);
978 /* Advanced attributes: */
979 adapter.SetPromiscModePolicy(adapterData.m_promiscuousMode);
980 /* Cable connected flag: */
981 adapter.SetCableConnected(adapterData.m_fCableConnected);
982 /* Redirect options: */
983 QVector<QString> oldRedirects = adapter.GetNATEngine().GetRedirects();
984 for (int i = 0; i < oldRedirects.size(); ++i)
985 adapter.GetNATEngine().RemoveRedirect(oldRedirects[i].section(',', 0, 0));
986 UIPortForwardingDataList newRedirects = adapterData.m_redirects;
987 for (int i = 0; i < newRedirects.size(); ++i)
988 {
989 UIPortForwardingData newRedirect = newRedirects[i];
990 adapter.GetNATEngine().AddRedirect(newRedirect.name, newRedirect.protocol,
991 newRedirect.hostIp, newRedirect.hostPort.value(),
992 newRedirect.guestIp, newRedirect.guestPort.value());
993 }
994 }
995 }
996 }
997 }
998 }
999
1000 /* Upload machine to data: */
1001 UISettingsPageMachine::uploadData(data);
1002}
1003
1004bool UIMachineSettingsNetworkPage::validate(QList<UIValidationMessage> &messages)
1005{
1006 /* Pass by default: */
1007 bool fValid = true;
1008
1009 /* Delegate validation to adapter tabs: */
1010 for (int i = 0; i < m_pTwAdapters->count(); ++i)
1011 {
1012 UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTwAdapters->widget(i));
1013 AssertMsg(pTab, ("Can't get adapter tab!\n"));
1014 if (!pTab->validate(messages))
1015 fValid = false;
1016 }
1017
1018 /* Return result: */
1019 return fValid;
1020}
1021
1022void UIMachineSettingsNetworkPage::retranslateUi()
1023{
1024 for (int i = 0; i < m_pTwAdapters->count(); ++ i)
1025 {
1026 UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTwAdapters->widget(i));
1027 Assert(pTab);
1028 m_pTwAdapters->setTabText(i, pTab->tabTitle());
1029 }
1030}
1031
1032void UIMachineSettingsNetworkPage::sltHandleUpdatedTab()
1033{
1034 /* Determine the sender: */
1035 UIMachineSettingsNetwork *pSender = qobject_cast<UIMachineSettingsNetwork*>(sender());
1036 AssertMsg(pSender, ("This slot should be called only through signal<->slot mechanism from one of UIMachineSettingsNetwork tabs!\n"));
1037
1038 /* Determine sender's attachment type: */
1039 KNetworkAttachmentType senderAttachmentType = pSender->attachmentType();
1040 switch (senderAttachmentType)
1041 {
1042 case KNetworkAttachmentType_Internal:
1043 {
1044 refreshInternalNetworkList();
1045 break;
1046 }
1047 case KNetworkAttachmentType_Generic:
1048 {
1049 refreshGenericDriverList();
1050 break;
1051 }
1052 default:
1053 break;
1054 }
1055
1056 /* Update all the tabs except the sender: */
1057 for (int iSlot = 0; iSlot < m_pTwAdapters->count(); ++iSlot)
1058 {
1059 /* Get the iterated tab: */
1060 UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTwAdapters->widget(iSlot));
1061 AssertMsg(pTab, ("All the tabs of m_pTwAdapters should be of the UIMachineSettingsNetwork type!\n"));
1062
1063 /* Update all the tabs (except sender) with the same attachment type as sender have: */
1064 if (pTab != pSender && pTab->attachmentType() == senderAttachmentType)
1065 pTab->reloadAlternative();
1066 }
1067}
1068
1069void UIMachineSettingsNetworkPage::polishPage()
1070{
1071 /* Get the count of network adapter tabs: */
1072 for (int iSlot = 0; iSlot < m_pTwAdapters->count(); ++iSlot)
1073 {
1074 m_pTwAdapters->setTabEnabled(iSlot,
1075 isMachineOffline() ||
1076 (isMachineInValidMode() && m_cache.child(iSlot).base().m_fAdapterEnabled));
1077 UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTwAdapters->widget(iSlot));
1078 pTab->polishTab();
1079 }
1080}
1081
1082void UIMachineSettingsNetworkPage::refreshBridgedAdapterList()
1083{
1084 /* Reload bridged interface list: */
1085 m_bridgedAdapterList.clear();
1086 const CHostNetworkInterfaceVector &ifaces = vboxGlobal().host().GetNetworkInterfaces();
1087 for (int i = 0; i < ifaces.size(); ++i)
1088 {
1089 const CHostNetworkInterface &iface = ifaces[i];
1090 if (iface.GetInterfaceType() == KHostNetworkInterfaceType_Bridged && !m_bridgedAdapterList.contains(iface.GetName()))
1091 m_bridgedAdapterList << iface.GetName();
1092 }
1093}
1094
1095void UIMachineSettingsNetworkPage::refreshInternalNetworkList(bool fFullRefresh /* = false */)
1096{
1097 /* Reload internal network list: */
1098 m_internalNetworkList.clear();
1099 /* Get internal network names from other VMs: */
1100 if (fFullRefresh)
1101 m_internalNetworkList << otherInternalNetworkList();
1102 /* Append internal network list with names from all the tabs: */
1103 for (int iTab = 0; iTab < m_pTwAdapters->count(); ++iTab)
1104 {
1105 UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTwAdapters->widget(iTab));
1106 if (pTab)
1107 {
1108 QString strName = pTab->alternativeName(KNetworkAttachmentType_Internal);
1109 if (!strName.isEmpty() && !m_internalNetworkList.contains(strName))
1110 m_internalNetworkList << strName;
1111 }
1112 }
1113}
1114
1115void UIMachineSettingsNetworkPage::refreshHostInterfaceList()
1116{
1117 /* Reload host-only interface list: */
1118 m_hostInterfaceList.clear();
1119 const CHostNetworkInterfaceVector &ifaces = vboxGlobal().host().GetNetworkInterfaces();
1120 for (int i = 0; i < ifaces.size(); ++i)
1121 {
1122 const CHostNetworkInterface &iface = ifaces[i];
1123 if (iface.GetInterfaceType() == KHostNetworkInterfaceType_HostOnly && !m_hostInterfaceList.contains(iface.GetName()))
1124 m_hostInterfaceList << iface.GetName();
1125 }
1126}
1127
1128void UIMachineSettingsNetworkPage::refreshGenericDriverList(bool fFullRefresh /* = false */)
1129{
1130 /* Load generic driver list: */
1131 m_genericDriverList.clear();
1132 /* Get generic driver names from other VMs: */
1133 if (fFullRefresh)
1134 m_genericDriverList << otherGenericDriverList();
1135 /* Append generic driver list with names from all the tabs: */
1136 for (int iTab = 0; iTab < m_pTwAdapters->count(); ++iTab)
1137 {
1138 UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTwAdapters->widget(iTab));
1139 if (pTab)
1140 {
1141 QString strName = pTab->alternativeName(KNetworkAttachmentType_Generic);
1142 if (!strName.isEmpty() && !m_genericDriverList.contains(strName))
1143 m_genericDriverList << strName;
1144 }
1145 }
1146}
1147
1148void UIMachineSettingsNetworkPage::refreshNATNetworkList()
1149{
1150 /* Reload NAT network list: */
1151 m_natNetworkList.clear();
1152 const CNATNetworkVector &nws = vboxGlobal().virtualBox().GetNATNetworks();
1153 for (int i = 0; i < nws.size(); ++i)
1154 {
1155 const CNATNetwork &nw = nws[i];
1156 m_natNetworkList << nw.GetNetworkName();
1157 }
1158}
1159
1160/* static */
1161QStringList UIMachineSettingsNetworkPage::otherInternalNetworkList()
1162{
1163 /* Load total internal network list of all VMs: */
1164 CVirtualBox vbox = vboxGlobal().virtualBox();
1165 QStringList otherInternalNetworks(QList<QString>::fromVector(vbox.GetInternalNetworks()));
1166 return otherInternalNetworks;
1167}
1168
1169/* static */
1170QStringList UIMachineSettingsNetworkPage::otherGenericDriverList()
1171{
1172 /* Load total generic driver list of all VMs: */
1173 CVirtualBox vbox = vboxGlobal().virtualBox();
1174 QStringList otherGenericDrivers(QList<QString>::fromVector(vbox.GetGenericNetworkDrivers()));
1175 return otherGenericDrivers;
1176}
1177
1178/* static */
1179QString UIMachineSettingsNetworkPage::summarizeGenericProperties(const CNetworkAdapter &adapter)
1180{
1181 /* Prepare formatted string: */
1182 QVector<QString> names;
1183 QVector<QString> props;
1184 props = adapter.GetProperties(QString(), names);
1185 QString strResult;
1186 /* Load generic properties: */
1187 for (int i = 0; i < names.size(); ++i)
1188 {
1189 strResult += names[i] + "=" + props[i];
1190 if (i < names.size() - 1)
1191 strResult += "\n";
1192 }
1193 /* Return formatted string: */
1194 return strResult;
1195}
1196
1197/* static */
1198void UIMachineSettingsNetworkPage::updateGenericProperties(CNetworkAdapter &adapter, const QString &strPropText)
1199{
1200 /* Parse new properties: */
1201 QStringList newProps = strPropText.split("\n");
1202 QHash<QString, QString> hash;
1203
1204 /* Save new properties: */
1205 for (int i = 0; i < newProps.size(); ++i)
1206 {
1207 QString strLine = newProps[i];
1208 int iSplitPos = strLine.indexOf("=");
1209 if (iSplitPos)
1210 {
1211 QString strKey = strLine.left(iSplitPos);
1212 QString strVal = strLine.mid(iSplitPos+1);
1213 adapter.SetProperty(strKey, strVal);
1214 hash[strKey] = strVal;
1215 }
1216 }
1217
1218 /* Removing deleted properties: */
1219 QVector<QString> names;
1220 QVector<QString> props;
1221 props = adapter.GetProperties(QString(), names);
1222 for (int i = 0; i < names.size(); ++i)
1223 {
1224 QString strName = names[i];
1225 QString strValue = props[i];
1226 if (strValue != hash[strName])
1227 adapter.SetProperty(strName, hash[strName]);
1228 }
1229}
1230
Note: See TracBrowser for help on using the repository browser.

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