VirtualBox

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

Last change on this file was 104393, checked in by vboxsync, 4 weeks ago

FE/Qt. bugref:10622. Using new UITranslationEventListener in the UIActionPool class.

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

© 2023 Oracle
ContactPrivacy policyTerms of Use