VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/widgets/UINetworkAttachmentEditor.cpp@ 82781

Last change on this file since 82781 was 82563, checked in by vboxsync, 4 years ago

FE/Qt: bugref:9611: UINetworkAttachmentEditor: Get rid of hardcoded network attachment types, instead acquire these types through CSystemProperties interface.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 17.9 KB
Line 
1/* $Id: UINetworkAttachmentEditor.cpp 82563 2019-12-12 08:36:15Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UINetworkAttachmentEditor class implementation.
4 */
5
6/*
7 * Copyright (C) 2019 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18/* Qt includes: */
19#include <QGridLayout>
20#include <QHBoxLayout>
21#include <QLabel>
22
23/* GUI includes: */
24#include "QIComboBox.h"
25#include "UICommon.h"
26#include "UIConverter.h"
27#include "UIExtraDataManager.h"
28#include "UINetworkAttachmentEditor.h"
29
30/* COM includes: */
31#ifdef VBOX_WITH_CLOUD_NET
32# include "CCloudNetwork.h"
33#endif
34#include "CHostNetworkInterface.h"
35#include "CNATNetwork.h"
36#include "CSystemProperties.h"
37
38
39/* static */
40QString UINetworkAttachmentEditor::s_strEmptyItemId = QString("#empty#");
41
42UINetworkAttachmentEditor::UINetworkAttachmentEditor(QWidget *pParent /* = 0 */, bool fWithLabels /* = false */)
43 : QIWithRetranslateUI<QWidget>(pParent)
44 , m_fWithLabels(fWithLabels)
45 , m_enmRestrictedNetworkAttachmentTypes(UIExtraDataMetaDefs::DetailsElementOptionTypeNetwork_Invalid)
46 , m_enmType(KNetworkAttachmentType_Max)
47 , m_pLabelType(0)
48 , m_pComboType(0)
49 , m_pLabelName(0)
50 , m_pComboName(0)
51{
52 prepare();
53}
54
55QWidget *UINetworkAttachmentEditor::focusProxy1() const
56{
57 return m_pComboType->focusProxy();
58}
59
60QWidget *UINetworkAttachmentEditor::focusProxy2() const
61{
62 return m_pComboName->focusProxy();
63}
64
65void UINetworkAttachmentEditor::setValueType(KNetworkAttachmentType enmType)
66{
67 /* Make sure combo is there: */
68 if (!m_pComboType)
69 return;
70 /* Make sure type is changed: */
71 if (m_enmType == enmType)
72 return;
73
74 /* Remember requested type: */
75 m_enmType = enmType;
76 /* Repopulate finally, supported values might change: */
77 populateTypeCombo();
78}
79
80KNetworkAttachmentType UINetworkAttachmentEditor::valueType() const
81{
82 return m_pComboType ? m_pComboType->currentData().value<KNetworkAttachmentType>() : m_enmType;
83}
84
85void UINetworkAttachmentEditor::setValueNames(KNetworkAttachmentType enmType, const QStringList &names)
86{
87 /* Save possible names for passed type: */
88 m_names[enmType] = names;
89
90 /* If value type is the same, update the combo as well: */
91 if (valueType() == enmType)
92 populateNameCombo();
93}
94
95void UINetworkAttachmentEditor::setValueName(KNetworkAttachmentType enmType, const QString &strName)
96{
97 /* Save current name for passed type: */
98 m_name[enmType] = strName;
99
100 /* Make sure combo is there: */
101 if (!m_pComboName)
102 return;
103
104 /* If value type is the same, update the combo as well: */
105 if (valueType() == enmType)
106 {
107 const int iIndex = m_pComboName->findText(strName);
108 if (iIndex != -1)
109 m_pComboName->setCurrentIndex(iIndex);
110 }
111}
112
113QString UINetworkAttachmentEditor::valueName(KNetworkAttachmentType enmType) const
114{
115 return m_name.value(enmType);
116}
117
118/* static */
119QStringList UINetworkAttachmentEditor::bridgedAdapters()
120{
121 QStringList bridgedAdapterList;
122 foreach (const CHostNetworkInterface &comInterface, uiCommon().host().GetNetworkInterfaces())
123 {
124 if ( comInterface.GetInterfaceType() == KHostNetworkInterfaceType_Bridged
125 && !bridgedAdapterList.contains(comInterface.GetName()))
126 bridgedAdapterList << comInterface.GetName();
127 }
128 return bridgedAdapterList;
129}
130
131/* static */
132QStringList UINetworkAttachmentEditor::internalNetworks()
133{
134 return QList<QString>::fromVector(uiCommon().virtualBox().GetInternalNetworks());
135}
136
137/* static */
138QStringList UINetworkAttachmentEditor::hostInterfaces()
139{
140 QStringList hostInterfaceList;
141 foreach (const CHostNetworkInterface &comInterface, uiCommon().host().GetNetworkInterfaces())
142 {
143 if ( comInterface.GetInterfaceType() == KHostNetworkInterfaceType_HostOnly
144 && !hostInterfaceList.contains(comInterface.GetName()))
145 hostInterfaceList << comInterface.GetName();
146 }
147 return hostInterfaceList;
148}
149
150/* static */
151QStringList UINetworkAttachmentEditor::genericDrivers()
152{
153 return QList<QString>::fromVector(uiCommon().virtualBox().GetGenericNetworkDrivers());
154}
155
156/* static */
157QStringList UINetworkAttachmentEditor::natNetworks()
158{
159 QStringList natNetworkList;
160 foreach (const CNATNetwork &comNetwork, uiCommon().virtualBox().GetNATNetworks())
161 natNetworkList << comNetwork.GetNetworkName();
162 return natNetworkList;
163}
164
165#ifdef VBOX_WITH_CLOUD_NET
166/* static */
167QStringList UINetworkAttachmentEditor::cloudNetworks()
168{
169 QStringList cloudNetworkList;
170 foreach (const CCloudNetwork &comNetwork, uiCommon().virtualBox().GetCloudNetworks())
171 cloudNetworkList << comNetwork.GetNetworkName();
172 return cloudNetworkList;
173}
174#endif /* VBOX_WITH_CLOUD_NET */
175
176void UINetworkAttachmentEditor::retranslateUi()
177{
178 /* Translate type label: */
179 if (m_pLabelType)
180 m_pLabelType->setText(tr("&Attached to:"));
181
182 /* Translate name label: */
183 if (m_pLabelName)
184 m_pLabelName->setText(tr("&Name:"));
185
186 /* Translate type combo: */
187 if (m_pComboType)
188 {
189 for (int i = 0; i < m_pComboType->count(); ++i)
190 {
191 const KNetworkAttachmentType enmType = m_pComboType->itemData(i).value<KNetworkAttachmentType>();
192 const QString strName = gpConverter->toString(enmType);
193 m_pComboType->setItemData(i, strName, Qt::ToolTipRole);
194 m_pComboType->setItemText(i, strName);
195 }
196 }
197
198 /* Translate name combo: */
199 retranslateNameDescription();
200}
201
202void UINetworkAttachmentEditor::sltHandleCurrentTypeChanged()
203{
204 /* Update name label & combo: */
205 if (m_pLabelName)
206 m_pLabelName->setEnabled( valueType() != KNetworkAttachmentType_Null
207 && valueType() != KNetworkAttachmentType_NAT);
208 if (m_pComboName)
209 {
210 m_pComboName->setEnabled( valueType() != KNetworkAttachmentType_Null
211 && valueType() != KNetworkAttachmentType_NAT);
212 m_pComboName->setEditable( valueType() == KNetworkAttachmentType_Internal
213 || valueType() == KNetworkAttachmentType_Generic);
214 }
215
216 /* Update name combo description: */
217 retranslateNameDescription();
218
219 /* Notify listeners: */
220 emit sigValueTypeChanged();
221
222 /* Update name combo: */
223 populateNameCombo();
224
225 /* Revalidate: */
226 revalidate();
227}
228
229void UINetworkAttachmentEditor::sltHandleCurrentNameChanged()
230{
231 if (m_pComboName)
232 {
233 /* Acquire new value name: */
234 QString strNewName;
235 /* Make sure that's not a name of 'empty' item: */
236 if (m_pComboName->currentData().toString() != s_strEmptyItemId)
237 strNewName = m_pComboName->currentText().simplified();
238 /* Make sure that's not an empty name itself: */
239 if (strNewName.isEmpty())
240 strNewName = QString();
241 /* If name is really changed: */
242 if (m_name[valueType()] != strNewName)
243 {
244 /* Store it: */
245 m_name[valueType()] = strNewName;
246 /* Notify listeners: */
247 emit sigValueNameChanged();
248 }
249 }
250
251 /* Revalidate: */
252 revalidate();
253}
254
255void UINetworkAttachmentEditor::prepare()
256{
257 /* Read current limitations: */
258 m_enmRestrictedNetworkAttachmentTypes = gEDataManager->restrictedNetworkAttachmentTypes();
259
260 /* Create main layout: */
261 QGridLayout *pMainLayout = new QGridLayout(this);
262 if (pMainLayout)
263 {
264 pMainLayout->setContentsMargins(0, 0, 0, 0);
265
266 int iColumn = 0;
267
268 /* Create type label: */
269 if (m_fWithLabels)
270 {
271 m_pLabelType = new QLabel(this);
272 m_pLabelType->setAlignment(Qt::AlignVCenter | Qt::AlignRight);
273 }
274 if (m_pLabelType)
275 pMainLayout->addWidget(m_pLabelType, 0, iColumn++);
276
277 /* Create type combo layout: */
278 QHBoxLayout *pComboLayout = new QHBoxLayout;
279 if (pComboLayout)
280 {
281 /* Create type combo: */
282 m_pComboType = new QIComboBox(this);
283 if (m_pComboType)
284 {
285 setFocusProxy(m_pComboType->focusProxy());
286 if (m_pLabelType)
287 m_pLabelType->setBuddy(m_pComboType->focusProxy());
288 connect(m_pComboType, static_cast<void(QIComboBox::*)(int)>(&QIComboBox::currentIndexChanged),
289 this, &UINetworkAttachmentEditor::sltHandleCurrentTypeChanged);
290 pComboLayout->addWidget(m_pComboType);
291 }
292
293 /* Add stretch: */
294 pComboLayout->addStretch();
295
296 /* Add combo-layout into main-layout: */
297 pMainLayout->addLayout(pComboLayout, 0, iColumn++);
298 }
299
300 iColumn = 0;
301
302 /* Create name label: */
303 if (m_fWithLabels)
304 {
305 m_pLabelName = new QLabel(this);
306 m_pLabelName->setAlignment(Qt::AlignVCenter | Qt::AlignRight);
307 }
308 if (m_pLabelName)
309 pMainLayout->addWidget(m_pLabelName, 1, iColumn++);
310
311 /* Create name combo: */
312 m_pComboName = new QIComboBox(this);
313 if (m_pComboName)
314 {
315 if (m_pLabelName)
316 m_pLabelName->setBuddy(m_pComboName->focusProxy());
317 m_pComboName->setInsertPolicy(QComboBox::NoInsert);
318 connect(m_pComboName, static_cast<void(QIComboBox::*)(int)>(&QIComboBox::currentIndexChanged),
319 this, &UINetworkAttachmentEditor::sltHandleCurrentNameChanged);
320 connect(m_pComboName, &QIComboBox::editTextChanged,
321 this, &UINetworkAttachmentEditor::sltHandleCurrentNameChanged);
322 pMainLayout->addWidget(m_pComboName, 1, iColumn++);
323 }
324 }
325
326 /* Populate type combo: */
327 populateTypeCombo();
328
329 /* Apply language settings: */
330 retranslateUi();
331}
332
333void UINetworkAttachmentEditor::populateTypeCombo()
334{
335 /* Make sure combo is there: */
336 if (!m_pComboType)
337 return;
338
339 /* Block signals initially: */
340 m_pComboType->blockSignals(true);
341
342 /* Clear the type combo-box: */
343 m_pComboType->clear();
344
345 /* Load currently supported network attachment types (system-properties getter): */
346 CSystemProperties comProperties = uiCommon().virtualBox().GetSystemProperties();
347 QVector<KNetworkAttachmentType> supportedTypes = comProperties.GetSupportedNetworkAttachmentTypes();
348 /* Take currently requested type into account if it's sane: */
349 if (!supportedTypes.contains(m_enmType) && m_enmType != KNetworkAttachmentType_Max)
350 supportedTypes.prepend(m_enmType);
351
352 /* Populate attachment types: */
353 int iAttachmentTypeIndex = 0;
354 foreach (const KNetworkAttachmentType &enmType, supportedTypes)
355 {
356 /* Filter currently restricted network attachment types (extra-data getter): */
357 if (m_enmRestrictedNetworkAttachmentTypes & toUiNetworkAdapterEnum(enmType))
358 continue;
359 m_pComboType->insertItem(iAttachmentTypeIndex, gpConverter->toString(enmType));
360 m_pComboType->setItemData(iAttachmentTypeIndex, QVariant::fromValue(enmType));
361 m_pComboType->setItemData(iAttachmentTypeIndex, m_pComboType->itemText(iAttachmentTypeIndex), Qt::ToolTipRole);
362 ++iAttachmentTypeIndex;
363 }
364
365 /* Restore previously selected type if possible: */
366 const int iIndex = m_pComboType->findData(m_enmType);
367 m_pComboType->setCurrentIndex(iIndex != -1 ? iIndex : 0);
368
369 /* Handle combo item change: */
370 sltHandleCurrentTypeChanged();
371
372 /* Unblock signals finally: */
373 m_pComboType->blockSignals(false);
374}
375
376void UINetworkAttachmentEditor::populateNameCombo()
377{
378 /* Make sure combo is there: */
379 if (!m_pComboName)
380 return;
381
382 /* Block signals initially: */
383 m_pComboName->blockSignals(true);
384
385 /* Clear the name combo: */
386 m_pComboName->clear();
387
388 /* Add corresponding names to combo: */
389 m_pComboName->addItems(m_names.value(valueType()));
390
391 /* Prepend 'empty' or 'default' item to combo: */
392 if (m_pComboName->count() == 0)
393 {
394 switch (valueType())
395 {
396 case KNetworkAttachmentType_Bridged:
397 case KNetworkAttachmentType_HostOnly:
398 case KNetworkAttachmentType_NATNetwork:
399#ifdef VBOX_WITH_CLOUD_NET
400 case KNetworkAttachmentType_Cloud:
401#endif /* VBOX_WITH_CLOUD_NET */
402 {
403 /* If adapter list is empty => add 'Not selected' item: */
404 const int iIndex = m_pComboName->findData(s_strEmptyItemId);
405 if (iIndex == -1)
406 m_pComboName->insertItem(0, tr("Not selected", "network adapter name"), s_strEmptyItemId);
407 else
408 m_pComboName->setItemText(iIndex, tr("Not selected", "network adapter name"));
409 break;
410 }
411 case KNetworkAttachmentType_Internal:
412 {
413 /* Internal network list should have a default item: */
414 if (m_pComboName->findText("intnet") == -1)
415 m_pComboName->insertItem(0, "intnet");
416 break;
417 }
418 default:
419 break;
420 }
421 }
422
423 /* Restore previously selected name: */
424 const int iIndex = m_pComboName->findText(m_name.value(valueType()));
425 if (iIndex != -1)
426 m_pComboName->setCurrentIndex(iIndex);
427
428 /* Handle combo item change: */
429 sltHandleCurrentNameChanged();
430
431 /* Unblock signals finally: */
432 m_pComboName->blockSignals(false);
433}
434
435void UINetworkAttachmentEditor::retranslateNameDescription()
436{
437 /* Update name combo description: */
438 switch (valueType())
439 {
440 case KNetworkAttachmentType_Bridged:
441 m_pComboName->setWhatsThis(tr("Selects the network adapter on the host system that traffic "
442 "to and from this network card will go through."));
443 break;
444 case KNetworkAttachmentType_Internal:
445 m_pComboName->setWhatsThis(tr("Holds the name of the internal network that this network card "
446 "will be connected to. You can create a new internal network by "
447 "choosing a name which is not used by any other network cards "
448 "in this virtual machine or others."));
449 break;
450 case KNetworkAttachmentType_HostOnly:
451 m_pComboName->setWhatsThis(tr("Selects the virtual network adapter on the host system that traffic "
452 "to and from this network card will go through. "
453 "You can create and remove adapters using the global network "
454 "settings in the virtual machine manager window."));
455 break;
456 case KNetworkAttachmentType_Generic:
457 m_pComboName->setWhatsThis(tr("Selects the driver to be used with this network card."));
458 break;
459 case KNetworkAttachmentType_NATNetwork:
460 m_pComboName->setWhatsThis(tr("Holds the name of the NAT network that this network card "
461 "will be connected to. You can create and remove networks "
462 "using the global network settings in the virtual machine "
463 "manager window."));
464 break;
465#ifdef VBOX_WITH_CLOUD_NET
466 case KNetworkAttachmentType_Cloud:
467 m_pComboName->setWhatsThis(tr("(experimental) Holds the name of the cloud network that this network card "
468 "will be connected to. You can add and remove cloud networks "
469 "using the global network settings in the virtual machine "
470 "manager window."));
471 break;
472#endif /* VBOX_WITH_CLOUD_NET */
473 default:
474 m_pComboName->setWhatsThis(QString());
475 break;
476 }
477}
478
479void UINetworkAttachmentEditor::revalidate()
480{
481 bool fSuccess = false;
482 switch (valueType())
483 {
484 case KNetworkAttachmentType_Bridged:
485 case KNetworkAttachmentType_Internal:
486 case KNetworkAttachmentType_HostOnly:
487 case KNetworkAttachmentType_Generic:
488 case KNetworkAttachmentType_NATNetwork:
489#ifdef VBOX_WITH_CLOUD_NET
490 case KNetworkAttachmentType_Cloud:
491#endif /* VBOX_WITH_CLOUD_NET */
492 fSuccess = !valueName(valueType()).isEmpty();
493 break;
494 default:
495 fSuccess = true;
496 break;
497 }
498 emit sigValidChanged(fSuccess);
499}
500
501/* static */
502UIExtraDataMetaDefs::DetailsElementOptionTypeNetwork UINetworkAttachmentEditor::toUiNetworkAdapterEnum(KNetworkAttachmentType comEnum)
503{
504 switch (comEnum)
505 {
506 case KNetworkAttachmentType_NAT: return UIExtraDataMetaDefs::DetailsElementOptionTypeNetwork_NAT;
507 case KNetworkAttachmentType_Bridged: return UIExtraDataMetaDefs::DetailsElementOptionTypeNetwork_BridgetAdapter;
508 case KNetworkAttachmentType_Internal: return UIExtraDataMetaDefs::DetailsElementOptionTypeNetwork_InternalNetwork;
509 case KNetworkAttachmentType_HostOnly: return UIExtraDataMetaDefs::DetailsElementOptionTypeNetwork_HostOnlyAdapter;
510 case KNetworkAttachmentType_Generic: return UIExtraDataMetaDefs::DetailsElementOptionTypeNetwork_GenericDriver;
511 case KNetworkAttachmentType_NATNetwork: return UIExtraDataMetaDefs::DetailsElementOptionTypeNetwork_NATNetwork;
512#ifdef VBOX_WITH_CLOUD_NET
513 case KNetworkAttachmentType_Cloud: return UIExtraDataMetaDefs::DetailsElementOptionTypeNetwork_CloudNetwork;
514#endif /* VBOX_WITH_CLOUD_NET */
515 default: return UIExtraDataMetaDefs::DetailsElementOptionTypeNetwork_Invalid;
516 }
517}
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use