VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsNetwork.cpp@ 37571

Last change on this file since 37571 was 37571, checked in by vboxsync, 14 years ago

FE/Qt: 5746: Create generic network adapter UI in Machine settings / Network page: Initial version.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Revision Author Id
File size: 43.2 KB
Line 
1/* $Id: UIMachineSettingsNetwork.cpp 37571 2011-06-21 11:34:43Z vboxsync $ */
2/** @file
3 *
4 * VBox frontends: Qt4 GUI ("VirtualBox"):
5 * UIMachineSettingsNetwork class implementation
6 */
7
8/*
9 * Copyright (C) 2008-2011 Oracle Corporation
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.virtualbox.org. This file is free software;
13 * you can redistribute it and/or modify it under the terms of the GNU
14 * General Public License (GPL) as published by the Free Software
15 * Foundation, in version 2 as it comes in the "COPYING" file of the
16 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
17 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18 */
19
20/* Qt includes */
21#include <QTimer>
22#include <QCompleter>
23
24/* Local includes */
25#include "QIWidgetValidator.h"
26#include "QIArrowButtonSwitch.h"
27#include "VBoxGlobal.h"
28#include "UIMachineSettingsNetwork.h"
29#include "QITabWidget.h"
30
31#ifdef VBOX_WITH_VDE
32# include <iprt/ldr.h>
33# include <VBox/VDEPlug.h>
34#endif /* VBOX_WITH_VDE */
35
36/* Empty item extra-code: */
37const char *emptyItemCode = "#empty#";
38
39UIMachineSettingsNetwork::UIMachineSettingsNetwork(UIMachineSettingsNetworkPage *pParent)
40 : QIWithRetranslateUI<QWidget>(0)
41 , m_pParent(pParent)
42 , m_pValidator(0)
43 , m_iSlot(-1)
44 , m_fPolished(false)
45{
46 /* Apply UI decorations: */
47 Ui::UIMachineSettingsNetwork::setupUi(this);
48
49 /* Setup widgets: */
50 m_pAdapterNameCombo->setInsertPolicy(QComboBox::NoInsert);
51 m_pMACEditor->setValidator(new QRegExpValidator(QRegExp("[0-9A-Fa-f][02468ACEace][0-9A-Fa-f]{10}"), this));
52 m_pMACEditor->setMinimumWidthByText(QString().fill('0', 12));
53
54 /* Setup connections: */
55 connect(m_pAdvancedArrow, SIGNAL(clicked()), this, SLOT(sltToggleAdvanced()));
56 connect(m_pMACButton, SIGNAL(clicked()), this, SLOT(sltGenerateMac()));
57 connect(m_pPortForwardingButton, SIGNAL(clicked()), this, SLOT(sltOpenPortForwardingDlg()));
58
59 /* Applying language settings: */
60 retranslateUi();
61}
62
63void UIMachineSettingsNetwork::polishTab()
64{
65 /* Basic attributes: */
66 mCbEnableAdapter->setEnabled(m_pParent->isMachineOffline());
67 m_pAttachmentTypeLabel->setEnabled(m_pParent->isMachineInValidMode());
68 m_pAttachmentTypeCombo->setEnabled(m_pParent->isMachineInValidMode());
69 m_pAdapterNameLabel->setEnabled(m_pParent->isMachineInValidMode() &&
70 attachmentType() != KNetworkAttachmentType_Null &&
71 attachmentType() != KNetworkAttachmentType_NAT);
72 m_pAdapterNameCombo->setEnabled(m_pParent->isMachineInValidMode() &&
73 attachmentType() != KNetworkAttachmentType_Null &&
74 attachmentType() != KNetworkAttachmentType_NAT);
75 m_pAdvancedArrow->setEnabled(m_pParent->isMachineInValidMode());
76
77 /* Advanced attributes: */
78 m_pAdapterTypeLabel->setEnabled(m_pParent->isMachineOffline());
79 m_pAdapterTypeCombo->setEnabled(m_pParent->isMachineOffline());
80 m_pPromiscuousModeLabel->setEnabled(m_pParent->isMachineInValidMode() &&
81 attachmentType() != KNetworkAttachmentType_Null &&
82 attachmentType() != KNetworkAttachmentType_Generic &&
83 attachmentType() != KNetworkAttachmentType_NAT);
84 m_pPromiscuousModeCombo->setEnabled(m_pParent->isMachineInValidMode() &&
85 attachmentType() != KNetworkAttachmentType_Null &&
86 attachmentType() != KNetworkAttachmentType_Generic &&
87 attachmentType() != KNetworkAttachmentType_NAT);
88 m_pMACLabel->setEnabled(m_pParent->isMachineOffline());
89 m_pMACEditor->setEnabled(m_pParent->isMachineOffline());
90 m_pMACButton->setEnabled(m_pParent->isMachineOffline());
91
92 m_pPortForwardingButton->setEnabled(m_pParent->isMachineInValidMode() &&
93 attachmentType() == KNetworkAttachmentType_NAT);
94
95 /* Postprocessing: */
96 if ((m_pParent->isMachineSaved() || m_pParent->isMachineOnline()) && !m_pAdvancedArrow->isExpanded())
97 m_pAdvancedArrow->animateClick();
98 sltToggleAdvanced();
99}
100
101void UIMachineSettingsNetwork::fetchAdapterCache(const UICacheSettingsMachineNetworkAdapter &adapterCache)
102{
103 /* Get adapter data: */
104 const UIDataSettingsMachineNetworkAdapter &adapterData = adapterCache.base();
105
106 /* Load slot number: */
107 m_iSlot = adapterData.m_iSlot;
108
109 /* Load adapter activity state: */
110 mCbEnableAdapter->setChecked(adapterData.m_fAdapterEnabled);
111
112 /* Load attachment type: */
113 int iAttachmentPos = m_pAttachmentTypeCombo->findData(adapterData.m_attachmentType);
114 m_pAttachmentTypeCombo->setCurrentIndex(iAttachmentPos == -1 ? 0 : iAttachmentPos);
115
116 /* Load alternative name: */
117 m_strBrgName = adapterData.m_strBridgedAdapterName;
118 if (m_strBrgName.isEmpty())
119 m_strBrgName = QString();
120
121 m_strIntName = adapterData.m_strInternalNetworkName;
122 if (m_strIntName.isEmpty())
123 m_strIntName = QString();
124
125 m_strHoiName = adapterData.m_strHostInterfaceName;
126 if (m_strHoiName.isEmpty())
127 m_strHoiName = QString();
128
129 m_strGenericDriver = adapterData.m_strGenericDriver;
130 if (m_strGenericDriver.isEmpty())
131 m_strGenericDriver = QString();
132
133 sltUpdateAttachmentAlternative();
134
135 /* Load adapter type: */
136 int iAdapterPos = m_pAdapterTypeCombo->findData(adapterData.m_adapterType);
137 m_pAdapterTypeCombo->setCurrentIndex(iAdapterPos == -1 ? 0 : iAdapterPos);
138
139 /* Load promiscuous mode type: */
140 int iPromiscuousModePos = m_pPromiscuousModeCombo->findData(adapterData.m_promiscuousMode);
141 m_pPromiscuousModeCombo->setCurrentIndex(iPromiscuousModePos == -1 ? 0 : iPromiscuousModePos);
142
143 /* Other options: */
144 m_pMACEditor->setText(adapterData.m_strMACAddress);
145 m_pGenericPropertiesTextEdit->setText(adapterData.m_strGenericProperties);
146 m_pCableConnectedCheckBox->setChecked(adapterData.m_fCableConnected);
147
148 /* Load port forwarding rules: */
149 m_portForwardingRules = adapterData.m_redirects;
150}
151
152void UIMachineSettingsNetwork::uploadAdapterCache(UICacheSettingsMachineNetworkAdapter &adapterCache)
153{
154 /* Prepare adapter data: */
155 UIDataSettingsMachineNetworkAdapter adapterData = adapterCache.base();
156
157 /* Save adapter activity state: */
158 adapterData.m_fAdapterEnabled = mCbEnableAdapter->isChecked();
159
160 /* Save attachment type & alternative name: */
161 adapterData.m_attachmentType = attachmentType();
162 switch (adapterData.m_attachmentType)
163 {
164 case KNetworkAttachmentType_Null:
165 break;
166 case KNetworkAttachmentType_NAT:
167 break;
168 case KNetworkAttachmentType_Bridged:
169 adapterData.m_strBridgedAdapterName = alternativeName();
170 break;
171 case KNetworkAttachmentType_Internal:
172 adapterData.m_strInternalNetworkName = alternativeName();
173 break;
174 case KNetworkAttachmentType_HostOnly:
175 adapterData.m_strHostInterfaceName = alternativeName();
176 break;
177 case KNetworkAttachmentType_Generic:
178 adapterData.m_strGenericDriver = alternativeName();
179 adapterData.m_strGenericProperties = m_pGenericPropertiesTextEdit->toPlainText();
180 break;
181 default:
182 break;
183 }
184
185 /* Save adapter type: */
186 adapterData.m_adapterType = (KNetworkAdapterType)m_pAdapterTypeCombo->itemData(m_pAdapterTypeCombo->currentIndex()).toInt();
187
188 /* Save promiscuous mode type: */
189 adapterData.m_promiscuousMode = (KNetworkAdapterPromiscModePolicy)m_pPromiscuousModeCombo->itemData(m_pPromiscuousModeCombo->currentIndex()).toInt();
190
191 /* Other options: */
192 adapterData.m_strMACAddress = m_pMACEditor->text().isEmpty() ? QString() : m_pMACEditor->text();
193 adapterData.m_fCableConnected = m_pCableConnectedCheckBox->isChecked();
194
195 /* Save port forwarding rules: */
196 adapterData.m_redirects = m_portForwardingRules;
197
198 /* Cache adapter data: */
199 adapterCache.cacheCurrentData(adapterData);
200}
201
202void UIMachineSettingsNetwork::setValidator(QIWidgetValidator *pValidator)
203{
204 m_pValidator = pValidator;
205
206 connect(mCbEnableAdapter, SIGNAL(toggled(bool)), m_pValidator, SLOT(revalidate()));
207 connect(m_pAttachmentTypeCombo, SIGNAL(activated(const QString&)), this, SLOT(sltUpdateAttachmentAlternative()));
208 connect(m_pAdapterNameCombo, SIGNAL(activated(const QString&)), this, SLOT(sltUpdateAlternativeName()));
209 connect(m_pAdapterNameCombo, SIGNAL(editTextChanged(const QString&)), this, SLOT(sltUpdateAlternativeName()));
210
211 m_pValidator->revalidate();
212}
213
214bool UIMachineSettingsNetwork::revalidate(QString &strWarning, QString &strTitle)
215{
216 /* 'True' for disabled adapter: */
217 if (!mCbEnableAdapter->isChecked())
218 return true;
219
220 /* Validate alternatives: */
221 bool fValid = true;
222 switch (attachmentType())
223 {
224 case KNetworkAttachmentType_Bridged:
225 if (alternativeName().isNull())
226 {
227 strWarning = tr("no bridged network adapter is selected");
228 fValid = false;
229 }
230 break;
231 case KNetworkAttachmentType_Internal:
232 if (alternativeName().isNull())
233 {
234 strWarning = tr("no internal network name is specified");
235 fValid = false;
236 }
237 break;
238 case KNetworkAttachmentType_HostOnly:
239 if (alternativeName().isNull())
240 {
241 strWarning = tr("no host-only network adapter is selected");
242 fValid = false;
243 }
244 break;
245 default:
246 break;
247 }
248 if (!fValid)
249 strTitle += ": " + vboxGlobal().removeAccelMark(pageTitle());
250
251 return fValid;
252}
253
254QWidget* UIMachineSettingsNetwork::setOrderAfter(QWidget *pAfter)
255{
256 setTabOrder(pAfter, mCbEnableAdapter);
257 setTabOrder(mCbEnableAdapter, m_pAttachmentTypeCombo);
258 setTabOrder(m_pAttachmentTypeCombo, m_pAdapterNameCombo);
259 setTabOrder(m_pAdapterNameCombo, m_pAdvancedArrow);
260 setTabOrder(m_pAdvancedArrow, m_pAdapterTypeCombo);
261 setTabOrder(m_pAdapterTypeCombo, m_pPromiscuousModeCombo);
262 setTabOrder(m_pPromiscuousModeCombo, m_pMACEditor);
263 setTabOrder(m_pMACEditor, m_pMACButton);
264 setTabOrder(m_pMACButton, m_pCableConnectedCheckBox);
265 setTabOrder(m_pCableConnectedCheckBox, m_pPortForwardingButton);
266 return m_pPortForwardingButton;
267}
268
269QString UIMachineSettingsNetwork::pageTitle() const
270{
271 return VBoxGlobal::tr("Adapter %1", "network").arg(QString("&%1").arg(m_iSlot + 1));;
272}
273
274KNetworkAttachmentType UIMachineSettingsNetwork::attachmentType() const
275{
276 return (KNetworkAttachmentType)m_pAttachmentTypeCombo->itemData(m_pAttachmentTypeCombo->currentIndex()).toInt();
277}
278
279QString UIMachineSettingsNetwork::alternativeName(int type) const
280{
281 if (type == -1)
282 type = attachmentType();
283 QString strResult;
284 switch (type)
285 {
286 case KNetworkAttachmentType_Bridged:
287 strResult = m_strBrgName;
288 break;
289 case KNetworkAttachmentType_Internal:
290 strResult = m_strIntName;
291 break;
292 case KNetworkAttachmentType_HostOnly:
293 strResult = m_strHoiName;
294 break;
295 case KNetworkAttachmentType_Generic:
296 strResult = m_strGenericDriver;
297 break;
298 default:
299 break;
300 }
301 Assert(strResult.isNull() || !strResult.isEmpty());
302 return strResult;
303}
304
305void UIMachineSettingsNetwork::showEvent(QShowEvent *pEvent)
306{
307 /* Polish page if necessary: */
308 if (!m_fPolished)
309 {
310 m_fPolished = true;
311 /* Give the minimum size hint to the first layout column: */
312 m_pNetworkChildGridLayout->setColumnMinimumWidth (0, m_pAttachmentTypeLabel->width());
313 }
314 /* Call for base-class: */
315 QWidget::showEvent(pEvent);
316}
317
318void UIMachineSettingsNetwork::retranslateUi()
319{
320 /* Translate uic generated strings: */
321 Ui::UIMachineSettingsNetwork::retranslateUi(this);
322
323 /* Translate combo-boxes content: */
324 populateComboboxes();
325
326 /* Translate attachment info: */
327 sltUpdateAttachmentAlternative();
328}
329
330void UIMachineSettingsNetwork::sltUpdateAttachmentAlternative()
331{
332 /* Blocking signals to change content manually: */
333 m_pAdapterNameCombo->blockSignals(true);
334
335 /* Update alternative-name combo-box availability: */
336 m_pAdapterNameLabel->setEnabled(attachmentType() != KNetworkAttachmentType_Null &&
337 attachmentType() != KNetworkAttachmentType_NAT);
338 m_pAdapterNameCombo->setEnabled(attachmentType() != KNetworkAttachmentType_Null &&
339 attachmentType() != KNetworkAttachmentType_NAT);
340 m_pPromiscuousModeLabel->setEnabled(attachmentType() != KNetworkAttachmentType_Null &&
341 attachmentType() != KNetworkAttachmentType_Generic &&
342 attachmentType() != KNetworkAttachmentType_NAT);
343 m_pPromiscuousModeCombo->setEnabled(attachmentType() != KNetworkAttachmentType_Null &&
344 attachmentType() != KNetworkAttachmentType_Generic &&
345 attachmentType() != KNetworkAttachmentType_NAT);
346
347 /* Refresh list: */
348 m_pAdapterNameCombo->clear();
349 switch (attachmentType())
350 {
351 case KNetworkAttachmentType_Bridged:
352 m_pAdapterNameCombo->insertItems(0, m_pParent->brgList());
353 m_pAdapterNameCombo->setEditable(false);
354 break;
355 case KNetworkAttachmentType_Internal:
356 m_pAdapterNameCombo->insertItems(0, m_pParent->fullIntList());
357 m_pAdapterNameCombo->setEditable(true);
358 m_pAdapterNameCombo->setCompleter(0);
359 break;
360 case KNetworkAttachmentType_HostOnly:
361 m_pAdapterNameCombo->insertItems(0, m_pParent->hoiList());
362 m_pAdapterNameCombo->setEditable(false);
363 break;
364 case KNetworkAttachmentType_Generic:
365 m_pAdapterNameCombo->insertItem(0, alternativeName());
366 m_pAdapterNameCombo->setEditable(true);
367 m_pAdapterNameCombo->setCompleter(0);
368 break;
369 default:
370 break;
371 }
372
373 /* Prepend 'empty' or 'default' item: */
374 if (m_pAdapterNameCombo->count() == 0)
375 {
376 switch (attachmentType())
377 {
378 case KNetworkAttachmentType_Bridged:
379 case KNetworkAttachmentType_HostOnly:
380 {
381 /* Adapters list 'empty': */
382 int pos = m_pAdapterNameCombo->findData(emptyItemCode);
383 if (pos == -1)
384 m_pAdapterNameCombo->insertItem(0, tr("Not selected", "network adapter name"), emptyItemCode);
385 else
386 m_pAdapterNameCombo->setItemText(pos, tr("Not selected", "network adapter name"));
387 break;
388 }
389 case KNetworkAttachmentType_Internal:
390 {
391 /* Internal network 'default' name: */
392 if (m_pAdapterNameCombo->findText("intnet") == -1)
393 m_pAdapterNameCombo->insertItem(0, "intnet");
394 break;
395 }
396 default:
397 break;
398 }
399 }
400
401 /* Select previous or default item: */
402 switch (attachmentType())
403 {
404 case KNetworkAttachmentType_Bridged:
405 case KNetworkAttachmentType_HostOnly:
406 {
407 int pos = m_pAdapterNameCombo->findText(alternativeName());
408 m_pAdapterNameCombo->setCurrentIndex(pos == -1 ? 0 : pos);
409 break;
410 }
411 case KNetworkAttachmentType_Internal:
412 {
413 int pos = m_pAdapterNameCombo->findText(alternativeName());
414 m_pAdapterNameCombo->setCurrentIndex(pos == -1 ? 0 : pos);
415 break;
416 }
417 default:
418 break;
419 }
420
421 /* Remember selected item: */
422 sltUpdateAlternativeName();
423
424 /* Update visibility of "generic" properties editor: */
425 m_pGenericPropertiesLabel->setVisible(attachmentType() == KNetworkAttachmentType_Generic &&
426 m_pAdvancedArrow->isExpanded());
427 m_pGenericPropertiesTextEdit->setVisible(attachmentType() == KNetworkAttachmentType_Generic &&
428 m_pAdvancedArrow->isExpanded());
429
430 /* Update Forwarding rules button availability: */
431 m_pPortForwardingButton->setEnabled(attachmentType() == KNetworkAttachmentType_NAT);
432
433 /* Unblocking signals as content is changed already: */
434 m_pAdapterNameCombo->blockSignals(false);
435}
436
437void UIMachineSettingsNetwork::sltUpdateAlternativeName()
438{
439 switch (attachmentType())
440 {
441 case KNetworkAttachmentType_Bridged:
442 {
443 QString newName(m_pAdapterNameCombo->itemData(m_pAdapterNameCombo->currentIndex()).toString() ==
444 QString(emptyItemCode) ||
445 m_pAdapterNameCombo->currentText().isEmpty() ?
446 QString::null : m_pAdapterNameCombo->currentText());
447 if (m_strBrgName != newName)
448 m_strBrgName = newName;
449 break;
450 }
451 case KNetworkAttachmentType_Internal:
452 {
453 QString newName((m_pAdapterNameCombo->itemData(m_pAdapterNameCombo->currentIndex()).toString() ==
454 QString(emptyItemCode) &&
455 m_pAdapterNameCombo->currentText() ==
456 m_pAdapterNameCombo->itemText(m_pAdapterNameCombo->currentIndex())) ||
457 m_pAdapterNameCombo->currentText().isEmpty() ?
458 QString::null : m_pAdapterNameCombo->currentText());
459 if (m_strIntName != newName)
460 {
461 m_strIntName = newName;
462 if (!m_strIntName.isNull())
463 QTimer::singleShot(0, m_pParent, SLOT (updatePages()));
464 }
465 break;
466 }
467 case KNetworkAttachmentType_HostOnly:
468 {
469 QString newName(m_pAdapterNameCombo->itemData(m_pAdapterNameCombo->currentIndex()).toString() ==
470 QString(emptyItemCode) ||
471 m_pAdapterNameCombo->currentText().isEmpty() ?
472 QString::null : m_pAdapterNameCombo->currentText());
473 if (m_strHoiName != newName)
474 m_strHoiName = newName;
475 break;
476 }
477 case KNetworkAttachmentType_Generic:
478 {
479 QString newName((m_pAdapterNameCombo->itemData(m_pAdapterNameCombo->currentIndex()).toString() ==
480 QString(emptyItemCode) &&
481 m_pAdapterNameCombo->currentText() ==
482 m_pAdapterNameCombo->itemText(m_pAdapterNameCombo->currentIndex())) ||
483 m_pAdapterNameCombo->currentText().isEmpty() ?
484 QString::null : m_pAdapterNameCombo->currentText());
485 if (m_strGenericDriver != newName)
486 m_strGenericDriver = newName;
487 break;
488 }
489 default:
490 break;
491 }
492
493 if (m_pValidator)
494 m_pValidator->revalidate();
495}
496
497void UIMachineSettingsNetwork::sltToggleAdvanced()
498{
499 m_pAdapterTypeLabel->setVisible(m_pAdvancedArrow->isExpanded());
500 m_pAdapterTypeCombo->setVisible(m_pAdvancedArrow->isExpanded());
501 m_pPromiscuousModeLabel->setVisible(m_pAdvancedArrow->isExpanded());
502 m_pPromiscuousModeCombo->setVisible(m_pAdvancedArrow->isExpanded());
503 m_pGenericPropertiesLabel->setVisible(attachmentType() == KNetworkAttachmentType_Generic &&
504 m_pAdvancedArrow->isExpanded());
505 m_pGenericPropertiesTextEdit->setVisible(attachmentType() == KNetworkAttachmentType_Generic &&
506 m_pAdvancedArrow->isExpanded());
507 m_pMACLabel->setVisible(m_pAdvancedArrow->isExpanded());
508 m_pMACEditor->setVisible(m_pAdvancedArrow->isExpanded());
509 m_pMACButton->setVisible(m_pAdvancedArrow->isExpanded());
510 m_pCableConnectedCheckBox->setVisible(m_pAdvancedArrow->isExpanded());
511 m_pPortForwardingButton->setVisible(m_pAdvancedArrow->isExpanded());
512}
513
514void UIMachineSettingsNetwork::sltGenerateMac()
515{
516 m_pMACEditor->setText(vboxGlobal().virtualBox().GetHost().GenerateMACAddress());
517}
518
519void UIMachineSettingsNetwork::sltOpenPortForwardingDlg()
520{
521 UIMachineSettingsPortForwardingDlg dlg(this, m_portForwardingRules);
522 if (dlg.exec() == QDialog::Accepted)
523 m_portForwardingRules = dlg.rules();
524}
525
526void UIMachineSettingsNetwork::populateComboboxes()
527{
528 /* Attachment type: */
529 {
530 /* Remember the currently selected attachment type: */
531 int iCurrentAttachment = m_pAttachmentTypeCombo->currentIndex();
532
533 /* Clear the attachments combo-box: */
534 m_pAttachmentTypeCombo->clear();
535
536 /* Populate attachments: */
537 int iAttachmentTypeIndex = 0;
538 m_pAttachmentTypeCombo->insertItem(iAttachmentTypeIndex, vboxGlobal().toString(KNetworkAttachmentType_Null));
539 m_pAttachmentTypeCombo->setItemData(iAttachmentTypeIndex, KNetworkAttachmentType_Null);
540 m_pAttachmentTypeCombo->setItemData(iAttachmentTypeIndex, m_pAttachmentTypeCombo->itemText(iAttachmentTypeIndex), Qt::ToolTipRole);
541 ++iAttachmentTypeIndex;
542 m_pAttachmentTypeCombo->insertItem(iAttachmentTypeIndex, vboxGlobal().toString(KNetworkAttachmentType_NAT));
543 m_pAttachmentTypeCombo->setItemData(iAttachmentTypeIndex, KNetworkAttachmentType_NAT);
544 m_pAttachmentTypeCombo->setItemData(iAttachmentTypeIndex, m_pAttachmentTypeCombo->itemText(iAttachmentTypeIndex), Qt::ToolTipRole);
545 ++iAttachmentTypeIndex;
546 m_pAttachmentTypeCombo->insertItem(iAttachmentTypeIndex, vboxGlobal().toString(KNetworkAttachmentType_Bridged));
547 m_pAttachmentTypeCombo->setItemData(iAttachmentTypeIndex, KNetworkAttachmentType_Bridged);
548 m_pAttachmentTypeCombo->setItemData(iAttachmentTypeIndex, m_pAttachmentTypeCombo->itemText(iAttachmentTypeIndex), Qt::ToolTipRole);
549 ++iAttachmentTypeIndex;
550 m_pAttachmentTypeCombo->insertItem(iAttachmentTypeIndex, vboxGlobal().toString(KNetworkAttachmentType_Internal));
551 m_pAttachmentTypeCombo->setItemData(iAttachmentTypeIndex, KNetworkAttachmentType_Internal);
552 m_pAttachmentTypeCombo->setItemData(iAttachmentTypeIndex, m_pAttachmentTypeCombo->itemText(iAttachmentTypeIndex), Qt::ToolTipRole);
553 ++iAttachmentTypeIndex;
554 m_pAttachmentTypeCombo->insertItem(iAttachmentTypeIndex, vboxGlobal().toString(KNetworkAttachmentType_HostOnly));
555 m_pAttachmentTypeCombo->setItemData(iAttachmentTypeIndex, KNetworkAttachmentType_HostOnly);
556 m_pAttachmentTypeCombo->setItemData(iAttachmentTypeIndex, m_pAttachmentTypeCombo->itemText(iAttachmentTypeIndex), Qt::ToolTipRole);
557 ++iAttachmentTypeIndex;
558 m_pAttachmentTypeCombo->insertItem(iAttachmentTypeIndex, vboxGlobal().toString(KNetworkAttachmentType_Generic));
559 m_pAttachmentTypeCombo->setItemData(iAttachmentTypeIndex, KNetworkAttachmentType_Generic);
560 m_pAttachmentTypeCombo->setItemData(iAttachmentTypeIndex, m_pAttachmentTypeCombo->itemText(iAttachmentTypeIndex), Qt::ToolTipRole);
561 ++iAttachmentTypeIndex;
562
563 /* Restore the previously selected attachment type: */
564 m_pAttachmentTypeCombo->setCurrentIndex(iCurrentAttachment);
565 }
566
567 /* Adapter type: */
568 {
569 /* Remember the currently selected adapter type: */
570 int iCurrentAdapter = m_pAdapterTypeCombo->currentIndex();
571
572 /* Clear the adapter type combo-box: */
573 m_pAdapterTypeCombo->clear();
574
575 /* Populate adapter types: */
576 int iAdapterTypeIndex = 0;
577 m_pAdapterTypeCombo->insertItem(iAdapterTypeIndex, vboxGlobal().toString(KNetworkAdapterType_Am79C970A));
578 m_pAdapterTypeCombo->setItemData(iAdapterTypeIndex, KNetworkAdapterType_Am79C970A);
579 m_pAdapterTypeCombo->setItemData(iAdapterTypeIndex, m_pAdapterTypeCombo->itemText(iAdapterTypeIndex), Qt::ToolTipRole);
580 ++iAdapterTypeIndex;
581 m_pAdapterTypeCombo->insertItem(iAdapterTypeIndex, vboxGlobal().toString(KNetworkAdapterType_Am79C973));
582 m_pAdapterTypeCombo->setItemData(iAdapterTypeIndex, KNetworkAdapterType_Am79C973);
583 m_pAdapterTypeCombo->setItemData(iAdapterTypeIndex, m_pAdapterTypeCombo->itemText(iAdapterTypeIndex), Qt::ToolTipRole);
584 ++iAdapterTypeIndex;
585#ifdef VBOX_WITH_E1000
586 m_pAdapterTypeCombo->insertItem(iAdapterTypeIndex, vboxGlobal().toString(KNetworkAdapterType_I82540EM));
587 m_pAdapterTypeCombo->setItemData(iAdapterTypeIndex, KNetworkAdapterType_I82540EM);
588 m_pAdapterTypeCombo->setItemData(iAdapterTypeIndex, m_pAdapterTypeCombo->itemText(iAdapterTypeIndex), Qt::ToolTipRole);
589 ++iAdapterTypeIndex;
590 m_pAdapterTypeCombo->insertItem(iAdapterTypeIndex, vboxGlobal().toString(KNetworkAdapterType_I82543GC));
591 m_pAdapterTypeCombo->setItemData(iAdapterTypeIndex, KNetworkAdapterType_I82543GC);
592 m_pAdapterTypeCombo->setItemData(iAdapterTypeIndex, m_pAdapterTypeCombo->itemText(iAdapterTypeIndex), Qt::ToolTipRole);
593 ++iAdapterTypeIndex;
594 m_pAdapterTypeCombo->insertItem(iAdapterTypeIndex, vboxGlobal().toString(KNetworkAdapterType_I82545EM));
595 m_pAdapterTypeCombo->setItemData(iAdapterTypeIndex, KNetworkAdapterType_I82545EM);
596 m_pAdapterTypeCombo->setItemData(iAdapterTypeIndex, m_pAdapterTypeCombo->itemText(iAdapterTypeIndex), Qt::ToolTipRole);
597 ++iAdapterTypeIndex;
598#endif /* VBOX_WITH_E1000 */
599#ifdef VBOX_WITH_VIRTIO
600 m_pAdapterTypeCombo->insertItem(iAdapterTypeIndex, vboxGlobal().toString(KNetworkAdapterType_Virtio));
601 m_pAdapterTypeCombo->setItemData(iAdapterTypeIndex, KNetworkAdapterType_Virtio);
602 m_pAdapterTypeCombo->setItemData(iAdapterTypeIndex, m_pAdapterTypeCombo->itemText(iAdapterTypeIndex), Qt::ToolTipRole);
603 ++iAdapterTypeIndex;
604#endif /* VBOX_WITH_VIRTIO */
605
606 /* Restore the previously selected adapter type: */
607 m_pAdapterTypeCombo->setCurrentIndex(iCurrentAdapter == -1 ? 0 : iCurrentAdapter);
608 }
609
610 /* Promiscuous Mode type: */
611 {
612 /* Remember the currently selected promiscuous mode type: */
613 int iCurrentPromiscuousMode = m_pPromiscuousModeCombo->currentIndex();
614
615 /* Clear the promiscuous mode combo-box: */
616 m_pPromiscuousModeCombo->clear();
617
618 /* Populate promiscuous modes: */
619 int iPromiscuousModeIndex = 0;
620 m_pPromiscuousModeCombo->insertItem(iPromiscuousModeIndex, vboxGlobal().toString(KNetworkAdapterPromiscModePolicy_Deny));
621 m_pPromiscuousModeCombo->setItemData(iPromiscuousModeIndex, KNetworkAdapterPromiscModePolicy_Deny);
622 m_pPromiscuousModeCombo->setItemData(iPromiscuousModeIndex, m_pPromiscuousModeCombo->itemText(iPromiscuousModeIndex), Qt::ToolTipRole);
623 ++iPromiscuousModeIndex;
624 m_pPromiscuousModeCombo->insertItem(iPromiscuousModeIndex, vboxGlobal().toString(KNetworkAdapterPromiscModePolicy_AllowNetwork));
625 m_pPromiscuousModeCombo->setItemData(iPromiscuousModeIndex, KNetworkAdapterPromiscModePolicy_AllowNetwork);
626 m_pPromiscuousModeCombo->setItemData(iPromiscuousModeIndex, m_pPromiscuousModeCombo->itemText(iPromiscuousModeIndex), Qt::ToolTipRole);
627 ++iPromiscuousModeIndex;
628 m_pPromiscuousModeCombo->insertItem(iPromiscuousModeIndex, vboxGlobal().toString(KNetworkAdapterPromiscModePolicy_AllowAll));
629 m_pPromiscuousModeCombo->setItemData(iPromiscuousModeIndex, KNetworkAdapterPromiscModePolicy_AllowAll);
630 m_pPromiscuousModeCombo->setItemData(iPromiscuousModeIndex, m_pPromiscuousModeCombo->itemText(iPromiscuousModeIndex), Qt::ToolTipRole);
631 ++iPromiscuousModeIndex;
632
633 /* Restore the previously selected promiscuous mode type: */
634 m_pPromiscuousModeCombo->setCurrentIndex(iCurrentPromiscuousMode);
635 }
636}
637
638/* UIMachineSettingsNetworkPage Stuff */
639UIMachineSettingsNetworkPage::UIMachineSettingsNetworkPage()
640 : m_pValidator(0)
641 , m_pTwAdapters(0)
642{
643 /* Setup main layout: */
644 QVBoxLayout *pMainLayout = new QVBoxLayout(this);
645 pMainLayout->setContentsMargins(0, 5, 0, 5);
646
647 /* Creating tab-widget: */
648 m_pTwAdapters = new QITabWidget(this);
649 pMainLayout->addWidget(m_pTwAdapters);
650
651 /* How many adapters to display: */
652 ulong uCount = qMin((ULONG)4, vboxGlobal().virtualBox().GetSystemProperties().GetMaxNetworkAdapters(KChipsetType_PIIX3));
653 /* Add corresponding tab pages to parent tab widget: */
654 for (ulong uSlot = 0; uSlot < uCount; ++uSlot)
655 {
656 /* Creating adapter page: */
657 UIMachineSettingsNetwork *pPage = new UIMachineSettingsNetwork(this);
658 m_pTwAdapters->addTab(pPage, pPage->pageTitle());
659 }
660}
661
662QStringList UIMachineSettingsNetworkPage::brgList(bool fRefresh)
663{
664 if (fRefresh)
665 {
666 /* Load & filter interface list: */
667 m_brgList.clear();
668 CHostNetworkInterfaceVector interfaces = vboxGlobal().virtualBox().GetHost().GetNetworkInterfaces();
669 for (CHostNetworkInterfaceVector::ConstIterator it = interfaces.begin();
670 it != interfaces.end(); ++it)
671 {
672 if (it->GetInterfaceType() == KHostNetworkInterfaceType_Bridged)
673 m_brgList << it->GetName();
674 }
675 }
676
677 return m_brgList;
678}
679
680QStringList UIMachineSettingsNetworkPage::intList(bool fRefresh)
681{
682 if (fRefresh)
683 {
684 /* Load total network list of all VMs: */
685 m_intList.clear();
686 CVirtualBox vbox = vboxGlobal().virtualBox();
687 ulong count = qMin ((ULONG) 4, vbox.GetSystemProperties().GetMaxNetworkAdapters(KChipsetType_PIIX3));
688 CMachineVector vec = vbox.GetMachines();
689 for (CMachineVector::ConstIterator m = vec.begin(); m != vec.end(); ++m)
690 {
691 if (m->GetAccessible())
692 {
693 for (ulong slot = 0; slot < count; ++slot)
694 {
695 QString strName = m->GetNetworkAdapter(slot).GetInternalNetwork();
696 if (!strName.isEmpty() && !m_intList.contains(strName))
697 m_intList << strName;
698 }
699 }
700 }
701 }
702
703 return m_intList;
704}
705
706QStringList UIMachineSettingsNetworkPage::fullIntList(bool fRefresh)
707{
708 QStringList list(intList(fRefresh));
709 /* Append network list with names from all the pages: */
710 for (int index = 0; index < m_pTwAdapters->count(); ++index)
711 {
712 UIMachineSettingsNetwork *pPage =
713 qobject_cast <UIMachineSettingsNetwork*>(m_pTwAdapters->widget(index));
714 if (pPage)
715 {
716 QString strName = pPage->alternativeName(KNetworkAttachmentType_Internal);
717 if (!strName.isEmpty() && !list.contains(strName))
718 list << strName;
719 }
720 }
721 return list;
722}
723
724QStringList UIMachineSettingsNetworkPage::hoiList(bool fRefresh)
725{
726 if (fRefresh)
727 {
728 /* Load & filter interface list: */
729 m_hoiList.clear();
730 CHostNetworkInterfaceVector interfaces = vboxGlobal().virtualBox().GetHost().GetNetworkInterfaces();
731 for (CHostNetworkInterfaceVector::ConstIterator it = interfaces.begin();
732 it != interfaces.end(); ++it)
733 {
734 if (it->GetInterfaceType() == KHostNetworkInterfaceType_HostOnly)
735 m_hoiList << it->GetName();
736 }
737 }
738
739 return m_hoiList;
740}
741
742/* Load data to cashe from corresponding external object(s),
743 * this task COULD be performed in other than GUI thread: */
744void UIMachineSettingsNetworkPage::loadToCacheFrom(QVariant &data)
745{
746 /* Fetch data to machine: */
747 UISettingsPageMachine::fetchData(data);
748
749 /* Clear cache initially: */
750 m_cache.clear();
751
752 /* Cache names lists: */
753 brgList(true);
754 intList(true);
755 hoiList(true);
756
757 /* For each network adapter: */
758 for (int iSlot = 0; iSlot < m_pTwAdapters->count(); ++iSlot)
759 {
760 /* Prepare adapter data: */
761 UIDataSettingsMachineNetworkAdapter adapterData;
762
763 /* Check if adapter is valid: */
764 const CNetworkAdapter &adapter = m_machine.GetNetworkAdapter(iSlot);
765 if (!adapter.isNull())
766 {
767 /* Gather main options: */
768 adapterData.m_iSlot = iSlot;
769 adapterData.m_fAdapterEnabled = adapter.GetEnabled();
770 adapterData.m_attachmentType = adapter.GetAttachmentType();
771
772 adapterData.m_strBridgedAdapterName = adapter.GetBridgedInterface();
773 if (adapterData.m_strBridgedAdapterName.isEmpty())
774 adapterData.m_strBridgedAdapterName = QString();
775
776 adapterData.m_strInternalNetworkName = adapter.GetInternalNetwork();
777 if (adapterData.m_strInternalNetworkName.isEmpty())
778 adapterData.m_strInternalNetworkName = QString();
779
780 adapterData.m_strHostInterfaceName = adapter.GetHostOnlyInterface();
781 if (adapterData.m_strHostInterfaceName.isEmpty())
782 adapterData.m_strHostInterfaceName = QString();
783
784 adapterData.m_strGenericDriver = adapter.GetGenericDriver();
785 if (adapterData.m_strGenericDriver.isEmpty())
786 adapterData.m_strGenericDriver = QString();
787
788 /* Gather advanced options: */
789 adapterData.m_adapterType = adapter.GetAdapterType();
790 adapterData.m_promiscuousMode = adapter.GetPromiscModePolicy();
791 adapterData.m_strMACAddress = adapter.GetMACAddress();
792 adapterData.m_strGenericProperties = summarizeGenericProperties(adapter);
793 adapterData.m_fCableConnected = adapter.GetCableConnected();
794
795 /* Gather redirect options: */
796 QVector<QString> redirects = adapter.GetNatDriver().GetRedirects();
797 for (int i = 0; i < redirects.size(); ++i)
798 {
799 QStringList redirectData = redirects[i].split(',');
800 AssertMsg(redirectData.size() == 6, ("Redirect rule should be composed of 6 parts!\n"));
801 adapterData.m_redirects << UIPortForwardingData(redirectData[0],
802 (KNATProtocol)redirectData[1].toUInt(),
803 redirectData[2],
804 redirectData[3].toUInt(),
805 redirectData[4],
806 redirectData[5].toUInt());
807 }
808 }
809
810 /* Cache adapter data: */
811 m_cache.child(iSlot).cacheInitialData(adapterData);
812 }
813
814 /* Upload machine to data: */
815 UISettingsPageMachine::uploadData(data);
816}
817
818/* Load data to corresponding widgets from cache,
819 * this task SHOULD be performed in GUI thread only: */
820void UIMachineSettingsNetworkPage::getFromCache()
821{
822 /* Setup tab order: */
823 Assert(firstWidget());
824 setTabOrder(firstWidget(), m_pTwAdapters->focusProxy());
825 QWidget *pLastFocusWidget = m_pTwAdapters->focusProxy();
826
827 /* For each network adapter: */
828 for (int iSlot = 0; iSlot < m_pTwAdapters->count(); ++iSlot)
829 {
830 /* Get adapter page: */
831 UIMachineSettingsNetwork *pPage = qobject_cast<UIMachineSettingsNetwork*>(m_pTwAdapters->widget(iSlot));
832
833 /* Load adapter data to page: */
834 pPage->fetchAdapterCache(m_cache.child(iSlot));
835
836 /* Setup page validation: */
837 pPage->setValidator(m_pValidator);
838
839 /* Setup tab order: */
840 pLastFocusWidget = pPage->setOrderAfter(pLastFocusWidget);
841 }
842
843 /* Applying language settings: */
844 retranslateUi();
845
846 /* Polish page finally: */
847 polishPage();
848
849 /* Revalidate if possible: */
850 if (m_pValidator)
851 m_pValidator->revalidate();
852}
853
854/* Save data from corresponding widgets to cache,
855 * this task SHOULD be performed in GUI thread only: */
856void UIMachineSettingsNetworkPage::putToCache()
857{
858 /* For each network adapter: */
859 for (int iSlot = 0; iSlot < m_pTwAdapters->count(); ++iSlot)
860 {
861 /* Get adapter page: */
862 UIMachineSettingsNetwork *pPage = qobject_cast<UIMachineSettingsNetwork*>(m_pTwAdapters->widget(iSlot));
863
864 /* Gather & cache adapter data: */
865 pPage->uploadAdapterCache(m_cache.child(iSlot));
866 }
867}
868
869/* Save data from cache to corresponding external object(s),
870 * this task COULD be performed in other than GUI thread: */
871void UIMachineSettingsNetworkPage::saveFromCacheTo(QVariant &data)
872{
873 /* Fetch data to machine: */
874 UISettingsPageMachine::fetchData(data);
875
876 /* Check if network data was changed: */
877 if (m_cache.wasChanged())
878 {
879 /* For each network adapter: */
880 for (int iSlot = 0; iSlot < m_pTwAdapters->count(); ++iSlot)
881 {
882 /* Check if adapter data was changed: */
883 const UICacheSettingsMachineNetworkAdapter &adapterCache = m_cache.child(iSlot);
884 if (adapterCache.wasChanged())
885 {
886 /* Check if adapter still valid: */
887 CNetworkAdapter adapter = m_machine.GetNetworkAdapter(iSlot);
888 if (!adapter.isNull())
889 {
890 /* Get adapter data from cache: */
891 const UIDataSettingsMachineNetworkAdapter &adapterData = adapterCache.data();
892
893 /* Store adapter data: */
894 if (isMachineOffline())
895 {
896 /* Basic attributes: */
897 adapter.SetEnabled(adapterData.m_fAdapterEnabled);
898 adapter.SetAdapterType(adapterData.m_adapterType);
899 adapter.SetMACAddress(adapterData.m_strMACAddress);
900 }
901 if (isMachineInValidMode())
902 {
903 /* Attachment type: */
904 switch (adapterData.m_attachmentType)
905 {
906 case KNetworkAttachmentType_Bridged:
907 adapter.SetBridgedInterface(adapterData.m_strBridgedAdapterName);
908 break;
909 case KNetworkAttachmentType_Internal:
910 adapter.SetInternalNetwork(adapterData.m_strInternalNetworkName);
911 break;
912 case KNetworkAttachmentType_HostOnly:
913 adapter.SetHostOnlyInterface(adapterData.m_strHostInterfaceName);
914 break;
915 case KNetworkAttachmentType_Generic:
916 adapter.SetGenericDriver(adapterData.m_strGenericDriver);
917 updateGenericProperties(adapter, adapterData.m_strGenericProperties);
918 break;
919 default:
920 break;
921 }
922 adapter.SetAttachmentType(adapterData.m_attachmentType);
923 /* Advanced attributes: */
924 adapter.SetPromiscModePolicy(adapterData.m_promiscuousMode);
925 /* Cable connected flag: */
926 adapter.SetCableConnected(adapterData.m_fCableConnected);
927 /* Redirect options: */
928 QVector<QString> oldRedirects = adapter.GetNatDriver().GetRedirects();
929 for (int i = 0; i < oldRedirects.size(); ++i)
930 adapter.GetNatDriver().RemoveRedirect(oldRedirects[i].section(',', 0, 0));
931 UIPortForwardingDataList newRedirects = adapterData.m_redirects;
932 for (int i = 0; i < newRedirects.size(); ++i)
933 {
934 UIPortForwardingData newRedirect = newRedirects[i];
935 adapter.GetNatDriver().AddRedirect(newRedirect.name, newRedirect.protocol,
936 newRedirect.hostIp, newRedirect.hostPort.value(),
937 newRedirect.guestIp, newRedirect.guestPort.value());
938 }
939 }
940 }
941 }
942 }
943 }
944
945 /* Upload machine to data: */
946 UISettingsPageMachine::uploadData(data);
947}
948
949void UIMachineSettingsNetworkPage::setValidator(QIWidgetValidator *pValidator)
950{
951 m_pValidator = pValidator;
952}
953
954bool UIMachineSettingsNetworkPage::revalidate(QString &strWarning, QString &strTitle)
955{
956 bool fValid = true;
957
958 for (int i = 0; i < m_pTwAdapters->count(); ++i)
959 {
960 UIMachineSettingsNetwork *pPage = qobject_cast<UIMachineSettingsNetwork*>(m_pTwAdapters->widget(i));
961 Assert(pPage);
962 fValid = pPage->revalidate(strWarning, strTitle);
963 if (!fValid)
964 break;
965 }
966
967 return fValid;
968}
969
970void UIMachineSettingsNetworkPage::retranslateUi()
971{
972 for (int i = 0; i < m_pTwAdapters->count(); ++ i)
973 {
974 UIMachineSettingsNetwork *pPage = qobject_cast<UIMachineSettingsNetwork*>(m_pTwAdapters->widget(i));
975 Assert(pPage);
976 m_pTwAdapters->setTabText(i, pPage->pageTitle());
977 }
978}
979
980void UIMachineSettingsNetworkPage::updatePages()
981{
982 for (int i = 0; i < m_pTwAdapters->count(); ++ i)
983 {
984 /* Get the iterated page: */
985 UIMachineSettingsNetwork *pPage = qobject_cast<UIMachineSettingsNetwork*>(m_pTwAdapters->widget(i));
986 Assert(pPage);
987
988 /* Update the page if the attachment type is 'internal network' */
989 if (pPage->attachmentType() == KNetworkAttachmentType_Internal)
990 QTimer::singleShot(0, pPage, SLOT(sltUpdateAttachmentAlternative()));
991 }
992}
993
994void UIMachineSettingsNetworkPage::polishPage()
995{
996 /* Get the count of network adapter tabs: */
997 for (int iSlot = 0; iSlot < m_pTwAdapters->count(); ++iSlot)
998 {
999 m_pTwAdapters->setTabEnabled(iSlot,
1000 isMachineOffline() ||
1001 (isMachineInValidMode() && m_cache.child(iSlot).base().m_fAdapterEnabled));
1002 UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTwAdapters->widget(iSlot));
1003 pTab->polishTab();
1004 }
1005}
1006
1007/* static */
1008QString UIMachineSettingsNetworkPage::summarizeGenericProperties(const CNetworkAdapter &adapter)
1009{
1010 /* Prepare formatted string: */
1011 QVector<QString> names;
1012 QVector<QString> props;
1013 props = adapter.GetProperties(QString(), names);
1014 QString strResult;
1015 /* Load generic properties: */
1016 for (int i = 0; i < names.size(); ++i)
1017 {
1018 strResult += names[i] + "=" + props[i];
1019 if (i < names.size() - 1)
1020 strResult += "\n";
1021 }
1022 /* Return formatted string: */
1023 return strResult;
1024}
1025
1026/* static */
1027void UIMachineSettingsNetworkPage::updateGenericProperties(CNetworkAdapter &adapter, const QString &strPropText)
1028{
1029 /* Parse new properties: */
1030 QStringList newProps = strPropText.split("\n");
1031 QHash<QString, QString> hash;
1032
1033 /* Save new properties: */
1034 for (int i = 0; i < newProps.size(); ++i)
1035 {
1036 QString strLine = newProps[i];
1037 int iSplitPos = strLine.indexOf("=");
1038 if (iSplitPos)
1039 {
1040 QString strKey = strLine.left(iSplitPos);
1041 QString strVal = strLine.mid(iSplitPos+1);
1042 adapter.SetProperty(strKey, strVal);
1043 hash[strKey] = strVal;
1044 }
1045 }
1046
1047 /* Removing deleted properties: */
1048 QVector<QString> names;
1049 QVector<QString> props;
1050 props = adapter.GetProperties(QString(), names);
1051 for (int i = 0; i < names.size(); ++i)
1052 {
1053 QString strName = names[i];
1054 QString strValue = props[i];
1055 if (strValue != hash[strName])
1056 adapter.SetProperty(strName, hash[strName]);
1057 }
1058}
1059
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