VirtualBox

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

Last change on this file since 102493 was 102269, checked in by vboxsync, 10 months ago

FE/Qt: bugref:10450: macOS: No need to QIToolBar layout/paint hacks since Qt6.

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