VirtualBox

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

Last change on this file since 100347 was 98103, checked in by vboxsync, 2 years ago

Copyright year updates by scm.

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

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