VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/networkmanager/UINetworkManager.cpp@ 104158

Last change on this file since 104158 was 103771, checked in by vboxsync, 9 months ago

FE/Qt: UICommon: Switching dependency from UICommon to UIGlobalSession whenever is possible.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 105.7 KB
Line 
1/* $Id: UINetworkManager.cpp 103771 2024-03-11 15:16:04Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UINetworkManager class implementation.
4 */
5
6/*
7 * Copyright (C) 2009-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28/* Qt includes: */
29#include <QHeaderView>
30#include <QMenuBar>
31#include <QPushButton>
32#include <QRegularExpression>
33#include <QVBoxLayout>
34
35/* GUI includes: */
36#include "QIDialogButtonBox.h"
37#include "QITabWidget.h"
38#include "QITreeWidget.h"
39#include "QIToolBar.h"
40#include "UIActionPoolManager.h"
41#include "UICommon.h"
42#include "UIConverter.h"
43#include "UIDetailsWidgetCloudNetwork.h"
44#include "UIDetailsWidgetHostNetwork.h"
45#include "UIDetailsWidgetNATNetwork.h"
46#include "UIExtraDataManager.h"
47#include "UIGlobalSession.h"
48#include "UIIconPool.h"
49#include "UIMessageCenter.h"
50#include "UINetworkManager.h"
51#include "UINetworkManagerUtils.h"
52#include "UINotificationCenter.h"
53#include "UIShortcutPool.h"
54#ifdef VBOX_WS_MAC
55# include "UIWindowMenuManager.h"
56#endif
57
58/* COM includes: */
59#include "CCloudNetwork.h"
60#include "CDHCPServer.h"
61#include "CHost.h"
62#ifdef VBOX_WS_MAC
63# include "CHostOnlyNetwork.h"
64#else
65# include "CHostNetworkInterface.h"
66#endif
67#include "CNATNetwork.h"
68
69
70/** Tab-widget indexes. */
71enum TabWidgetIndex
72{
73 TabWidgetIndex_HostNetwork,
74 TabWidgetIndex_NATNetwork,
75 TabWidgetIndex_CloudNetwork,
76};
77
78
79#ifdef VBOX_WS_MAC
80/** Host network tree-widget column indexes. */
81enum HostNetworkColumn
82{
83 HostNetworkColumn_Name,
84 HostNetworkColumn_Mask,
85 HostNetworkColumn_LBnd,
86 HostNetworkColumn_UBnd,
87 HostNetworkColumn_Max,
88};
89
90#else /* !VBOX_WS_MAC */
91
92/** Host network tree-widget column indexes. */
93enum HostNetworkColumn
94{
95 HostNetworkColumn_Name,
96 HostNetworkColumn_IPv4,
97 HostNetworkColumn_IPv6,
98 HostNetworkColumn_DHCP,
99 HostNetworkColumn_Max,
100};
101#endif /* !VBOX_WS_MAC */
102
103
104/** NAT network tree-widget column indexes. */
105enum NATNetworkColumn
106{
107 NATNetworkColumn_Name,
108 NATNetworkColumn_IPv4,
109 NATNetworkColumn_IPv6,
110 NATNetworkColumn_DHCP,
111 NATNetworkColumn_Max,
112};
113
114
115/** Cloud network tree-widget column indexes. */
116enum CloudNetworkColumn
117{
118 CloudNetworkColumn_Name,
119 CloudNetworkColumn_Provider,
120 CloudNetworkColumn_Profile,
121 CloudNetworkColumn_Max,
122};
123
124
125/** Network Manager: Host Network tree-widget item. */
126class UIItemHostNetwork : public QITreeWidgetItem, public UIDataHostNetwork
127{
128 Q_OBJECT;
129
130public:
131
132 /** Updates item fields from data. */
133 void updateFields();
134
135#ifdef VBOX_WS_MAC
136 /** Returns item name. */
137 QString name() const { return m_strName; }
138#else
139 /** Returns item name. */
140 QString name() const { return m_interface.m_strName; }
141#endif
142
143private:
144
145#ifndef VBOX_WS_MAC
146 /** Returns CIDR for a passed @a strMask. */
147 static int maskToCidr(const QString &strMask);
148#endif
149};
150
151
152/** Network Manager: NAT Network tree-widget item. */
153class UIItemNATNetwork : public QITreeWidgetItem, public UIDataNATNetwork
154{
155 Q_OBJECT;
156
157public:
158
159 /** Updates item fields from data. */
160 void updateFields();
161
162 /** Returns item name. */
163 QString name() const { return m_strName; }
164};
165
166
167/** Network Manager: Cloud Network tree-widget item. */
168class UIItemCloudNetwork : public QITreeWidgetItem, public UIDataCloudNetwork
169{
170 Q_OBJECT;
171
172public:
173
174 /** Updates item fields from data. */
175 void updateFields();
176
177 /** Returns item name. */
178 QString name() const { return m_strName; }
179};
180
181
182/*********************************************************************************************************************************
183* Class UIItemHostNetwork implementation. *
184*********************************************************************************************************************************/
185
186void UIItemHostNetwork::updateFields()
187{
188#ifdef VBOX_WS_MAC
189 /* Compose item fields: */
190 setText(HostNetworkColumn_Name, m_strName);
191 setText(HostNetworkColumn_Mask, m_strMask);
192 setText(HostNetworkColumn_LBnd, m_strLBnd);
193 setText(HostNetworkColumn_UBnd, m_strUBnd);
194
195 /* Compose item tool-tip: */
196 const QString strTable("<table cellspacing=5>%1</table>");
197 const QString strHeader("<tr><td><nobr>%1:&nbsp;</nobr></td><td><nobr>%2</nobr></td></tr>");
198 QString strToolTip;
199
200 /* Network information: */
201 strToolTip += strHeader.arg(UINetworkManager::tr("Name"), m_strName);
202 strToolTip += strHeader.arg(UINetworkManager::tr("Mask"), m_strMask);
203 strToolTip += strHeader.arg(UINetworkManager::tr("Lower Bound"), m_strLBnd);
204 strToolTip += strHeader.arg(UINetworkManager::tr("Upper Bound"), m_strUBnd);
205
206#else /* !VBOX_WS_MAC */
207
208 /* Compose item fields: */
209 setText(HostNetworkColumn_Name, m_interface.m_strName);
210 setText(HostNetworkColumn_IPv4, m_interface.m_strAddress.isEmpty() ? QString() :
211 QString("%1/%2").arg(m_interface.m_strAddress).arg(maskToCidr(m_interface.m_strMask)));
212 setText(HostNetworkColumn_IPv6, m_interface.m_strAddress6.isEmpty() || !m_interface.m_fSupportedIPv6 ? QString() :
213 QString("%1/%2").arg(m_interface.m_strAddress6).arg(m_interface.m_strPrefixLength6.toInt()));
214 setText(HostNetworkColumn_DHCP, m_dhcpserver.m_fEnabled ? UINetworkManager::tr("Enabled", "DHCP Server")
215 : UINetworkManager::tr("Disabled", "DHCP Server"));
216
217 /* Compose item tool-tip: */
218 const QString strTable("<table cellspacing=5>%1</table>");
219 const QString strHeader("<tr><td><nobr>%1:&nbsp;</nobr></td><td><nobr>%2</nobr></td></tr>");
220 const QString strSubHeader("<tr><td><nobr>&nbsp;&nbsp;%1:&nbsp;</nobr></td><td><nobr>%2</nobr></td></tr>");
221 QString strToolTip;
222
223 /* Interface information: */
224 strToolTip += strHeader.arg(UINetworkManager::tr("Adapter"))
225 .arg(m_interface.m_fDHCPEnabled ?
226 UINetworkManager::tr("Automatically configured", "interface") :
227 UINetworkManager::tr("Manually configured", "interface"));
228 strToolTip += strSubHeader.arg(UINetworkManager::tr("IPv4 Address"))
229 .arg(m_interface.m_strAddress.isEmpty() ?
230 UINetworkManager::tr ("Not set", "address") :
231 m_interface.m_strAddress) +
232 strSubHeader.arg(UINetworkManager::tr("IPv4 Network Mask"))
233 .arg(m_interface.m_strMask.isEmpty() ?
234 UINetworkManager::tr ("Not set", "mask") :
235 m_interface.m_strMask);
236 if (m_interface.m_fSupportedIPv6)
237 {
238 strToolTip += strSubHeader.arg(UINetworkManager::tr("IPv6 Address"))
239 .arg(m_interface.m_strAddress6.isEmpty() ?
240 UINetworkManager::tr("Not set", "address") :
241 m_interface.m_strAddress6) +
242 strSubHeader.arg(UINetworkManager::tr("IPv6 Prefix Length"))
243 .arg(m_interface.m_strPrefixLength6.isEmpty() ?
244 UINetworkManager::tr("Not set", "length") :
245 m_interface.m_strPrefixLength6);
246 }
247
248 /* DHCP server information: */
249 strToolTip += strHeader.arg(UINetworkManager::tr("DHCP Server"))
250 .arg(m_dhcpserver.m_fEnabled ?
251 UINetworkManager::tr("Enabled", "server") :
252 UINetworkManager::tr("Disabled", "server"));
253 if (m_dhcpserver.m_fEnabled)
254 {
255 strToolTip += strSubHeader.arg(UINetworkManager::tr("Address"))
256 .arg(m_dhcpserver.m_strAddress.isEmpty() ?
257 UINetworkManager::tr("Not set", "address") :
258 m_dhcpserver.m_strAddress) +
259 strSubHeader.arg(UINetworkManager::tr("Network Mask"))
260 .arg(m_dhcpserver.m_strMask.isEmpty() ?
261 UINetworkManager::tr("Not set", "mask") :
262 m_dhcpserver.m_strMask) +
263 strSubHeader.arg(UINetworkManager::tr("Lower Bound"))
264 .arg(m_dhcpserver.m_strLowerAddress.isEmpty() ?
265 UINetworkManager::tr("Not set", "bound") :
266 m_dhcpserver.m_strLowerAddress) +
267 strSubHeader.arg(UINetworkManager::tr("Upper Bound"))
268 .arg(m_dhcpserver.m_strUpperAddress.isEmpty() ?
269 UINetworkManager::tr("Not set", "bound") :
270 m_dhcpserver.m_strUpperAddress);
271 }
272#endif /* !VBOX_WS_MAC */
273
274 /* Assign tool-tip finally: */
275 setToolTip(HostNetworkColumn_Name, strTable.arg(strToolTip));
276}
277
278#ifndef VBOX_WS_MAC
279/* static */
280int UIItemHostNetwork::maskToCidr(const QString &strMask)
281{
282 /* Parse passed mask: */
283 QList<int> address;
284 foreach (const QString &strValue, strMask.split('.'))
285 address << strValue.toInt();
286
287 /* Calculate CIDR: */
288 int iCidr = 0;
289 for (int i = 0; i < 4 || i < address.size(); ++i)
290 {
291 switch(address.at(i))
292 {
293 case 0x80: iCidr += 1; break;
294 case 0xC0: iCidr += 2; break;
295 case 0xE0: iCidr += 3; break;
296 case 0xF0: iCidr += 4; break;
297 case 0xF8: iCidr += 5; break;
298 case 0xFC: iCidr += 6; break;
299 case 0xFE: iCidr += 7; break;
300 case 0xFF: iCidr += 8; break;
301 /* Return CIDR prematurelly: */
302 default: return iCidr;
303 }
304 }
305
306 /* Return CIDR: */
307 return iCidr;
308}
309#endif /* !VBOX_WS_MAC */
310
311
312/*********************************************************************************************************************************
313* Class UIItemNATNetwork implementation. *
314*********************************************************************************************************************************/
315
316void UIItemNATNetwork::updateFields()
317{
318 /* Compose item fields: */
319 setText(NATNetworkColumn_Name, m_strName);
320 setText(NATNetworkColumn_IPv4, m_strPrefixIPv4);
321 setText(NATNetworkColumn_IPv6, m_strPrefixIPv6);
322 setText(NATNetworkColumn_DHCP, m_fSupportsDHCP ? UINetworkManager::tr("Enabled", "DHCP Server")
323 : UINetworkManager::tr("Disabled", "DHCP Server"));
324
325 /* Compose item tool-tip: */
326 const QString strTable("<table cellspacing=5>%1</table>");
327 const QString strHeader("<tr><td><nobr>%1:&nbsp;</nobr></td><td><nobr>%2</nobr></td></tr>");
328 const QString strSubHeader("<tr><td><nobr>&nbsp;&nbsp;%1:&nbsp;</nobr></td><td><nobr>%2</nobr></td></tr>");
329 QString strToolTip;
330
331 /* Network information: */
332 strToolTip += strHeader.arg(UINetworkManager::tr("Network Name"), m_strName);
333 strToolTip += strHeader.arg(UINetworkManager::tr("Network IPv4 Prefix"), m_strPrefixIPv4);
334 strToolTip += strHeader.arg(UINetworkManager::tr("Network IPv6 Prefix"), m_strPrefixIPv6);
335 strToolTip += strHeader.arg(UINetworkManager::tr("Supports DHCP"), m_fSupportsDHCP ? UINetworkManager::tr("yes")
336 : UINetworkManager::tr("no"));
337 strToolTip += strHeader.arg(UINetworkManager::tr("Supports IPv6"), m_fSupportsIPv6 ? UINetworkManager::tr("yes")
338 : UINetworkManager::tr("no"));
339 if (m_fSupportsIPv6 && m_fAdvertiseDefaultIPv6Route)
340 strToolTip += strSubHeader.arg(UINetworkManager::tr("Default IPv6 route"), UINetworkManager::tr("yes"));
341
342 /* Assign tool-tip finally: */
343 setToolTip(NATNetworkColumn_Name, strTable.arg(strToolTip));
344}
345
346
347/*********************************************************************************************************************************
348* Class UIItemCloudNetwork implementation. *
349*********************************************************************************************************************************/
350
351void UIItemCloudNetwork::updateFields()
352{
353 /* Compose item fields: */
354 setText(CloudNetworkColumn_Name, m_strName);
355 setText(CloudNetworkColumn_Provider, m_strProvider);
356 setText(CloudNetworkColumn_Profile, m_strProfile);
357
358 /* Compose item tool-tip: */
359 const QString strTable("<table cellspacing=5>%1</table>");
360 const QString strHeader("<tr><td><nobr>%1:&nbsp;</nobr></td><td><nobr>%2</nobr></td></tr>");
361 QString strToolTip;
362
363 /* Network information: */
364 strToolTip += strHeader.arg(UINetworkManager::tr("Network Name"), m_strName);
365 strToolTip += strHeader.arg(UINetworkManager::tr("Provider"), m_strProvider);
366 strToolTip += strHeader.arg(UINetworkManager::tr("Profile"), m_strProfile);
367
368 /* Assign tool-tip finally: */
369 setToolTip(CloudNetworkColumn_Name, strTable.arg(strToolTip));
370}
371
372
373/*********************************************************************************************************************************
374* Class UINetworkManagerWidget implementation. *
375*********************************************************************************************************************************/
376
377UINetworkManagerWidget::UINetworkManagerWidget(EmbedTo enmEmbedding, UIActionPool *pActionPool,
378 bool fShowToolbar /* = true */, QWidget *pParent /* = 0 */)
379 : QIWithRetranslateUI<QWidget>(pParent)
380 , m_enmEmbedding(enmEmbedding)
381 , m_pActionPool(pActionPool)
382 , m_fShowToolbar(fShowToolbar)
383 , m_pToolBar(0)
384 , m_pTabWidget(0)
385 , m_pTabHostNetwork(0)
386 , m_pLayoutHostNetwork(0)
387 , m_pTreeWidgetHostNetwork(0)
388 , m_pDetailsWidgetHostNetwork(0)
389 , m_pTabNATNetwork(0)
390 , m_pLayoutNATNetwork(0)
391 , m_pTreeWidgetNATNetwork(0)
392 , m_pDetailsWidgetNATNetwork(0)
393 , m_pTabCloudNetwork(0)
394 , m_pLayoutCloudNetwork(0)
395 , m_pTreeWidgetCloudNetwork(0)
396 , m_pDetailsWidgetCloudNetwork(0)
397{
398 prepare();
399}
400
401QMenu *UINetworkManagerWidget::menu() const
402{
403 AssertPtrReturn(m_pActionPool, 0);
404 return m_pActionPool->action(UIActionIndexMN_M_NetworkWindow)->menu();
405}
406
407void UINetworkManagerWidget::retranslateUi()
408{
409 /* Translate tab-widget: */
410 if (m_pTabWidget)
411 {
412 m_pTabWidget->setTabText(0, UINetworkManager::tr("Host-only Networks"));
413 m_pTabWidget->setTabText(1, UINetworkManager::tr("NAT Networks"));
414 m_pTabWidget->setTabText(2, UINetworkManager::tr("Cloud Networks"));
415 }
416
417 /* Translate host network tree-widget: */
418 if (m_pTreeWidgetHostNetwork)
419 {
420#ifdef VBOX_WS_MAC
421 const QStringList fields = QStringList()
422 << UINetworkManager::tr("Name")
423 << UINetworkManager::tr("Mask")
424 << UINetworkManager::tr("Lower Bound")
425 << UINetworkManager::tr("Upper Bound");
426#else /* !VBOX_WS_MAC */
427 const QStringList fields = QStringList()
428 << UINetworkManager::tr("Name")
429 << UINetworkManager::tr("IPv4 Prefix")
430 << UINetworkManager::tr("IPv6 Prefix")
431 << UINetworkManager::tr("DHCP Server");
432#endif /* !VBOX_WS_MAC */
433 m_pTreeWidgetHostNetwork->setHeaderLabels(fields);
434 m_pTreeWidgetHostNetwork->setWhatsThis(UINetworkManager::tr("Registered host-only networks"));
435 }
436
437 /* Translate NAT network tree-widget: */
438 if (m_pTreeWidgetNATNetwork)
439 {
440 const QStringList fields = QStringList()
441 << UINetworkManager::tr("Name")
442 << UINetworkManager::tr("IPv4 Prefix")
443 << UINetworkManager::tr("IPv6 Prefix")
444 << UINetworkManager::tr("DHCP Server");
445 m_pTreeWidgetNATNetwork->setHeaderLabels(fields);
446 m_pTreeWidgetNATNetwork->setWhatsThis(UINetworkManager::tr("Registered NAT networks"));
447 }
448
449 /* Translate cloud network tree-widget: */
450 if (m_pTreeWidgetCloudNetwork)
451 {
452 const QStringList fields = QStringList()
453 << UINetworkManager::tr("Name")
454 << UINetworkManager::tr("Provider")
455 << UINetworkManager::tr("Profile");
456 m_pTreeWidgetCloudNetwork->setHeaderLabels(fields);
457 m_pTreeWidgetCloudNetwork->setWhatsThis(UINetworkManager::tr("Registered cloud networks"));
458 }
459}
460
461void UINetworkManagerWidget::resizeEvent(QResizeEvent *pEvent)
462{
463 /* Call to base-class: */
464 QIWithRetranslateUI<QWidget>::resizeEvent(pEvent);
465
466 /* Adjust tree-widgets: */
467 sltAdjustTreeWidgets();
468}
469
470void UINetworkManagerWidget::showEvent(QShowEvent *pEvent)
471{
472 /* Call to base-class: */
473 QIWithRetranslateUI<QWidget>::showEvent(pEvent);
474
475 /* Adjust tree-widgets: */
476 sltAdjustTreeWidgets();
477}
478
479void UINetworkManagerWidget::sltResetDetailsChanges()
480{
481 /* Check tab-widget: */
482 AssertMsgReturnVoid(m_pTabWidget, ("This action should not be allowed!\n"));
483
484 /* Just push current item data to details-widget again: */
485 switch (m_pTabWidget->currentIndex())
486 {
487 case TabWidgetIndex_HostNetwork: sltHandleCurrentItemChangeHostNetwork(); break;
488 case TabWidgetIndex_NATNetwork: sltHandleCurrentItemChangeNATNetwork(); break;
489 case TabWidgetIndex_CloudNetwork: sltHandleCurrentItemChangeCloudNetwork(); break;
490 default: break;
491 }
492}
493
494void UINetworkManagerWidget::sltApplyDetailsChanges()
495{
496 /* Check tab-widget: */
497 AssertMsgReturnVoid(m_pTabWidget, ("This action should not be allowed!\n"));
498
499 /* Apply details-widget data changes: */
500 switch (m_pTabWidget->currentIndex())
501 {
502 case TabWidgetIndex_HostNetwork: sltApplyDetailsChangesHostNetwork(); break;
503 case TabWidgetIndex_NATNetwork: sltApplyDetailsChangesNATNetwork(); break;
504 case TabWidgetIndex_CloudNetwork: sltApplyDetailsChangesCloudNetwork(); break;
505 default: break;
506 }
507}
508
509void UINetworkManagerWidget::sltCreateHostNetwork()
510{
511 /* For host networks only: */
512 if (m_pTabWidget->currentIndex() != TabWidgetIndex_HostNetwork)
513 return;
514
515 /* Check host network tree-widget: */
516 AssertMsgReturnVoid(m_pTreeWidgetHostNetwork, ("Host network tree-widget isn't created!\n"));
517
518#ifdef VBOX_WS_MAC
519 /* Compose a set of busy names: */
520 QSet<QString> names;
521 for (int i = 0; i < m_pTreeWidgetHostNetwork->topLevelItemCount(); ++i)
522 names << qobject_cast<UIItemHostNetwork*>(m_pTreeWidgetHostNetwork->childItem(i))->name();
523 /* Compose a map of busy indexes: */
524 QMap<int, bool> presence;
525 const QString strNameTemplate("HostNetwork%1");
526 const QRegularExpression re(strNameTemplate.arg("([\\d]*)"));
527 foreach (const QString &strName, names)
528 {
529 const QRegularExpressionMatch mt = re.match(strName);
530 if (mt.hasMatch())
531 presence[mt.captured(1).toInt()] = true;
532 }
533 /* Search for a minimum index: */
534 int iMinimumIndex = 0;
535 for (int i = 0; !presence.isEmpty() && i <= presence.lastKey() + 1; ++i)
536 if (!presence.contains(i))
537 {
538 iMinimumIndex = i;
539 break;
540 }
541 /* Compose resulting index and name: */
542 const QString strNetworkName = strNameTemplate.arg(iMinimumIndex == 0 ? QString() : QString::number(iMinimumIndex));
543
544 /* Compose new item data: */
545 UIDataHostNetwork oldData;
546 oldData.m_fExists = true;
547 oldData.m_strName = strNetworkName;
548
549 /* Get VirtualBox for further activities: */
550 CVirtualBox comVBox = gpGlobalSession->virtualBox();
551
552 /* Create network: */
553 CHostOnlyNetwork comNetwork = comVBox.CreateHostOnlyNetwork(oldData.m_strName);
554 CHostOnlyNetwork comNetworkBase = comNetwork;
555
556 /* Show error message if necessary: */
557 if (!comVBox.isOk())
558 UINotificationMessage::cannotCreateHostOnlyNetwork(comVBox);
559 else
560 {
561 /* Save host network name: */
562 if (comNetwork.isOk())
563 comNetwork.SetNetworkName(oldData.m_strName);
564
565 /* Show error message if necessary: */
566 if (!comNetwork.isOk())
567 UINotificationMessage::cannotChangeHostOnlyNetworkParameter(comNetwork);
568
569 /* Add network to the tree: */
570 UIDataHostNetwork newData;
571 loadHostNetwork(comNetworkBase, newData);
572 createItemForHostNetwork(newData, true);
573
574 /* Adjust tree-widgets: */
575 sltAdjustTreeWidgets();
576 }
577
578#else /* !VBOX_WS_MAC */
579
580 /* Get host for further activities: */
581 CHost comHost = gpGlobalSession->host();
582 CHostNetworkInterface comInterface;
583
584 /* Create interface: */
585 UINotificationProgressHostOnlyNetworkInterfaceCreate *pNotification =
586 new UINotificationProgressHostOnlyNetworkInterfaceCreate(comHost, comInterface);
587 connect(pNotification, &UINotificationProgressHostOnlyNetworkInterfaceCreate::sigHostOnlyNetworkInterfaceCreated,
588 this, &UINetworkManagerWidget::sigHandleHostOnlyNetworkInterfaceCreated);
589 gpNotificationCenter->append(pNotification);
590#endif /* !VBOX_WS_MAC */
591}
592
593#ifndef VBOX_WS_MAC
594void UINetworkManagerWidget::sigHandleHostOnlyNetworkInterfaceCreated(const CHostNetworkInterface &comInterface)
595{
596 /* Get network name for further activities: */
597 const QString strNetworkName = comInterface.GetNetworkName();
598
599 /* Show error message if necessary: */
600 if (!comInterface.isOk())
601 UINotificationMessage::cannotAcquireHostNetworkInterfaceParameter(comInterface);
602 else
603 {
604 /* Get VBox for further activities: */
605 CVirtualBox comVBox = gpGlobalSession->virtualBox();
606
607 /* Find corresponding DHCP server (create if necessary): */
608 CDHCPServer comServer = comVBox.FindDHCPServerByNetworkName(strNetworkName);
609 if (!comVBox.isOk() || comServer.isNull())
610 comServer = comVBox.CreateDHCPServer(strNetworkName);
611
612 /* Show error message if necessary: */
613 if (!comVBox.isOk() || comServer.isNull())
614 UINotificationMessage::cannotCreateDHCPServer(comVBox, strNetworkName);
615
616 /* Add interface to the tree: */
617 UIDataHostNetwork data;
618 loadHostNetwork(comInterface, data);
619 createItemForHostNetwork(data, true);
620
621 /* Adjust tree-widgets: */
622 sltAdjustTreeWidgets();
623 }
624}
625#endif /* !VBOX_WS_MAC */
626
627void UINetworkManagerWidget::sltRemoveHostNetwork()
628{
629 /* For host networks only: */
630 if (m_pTabWidget->currentIndex() != TabWidgetIndex_HostNetwork)
631 return;
632
633 /* Check host network tree-widget: */
634 AssertMsgReturnVoid(m_pTreeWidgetHostNetwork, ("Host network tree-widget isn't created!\n"));
635
636 /* Get network item: */
637 UIItemHostNetwork *pItem = static_cast<UIItemHostNetwork*>(m_pTreeWidgetHostNetwork->currentItem());
638 AssertMsgReturnVoid(pItem, ("Current item must not be null!\n"));
639
640#ifdef VBOX_WS_MAC
641
642 /* Get network name: */
643 const QString strNetworkName(pItem->name());
644
645 /* Confirm host network removal: */
646 if (!msgCenter().confirmHostOnlyNetworkRemoval(strNetworkName, this))
647 return;
648
649 /* Get VirtualBox for further activities: */
650 CVirtualBox comVBox = gpGlobalSession->virtualBox();
651
652 /* Find corresponding network: */
653 const CHostOnlyNetwork &comNetwork = comVBox.FindHostOnlyNetworkByName(strNetworkName);
654
655 /* Show error message if necessary: */
656 if (!comVBox.isOk() || comNetwork.isNull())
657 UINotificationMessage::cannotFindHostOnlyNetwork(comVBox, strNetworkName);
658 else
659 {
660 /* Remove network finally: */
661 comVBox.RemoveHostOnlyNetwork(comNetwork);
662
663 /* Show error message if necessary: */
664 if (!comVBox.isOk())
665 UINotificationMessage::cannotRemoveHostOnlyNetwork(comVBox, strNetworkName);
666 else
667 {
668 /* Move selection to somewhere else: */
669 if (m_pTreeWidgetHostNetwork->itemBelow(pItem))
670 m_pTreeWidgetHostNetwork->setCurrentItem(m_pTreeWidgetHostNetwork->itemBelow(pItem));
671 else if (m_pTreeWidgetHostNetwork->itemAbove(pItem))
672 m_pTreeWidgetHostNetwork->setCurrentItem(m_pTreeWidgetHostNetwork->itemAbove(pItem));
673 else
674 m_pTreeWidgetHostNetwork->setCurrentItem(0);
675
676 /* Remove interface from the tree: */
677 delete pItem;
678
679 /* Adjust tree-widgets: */
680 sltAdjustTreeWidgets();
681 }
682 }
683
684#else /* !VBOX_WS_MAC */
685
686 /* Get interface name: */
687 const QString strInterfaceName(pItem->name());
688
689 /* Confirm host network removal: */
690 if (!msgCenter().confirmHostNetworkInterfaceRemoval(strInterfaceName, this))
691 return;
692
693 /* Get host for further activities: */
694 CHost comHost = gpGlobalSession->host();
695
696 /* Find corresponding interface: */
697 const CHostNetworkInterface comInterface = comHost.FindHostNetworkInterfaceByName(strInterfaceName);
698
699 /* Show error message if necessary: */
700 if (!comHost.isOk() || comInterface.isNull())
701 UINotificationMessage::cannotFindHostNetworkInterface(comHost, strInterfaceName);
702 else
703 {
704 /* Get network name for further activities: */
705 QString strNetworkName;
706 if (comInterface.isOk())
707 strNetworkName = comInterface.GetNetworkName();
708 /* Get interface id for further activities: */
709 QUuid uInterfaceId;
710 if (comInterface.isOk())
711 uInterfaceId = comInterface.GetId();
712
713 /* Show error message if necessary: */
714 if (!comInterface.isOk())
715 UINotificationMessage::cannotAcquireHostNetworkInterfaceParameter(comInterface);
716 else
717 {
718 /* Get VBox for further activities: */
719 CVirtualBox comVBox = gpGlobalSession->virtualBox();
720
721 /* Find corresponding DHCP server: */
722 const CDHCPServer &comServer = comVBox.FindDHCPServerByNetworkName(strNetworkName);
723 if (comVBox.isOk() && comServer.isNotNull())
724 {
725 /* Remove server if any: */
726 comVBox.RemoveDHCPServer(comServer);
727
728 /* Show error message if necessary: */
729 if (!comVBox.isOk())
730 UINotificationMessage::cannotRemoveDHCPServer(comVBox, strInterfaceName);
731 }
732
733 /* Create interface: */
734 UINotificationProgressHostOnlyNetworkInterfaceRemove *pNotification =
735 new UINotificationProgressHostOnlyNetworkInterfaceRemove(comHost, uInterfaceId);
736 connect(pNotification, &UINotificationProgressHostOnlyNetworkInterfaceRemove::sigHostOnlyNetworkInterfaceRemoved,
737 this, &UINetworkManagerWidget::sigHandleHostOnlyNetworkInterfaceRemoved);
738 gpNotificationCenter->append(pNotification);
739 }
740 }
741#endif /* !VBOX_WS_MAC */
742}
743
744#ifndef VBOX_WS_MAC
745void UINetworkManagerWidget::sigHandleHostOnlyNetworkInterfaceRemoved(const QString &strInterfaceName)
746{
747 /* Check host network tree-widget: */
748 AssertMsgReturnVoid(m_pTreeWidgetHostNetwork, ("Host network tree-widget isn't created!\n"));
749
750 /* Search for required item: */
751 QList<QTreeWidgetItem*> items = m_pTreeWidgetHostNetwork->findItems(strInterfaceName, Qt::MatchCaseSensitive);
752 AssertReturnVoid(!items.isEmpty());
753 QTreeWidgetItem *pItem = items.first();
754
755 /* Move selection to somewhere else: */
756 if (m_pTreeWidgetHostNetwork->itemBelow(pItem))
757 m_pTreeWidgetHostNetwork->setCurrentItem(m_pTreeWidgetHostNetwork->itemBelow(pItem));
758 else if (m_pTreeWidgetHostNetwork->itemAbove(pItem))
759 m_pTreeWidgetHostNetwork->setCurrentItem(m_pTreeWidgetHostNetwork->itemAbove(pItem));
760 else
761 m_pTreeWidgetHostNetwork->setCurrentItem(0);
762
763 /* Remove interface from the tree: */
764 delete pItem;
765
766 /* Adjust tree-widgets: */
767 sltAdjustTreeWidgets();
768}
769#endif /* !VBOX_WS_MAC */
770
771void UINetworkManagerWidget::sltCreateNATNetwork()
772{
773 /* For NAT networks only: */
774 if (m_pTabWidget->currentIndex() != TabWidgetIndex_NATNetwork)
775 return;
776
777 /* Compose a set of busy names: */
778 QSet<QString> names;
779 for (int i = 0; i < m_pTreeWidgetNATNetwork->topLevelItemCount(); ++i)
780 names << qobject_cast<UIItemNATNetwork*>(m_pTreeWidgetNATNetwork->childItem(i))->name();
781 /* Compose a map of busy indexes: */
782 QMap<int, bool> presence;
783 const QString strNameTemplate("NatNetwork%1");
784 const QRegularExpression re(strNameTemplate.arg("([\\d]*)"));
785 foreach (const QString &strName, names)
786 {
787 const QRegularExpressionMatch mt = re.match(strName);
788 if (mt.hasMatch())
789 presence[mt.captured(1).toInt()] = true;
790 }
791 /* Search for a minimum index: */
792 int iMinimumIndex = 0;
793 for (int i = 0; !presence.isEmpty() && i <= presence.lastKey() + 1; ++i)
794 if (!presence.contains(i))
795 {
796 iMinimumIndex = i;
797 break;
798 }
799 /* Compose resulting index and name: */
800 const QString strNetworkName = strNameTemplate.arg(iMinimumIndex == 0 ? QString() : QString::number(iMinimumIndex));
801
802 /* Compose new item data: */
803 UIDataNATNetwork oldData;
804 oldData.m_fExists = true;
805 oldData.m_strName = strNetworkName;
806 oldData.m_strPrefixIPv4 = "10.0.2.0/24";
807 oldData.m_strPrefixIPv6 = ""; // do we need something here?
808 oldData.m_fSupportsDHCP = true;
809 oldData.m_fSupportsIPv6 = false;
810 oldData.m_fAdvertiseDefaultIPv6Route = false;
811
812 /* Get VirtualBox for further activities: */
813 CVirtualBox comVBox = gpGlobalSession->virtualBox();
814
815 /* Create network: */
816 CNATNetwork comNetwork = comVBox.CreateNATNetwork(oldData.m_strName);
817 CNATNetwork comNetworkBase = comNetwork;
818
819 /* Show error message if necessary: */
820 if (!comVBox.isOk())
821 UINotificationMessage::cannotCreateNATNetwork(comVBox);
822 else
823 {
824 /* Save NAT network name: */
825 if (comNetwork.isOk())
826 comNetwork.SetNetworkName(oldData.m_strName);
827 /* Save NAT network IPv4 prefix: */
828 if (comNetwork.isOk())
829 comNetwork.SetNetwork(oldData.m_strPrefixIPv4);
830 /* Save NAT network IPv6 prefix: */
831 if (comNetwork.isOk())
832 comNetwork.SetIPv6Prefix(oldData.m_strPrefixIPv6);
833 /* Save whether NAT network needs DHCP server: */
834 if (comNetwork.isOk())
835 comNetwork.SetNeedDhcpServer(oldData.m_fSupportsDHCP);
836 /* Save whether NAT network supports IPv6: */
837 if (comNetwork.isOk())
838 comNetwork.SetIPv6Enabled(oldData.m_fSupportsIPv6);
839 /* Save whether NAT network should advertise default IPv6 route: */
840 if (comNetwork.isOk())
841 comNetwork.SetAdvertiseDefaultIPv6RouteEnabled(oldData.m_fAdvertiseDefaultIPv6Route);
842
843 /* Show error message if necessary: */
844 if (!comNetwork.isOk())
845 UINotificationMessage::cannotChangeNATNetworkParameter(comNetwork);
846
847 /* Add network to the tree: */
848 UIDataNATNetwork newData;
849 loadNATNetwork(comNetworkBase, newData);
850 createItemForNATNetwork(newData, true);
851
852 /* Adjust tree-widgets: */
853 sltAdjustTreeWidgets();
854 }
855}
856
857void UINetworkManagerWidget::sltRemoveNATNetwork()
858{
859 /* For NAT networks only: */
860 if (m_pTabWidget->currentIndex() != TabWidgetIndex_NATNetwork)
861 return;
862
863 /* Check NAT network tree-widget: */
864 AssertMsgReturnVoid(m_pTreeWidgetNATNetwork, ("NAT network tree-widget isn't created!\n"));
865
866 /* Get network item: */
867 UIItemNATNetwork *pItem = static_cast<UIItemNATNetwork*>(m_pTreeWidgetNATNetwork->currentItem());
868 AssertMsgReturnVoid(pItem, ("Current item must not be null!\n"));
869
870 /* Get network name: */
871 const QString strNetworkName(pItem->name());
872
873 /* Confirm host network removal: */
874 if (!msgCenter().confirmNATNetworkRemoval(strNetworkName, this))
875 return;
876
877 /* Get VirtualBox for further activities: */
878 CVirtualBox comVBox = gpGlobalSession->virtualBox();
879
880 /* Find corresponding network: */
881 const CNATNetwork &comNetwork = comVBox.FindNATNetworkByName(strNetworkName);
882
883 /* Show error message if necessary: */
884 if (!comVBox.isOk() || comNetwork.isNull())
885 UINotificationMessage::cannotFindNATNetwork(comVBox, strNetworkName);
886 else
887 {
888 /* Remove network finally: */
889 comVBox.RemoveNATNetwork(comNetwork);
890
891 /* Show error message if necessary: */
892 if (!comVBox.isOk())
893 UINotificationMessage::cannotRemoveNATNetwork(comVBox, strNetworkName);
894 else
895 {
896 /* Move selection to somewhere else: */
897 if (m_pTreeWidgetNATNetwork->itemBelow(pItem))
898 m_pTreeWidgetNATNetwork->setCurrentItem(m_pTreeWidgetNATNetwork->itemBelow(pItem));
899 else if (m_pTreeWidgetNATNetwork->itemAbove(pItem))
900 m_pTreeWidgetNATNetwork->setCurrentItem(m_pTreeWidgetNATNetwork->itemAbove(pItem));
901 else
902 m_pTreeWidgetNATNetwork->setCurrentItem(0);
903
904 /* Remove interface from the tree: */
905 delete pItem;
906
907 /* Adjust tree-widgets: */
908 sltAdjustTreeWidgets();
909 }
910 }
911}
912
913void UINetworkManagerWidget::sltCreateCloudNetwork()
914{
915 /* For cloud networks only: */
916 if (m_pTabWidget->currentIndex() != TabWidgetIndex_CloudNetwork)
917 return;
918
919 /* Compose a set of busy names: */
920 QSet<QString> names;
921 for (int i = 0; i < m_pTreeWidgetCloudNetwork->topLevelItemCount(); ++i)
922 names << qobject_cast<UIItemCloudNetwork*>(m_pTreeWidgetCloudNetwork->childItem(i))->name();
923 /* Compose a map of busy indexes: */
924 QMap<int, bool> presence;
925 const QString strNameTemplate("CloudNetwork%1");
926 const QRegularExpression re(strNameTemplate.arg("([\\d]*)"));
927 foreach (const QString &strName, names)
928 {
929 const QRegularExpressionMatch mt = re.match(strName);
930 if (mt.hasMatch())
931 presence[mt.captured(1).toInt()] = true;
932 }
933 /* Search for a minimum index: */
934 int iMinimumIndex = 0;
935 for (int i = 0; !presence.isEmpty() && i <= presence.lastKey() + 1; ++i)
936 if (!presence.contains(i))
937 {
938 iMinimumIndex = i;
939 break;
940 }
941 /* Compose resulting index and name: */
942 const QString strNetworkName = strNameTemplate.arg(iMinimumIndex == 0 ? QString() : QString::number(iMinimumIndex));
943
944 /* Compose new item data: */
945 UIDataCloudNetwork oldData;
946 oldData.m_fEnabled = true;
947 oldData.m_strName = strNetworkName;
948
949 /* Get VirtualBox for further activities: */
950 CVirtualBox comVBox = gpGlobalSession->virtualBox();
951
952 /* Create network: */
953 CCloudNetwork comNetwork = comVBox.CreateCloudNetwork(oldData.m_strName);
954 CCloudNetwork comNetworkBase = comNetwork;
955
956 /* Show error message if necessary: */
957 if (!comVBox.isOk())
958 UINotificationMessage::cannotCreateCloudNetwork(comVBox);
959 else
960 {
961 /* Save whether network enabled: */
962 if (comNetwork.isOk())
963 comNetwork.SetEnabled(oldData.m_fEnabled);
964 /* Save cloud network name: */
965 if (comNetwork.isOk())
966 comNetwork.SetNetworkName(oldData.m_strName);
967
968 /* Show error message if necessary: */
969 if (!comNetwork.isOk())
970 UINotificationMessage::cannotChangeCloudNetworkParameter(comNetwork);
971
972 /* Add network to the tree: */
973 UIDataCloudNetwork newData;
974 loadCloudNetwork(comNetworkBase, newData);
975 createItemForCloudNetwork(newData, true);
976
977 /* Adjust tree-widgets: */
978 sltAdjustTreeWidgets();
979 }
980}
981
982void UINetworkManagerWidget::sltRemoveCloudNetwork()
983{
984 /* For cloud networks only: */
985 if (m_pTabWidget->currentIndex() != TabWidgetIndex_CloudNetwork)
986 return;
987
988 /* Check cloud network tree-widget: */
989 AssertMsgReturnVoid(m_pTreeWidgetCloudNetwork, ("Cloud network tree-widget isn't created!\n"));
990
991 /* Get network item: */
992 UIItemCloudNetwork *pItem = static_cast<UIItemCloudNetwork*>(m_pTreeWidgetCloudNetwork->currentItem());
993 AssertMsgReturnVoid(pItem, ("Current item must not be null!\n"));
994
995 /* Get network name: */
996 const QString strNetworkName(pItem->name());
997
998 /* Confirm host network removal: */
999 if (!msgCenter().confirmCloudNetworkRemoval(strNetworkName, this))
1000 return;
1001
1002 /* Get VirtualBox for further activities: */
1003 CVirtualBox comVBox = gpGlobalSession->virtualBox();
1004
1005 /* Find corresponding network: */
1006 const CCloudNetwork &comNetwork = comVBox.FindCloudNetworkByName(strNetworkName);
1007
1008 /* Show error message if necessary: */
1009 if (!comVBox.isOk() || comNetwork.isNull())
1010 UINotificationMessage::cannotFindCloudNetwork(comVBox, strNetworkName);
1011 else
1012 {
1013 /* Remove network finally: */
1014 comVBox.RemoveCloudNetwork(comNetwork);
1015
1016 /* Show error message if necessary: */
1017 if (!comVBox.isOk())
1018 UINotificationMessage::cannotRemoveCloudNetwork(comVBox, strNetworkName);
1019 else
1020 {
1021 /* Move selection to somewhere else: */
1022 if (m_pTreeWidgetCloudNetwork->itemBelow(pItem))
1023 m_pTreeWidgetCloudNetwork->setCurrentItem(m_pTreeWidgetCloudNetwork->itemBelow(pItem));
1024 else if (m_pTreeWidgetCloudNetwork->itemAbove(pItem))
1025 m_pTreeWidgetCloudNetwork->setCurrentItem(m_pTreeWidgetCloudNetwork->itemAbove(pItem));
1026 else
1027 m_pTreeWidgetCloudNetwork->setCurrentItem(0);
1028
1029 /* Remove interface from the tree: */
1030 delete pItem;
1031
1032 /* Adjust tree-widgets: */
1033 sltAdjustTreeWidgets();
1034 }
1035 }
1036}
1037
1038void UINetworkManagerWidget::sltToggleDetailsVisibility(bool fVisible)
1039{
1040 /* Save the setting: */
1041 gEDataManager->setHostNetworkManagerDetailsExpanded(fVisible);
1042 /* Show/hide details area and Apply/Reset buttons: */
1043 switch (m_pTabWidget->currentIndex())
1044 {
1045 case TabWidgetIndex_HostNetwork:
1046 {
1047 if (m_pDetailsWidgetNATNetwork)
1048 m_pDetailsWidgetNATNetwork->setVisible(false);
1049 if (m_pDetailsWidgetCloudNetwork)
1050 m_pDetailsWidgetCloudNetwork->setVisible(false);
1051 if (m_pDetailsWidgetHostNetwork)
1052 m_pDetailsWidgetHostNetwork->setVisible(fVisible);
1053 break;
1054 }
1055 case TabWidgetIndex_NATNetwork:
1056 {
1057 if (m_pDetailsWidgetHostNetwork)
1058 m_pDetailsWidgetHostNetwork->setVisible(false);
1059 if (m_pDetailsWidgetCloudNetwork)
1060 m_pDetailsWidgetCloudNetwork->setVisible(false);
1061 if (m_pDetailsWidgetNATNetwork)
1062 m_pDetailsWidgetNATNetwork->setVisible(fVisible);
1063 break;
1064 }
1065 case TabWidgetIndex_CloudNetwork:
1066 {
1067 if (m_pDetailsWidgetHostNetwork)
1068 m_pDetailsWidgetHostNetwork->setVisible(false);
1069 if (m_pDetailsWidgetNATNetwork)
1070 m_pDetailsWidgetNATNetwork->setVisible(false);
1071 if (m_pDetailsWidgetCloudNetwork)
1072 m_pDetailsWidgetCloudNetwork->setVisible(fVisible);
1073 break;
1074 }
1075 }
1076 /* Notify external listeners: */
1077 emit sigDetailsVisibilityChanged(fVisible);
1078}
1079
1080void UINetworkManagerWidget::sltHandleCurrentTabWidgetIndexChange()
1081{
1082 /* Update actions: */
1083 updateActionAvailability();
1084
1085 /* Adjust tree-widgets first of all: */
1086 sltAdjustTreeWidgets();
1087
1088 /* Show/hide details area and Apply/Reset buttons: */
1089 const bool fVisible = m_pActionPool->action(UIActionIndexMN_M_Network_T_Details)->isChecked();
1090 switch (m_pTabWidget->currentIndex())
1091 {
1092 case TabWidgetIndex_HostNetwork:
1093 {
1094 if (m_pDetailsWidgetNATNetwork)
1095 m_pDetailsWidgetNATNetwork->setVisible(false);
1096 if (m_pDetailsWidgetCloudNetwork)
1097 m_pDetailsWidgetCloudNetwork->setVisible(false);
1098 if (m_pDetailsWidgetHostNetwork)
1099 m_pDetailsWidgetHostNetwork->setVisible(fVisible);
1100 break;
1101 }
1102 case TabWidgetIndex_NATNetwork:
1103 {
1104 if (m_pDetailsWidgetHostNetwork)
1105 m_pDetailsWidgetHostNetwork->setVisible(false);
1106 if (m_pDetailsWidgetCloudNetwork)
1107 m_pDetailsWidgetCloudNetwork->setVisible(false);
1108 if (m_pDetailsWidgetNATNetwork)
1109 m_pDetailsWidgetNATNetwork->setVisible(fVisible);
1110 break;
1111 }
1112 case TabWidgetIndex_CloudNetwork:
1113 {
1114 if (m_pDetailsWidgetHostNetwork)
1115 m_pDetailsWidgetHostNetwork->setVisible(false);
1116 if (m_pDetailsWidgetNATNetwork)
1117 m_pDetailsWidgetNATNetwork->setVisible(false);
1118 if (m_pDetailsWidgetCloudNetwork)
1119 m_pDetailsWidgetCloudNetwork->setVisible(fVisible);
1120 break;
1121 }
1122 }
1123}
1124
1125void UINetworkManagerWidget::sltAdjustTreeWidgets()
1126{
1127 /* Check host network tree-widget: */
1128 if (m_pTreeWidgetHostNetwork)
1129 {
1130 /* Get the tree-widget abstract interface: */
1131 QAbstractItemView *pItemView = m_pTreeWidgetHostNetwork;
1132 /* Get the tree-widget header-view: */
1133 QHeaderView *pItemHeader = m_pTreeWidgetHostNetwork->header();
1134
1135 /* Calculate the total tree-widget width: */
1136 const int iTotal = m_pTreeWidgetHostNetwork->viewport()->width();
1137#ifdef VBOX_WS_MAC
1138 /* Look for a minimum width hints for non-important columns: */
1139 const int iMinWidth1 = qMax(pItemView->sizeHintForColumn(HostNetworkColumn_Mask), pItemHeader->sectionSizeHint(HostNetworkColumn_Mask));
1140 const int iMinWidth2 = qMax(pItemView->sizeHintForColumn(HostNetworkColumn_LBnd), pItemHeader->sectionSizeHint(HostNetworkColumn_LBnd));
1141 const int iMinWidth3 = qMax(pItemView->sizeHintForColumn(HostNetworkColumn_UBnd), pItemHeader->sectionSizeHint(HostNetworkColumn_UBnd));
1142#else /* !VBOX_WS_MAC */
1143 /* Look for a minimum width hints for non-important columns: */
1144 const int iMinWidth1 = qMax(pItemView->sizeHintForColumn(HostNetworkColumn_IPv4), pItemHeader->sectionSizeHint(HostNetworkColumn_IPv4));
1145 const int iMinWidth2 = qMax(pItemView->sizeHintForColumn(HostNetworkColumn_IPv6), pItemHeader->sectionSizeHint(HostNetworkColumn_IPv6));
1146 const int iMinWidth3 = qMax(pItemView->sizeHintForColumn(HostNetworkColumn_DHCP), pItemHeader->sectionSizeHint(HostNetworkColumn_DHCP));
1147#endif /* !VBOX_WS_MAC */
1148 /* Propose suitable width hints for non-important columns: */
1149 const int iWidth1 = iMinWidth1 < iTotal / HostNetworkColumn_Max ? iMinWidth1 : iTotal / HostNetworkColumn_Max;
1150 const int iWidth2 = iMinWidth2 < iTotal / HostNetworkColumn_Max ? iMinWidth2 : iTotal / HostNetworkColumn_Max;
1151 const int iWidth3 = iMinWidth3 < iTotal / HostNetworkColumn_Max ? iMinWidth3 : iTotal / HostNetworkColumn_Max;
1152 /* Apply the proposal: */
1153#ifdef VBOX_WS_MAC
1154 m_pTreeWidgetHostNetwork->setColumnWidth(HostNetworkColumn_Mask, iWidth1);
1155 m_pTreeWidgetHostNetwork->setColumnWidth(HostNetworkColumn_LBnd, iWidth2);
1156 m_pTreeWidgetHostNetwork->setColumnWidth(HostNetworkColumn_UBnd, iWidth3);
1157#else /* !VBOX_WS_MAC */
1158 m_pTreeWidgetHostNetwork->setColumnWidth(HostNetworkColumn_IPv4, iWidth1);
1159 m_pTreeWidgetHostNetwork->setColumnWidth(HostNetworkColumn_IPv6, iWidth2);
1160 m_pTreeWidgetHostNetwork->setColumnWidth(HostNetworkColumn_DHCP, iWidth3);
1161#endif /* !VBOX_WS_MAC */
1162 m_pTreeWidgetHostNetwork->setColumnWidth(HostNetworkColumn_Name, iTotal - iWidth1 - iWidth2 - iWidth3);
1163 }
1164
1165 /* Check NAT network tree-widget: */
1166 if (m_pTreeWidgetNATNetwork)
1167 {
1168 /* Get the tree-widget abstract interface: */
1169 QAbstractItemView *pItemView = m_pTreeWidgetNATNetwork;
1170 /* Get the tree-widget header-view: */
1171 QHeaderView *pItemHeader = m_pTreeWidgetNATNetwork->header();
1172
1173 /* Calculate the total tree-widget width: */
1174 const int iTotal = m_pTreeWidgetNATNetwork->viewport()->width();
1175 /* Look for a minimum width hints for non-important columns: */
1176 const int iMinWidth1 = qMax(pItemView->sizeHintForColumn(NATNetworkColumn_IPv4), pItemHeader->sectionSizeHint(NATNetworkColumn_IPv4));
1177 const int iMinWidth2 = qMax(pItemView->sizeHintForColumn(NATNetworkColumn_IPv6), pItemHeader->sectionSizeHint(NATNetworkColumn_IPv6));
1178 const int iMinWidth3 = qMax(pItemView->sizeHintForColumn(NATNetworkColumn_DHCP), pItemHeader->sectionSizeHint(NATNetworkColumn_DHCP));
1179 /* Propose suitable width hints for non-important columns: */
1180 const int iWidth1 = iMinWidth1 < iTotal / NATNetworkColumn_Max ? iMinWidth1 : iTotal / NATNetworkColumn_Max;
1181 const int iWidth2 = iMinWidth2 < iTotal / NATNetworkColumn_Max ? iMinWidth2 : iTotal / NATNetworkColumn_Max;
1182 const int iWidth3 = iMinWidth3 < iTotal / NATNetworkColumn_Max ? iMinWidth3 : iTotal / NATNetworkColumn_Max;
1183 /* Apply the proposal: */
1184 m_pTreeWidgetNATNetwork->setColumnWidth(NATNetworkColumn_IPv4, iWidth1);
1185 m_pTreeWidgetNATNetwork->setColumnWidth(NATNetworkColumn_IPv6, iWidth2);
1186 m_pTreeWidgetNATNetwork->setColumnWidth(NATNetworkColumn_DHCP, iWidth3);
1187 m_pTreeWidgetNATNetwork->setColumnWidth(NATNetworkColumn_Name, iTotal - iWidth1 - iWidth2 - iWidth3);
1188 }
1189
1190 /* Check cloud network tree-widget: */
1191 if (m_pTreeWidgetCloudNetwork)
1192 {
1193 /* Get the tree-widget abstract interface: */
1194 QAbstractItemView *pItemView = m_pTreeWidgetCloudNetwork;
1195 /* Get the tree-widget header-view: */
1196 QHeaderView *pItemHeader = m_pTreeWidgetCloudNetwork->header();
1197
1198 /* Calculate the total tree-widget width: */
1199 const int iTotal = m_pTreeWidgetCloudNetwork->viewport()->width();
1200 /* Look for a minimum width hints for non-important columns: */
1201 const int iMinWidth1 = qMax(pItemView->sizeHintForColumn(CloudNetworkColumn_Provider), pItemHeader->sectionSizeHint(CloudNetworkColumn_Provider));
1202 const int iMinWidth2 = qMax(pItemView->sizeHintForColumn(CloudNetworkColumn_Profile), pItemHeader->sectionSizeHint(CloudNetworkColumn_Profile));
1203 /* Propose suitable width hints for non-important columns: */
1204 const int iWidth1 = iMinWidth1 < iTotal / CloudNetworkColumn_Max ? iMinWidth1 : iTotal / CloudNetworkColumn_Max;
1205 const int iWidth2 = iMinWidth2 < iTotal / CloudNetworkColumn_Max ? iMinWidth2 : iTotal / CloudNetworkColumn_Max;
1206 /* Apply the proposal: */
1207 m_pTreeWidgetCloudNetwork->setColumnWidth(CloudNetworkColumn_Provider, iWidth1);
1208 m_pTreeWidgetCloudNetwork->setColumnWidth(CloudNetworkColumn_Profile, iWidth2);
1209 m_pTreeWidgetCloudNetwork->setColumnWidth(CloudNetworkColumn_Name, iTotal - iWidth1 - iWidth2);
1210 }
1211}
1212
1213void UINetworkManagerWidget::sltHandleCurrentItemChangeHostNetwork()
1214{
1215 /* Update actions: */
1216 updateActionAvailability();
1217
1218 /* Check host network tree-widget: */
1219 AssertMsgReturnVoid(m_pTreeWidgetHostNetwork, ("Host network tree-widget isn't created!\n"));
1220
1221 /* Get network item: */
1222 UIItemHostNetwork *pItem = static_cast<UIItemHostNetwork*>(m_pTreeWidgetHostNetwork->currentItem());
1223
1224 /* Check host network details-widget: */
1225 AssertMsgReturnVoid(m_pDetailsWidgetHostNetwork, ("Host network details-widget isn't created!\n"));
1226
1227 /* If there is an item => update details data: */
1228 if (pItem)
1229 m_pDetailsWidgetHostNetwork->setData(*pItem);
1230 /* Otherwise => clear details: */
1231 else
1232 m_pDetailsWidgetHostNetwork->setData(UIDataHostNetwork());
1233}
1234
1235void UINetworkManagerWidget::sltHandleContextMenuRequestHostNetwork(const QPoint &position)
1236{
1237 /* Check host network tree-widget: */
1238 AssertMsgReturnVoid(m_pTreeWidgetHostNetwork, ("Host network tree-widget isn't created!\n"));
1239
1240 /* Compose temporary context-menu: */
1241 QMenu menu;
1242 if (m_pTreeWidgetHostNetwork->itemAt(position))
1243 {
1244 menu.addAction(m_pActionPool->action(UIActionIndexMN_M_Network_S_Remove));
1245 menu.addAction(m_pActionPool->action(UIActionIndexMN_M_Network_T_Details));
1246 }
1247 else
1248 {
1249 menu.addAction(m_pActionPool->action(UIActionIndexMN_M_Network_S_Create));
1250// menu.addAction(m_pActionPool->action(UIActionIndexMN_M_Network_S_Refresh));
1251 }
1252 /* And show it: */
1253 menu.exec(m_pTreeWidgetHostNetwork->mapToGlobal(position));
1254}
1255
1256void UINetworkManagerWidget::sltApplyDetailsChangesHostNetwork()
1257{
1258 /* Check host network tree-widget: */
1259 AssertMsgReturnVoid(m_pTreeWidgetHostNetwork, ("Host network tree-widget isn't created!\n"));
1260
1261 /* Get host network item: */
1262 UIItemHostNetwork *pItem = static_cast<UIItemHostNetwork*>(m_pTreeWidgetHostNetwork->currentItem());
1263 AssertMsgReturnVoid(pItem, ("Current item must not be null!\n"));
1264
1265 /* Check host network details-widget: */
1266 AssertMsgReturnVoid(m_pDetailsWidgetHostNetwork, ("Host network details-widget isn't created!\n"));
1267
1268 /* Revalidate host network details: */
1269 if (m_pDetailsWidgetHostNetwork->revalidate())
1270 {
1271 /* Get item data: */
1272 UIDataHostNetwork oldData = *pItem;
1273 UIDataHostNetwork newData = m_pDetailsWidgetHostNetwork->data();
1274
1275#ifdef VBOX_WS_MAC
1276 /* Get VirtualBox for further activities: */
1277 CVirtualBox comVBox = gpGlobalSession->virtualBox();
1278
1279 /* Find corresponding network: */
1280 CHostOnlyNetwork comNetwork = comVBox.FindHostOnlyNetworkByName(oldData.m_strName);
1281 CHostOnlyNetwork comNetworkBase = comNetwork;
1282
1283 /* Show error message if necessary: */
1284 if (!comVBox.isOk() || comNetwork.isNull())
1285 UINotificationMessage::cannotFindHostOnlyNetwork(comVBox, oldData.m_strName);
1286 else
1287 {
1288 /* Save host network name: */
1289 if (comNetwork.isOk() && newData.m_strName != oldData.m_strName)
1290 comNetwork.SetNetworkName(newData.m_strName);
1291 /* Save host network mask: */
1292 if (comNetwork.isOk() && newData.m_strMask != oldData.m_strMask)
1293 comNetwork.SetNetworkMask(newData.m_strMask);
1294 /* Save host network lower bound: */
1295 if (comNetwork.isOk() && newData.m_strLBnd != oldData.m_strLBnd)
1296 comNetwork.SetLowerIP(newData.m_strLBnd);
1297 /* Save host network upper bound: */
1298 if (comNetwork.isOk() && newData.m_strUBnd != oldData.m_strUBnd)
1299 comNetwork.SetUpperIP(newData.m_strUBnd);
1300
1301 /* Show error message if necessary: */
1302 if (!comNetwork.isOk())
1303 UINotificationMessage::cannotChangeHostOnlyNetworkParameter(comNetwork);
1304
1305 /* Update network in the tree: */
1306 UIDataHostNetwork data;
1307 loadHostNetwork(comNetworkBase, data);
1308 updateItemForHostNetwork(data, true, pItem);
1309
1310 /* Make sure current item fetched: */
1311 sltHandleCurrentItemChangeHostNetwork();
1312
1313 /* Adjust tree-widgets: */
1314 sltAdjustTreeWidgets();
1315 }
1316
1317#else /* !VBOX_WS_MAC */
1318
1319 /* Get host for further activities: */
1320 CHost comHost = gpGlobalSession->host();
1321
1322 /* Find corresponding interface: */
1323 CHostNetworkInterface comInterface = comHost.FindHostNetworkInterfaceByName(oldData.m_interface.m_strName);
1324
1325 /* Show error message if necessary: */
1326 if (!comHost.isOk() || comInterface.isNull())
1327 UINotificationMessage::cannotFindHostNetworkInterface(comHost, oldData.m_interface.m_strName);
1328 else
1329 {
1330 /* Save automatic interface configuration: */
1331 if (newData.m_interface.m_fDHCPEnabled)
1332 {
1333 if ( comInterface.isOk()
1334 && !oldData.m_interface.m_fDHCPEnabled)
1335 comInterface.EnableDynamicIPConfig();
1336 }
1337 /* Save manual interface configuration: */
1338 else
1339 {
1340 /* Save IPv4 interface configuration: */
1341 if ( comInterface.isOk()
1342 && ( oldData.m_interface.m_fDHCPEnabled
1343 || newData.m_interface.m_strAddress != oldData.m_interface.m_strAddress
1344 || newData.m_interface.m_strMask != oldData.m_interface.m_strMask))
1345 comInterface.EnableStaticIPConfig(newData.m_interface.m_strAddress, newData.m_interface.m_strMask);
1346 /* Save IPv6 interface configuration: */
1347 if ( comInterface.isOk()
1348 && newData.m_interface.m_fSupportedIPv6
1349 && ( oldData.m_interface.m_fDHCPEnabled
1350 || newData.m_interface.m_strAddress6 != oldData.m_interface.m_strAddress6
1351 || newData.m_interface.m_strPrefixLength6 != oldData.m_interface.m_strPrefixLength6))
1352 comInterface.EnableStaticIPConfigV6(newData.m_interface.m_strAddress6, newData.m_interface.m_strPrefixLength6.toULong());
1353 }
1354
1355 /* Show error message if necessary: */
1356 if (!comInterface.isOk())
1357 UINotificationMessage::cannotChangeHostNetworkInterfaceParameter(comInterface);
1358 else
1359 {
1360 /* Get network name for further activities: */
1361 const QString strNetworkName = comInterface.GetNetworkName();
1362
1363 /* Show error message if necessary: */
1364 if (!comInterface.isOk())
1365 UINotificationMessage::cannotAcquireHostNetworkInterfaceParameter(comInterface);
1366 else
1367 {
1368 /* Get VBox for further activities: */
1369 CVirtualBox comVBox = gpGlobalSession->virtualBox();
1370
1371 /* Find corresponding DHCP server (create if necessary): */
1372 CDHCPServer comServer = comVBox.FindDHCPServerByNetworkName(strNetworkName);
1373 if (!comVBox.isOk() || comServer.isNull())
1374 comServer = comVBox.CreateDHCPServer(strNetworkName);
1375
1376 /* Show error message if necessary: */
1377 if (!comVBox.isOk() || comServer.isNull())
1378 UINotificationMessage::cannotCreateDHCPServer(comVBox, strNetworkName);
1379 else
1380 {
1381 /* Save whether DHCP server is enabled: */
1382 if ( comServer.isOk()
1383 && newData.m_dhcpserver.m_fEnabled != oldData.m_dhcpserver.m_fEnabled)
1384 comServer.SetEnabled(newData.m_dhcpserver.m_fEnabled);
1385 /* Save DHCP server configuration: */
1386 if ( comServer.isOk()
1387 && newData.m_dhcpserver.m_fEnabled
1388 && ( newData.m_dhcpserver.m_strAddress != oldData.m_dhcpserver.m_strAddress
1389 || newData.m_dhcpserver.m_strMask != oldData.m_dhcpserver.m_strMask
1390 || newData.m_dhcpserver.m_strLowerAddress != oldData.m_dhcpserver.m_strLowerAddress
1391 || newData.m_dhcpserver.m_strUpperAddress != oldData.m_dhcpserver.m_strUpperAddress))
1392 comServer.SetConfiguration(newData.m_dhcpserver.m_strAddress, newData.m_dhcpserver.m_strMask,
1393 newData.m_dhcpserver.m_strLowerAddress, newData.m_dhcpserver.m_strUpperAddress);
1394
1395 /* Show error message if necessary: */
1396 if (!comServer.isOk())
1397 UINotificationMessage::cannotChangeDHCPServerParameter(comServer);
1398 }
1399 }
1400 }
1401
1402 /* Find corresponding interface again (if necessary): */
1403 if (!comInterface.isOk())
1404 {
1405 comInterface = comHost.FindHostNetworkInterfaceByName(oldData.m_interface.m_strName);
1406
1407 /* Show error message if necessary: */
1408 if (!comHost.isOk() || comInterface.isNull())
1409 UINotificationMessage::cannotFindHostNetworkInterface(comHost, oldData.m_interface.m_strName);
1410 }
1411
1412 /* If interface is Ok now: */
1413 if (comInterface.isNotNull() && comInterface.isOk())
1414 {
1415 /* Update interface in the tree: */
1416 UIDataHostNetwork data;
1417 loadHostNetwork(comInterface, data);
1418 updateItemForHostNetwork(data, true, pItem);
1419
1420 /* Make sure current item fetched: */
1421 sltHandleCurrentItemChangeHostNetwork();
1422
1423 /* Adjust tree-widgets: */
1424 sltAdjustTreeWidgets();
1425 }
1426 }
1427#endif /* !VBOX_WS_MAC */
1428 }
1429
1430 /* Make sure button states updated: */
1431 m_pDetailsWidgetHostNetwork->updateButtonStates();
1432}
1433
1434void UINetworkManagerWidget::sltHandleCurrentItemChangeNATNetworkHoldingPosition(bool fHoldPosition)
1435{
1436 /* Update actions: */
1437 updateActionAvailability();
1438
1439 /* Check NAT network tree-widget: */
1440 AssertMsgReturnVoid(m_pTreeWidgetNATNetwork, ("NAT network tree-widget isn't created!\n"));
1441
1442 /* Get network item: */
1443 UIItemNATNetwork *pItem = static_cast<UIItemNATNetwork*>(m_pTreeWidgetNATNetwork->currentItem());
1444
1445 /* Check NAT network details-widget: */
1446 AssertMsgReturnVoid(m_pDetailsWidgetNATNetwork, ("NAT network details-widget isn't created!\n"));
1447
1448 /* If there is an item => update details data: */
1449 if (pItem)
1450 {
1451 QStringList busyNamesForItem = busyNamesNAT();
1452 busyNamesForItem.removeAll(pItem->name());
1453 m_pDetailsWidgetNATNetwork->setData(*pItem, busyNamesForItem, fHoldPosition);
1454 }
1455 /* Otherwise => clear details: */
1456 else
1457 m_pDetailsWidgetNATNetwork->setData(UIDataNATNetwork());
1458}
1459
1460void UINetworkManagerWidget::sltHandleCurrentItemChangeNATNetwork()
1461{
1462 sltHandleCurrentItemChangeNATNetworkHoldingPosition(false /* hold position? */);
1463}
1464
1465void UINetworkManagerWidget::sltHandleContextMenuRequestNATNetwork(const QPoint &position)
1466{
1467 /* Check NAT network tree-widget: */
1468 AssertMsgReturnVoid(m_pTreeWidgetNATNetwork, ("NAT network tree-widget isn't created!\n"));
1469
1470 /* Compose temporary context-menu: */
1471 QMenu menu;
1472 if (m_pTreeWidgetNATNetwork->itemAt(position))
1473 {
1474 menu.addAction(m_pActionPool->action(UIActionIndexMN_M_Network_S_Remove));
1475 menu.addAction(m_pActionPool->action(UIActionIndexMN_M_Network_T_Details));
1476 }
1477 else
1478 {
1479 menu.addAction(m_pActionPool->action(UIActionIndexMN_M_Network_S_Create));
1480// menu.addAction(m_pActionPool->action(UIActionIndexMN_M_Network_S_Refresh));
1481 }
1482 /* And show it: */
1483 menu.exec(m_pTreeWidgetNATNetwork->mapToGlobal(position));
1484}
1485
1486void UINetworkManagerWidget::sltApplyDetailsChangesNATNetwork()
1487{
1488 /* Check NAT network tree-widget: */
1489 AssertMsgReturnVoid(m_pTreeWidgetNATNetwork, ("NAT network tree-widget isn't created!\n"));
1490
1491 /* Get NAT network item: */
1492 UIItemNATNetwork *pItem = static_cast<UIItemNATNetwork*>(m_pTreeWidgetNATNetwork->currentItem());
1493 AssertMsgReturnVoid(pItem, ("Current item must not be null!\n"));
1494
1495 /* Check NAT network details-widget: */
1496 AssertMsgReturnVoid(m_pDetailsWidgetNATNetwork, ("NAT network details-widget isn't created!\n"));
1497
1498 /* Revalidate NAT network details: */
1499 if (m_pDetailsWidgetNATNetwork->revalidate())
1500 {
1501 /* Get item data: */
1502 UIDataNATNetwork oldData = *pItem;
1503 UIDataNATNetwork newData = m_pDetailsWidgetNATNetwork->data();
1504
1505 /* Get VirtualBox for further activities: */
1506 CVirtualBox comVBox = gpGlobalSession->virtualBox();
1507
1508 /* Find corresponding network: */
1509 CNATNetwork comNetwork = comVBox.FindNATNetworkByName(oldData.m_strName);
1510 CNATNetwork comNetworkBase = comNetwork;
1511
1512 /* Show error message if necessary: */
1513 if (!comVBox.isOk() || comNetwork.isNull())
1514 UINotificationMessage::cannotFindNATNetwork(comVBox, oldData.m_strName);
1515 else
1516 {
1517 /* Save NAT network name: */
1518 if (comNetwork.isOk() && newData.m_strName != oldData.m_strName)
1519 comNetwork.SetNetworkName(newData.m_strName);
1520 /* Save NAT network IPv4: */
1521 if (comNetwork.isOk() && newData.m_strPrefixIPv4 != oldData.m_strPrefixIPv4)
1522 comNetwork.SetNetwork(newData.m_strPrefixIPv4);
1523 /* Save NAT network IPv6: */
1524 if (comNetwork.isOk() && newData.m_strPrefixIPv6 != oldData.m_strPrefixIPv6)
1525 comNetwork.SetIPv6Prefix(newData.m_strPrefixIPv6);
1526 /* Save whether NAT network needs DHCP server: */
1527 if (comNetwork.isOk() && newData.m_fSupportsDHCP != oldData.m_fSupportsDHCP)
1528 comNetwork.SetNeedDhcpServer(newData.m_fSupportsDHCP);
1529 /* Save whether NAT network supports IPv6: */
1530 if (comNetwork.isOk() && newData.m_fSupportsIPv6 != oldData.m_fSupportsIPv6)
1531 comNetwork.SetIPv6Enabled(newData.m_fSupportsIPv6);
1532 /* Save whether NAT network should advertise default IPv6 route: */
1533 if (comNetwork.isOk() && newData.m_fAdvertiseDefaultIPv6Route != oldData.m_fAdvertiseDefaultIPv6Route)
1534 comNetwork.SetAdvertiseDefaultIPv6RouteEnabled(newData.m_fAdvertiseDefaultIPv6Route);
1535
1536 /* Save IPv4 forwarding rules: */
1537 if (comNetwork.isOk() && newData.m_rules4 != oldData.m_rules4)
1538 {
1539 UIPortForwardingDataList oldRules = oldData.m_rules4;
1540
1541 /* Remove rules to be removed: */
1542 foreach (const UIDataPortForwardingRule &oldRule, oldData.m_rules4)
1543 if (comNetwork.isOk() && !newData.m_rules4.contains(oldRule))
1544 {
1545 comNetwork.RemovePortForwardRule(false /* IPv6? */, oldRule.name);
1546 oldRules.removeAll(oldRule);
1547 }
1548 /* Add rules to be added: */
1549 foreach (const UIDataPortForwardingRule &newRule, newData.m_rules4)
1550 if (comNetwork.isOk() && !oldRules.contains(newRule))
1551 {
1552 comNetwork.AddPortForwardRule(false /* IPv6? */, newRule.name, newRule.protocol,
1553 newRule.hostIp, newRule.hostPort.value(),
1554 newRule.guestIp, newRule.guestPort.value());
1555 oldRules.append(newRule);
1556 }
1557 }
1558 /* Save IPv6 forwarding rules: */
1559 if (comNetwork.isOk() && newData.m_rules6 != oldData.m_rules6)
1560 {
1561 UIPortForwardingDataList oldRules = oldData.m_rules6;
1562
1563 /* Remove rules to be removed: */
1564 foreach (const UIDataPortForwardingRule &oldRule, oldData.m_rules6)
1565 if (comNetwork.isOk() && !newData.m_rules6.contains(oldRule))
1566 {
1567 comNetwork.RemovePortForwardRule(true /* IPv6? */, oldRule.name);
1568 oldRules.removeAll(oldRule);
1569 }
1570 /* Add rules to be added: */
1571 foreach (const UIDataPortForwardingRule &newRule, newData.m_rules6)
1572 if (comNetwork.isOk() && !oldRules.contains(newRule))
1573 {
1574 comNetwork.AddPortForwardRule(true /* IPv6? */, newRule.name, newRule.protocol,
1575 newRule.hostIp, newRule.hostPort.value(),
1576 newRule.guestIp, newRule.guestPort.value());
1577 oldRules.append(newRule);
1578 }
1579 }
1580
1581 /* Show error message if necessary: */
1582 if (!comNetwork.isOk())
1583 UINotificationMessage::cannotChangeNATNetworkParameter(comNetwork);
1584
1585 /* Update network in the tree: */
1586 UIDataNATNetwork data;
1587 loadNATNetwork(comNetworkBase, data);
1588 updateItemForNATNetwork(data, true, pItem);
1589
1590 /* Make sure current item fetched, trying to hold chosen position: */
1591 sltHandleCurrentItemChangeNATNetworkHoldingPosition(true /* hold position? */);
1592
1593 /* Adjust tree-widgets: */
1594 sltAdjustTreeWidgets();
1595 }
1596 }
1597
1598 /* Make sure button states updated: */
1599 m_pDetailsWidgetNATNetwork->updateButtonStates();
1600}
1601
1602void UINetworkManagerWidget::sltHandleCurrentItemChangeCloudNetwork()
1603{
1604 /* Update actions: */
1605 updateActionAvailability();
1606
1607 /* Check cloud network tree-widget: */
1608 AssertMsgReturnVoid(m_pTreeWidgetCloudNetwork, ("Cloud network tree-widget isn't created!\n"));
1609
1610 /* Get network item: */
1611 UIItemCloudNetwork *pItem = static_cast<UIItemCloudNetwork*>(m_pTreeWidgetCloudNetwork->currentItem());
1612
1613 /* Check Cloud network details-widget: */
1614 AssertMsgReturnVoid(m_pDetailsWidgetCloudNetwork, ("Cloud network details-widget isn't created!\n"));
1615
1616 /* If there is an item => update details data: */
1617 if (pItem)
1618 {
1619 QStringList busyNamesForItem = busyNamesCloud();
1620 busyNamesForItem.removeAll(pItem->name());
1621 m_pDetailsWidgetCloudNetwork->setData(*pItem, busyNamesForItem);
1622 }
1623 /* Otherwise => clear details: */
1624 else
1625 m_pDetailsWidgetCloudNetwork->setData(UIDataCloudNetwork());
1626}
1627
1628void UINetworkManagerWidget::sltHandleContextMenuRequestCloudNetwork(const QPoint &position)
1629{
1630 /* Check cloud network tree-widget: */
1631 AssertMsgReturnVoid(m_pTreeWidgetCloudNetwork, ("Cloud network tree-widget isn't created!\n"));
1632
1633 /* Compose temporary context-menu: */
1634 QMenu menu;
1635 if (m_pTreeWidgetCloudNetwork->itemAt(position))
1636 {
1637 menu.addAction(m_pActionPool->action(UIActionIndexMN_M_Network_S_Remove));
1638 menu.addAction(m_pActionPool->action(UIActionIndexMN_M_Network_T_Details));
1639 }
1640 else
1641 {
1642 menu.addAction(m_pActionPool->action(UIActionIndexMN_M_Network_S_Create));
1643// menu.addAction(m_pActionPool->action(UIActionIndexMN_M_Network_S_Refresh));
1644 }
1645 /* And show it: */
1646 menu.exec(m_pTreeWidgetCloudNetwork->mapToGlobal(position));
1647}
1648
1649void UINetworkManagerWidget::sltApplyDetailsChangesCloudNetwork()
1650{
1651 /* Check cloud network tree-widget: */
1652 AssertMsgReturnVoid(m_pTreeWidgetCloudNetwork, ("Cloud network tree-widget isn't created!\n"));
1653
1654 /* Get Cloud network item: */
1655 UIItemCloudNetwork *pItem = static_cast<UIItemCloudNetwork*>(m_pTreeWidgetCloudNetwork->currentItem());
1656 AssertMsgReturnVoid(pItem, ("Current item must not be null!\n"));
1657
1658 /* Check Cloud network details-widget: */
1659 AssertMsgReturnVoid(m_pDetailsWidgetCloudNetwork, ("Cloud network details-widget isn't created!\n"));
1660
1661 /* Revalidate Cloud network details: */
1662 if (m_pDetailsWidgetCloudNetwork->revalidate())
1663 {
1664 /* Get item data: */
1665 UIDataCloudNetwork oldData = *pItem;
1666 UIDataCloudNetwork newData = m_pDetailsWidgetCloudNetwork->data();
1667
1668 /* Get VirtualBox for further activities: */
1669 CVirtualBox comVBox = gpGlobalSession->virtualBox();
1670
1671 /* Find corresponding network: */
1672 CCloudNetwork comNetwork = comVBox.FindCloudNetworkByName(oldData.m_strName);
1673 CCloudNetwork comNetworkBase = comNetwork;
1674
1675 /* Show error message if necessary: */
1676 if (!comVBox.isOk() || comNetwork.isNull())
1677 UINotificationMessage::cannotFindCloudNetwork(comVBox, oldData.m_strName);
1678 else
1679 {
1680 /* Save whether cloud network enabled: */
1681 if (comNetwork.isOk() && newData.m_fEnabled != oldData.m_fEnabled)
1682 comNetwork.SetEnabled(newData.m_fEnabled);
1683 /* Save cloud network name: */
1684 if (comNetwork.isOk() && newData.m_strName != oldData.m_strName)
1685 comNetwork.SetNetworkName(newData.m_strName);
1686 /* Save cloud provider: */
1687 if (comNetwork.isOk() && newData.m_strProvider != oldData.m_strProvider)
1688 comNetwork.SetProvider(newData.m_strProvider);
1689 /* Save cloud profile: */
1690 if (comNetwork.isOk() && newData.m_strProfile != oldData.m_strProfile)
1691 comNetwork.SetProfile(newData.m_strProfile);
1692 /* Save cloud network id: */
1693 if (comNetwork.isOk() && newData.m_strId != oldData.m_strId)
1694 comNetwork.SetNetworkId(newData.m_strId);
1695
1696 /* Show error message if necessary: */
1697 if (!comNetwork.isOk())
1698 UINotificationMessage::cannotChangeCloudNetworkParameter(comNetwork);
1699
1700 /* Update network in the tree: */
1701 UIDataCloudNetwork data;
1702 loadCloudNetwork(comNetworkBase, data);
1703 updateItemForCloudNetwork(data, true, pItem);
1704
1705 /* Make sure current item fetched: */
1706 sltHandleCurrentItemChangeCloudNetwork();
1707
1708 /* Adjust tree-widgets: */
1709 sltAdjustTreeWidgets();
1710 }
1711 }
1712
1713 /* Make sure button states updated: */
1714 m_pDetailsWidgetNATNetwork->updateButtonStates();
1715}
1716
1717void UINetworkManagerWidget::prepare()
1718{
1719 /* Prepare self: */
1720 uiCommon().setHelpKeyword(this, "network-manager");
1721
1722 /* Prepare stuff: */
1723 prepareActions();
1724 prepareWidgets();
1725
1726 /* Load settings: */
1727 loadSettings();
1728
1729 /* Apply language settings: */
1730 retranslateUi();
1731
1732 /* Load networks: */
1733 loadHostNetworks();
1734 loadNATNetworks();
1735 loadCloudNetworks();
1736}
1737
1738void UINetworkManagerWidget::prepareActions()
1739{
1740 /* First of all, add actions which has smaller shortcut scope: */
1741 addAction(m_pActionPool->action(UIActionIndexMN_M_Network_S_Create));
1742 addAction(m_pActionPool->action(UIActionIndexMN_M_Network_S_Remove));
1743 addAction(m_pActionPool->action(UIActionIndexMN_M_Network_T_Details));
1744 addAction(m_pActionPool->action(UIActionIndexMN_M_Network_S_Refresh));
1745
1746 /* Connect actions: */
1747 connect(m_pActionPool->action(UIActionIndexMN_M_Network_S_Create), &QAction::triggered,
1748 this, &UINetworkManagerWidget::sltCreateHostNetwork);
1749 connect(m_pActionPool->action(UIActionIndexMN_M_Network_S_Create), &QAction::triggered,
1750 this, &UINetworkManagerWidget::sltCreateNATNetwork);
1751 connect(m_pActionPool->action(UIActionIndexMN_M_Network_S_Create), &QAction::triggered,
1752 this, &UINetworkManagerWidget::sltCreateCloudNetwork);
1753 connect(m_pActionPool->action(UIActionIndexMN_M_Network_S_Remove), &QAction::triggered,
1754 this, &UINetworkManagerWidget::sltRemoveHostNetwork);
1755 connect(m_pActionPool->action(UIActionIndexMN_M_Network_S_Remove), &QAction::triggered,
1756 this, &UINetworkManagerWidget::sltRemoveNATNetwork);
1757 connect(m_pActionPool->action(UIActionIndexMN_M_Network_S_Remove), &QAction::triggered,
1758 this, &UINetworkManagerWidget::sltRemoveCloudNetwork);
1759 connect(m_pActionPool->action(UIActionIndexMN_M_Network_T_Details), &QAction::toggled,
1760 this, &UINetworkManagerWidget::sltToggleDetailsVisibility);
1761}
1762
1763void UINetworkManagerWidget::prepareWidgets()
1764{
1765 /* Create main-layout: */
1766 new QVBoxLayout(this);
1767 if (layout())
1768 {
1769 /* Configure layout: */
1770 layout()->setContentsMargins(0, 0, 0, 0);
1771#ifdef VBOX_WS_MAC
1772 layout()->setSpacing(10);
1773#else
1774 layout()->setSpacing(qApp->style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing) / 2);
1775#endif
1776
1777 /* Prepare toolbar, if requested: */
1778 if (m_fShowToolbar)
1779 prepareToolBar();
1780
1781 /* Prepare tab-widget: */
1782 prepareTabWidget();
1783
1784 /* Prepare details widgets: */
1785 prepareDetailsWidgetHostNetwork();
1786 prepareDetailsWidgetNATNetwork();
1787 prepareDetailsWidgetCloudNetwork();
1788 }
1789}
1790
1791void UINetworkManagerWidget::prepareToolBar()
1792{
1793 /* Prepare toolbar: */
1794 m_pToolBar = new QIToolBar(parentWidget());
1795 if (m_pToolBar)
1796 {
1797 const int iIconMetric = (int)(QApplication::style()->pixelMetric(QStyle::PM_LargeIconSize));
1798 m_pToolBar->setIconSize(QSize(iIconMetric, iIconMetric));
1799 m_pToolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
1800 m_pToolBar->addAction(m_pActionPool->action(UIActionIndexMN_M_Network_S_Create));
1801 m_pToolBar->addSeparator();
1802 m_pToolBar->addAction(m_pActionPool->action(UIActionIndexMN_M_Network_S_Remove));
1803 m_pToolBar->addAction(m_pActionPool->action(UIActionIndexMN_M_Network_T_Details));
1804
1805#ifdef VBOX_WS_MAC
1806 /* Check whether we are embedded into a stack: */
1807 if (m_enmEmbedding == EmbedTo_Stack)
1808 {
1809 /* Add into layout: */
1810 layout()->addWidget(m_pToolBar);
1811 }
1812#else /* !VBOX_WS_MAC */
1813 /* Add into layout: */
1814 layout()->addWidget(m_pToolBar);
1815#endif /* !VBOX_WS_MAC */
1816 }
1817}
1818
1819void UINetworkManagerWidget::prepareTabWidget()
1820{
1821 /* Create tab-widget: */
1822 m_pTabWidget = new QITabWidget(this);
1823 if (m_pTabWidget)
1824 {
1825 connect(m_pTabWidget, &QITabWidget::currentChanged,
1826 this, &UINetworkManagerWidget::sltHandleCurrentTabWidgetIndexChange);
1827
1828 prepareTabHostNetwork();
1829 prepareTabNATNetwork();
1830 prepareTabCloudNetwork();
1831
1832 /* Add into layout: */
1833 layout()->addWidget(m_pTabWidget);
1834 }
1835}
1836
1837void UINetworkManagerWidget::prepareTabHostNetwork()
1838{
1839 /* Prepare host network tab: */
1840 m_pTabHostNetwork = new QWidget(m_pTabWidget);
1841 if (m_pTabHostNetwork)
1842 {
1843 /* Prepare host network layout: */
1844 m_pLayoutHostNetwork = new QVBoxLayout(m_pTabHostNetwork);
1845 if (m_pLayoutHostNetwork)
1846 prepareTreeWidgetHostNetwork();
1847
1848 /* Add into tab-widget: */
1849 m_pTabWidget->insertTab(TabWidgetIndex_HostNetwork, m_pTabHostNetwork, QString());
1850 }
1851}
1852
1853void UINetworkManagerWidget::prepareTreeWidgetHostNetwork()
1854{
1855 /* Prepare host network tree-widget: */
1856 m_pTreeWidgetHostNetwork = new QITreeWidget(m_pTabHostNetwork);
1857 if (m_pTreeWidgetHostNetwork)
1858 {
1859 m_pTreeWidgetHostNetwork->setRootIsDecorated(false);
1860 m_pTreeWidgetHostNetwork->setAlternatingRowColors(true);
1861 m_pTreeWidgetHostNetwork->setContextMenuPolicy(Qt::CustomContextMenu);
1862 m_pTreeWidgetHostNetwork->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
1863 m_pTreeWidgetHostNetwork->setColumnCount(HostNetworkColumn_Max);
1864 m_pTreeWidgetHostNetwork->setSortingEnabled(true);
1865 m_pTreeWidgetHostNetwork->sortByColumn(HostNetworkColumn_Name, Qt::AscendingOrder);
1866 m_pTreeWidgetHostNetwork->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Expanding);
1867 connect(m_pTreeWidgetHostNetwork, &QITreeWidget::currentItemChanged,
1868 this, &UINetworkManagerWidget::sltHandleCurrentItemChangeHostNetwork);
1869 connect(m_pTreeWidgetHostNetwork, &QITreeWidget::customContextMenuRequested,
1870 this, &UINetworkManagerWidget::sltHandleContextMenuRequestHostNetwork);
1871 connect(m_pTreeWidgetHostNetwork, &QITreeWidget::itemDoubleClicked,
1872 m_pActionPool->action(UIActionIndexMN_M_Network_T_Details), &QAction::setChecked);
1873
1874 /* Add into layout: */
1875 m_pLayoutHostNetwork->addWidget(m_pTreeWidgetHostNetwork);
1876 }
1877}
1878
1879void UINetworkManagerWidget::prepareDetailsWidgetHostNetwork()
1880{
1881 /* Prepare host network details-widget: */
1882 m_pDetailsWidgetHostNetwork = new UIDetailsWidgetHostNetwork(m_enmEmbedding, this);
1883 if (m_pDetailsWidgetHostNetwork)
1884 {
1885 m_pDetailsWidgetHostNetwork->setVisible(false);
1886 m_pDetailsWidgetHostNetwork->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
1887 connect(m_pDetailsWidgetHostNetwork, &UIDetailsWidgetHostNetwork::sigDataChanged,
1888 this, &UINetworkManagerWidget::sigDetailsDataChangedHostNetwork);
1889 connect(m_pDetailsWidgetHostNetwork, &UIDetailsWidgetHostNetwork::sigDataChangeRejected,
1890 this, &UINetworkManagerWidget::sltHandleCurrentItemChangeHostNetwork);
1891 connect(m_pDetailsWidgetHostNetwork, &UIDetailsWidgetHostNetwork::sigDataChangeAccepted,
1892 this, &UINetworkManagerWidget::sltApplyDetailsChangesHostNetwork);
1893
1894 /* Add into layout: */
1895 layout()->addWidget(m_pDetailsWidgetHostNetwork);
1896 }
1897}
1898
1899void UINetworkManagerWidget::prepareTabNATNetwork()
1900{
1901 /* Prepare NAT network tab: */
1902 m_pTabNATNetwork = new QWidget(m_pTabWidget);
1903 if (m_pTabNATNetwork)
1904 {
1905 /* Prepare NAT network layout: */
1906 m_pLayoutNATNetwork = new QVBoxLayout(m_pTabNATNetwork);
1907 if (m_pLayoutNATNetwork)
1908 prepareTreeWidgetNATNetwork();
1909
1910 /* Add into tab-widget: */
1911 m_pTabWidget->insertTab(TabWidgetIndex_NATNetwork, m_pTabNATNetwork, QString());
1912 }
1913}
1914
1915void UINetworkManagerWidget::prepareTreeWidgetNATNetwork()
1916{
1917 /* Prepare NAT network tree-widget: */
1918 m_pTreeWidgetNATNetwork = new QITreeWidget(m_pTabNATNetwork);
1919 if (m_pTreeWidgetNATNetwork)
1920 {
1921 m_pTreeWidgetNATNetwork->setRootIsDecorated(false);
1922 m_pTreeWidgetNATNetwork->setAlternatingRowColors(true);
1923 m_pTreeWidgetNATNetwork->setContextMenuPolicy(Qt::CustomContextMenu);
1924 m_pTreeWidgetNATNetwork->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
1925 m_pTreeWidgetNATNetwork->setColumnCount(NATNetworkColumn_Max);
1926 m_pTreeWidgetNATNetwork->setSortingEnabled(true);
1927 m_pTreeWidgetNATNetwork->sortByColumn(NATNetworkColumn_Name, Qt::AscendingOrder);
1928 m_pTreeWidgetNATNetwork->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Expanding);
1929 connect(m_pTreeWidgetNATNetwork, &QITreeWidget::currentItemChanged,
1930 this, &UINetworkManagerWidget::sltHandleCurrentItemChangeNATNetwork);
1931 connect(m_pTreeWidgetNATNetwork, &QITreeWidget::customContextMenuRequested,
1932 this, &UINetworkManagerWidget::sltHandleContextMenuRequestNATNetwork);
1933 connect(m_pTreeWidgetNATNetwork, &QITreeWidget::itemDoubleClicked,
1934 m_pActionPool->action(UIActionIndexMN_M_Network_T_Details), &QAction::setChecked);
1935
1936 /* Add into layout: */
1937 m_pLayoutNATNetwork->addWidget(m_pTreeWidgetNATNetwork);
1938 }
1939}
1940
1941void UINetworkManagerWidget::prepareDetailsWidgetNATNetwork()
1942{
1943 /* Prepare NAT network details-widget: */
1944 m_pDetailsWidgetNATNetwork = new UIDetailsWidgetNATNetwork(m_enmEmbedding, this);
1945 if (m_pDetailsWidgetNATNetwork)
1946 {
1947 m_pDetailsWidgetNATNetwork->setVisible(false);
1948 m_pDetailsWidgetNATNetwork->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
1949 connect(m_pDetailsWidgetNATNetwork, &UIDetailsWidgetNATNetwork::sigDataChanged,
1950 this, &UINetworkManagerWidget::sigDetailsDataChangedNATNetwork);
1951 connect(m_pDetailsWidgetNATNetwork, &UIDetailsWidgetNATNetwork::sigDataChangeRejected,
1952 this, &UINetworkManagerWidget::sltHandleCurrentItemChangeNATNetwork);
1953 connect(m_pDetailsWidgetNATNetwork, &UIDetailsWidgetNATNetwork::sigDataChangeAccepted,
1954 this, &UINetworkManagerWidget::sltApplyDetailsChangesNATNetwork);
1955
1956 /* Add into layout: */
1957 layout()->addWidget(m_pDetailsWidgetNATNetwork);
1958 }
1959}
1960
1961void UINetworkManagerWidget::prepareTabCloudNetwork()
1962{
1963 /* Prepare cloud network tab: */
1964 m_pTabCloudNetwork = new QWidget(m_pTabWidget);
1965 if (m_pTabCloudNetwork)
1966 {
1967 /* Prepare cloud network layout: */
1968 m_pLayoutCloudNetwork = new QVBoxLayout(m_pTabCloudNetwork);
1969 if (m_pLayoutCloudNetwork)
1970 prepareTreeWidgetCloudNetwork();
1971
1972 /* Add into tab-widget: */
1973 m_pTabWidget->insertTab(TabWidgetIndex_CloudNetwork, m_pTabCloudNetwork, QString());
1974 }
1975}
1976
1977void UINetworkManagerWidget::prepareTreeWidgetCloudNetwork()
1978{
1979 /* Prepare cloud network tree-widget: */
1980 m_pTreeWidgetCloudNetwork = new QITreeWidget(m_pTabCloudNetwork);
1981 if (m_pTreeWidgetCloudNetwork)
1982 {
1983 m_pTreeWidgetCloudNetwork->setRootIsDecorated(false);
1984 m_pTreeWidgetCloudNetwork->setAlternatingRowColors(true);
1985 m_pTreeWidgetCloudNetwork->setContextMenuPolicy(Qt::CustomContextMenu);
1986 m_pTreeWidgetCloudNetwork->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
1987 m_pTreeWidgetCloudNetwork->setColumnCount(CloudNetworkColumn_Max);
1988 m_pTreeWidgetCloudNetwork->setSortingEnabled(true);
1989 m_pTreeWidgetCloudNetwork->sortByColumn(CloudNetworkColumn_Name, Qt::AscendingOrder);
1990 m_pTreeWidgetCloudNetwork->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Expanding);
1991 connect(m_pTreeWidgetCloudNetwork, &QITreeWidget::currentItemChanged,
1992 this, &UINetworkManagerWidget::sltHandleCurrentItemChangeCloudNetwork);
1993 connect(m_pTreeWidgetCloudNetwork, &QITreeWidget::customContextMenuRequested,
1994 this, &UINetworkManagerWidget::sltHandleContextMenuRequestCloudNetwork);
1995 connect(m_pTreeWidgetCloudNetwork, &QITreeWidget::itemDoubleClicked,
1996 m_pActionPool->action(UIActionIndexMN_M_Network_T_Details), &QAction::setChecked);
1997
1998 /* Add into layout: */
1999 m_pLayoutCloudNetwork->addWidget(m_pTreeWidgetCloudNetwork);
2000 }
2001}
2002
2003void UINetworkManagerWidget::prepareDetailsWidgetCloudNetwork()
2004{
2005 /* Prepare cloud network details-widget: */
2006 m_pDetailsWidgetCloudNetwork = new UIDetailsWidgetCloudNetwork(m_enmEmbedding, this);
2007 if (m_pDetailsWidgetCloudNetwork)
2008 {
2009 m_pDetailsWidgetCloudNetwork->setVisible(false);
2010 m_pDetailsWidgetCloudNetwork->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
2011 connect(m_pDetailsWidgetCloudNetwork, &UIDetailsWidgetCloudNetwork::sigDataChanged,
2012 this, &UINetworkManagerWidget::sigDetailsDataChangedCloudNetwork);
2013 connect(m_pDetailsWidgetCloudNetwork, &UIDetailsWidgetCloudNetwork::sigDataChangeRejected,
2014 this, &UINetworkManagerWidget::sltHandleCurrentItemChangeCloudNetwork);
2015 connect(m_pDetailsWidgetCloudNetwork, &UIDetailsWidgetCloudNetwork::sigDataChangeAccepted,
2016 this, &UINetworkManagerWidget::sltApplyDetailsChangesCloudNetwork);
2017
2018 /* Add into layout: */
2019 layout()->addWidget(m_pDetailsWidgetCloudNetwork);
2020 }
2021}
2022
2023void UINetworkManagerWidget::loadSettings()
2024{
2025 /* Details action/widget: */
2026 if (m_pActionPool)
2027 {
2028 m_pActionPool->action(UIActionIndexMN_M_Network_T_Details)->setChecked(gEDataManager->hostNetworkManagerDetailsExpanded());
2029 sltToggleDetailsVisibility(m_pActionPool->action(UIActionIndexMN_M_Network_T_Details)->isChecked());
2030 }
2031}
2032
2033void UINetworkManagerWidget::loadHostNetworks()
2034{
2035 /* Check host network tree-widget: */
2036 if (!m_pTreeWidgetHostNetwork)
2037 return;
2038
2039 /* Clear tree first of all: */
2040 m_pTreeWidgetHostNetwork->clear();
2041
2042#ifdef VBOX_WS_MAC
2043 /* Get VirtualBox for further activities: */
2044 const CVirtualBox comVBox = gpGlobalSession->virtualBox();
2045
2046 /* Get networks for further activities: */
2047 const QVector<CHostOnlyNetwork> networks = comVBox.GetHostOnlyNetworks();
2048
2049 /* Show error message if necessary: */
2050 if (!comVBox.isOk())
2051 UINotificationMessage::cannotAcquireVirtualBoxParameter(comVBox);
2052 else
2053 {
2054 /* For each host network => load it to the tree: */
2055 foreach (const CHostOnlyNetwork &comNetwork, networks)
2056 {
2057 UIDataHostNetwork data;
2058 loadHostNetwork(comNetwork, data);
2059 createItemForHostNetwork(data, false);
2060 }
2061
2062 /* Choose the 1st item as current initially: */
2063 m_pTreeWidgetHostNetwork->setCurrentItem(m_pTreeWidgetHostNetwork->topLevelItem(0));
2064 sltHandleCurrentItemChangeHostNetwork();
2065
2066 /* Adjust tree-widgets: */
2067 sltAdjustTreeWidgets();
2068 }
2069
2070#else /* !VBOX_WS_MAC */
2071
2072 /* Get host for further activities: */
2073 const CHost comHost = gpGlobalSession->host();
2074
2075 /* Get interfaces for further activities: */
2076 const QVector<CHostNetworkInterface> interfaces = comHost.GetNetworkInterfaces();
2077
2078 /* Show error message if necessary: */
2079 if (!comHost.isOk())
2080 UINotificationMessage::cannotAcquireHostParameter(comHost);
2081 else
2082 {
2083 /* For each host-only interface => load it to the tree: */
2084 foreach (const CHostNetworkInterface &comInterface, interfaces)
2085 if (comInterface.GetInterfaceType() == KHostNetworkInterfaceType_HostOnly)
2086 {
2087 UIDataHostNetwork data;
2088 loadHostNetwork(comInterface, data);
2089 createItemForHostNetwork(data, false);
2090 }
2091
2092 /* Choose the 1st item as current initially: */
2093 m_pTreeWidgetHostNetwork->setCurrentItem(m_pTreeWidgetHostNetwork->topLevelItem(0));
2094 sltHandleCurrentItemChangeHostNetwork();
2095
2096 /* Adjust tree-widgets: */
2097 sltAdjustTreeWidgets();
2098 }
2099#endif /* !VBOX_WS_MAC */
2100}
2101
2102#ifdef VBOX_WS_MAC
2103void UINetworkManagerWidget::loadHostNetwork(const CHostOnlyNetwork &comNetwork, UIDataHostNetwork &data)
2104{
2105 /* Gather network settings: */
2106 if (comNetwork.isNotNull())
2107 data.m_fExists = true;
2108 if (comNetwork.isOk())
2109 data.m_strName = comNetwork.GetNetworkName();
2110 if (comNetwork.isOk())
2111 data.m_strMask = comNetwork.GetNetworkMask();
2112 if (comNetwork.isOk())
2113 data.m_strLBnd = comNetwork.GetLowerIP();
2114 if (comNetwork.isOk())
2115 data.m_strUBnd = comNetwork.GetUpperIP();
2116
2117 /* Show error message if necessary: */
2118 if (!comNetwork.isOk())
2119 UINotificationMessage::cannotAcquireHostOnlyNetworkParameter(comNetwork);
2120}
2121
2122#else /* !VBOX_WS_MAC */
2123
2124void UINetworkManagerWidget::loadHostNetwork(const CHostNetworkInterface &comInterface, UIDataHostNetwork &data)
2125{
2126 /* Gather interface settings: */
2127 if (comInterface.isNotNull())
2128 data.m_interface.m_fExists = true;
2129 if (comInterface.isOk())
2130 data.m_interface.m_strName = comInterface.GetName();
2131 if (comInterface.isOk())
2132 data.m_interface.m_fDHCPEnabled = comInterface.GetDHCPEnabled();
2133 if (comInterface.isOk())
2134 data.m_interface.m_strAddress = comInterface.GetIPAddress();
2135 if (comInterface.isOk())
2136 data.m_interface.m_strMask = comInterface.GetNetworkMask();
2137 if (comInterface.isOk())
2138 data.m_interface.m_fSupportedIPv6 = comInterface.GetIPV6Supported();
2139 if (comInterface.isOk())
2140 data.m_interface.m_strAddress6 = comInterface.GetIPV6Address();
2141 if (comInterface.isOk())
2142 data.m_interface.m_strPrefixLength6 = QString::number(comInterface.GetIPV6NetworkMaskPrefixLength());
2143
2144 /* Get host interface network name for further activities: */
2145 QString strNetworkName;
2146 if (comInterface.isOk())
2147 strNetworkName = comInterface.GetNetworkName();
2148
2149 /* Show error message if necessary: */
2150 if (!comInterface.isOk())
2151 UINotificationMessage::cannotAcquireHostNetworkInterfaceParameter(comInterface);
2152
2153 /* Get VBox for further activities: */
2154 CVirtualBox comVBox = gpGlobalSession->virtualBox();
2155
2156 /* Find corresponding DHCP server (create if necessary): */
2157 CDHCPServer comServer = comVBox.FindDHCPServerByNetworkName(strNetworkName);
2158 if (!comVBox.isOk() || comServer.isNull())
2159 comServer = comVBox.CreateDHCPServer(strNetworkName);
2160
2161 /* Show error message if necessary: */
2162 if (!comVBox.isOk() || comServer.isNull())
2163 UINotificationMessage::cannotCreateDHCPServer(comVBox, strNetworkName);
2164 else
2165 {
2166 /* Gather DHCP server settings: */
2167 if (comServer.isOk())
2168 data.m_dhcpserver.m_fEnabled = comServer.GetEnabled();
2169 if (comServer.isOk())
2170 data.m_dhcpserver.m_strAddress = comServer.GetIPAddress();
2171 if (comServer.isOk())
2172 data.m_dhcpserver.m_strMask = comServer.GetNetworkMask();
2173 if (comServer.isOk())
2174 data.m_dhcpserver.m_strLowerAddress = comServer.GetLowerIP();
2175 if (comServer.isOk())
2176 data.m_dhcpserver.m_strUpperAddress = comServer.GetUpperIP();
2177
2178 /* Show error message if necessary: */
2179 if (!comServer.isOk())
2180 return UINotificationMessage::cannotAcquireDHCPServerParameter(comServer);
2181 }
2182}
2183#endif /* !VBOX_WS_MAC */
2184
2185void UINetworkManagerWidget::loadNATNetworks()
2186{
2187 /* Check NAT network tree-widget: */
2188 if (!m_pTreeWidgetNATNetwork)
2189 return;
2190
2191 /* Clear tree first of all: */
2192 m_pTreeWidgetNATNetwork->clear();
2193
2194 /* Get VirtualBox for further activities: */
2195 const CVirtualBox comVBox = gpGlobalSession->virtualBox();
2196
2197 /* Get interfaces for further activities: */
2198 const QVector<CNATNetwork> networks = comVBox.GetNATNetworks();
2199
2200 /* Show error message if necessary: */
2201 if (!comVBox.isOk())
2202 UINotificationMessage::cannotAcquireVirtualBoxParameter(comVBox);
2203 else
2204 {
2205 /* For each NAT network => load it to the tree: */
2206 foreach (const CNATNetwork &comNetwork, networks)
2207 {
2208 UIDataNATNetwork data;
2209 loadNATNetwork(comNetwork, data);
2210 createItemForNATNetwork(data, false);
2211 }
2212
2213 /* Choose the 1st item as current initially: */
2214 m_pTreeWidgetNATNetwork->setCurrentItem(m_pTreeWidgetNATNetwork->topLevelItem(0));
2215 sltHandleCurrentItemChangeNATNetwork();
2216
2217 /* Adjust tree-widgets: */
2218 sltAdjustTreeWidgets();
2219 }
2220}
2221
2222void UINetworkManagerWidget::loadNATNetwork(const CNATNetwork &comNetwork, UIDataNATNetwork &data)
2223{
2224 /* Gather network settings: */
2225 if (comNetwork.isNotNull())
2226 data.m_fExists = true;
2227 if (comNetwork.isOk())
2228 data.m_strName = comNetwork.GetNetworkName();
2229 if (comNetwork.isOk())
2230 data.m_strPrefixIPv4 = comNetwork.GetNetwork();
2231 if (comNetwork.isOk())
2232 data.m_strPrefixIPv6 = comNetwork.GetIPv6Prefix();
2233 if (comNetwork.isOk())
2234 data.m_fSupportsDHCP = comNetwork.GetNeedDhcpServer();
2235 if (comNetwork.isOk())
2236 data.m_fSupportsIPv6 = comNetwork.GetIPv6Enabled();
2237 if (comNetwork.isOk())
2238 data.m_fAdvertiseDefaultIPv6Route = comNetwork.GetAdvertiseDefaultIPv6RouteEnabled();
2239
2240 /* Gather forwarding rules: */
2241 if (comNetwork.isOk())
2242 {
2243 /* Load IPv4 rules: */
2244 foreach (QString strIPv4Rule, comNetwork.GetPortForwardRules4())
2245 {
2246 /* Replace all ':' with ',' first: */
2247 strIPv4Rule.replace(':', ',');
2248 /* Parse rules: */
2249 QStringList rules = strIPv4Rule.split(',');
2250 Assert(rules.size() == 6);
2251 if (rules.size() != 6)
2252 continue;
2253 data.m_rules4 << UIDataPortForwardingRule(rules.at(0),
2254 gpConverter->fromInternalString<KNATProtocol>(rules.at(1)),
2255 QString(rules.at(2)).remove('[').remove(']'),
2256 rules.at(3).toUInt(),
2257 QString(rules.at(4)).remove('[').remove(']'),
2258 rules.at(5).toUInt());
2259 }
2260
2261 /* Load IPv6 rules: */
2262 foreach (QString strIPv6Rule, comNetwork.GetPortForwardRules6())
2263 {
2264 /* Replace all ':' with ',' first: */
2265 strIPv6Rule.replace(':', ',');
2266 /* But replace ',' back with ':' for addresses: */
2267 QRegularExpression re("\\[[0-9a-fA-F,]*,[0-9a-fA-F,]*\\]");
2268 re.setPatternOptions(QRegularExpression::InvertedGreedinessOption);
2269 QRegularExpressionMatch mt = re.match(strIPv6Rule);
2270 while (mt.hasMatch())
2271 {
2272 QString strCapOld = mt.captured();
2273 QString strCapNew = strCapOld;
2274 strCapNew.replace(',', ':');
2275 strIPv6Rule.replace(strCapOld, strCapNew);
2276 mt = re.match(strIPv6Rule);
2277 }
2278 /* Parse rules: */
2279 QStringList rules = strIPv6Rule.split(',');
2280 Assert(rules.size() == 6);
2281 if (rules.size() != 6)
2282 continue;
2283 data.m_rules6 << UIDataPortForwardingRule(rules.at(0),
2284 gpConverter->fromInternalString<KNATProtocol>(rules.at(1)),
2285 QString(rules.at(2)).remove('[').remove(']'),
2286 rules.at(3).toUInt(),
2287 QString(rules.at(4)).remove('[').remove(']'),
2288 rules.at(5).toUInt());
2289 }
2290 }
2291
2292 /* Show error message if necessary: */
2293 if (!comNetwork.isOk())
2294 UINotificationMessage::cannotAcquireNATNetworkParameter(comNetwork);
2295}
2296
2297void UINetworkManagerWidget::loadCloudNetworks()
2298{
2299 /* Check cloud network tree-widget: */
2300 if (!m_pTreeWidgetCloudNetwork)
2301 return;
2302
2303 /* Clear tree first of all: */
2304 m_pTreeWidgetCloudNetwork->clear();
2305
2306 /* Get VirtualBox for further activities: */
2307 const CVirtualBox comVBox = gpGlobalSession->virtualBox();
2308
2309 /* Get interfaces for further activities: */
2310 const QVector<CCloudNetwork> networks = comVBox.GetCloudNetworks();
2311
2312 /* Show error message if necessary: */
2313 if (!comVBox.isOk())
2314 UINotificationMessage::cannotAcquireVirtualBoxParameter(comVBox);
2315 else
2316 {
2317 /* For each cloud network => load it to the tree: */
2318 foreach (const CCloudNetwork &comNetwork, networks)
2319 {
2320 UIDataCloudNetwork data;
2321 loadCloudNetwork(comNetwork, data);
2322 createItemForCloudNetwork(data, false);
2323 }
2324
2325 /* Choose the 1st item as current initially: */
2326 m_pTreeWidgetCloudNetwork->setCurrentItem(m_pTreeWidgetCloudNetwork->topLevelItem(0));
2327 sltHandleCurrentItemChangeCloudNetwork();
2328
2329 /* Adjust tree-widgets: */
2330 sltAdjustTreeWidgets();
2331 }
2332}
2333
2334void UINetworkManagerWidget::loadCloudNetwork(const CCloudNetwork &comNetwork, UIDataCloudNetwork &data)
2335{
2336 /* Gather network settings: */
2337 if (comNetwork.isNotNull())
2338 data.m_fExists = true;
2339 if (comNetwork.isNotNull())
2340 data.m_fEnabled = comNetwork.GetEnabled();
2341 if (comNetwork.isOk())
2342 data.m_strName = comNetwork.GetNetworkName();
2343 if (comNetwork.isOk())
2344 data.m_strProvider = comNetwork.GetProvider();
2345 if (comNetwork.isOk())
2346 data.m_strProfile = comNetwork.GetProfile();
2347 if (comNetwork.isOk())
2348 data.m_strId = comNetwork.GetNetworkId();
2349
2350 /* Show error message if necessary: */
2351 if (!comNetwork.isOk())
2352 UINotificationMessage::cannotAcquireCloudNetworkParameter(comNetwork);
2353}
2354
2355void UINetworkManagerWidget::updateActionAvailability()
2356{
2357 /* Check which tab we have currently: */
2358 switch (m_pTabWidget->currentIndex())
2359 {
2360 case TabWidgetIndex_HostNetwork:
2361 {
2362 AssertMsgReturnVoid(m_pTreeWidgetHostNetwork, ("Host network tree-widget isn't created!\n"));
2363 UIItemHostNetwork *pItem = static_cast<UIItemHostNetwork*>(m_pTreeWidgetHostNetwork->currentItem());
2364 m_pActionPool->action(UIActionIndexMN_M_Network_S_Remove)->setEnabled(pItem);
2365 break;
2366 }
2367 case TabWidgetIndex_NATNetwork:
2368 {
2369 AssertMsgReturnVoid(m_pTreeWidgetNATNetwork, ("NAT network tree-widget isn't created!\n"));
2370 UIItemNATNetwork *pItem = static_cast<UIItemNATNetwork*>(m_pTreeWidgetNATNetwork->currentItem());
2371 m_pActionPool->action(UIActionIndexMN_M_Network_S_Remove)->setEnabled(pItem);
2372 break;
2373 }
2374 case TabWidgetIndex_CloudNetwork:
2375 {
2376 AssertMsgReturnVoid(m_pTreeWidgetCloudNetwork, ("Cloud network tree-widget isn't created!\n"));
2377 UIItemCloudNetwork *pItem = static_cast<UIItemCloudNetwork*>(m_pTreeWidgetCloudNetwork->currentItem());
2378 m_pActionPool->action(UIActionIndexMN_M_Network_S_Remove)->setEnabled(pItem);
2379 break;
2380 }
2381 default:
2382 break;
2383 }
2384}
2385
2386void UINetworkManagerWidget::createItemForHostNetwork(const UIDataHostNetwork &data, bool fChooseItem)
2387{
2388 /* Prepare new item: */
2389 UIItemHostNetwork *pItem = new UIItemHostNetwork;
2390 if (pItem)
2391 {
2392 pItem->UIDataHostNetwork::operator=(data);
2393 pItem->updateFields();
2394
2395 /* Add item to the tree: */
2396 m_pTreeWidgetHostNetwork->addTopLevelItem(pItem);
2397
2398 /* And choose it as current if necessary: */
2399 if (fChooseItem)
2400 m_pTreeWidgetHostNetwork->setCurrentItem(pItem);
2401 }
2402}
2403
2404void UINetworkManagerWidget::updateItemForHostNetwork(const UIDataHostNetwork &data, bool fChooseItem, UIItemHostNetwork *pItem)
2405{
2406 /* Update passed item: */
2407 if (pItem)
2408 {
2409 /* Configure item: */
2410 pItem->UIDataHostNetwork::operator=(data);
2411 pItem->updateFields();
2412 /* And choose it as current if necessary: */
2413 if (fChooseItem)
2414 m_pTreeWidgetHostNetwork->setCurrentItem(pItem);
2415 }
2416}
2417
2418void UINetworkManagerWidget::createItemForNATNetwork(const UIDataNATNetwork &data, bool fChooseItem)
2419{
2420 /* Create new item: */
2421 UIItemNATNetwork *pItem = new UIItemNATNetwork;
2422 if (pItem)
2423 {
2424 /* Configure item: */
2425 pItem->UIDataNATNetwork::operator=(data);
2426 pItem->updateFields();
2427 /* Add item to the tree: */
2428 m_pTreeWidgetNATNetwork->addTopLevelItem(pItem);
2429 /* And choose it as current if necessary: */
2430 if (fChooseItem)
2431 m_pTreeWidgetNATNetwork->setCurrentItem(pItem);
2432 }
2433}
2434
2435void UINetworkManagerWidget::updateItemForNATNetwork(const UIDataNATNetwork &data, bool fChooseItem, UIItemNATNetwork *pItem)
2436{
2437 /* Update passed item: */
2438 if (pItem)
2439 {
2440 /* Configure item: */
2441 pItem->UIDataNATNetwork::operator=(data);
2442 pItem->updateFields();
2443 /* And choose it as current if necessary: */
2444 if (fChooseItem)
2445 m_pTreeWidgetNATNetwork->setCurrentItem(pItem);
2446 }
2447}
2448
2449void UINetworkManagerWidget::createItemForCloudNetwork(const UIDataCloudNetwork &data, bool fChooseItem)
2450{
2451 /* Create new item: */
2452 UIItemCloudNetwork *pItem = new UIItemCloudNetwork;
2453 if (pItem)
2454 {
2455 /* Configure item: */
2456 pItem->UIDataCloudNetwork::operator=(data);
2457 pItem->updateFields();
2458 /* Add item to the tree: */
2459 m_pTreeWidgetCloudNetwork->addTopLevelItem(pItem);
2460 /* And choose it as current if necessary: */
2461 if (fChooseItem)
2462 m_pTreeWidgetCloudNetwork->setCurrentItem(pItem);
2463 }
2464}
2465
2466void UINetworkManagerWidget::updateItemForCloudNetwork(const UIDataCloudNetwork &data, bool fChooseItem, UIItemCloudNetwork *pItem)
2467{
2468 /* Update passed item: */
2469 if (pItem)
2470 {
2471 /* Configure item: */
2472 pItem->UIDataCloudNetwork::operator=(data);
2473 pItem->updateFields();
2474 /* And choose it as current if necessary: */
2475 if (fChooseItem)
2476 m_pTreeWidgetCloudNetwork->setCurrentItem(pItem);
2477 }
2478}
2479
2480#ifdef VBOX_WS_MAC
2481QStringList UINetworkManagerWidget::busyNamesHost() const
2482{
2483 QStringList names;
2484 for (int i = 0; i < m_pTreeWidgetHostNetwork->topLevelItemCount(); ++i)
2485 {
2486 UIItemHostNetwork *pItem = qobject_cast<UIItemHostNetwork*>(m_pTreeWidgetHostNetwork->childItem(i));
2487 const QString strItemName(pItem->name());
2488 if (!strItemName.isEmpty() && !names.contains(strItemName))
2489 names << strItemName;
2490 }
2491 return names;
2492}
2493#endif /* VBOX_WS_MAC */
2494
2495QStringList UINetworkManagerWidget::busyNamesNAT() const
2496{
2497 QStringList names;
2498 for (int i = 0; i < m_pTreeWidgetNATNetwork->topLevelItemCount(); ++i)
2499 {
2500 UIItemNATNetwork *pItem = qobject_cast<UIItemNATNetwork*>(m_pTreeWidgetNATNetwork->childItem(i));
2501 const QString strItemName(pItem->name());
2502 if (!strItemName.isEmpty() && !names.contains(strItemName))
2503 names << strItemName;
2504 }
2505 return names;
2506}
2507
2508QStringList UINetworkManagerWidget::busyNamesCloud() const
2509{
2510 QStringList names;
2511 for (int i = 0; i < m_pTreeWidgetCloudNetwork->topLevelItemCount(); ++i)
2512 {
2513 UIItemCloudNetwork *pItem = qobject_cast<UIItemCloudNetwork*>(m_pTreeWidgetCloudNetwork->childItem(i));
2514 const QString strItemName(pItem->name());
2515 if (!strItemName.isEmpty() && !names.contains(strItemName))
2516 names << strItemName;
2517 }
2518 return names;
2519}
2520
2521
2522/*********************************************************************************************************************************
2523* Class UINetworkManagerFactory implementation. *
2524*********************************************************************************************************************************/
2525
2526UINetworkManagerFactory::UINetworkManagerFactory(UIActionPool *pActionPool /* = 0 */)
2527 : m_pActionPool(pActionPool)
2528{
2529}
2530
2531void UINetworkManagerFactory::create(QIManagerDialog *&pDialog, QWidget *pCenterWidget)
2532{
2533 pDialog = new UINetworkManager(pCenterWidget, m_pActionPool);
2534}
2535
2536
2537/*********************************************************************************************************************************
2538* Class UINetworkManager implementation. *
2539*********************************************************************************************************************************/
2540
2541UINetworkManager::UINetworkManager(QWidget *pCenterWidget, UIActionPool *pActionPool)
2542 : QIWithRetranslateUI<QIManagerDialog>(pCenterWidget)
2543 , m_pActionPool(pActionPool)
2544{
2545}
2546
2547void UINetworkManager::sltHandleButtonBoxClick(QAbstractButton *pButton)
2548{
2549 /* Disable buttons first of all: */
2550 button(ButtonType_Reset)->setEnabled(false);
2551 button(ButtonType_Apply)->setEnabled(false);
2552
2553 /* Compare with known buttons: */
2554 if (pButton == button(ButtonType_Reset))
2555 emit sigDataChangeRejected();
2556 else
2557 if (pButton == button(ButtonType_Apply))
2558 emit sigDataChangeAccepted();
2559}
2560
2561void UINetworkManager::retranslateUi()
2562{
2563 /* Translate window title: */
2564 setWindowTitle(tr("Network Manager"));
2565
2566 /* Translate buttons: */
2567 button(ButtonType_Reset)->setText(tr("Reset"));
2568 button(ButtonType_Apply)->setText(tr("Apply"));
2569 button(ButtonType_Close)->setText(tr("Close"));
2570 button(ButtonType_Help)->setText(tr("Help"));
2571 button(ButtonType_Reset)->setStatusTip(tr("Reset changes in current network details"));
2572 button(ButtonType_Apply)->setStatusTip(tr("Apply changes in current network details"));
2573 button(ButtonType_Close)->setStatusTip(tr("Close dialog without saving"));
2574 button(ButtonType_Help)->setStatusTip(tr("Show dialog help"));
2575 button(ButtonType_Reset)->setShortcut(QString("Ctrl+Backspace"));
2576 button(ButtonType_Apply)->setShortcut(QString("Ctrl+Return"));
2577 button(ButtonType_Close)->setShortcut(Qt::Key_Escape);
2578 button(ButtonType_Help)->setShortcut(UIShortcutPool::standardSequence(QKeySequence::HelpContents));
2579 button(ButtonType_Reset)->setToolTip(tr("Reset Changes (%1)").arg(button(ButtonType_Reset)->shortcut().toString()));
2580 button(ButtonType_Apply)->setToolTip(tr("Apply Changes (%1)").arg(button(ButtonType_Apply)->shortcut().toString()));
2581 button(ButtonType_Close)->setToolTip(tr("Close Window (%1)").arg(button(ButtonType_Close)->shortcut().toString()));
2582 button(ButtonType_Help)->setToolTip(tr("Show Help (%1)").arg(button(ButtonType_Help)->shortcut().toString()));
2583}
2584
2585void UINetworkManager::configure()
2586{
2587#ifndef VBOX_WS_MAC
2588 /* Assign window icon: */
2589 setWindowIcon(UIIconPool::iconSetFull(":/host_iface_manager_32px.png", ":/host_iface_manager_16px.png"));
2590#endif
2591}
2592
2593void UINetworkManager::configureCentralWidget()
2594{
2595 /* Prepare widget: */
2596 UINetworkManagerWidget *pWidget = new UINetworkManagerWidget(EmbedTo_Dialog, m_pActionPool, true, this);
2597 if (pWidget)
2598 {
2599 setWidget(pWidget);
2600 setWidgetMenu(pWidget->menu());
2601#ifdef VBOX_WS_MAC
2602 setWidgetToolbar(pWidget->toolbar());
2603#endif
2604 connect(this, &UINetworkManager::sigDataChangeRejected,
2605 pWidget, &UINetworkManagerWidget::sltResetDetailsChanges);
2606 connect(this, &UINetworkManager::sigDataChangeAccepted,
2607 pWidget, &UINetworkManagerWidget::sltApplyDetailsChanges);
2608
2609 /* Add into layout: */
2610 centralWidget()->layout()->addWidget(pWidget);
2611 }
2612}
2613
2614void UINetworkManager::configureButtonBox()
2615{
2616 /* Configure button-box: */
2617 connect(widget(), &UINetworkManagerWidget::sigDetailsVisibilityChanged,
2618 button(ButtonType_Apply), &QPushButton::setVisible);
2619 connect(widget(), &UINetworkManagerWidget::sigDetailsVisibilityChanged,
2620 button(ButtonType_Reset), &QPushButton::setVisible);
2621 connect(widget(), &UINetworkManagerWidget::sigDetailsDataChangedHostNetwork,
2622 button(ButtonType_Apply), &QPushButton::setEnabled);
2623 connect(widget(), &UINetworkManagerWidget::sigDetailsDataChangedHostNetwork,
2624 button(ButtonType_Reset), &QPushButton::setEnabled);
2625 connect(widget(), &UINetworkManagerWidget::sigDetailsDataChangedNATNetwork,
2626 button(ButtonType_Apply), &QPushButton::setEnabled);
2627 connect(widget(), &UINetworkManagerWidget::sigDetailsDataChangedNATNetwork,
2628 button(ButtonType_Reset), &QPushButton::setEnabled);
2629 connect(widget(), &UINetworkManagerWidget::sigDetailsDataChangedCloudNetwork,
2630 button(ButtonType_Apply), &QPushButton::setEnabled);
2631 connect(widget(), &UINetworkManagerWidget::sigDetailsDataChangedCloudNetwork,
2632 button(ButtonType_Reset), &QPushButton::setEnabled);
2633 connect(buttonBox(), &QIDialogButtonBox::clicked,
2634 this, &UINetworkManager::sltHandleButtonBoxClick);
2635 // WORKAROUND:
2636 // Since we connected signals later than extra-data loaded
2637 // for signals above, we should handle that stuff here again:
2638 button(ButtonType_Apply)->setVisible(gEDataManager->hostNetworkManagerDetailsExpanded());
2639 button(ButtonType_Reset)->setVisible(gEDataManager->hostNetworkManagerDetailsExpanded());
2640}
2641
2642void UINetworkManager::finalize()
2643{
2644 /* Apply language settings: */
2645 retranslateUi();
2646}
2647
2648UINetworkManagerWidget *UINetworkManager::widget()
2649{
2650 return qobject_cast<UINetworkManagerWidget*>(QIManagerDialog::widget());
2651}
2652
2653
2654#include "UINetworkManager.moc"
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