VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/widgets/UINameAndSystemEditor.cpp@ 76553

Last change on this file since 76553 was 76553, checked in by vboxsync, 5 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 15.6 KB
Line 
1/* $Id: UINameAndSystemEditor.cpp 76553 2019-01-01 01:45:53Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UINameAndSystemEditor class implementation.
4 */
5
6/*
7 * Copyright (C) 2008-2019 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#ifdef VBOX_WITH_PRECOMPILED_HEADERS
19# include <precomp.h>
20#else /* !VBOX_WITH_PRECOMPILED_HEADERS */
21
22/* Qt includes: */
23# include <QComboBox>
24# include <QGridLayout>
25# include <QLabel>
26# include <QVBoxLayout>
27
28/* GUI includes: */
29# include "QILineEdit.h"
30# include "VBoxGlobal.h"
31# include "UIFilePathSelector.h"
32# include "UINameAndSystemEditor.h"
33
34/* COM includes: */
35# include "CSystemProperties.h"
36
37#endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
38
39
40/** Defines the VM OS type ID. */
41enum
42{
43 TypeID = Qt::UserRole + 1
44};
45
46
47UINameAndSystemEditor::UINameAndSystemEditor(QWidget *pParent, bool fChooseLocation /* = false */)
48 : QIWithRetranslateUI<QWidget>(pParent)
49 , m_fChooseLocation(fChooseLocation)
50 , m_fSupportsHWVirtEx(false)
51 , m_fSupportsLongMode(false)
52 , m_pLabelFamily(0)
53 , m_pLabelType(0)
54 , m_pIconType(0)
55 , m_pNameLabel(0)
56 , m_pPathLabel(0)
57 , m_pNameLineEdit(0)
58 , m_pPathSelector(0)
59 , m_pComboFamily(0)
60 , m_pComboType(0)
61{
62 /* Prepare: */
63 prepare();
64}
65
66QString UINameAndSystemEditor::name() const
67{
68 if (!m_pNameLineEdit)
69 return QString();
70 return m_pNameLineEdit->text();
71}
72
73QString UINameAndSystemEditor::path() const
74{
75 if (!m_pPathSelector)
76 return vboxGlobal().virtualBox().GetSystemProperties().GetDefaultMachineFolder();
77 return m_pPathSelector->path();
78}
79
80void UINameAndSystemEditor::setName(const QString &strName)
81{
82 if (!m_pNameLineEdit)
83 return;
84 m_pNameLineEdit->setText(strName);
85}
86
87void UINameAndSystemEditor::setTypeId(QString strTypeId, QString strFamilyId /* = QString() */)
88{
89 AssertMsgReturnVoid(!strTypeId.isNull(), ("Null guest OS type ID"));
90
91 /* Initialize indexes: */
92 int iTypeIndex = -1;
93 int iFamilyIndex = -1;
94
95 /* If family ID isn't empty: */
96 if (!strFamilyId.isEmpty())
97 {
98 /* Search for corresponding family ID index: */
99 iFamilyIndex = m_pComboFamily->findData(strFamilyId, TypeID);
100
101 /* If that family ID isn't present, we have to add it: */
102 if (iFamilyIndex == -1)
103 {
104 /* Append family ID to corresponding combo: */
105 m_pComboFamily->addItem(strFamilyId);
106 m_pComboFamily->setItemData(m_pComboFamily->count() - 1, strFamilyId, TypeID);
107 /* Append family ID to type cache: */
108 m_types[strFamilyId] = QList<UIGuestOSType>();
109
110 /* Search for corresponding family ID index finally: */
111 iFamilyIndex = m_pComboFamily->findData(strFamilyId, TypeID);
112 }
113 }
114 /* If family ID is empty: */
115 else
116 {
117 /* We'll try to find it by type ID: */
118 foreach (const QString &strKnownFamilyId, m_types.keys())
119 {
120 foreach (const UIGuestOSType &guiType, m_types.value(strKnownFamilyId))
121 {
122 if (guiType.typeId == strTypeId)
123 strFamilyId = strKnownFamilyId;
124 if (!strFamilyId.isNull())
125 break;
126 }
127 if (!strFamilyId.isNull())
128 break;
129 }
130
131 /* If we were unable to find it => use "Other": */
132 if (strFamilyId.isNull())
133 strFamilyId = "Other";
134
135 /* Search for corresponding family ID index finally: */
136 iFamilyIndex = m_pComboFamily->findData(strFamilyId, TypeID);
137 }
138
139 /* To that moment family ID index should be always found: */
140 AssertReturnVoid(iFamilyIndex != -1);
141 /* So we choose it: */
142 m_pComboFamily->setCurrentIndex(iFamilyIndex);
143 sltFamilyChanged(m_pComboFamily->currentIndex());
144
145 /* Search for corresponding type ID index: */
146 iTypeIndex = m_pComboType->findData(strTypeId, TypeID);
147
148 /* If that type ID isn't present, we have to add it: */
149 if (iTypeIndex == -1)
150 {
151 /* Append type ID to type cache: */
152 UIGuestOSType guiType;
153 guiType.typeId = strTypeId;
154 guiType.typeDescription = strTypeId;
155 guiType.is64bit = false;
156 m_types[strFamilyId] << guiType;
157
158 /* So we re-choose family again: */
159 m_pComboFamily->setCurrentIndex(iFamilyIndex);
160 sltFamilyChanged(m_pComboFamily->currentIndex());
161
162 /* Search for corresponding type ID index finally: */
163 iTypeIndex = m_pComboType->findData(strTypeId, TypeID);
164 }
165
166 /* To that moment type ID index should be always found: */
167 AssertReturnVoid(iTypeIndex != -1);
168 /* So we choose it: */
169 m_pComboType->setCurrentIndex(iTypeIndex);
170 sltTypeChanged(m_pComboType->currentIndex());
171}
172
173QString UINameAndSystemEditor::typeId() const
174{
175 return m_strTypeId;
176}
177
178QString UINameAndSystemEditor::familyId() const
179{
180 return m_strFamilyId;
181}
182
183CGuestOSType UINameAndSystemEditor::type() const
184{
185 return vboxGlobal().vmGuestOSType(typeId(), familyId());
186}
187
188void UINameAndSystemEditor::setType(const CGuestOSType &enmType)
189{
190 // WORKAROUND:
191 // We're getting here with a NULL enmType when creating new VMs.
192 // Very annoying, so just workarounded for now.
193 /** @todo find out the reason and way to fix that.. */
194 if (enmType.isNull())
195 return;
196
197 /* Pass to function above: */
198 setTypeId(enmType.GetId(), enmType.GetFamilyId());
199}
200
201void UINameAndSystemEditor::retranslateUi()
202{
203 m_pLabelFamily->setText(tr("&Type:"));
204 m_pLabelType->setText(tr("&Version:"));
205 m_pNameLabel->setText(tr("Name:"));
206 if (m_pPathLabel)
207 m_pPathLabel->setText(tr("Machine Folder:"));
208
209 m_pComboFamily->setWhatsThis(tr("Selects the operating system family that "
210 "you plan to install into this virtual machine."));
211 m_pComboType->setWhatsThis(tr("Selects the operating system type that "
212 "you plan to install into this virtual machine "
213 "(called a guest operating system)."));
214}
215
216void UINameAndSystemEditor::sltFamilyChanged(int iIndex)
217{
218 /* Lock the signals of m_pComboType to prevent it's reaction on clearing: */
219 m_pComboType->blockSignals(true);
220 m_pComboType->clear();
221
222 /* Acquire family ID: */
223 m_strFamilyId = m_pComboFamily->itemData(iIndex, TypeID).toString();
224
225 /* Populate combo-box with OS types related to currently selected family id: */
226 foreach (const UIGuestOSType &guiType, m_types.value(m_strFamilyId))
227 {
228 /* Skip 64bit OS types if hardware virtualization or long mode is not supported: */
229 if (guiType.is64bit && (!m_fSupportsHWVirtEx || !m_fSupportsLongMode))
230 continue;
231 const int iIndex = m_pComboType->count();
232 m_pComboType->insertItem(iIndex, guiType.typeDescription);
233 m_pComboType->setItemData(iIndex, guiType.typeId, TypeID);
234 }
235
236 /* Select the most recently chosen item: */
237 if (m_currentIds.contains(m_strFamilyId))
238 {
239 const QString strTypeId = m_currentIds.value(m_strFamilyId);
240 const int iTypeIndex = m_pComboType->findData(strTypeId, TypeID);
241 if (iTypeIndex != -1)
242 m_pComboType->setCurrentIndex(iTypeIndex);
243 }
244 /* Or select Windows 7 item for Windows family as default: */
245 else if (m_strFamilyId == "Windows")
246 {
247 QString strDefaultID = "Windows7";
248 if (ARCH_BITS == 64 && m_fSupportsHWVirtEx && m_fSupportsLongMode)
249 strDefaultID += "_64";
250 const int iIndexWin7 = m_pComboType->findData(strDefaultID, TypeID);
251 if (iIndexWin7 != -1)
252 m_pComboType->setCurrentIndex(iIndexWin7);
253 }
254 /* Or select Oracle Linux item for Linux family as default: */
255 else if (m_strFamilyId == "Linux")
256 {
257 QString strDefaultID = "Oracle";
258 if (ARCH_BITS == 64 && m_fSupportsHWVirtEx && m_fSupportsLongMode)
259 strDefaultID += "_64";
260 const int iIndexUbuntu = m_pComboType->findData(strDefaultID, TypeID);
261 if (iIndexUbuntu != -1)
262 m_pComboType->setCurrentIndex(iIndexUbuntu);
263 }
264 /* Else simply select the first one present: */
265 else
266 m_pComboType->setCurrentIndex(0);
267
268 /* Update all the stuff: */
269 sltTypeChanged(m_pComboType->currentIndex());
270
271 /* Unlock the signals of m_pComboType: */
272 m_pComboType->blockSignals(false);
273}
274
275void UINameAndSystemEditor::sltTypeChanged(int iIndex)
276{
277 /* Acquire type ID: */
278 m_strTypeId = m_pComboType->itemData(iIndex, TypeID).toString();
279
280 /* Update selected type pixmap: */
281 m_pIconType->setPixmap(vboxGlobal().vmGuestOSTypePixmapDefault(m_strTypeId));
282
283 /* Save the most recently used item: */
284 m_currentIds[m_strFamilyId] = m_strTypeId;
285
286 /* Notifies listeners about OS type change: */
287 emit sigOsTypeChanged();
288}
289
290void UINameAndSystemEditor::prepare()
291{
292 /* Prepare this: */
293 prepareThis();
294 /* Prepare widgets: */
295 prepareWidgets();
296 /* Prepare connections: */
297 prepareConnections();
298 /* Apply language settings: */
299 retranslateUi();
300}
301
302void UINameAndSystemEditor::prepareThis()
303{
304 /* Check if host supports (AMD-V or VT-x) and long mode: */
305 CHost host = vboxGlobal().host();
306 m_fSupportsHWVirtEx = host.GetProcessorFeature(KProcessorFeature_HWVirtEx);
307 m_fSupportsLongMode = host.GetProcessorFeature(KProcessorFeature_LongMode);
308}
309
310void UINameAndSystemEditor::prepareWidgets()
311{
312 /* Create main-layout: */
313 QGridLayout *pMainLayout = new QGridLayout(this);
314 if (pMainLayout)
315 {
316 pMainLayout->setContentsMargins(0, 0, 0, 0);
317
318 int iRow = 0;
319
320 /* Create name label: */
321 m_pNameLabel = new QLabel;
322 if (m_pNameLabel)
323 {
324 m_pNameLabel->setAlignment(Qt::AlignRight);
325 m_pNameLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
326
327 /* Add into layout: */
328 pMainLayout->addWidget(m_pNameLabel, iRow, 0, 1, 1);
329 }
330 /* Create name editor: */
331 m_pNameLineEdit = new QILineEdit;
332 if (m_pNameLineEdit)
333 {
334 /* Add into layout: */
335 pMainLayout->addWidget(m_pNameLineEdit, iRow, 1, 1, 2);
336 }
337
338 ++iRow;
339
340 if (m_fChooseLocation)
341 {
342 /* Create path label: */
343 m_pPathLabel = new QLabel;
344 if (m_pPathLabel)
345 {
346 m_pPathLabel->setAlignment(Qt::AlignRight);
347 m_pPathLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
348
349 /* Add into layout: */
350 pMainLayout->addWidget(m_pPathLabel, iRow, 0, 1, 1);
351 }
352 /* Create path selector: */
353 m_pPathSelector = new UIFilePathSelector;
354 if (m_pPathSelector)
355 {
356 QString strDefaultMachineFolder = vboxGlobal().virtualBox().GetSystemProperties().GetDefaultMachineFolder();
357 m_pPathSelector->setPath(strDefaultMachineFolder);
358 m_pPathSelector->setDefaultPath(strDefaultMachineFolder);
359
360 /* Add into layout: */
361 pMainLayout->addWidget(m_pPathSelector, iRow, 1, 1, 2);
362 }
363
364 ++iRow;
365 }
366
367 /* Create VM OS family label: */
368 m_pLabelFamily = new QLabel;
369 if (m_pLabelFamily)
370 {
371 m_pLabelFamily->setAlignment(Qt::AlignRight);
372 m_pLabelFamily->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
373
374 /* Add into layout: */
375 pMainLayout->addWidget(m_pLabelFamily, iRow, 0);
376 }
377
378 int iIconRow = iRow;
379
380 /* Create VM OS family combo: */
381 m_pComboFamily = new QComboBox;
382 if (m_pComboFamily)
383 {
384 m_pComboFamily->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
385 m_pLabelFamily->setBuddy(m_pComboFamily);
386
387 /* Add into layout: */
388 pMainLayout->addWidget(m_pComboFamily, iRow, 1);
389 }
390
391 ++iRow;
392
393 /* Create VM OS type label: */
394 m_pLabelType = new QLabel;
395 if (m_pLabelType)
396 {
397 m_pLabelType->setAlignment(Qt::AlignRight);
398 m_pLabelType->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
399
400 /* Add into layout: */
401 pMainLayout->addWidget(m_pLabelType, iRow, 0);
402 }
403 /* Create VM OS type combo: */
404 m_pComboType = new QComboBox;
405 if (m_pComboType)
406 {
407 m_pComboType->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
408 m_pLabelType->setBuddy(m_pComboType);
409
410 /* Add into layout: */
411 pMainLayout->addWidget(m_pComboType, iRow, 1);
412 }
413
414 ++iRow;
415
416 /* Create sub-layout: */
417 QVBoxLayout *pLayoutIcon = new QVBoxLayout;
418 if (pLayoutIcon)
419 {
420 /* Create VM OS type icon: */
421 m_pIconType = new QLabel;
422 if (m_pIconType)
423 {
424 m_pIconType->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
425
426 /* Add into layout: */
427 pLayoutIcon->addWidget(m_pIconType);
428 }
429
430 /* Add stretch to sub-layout: */
431 pLayoutIcon->addStretch();
432
433 /* Add into layout: */
434 pMainLayout->addLayout(pLayoutIcon, iIconRow, 2, 2, 1);
435 }
436 }
437
438 /* Initialize VM OS family combo
439 * after all widgets were created: */
440 prepareFamilyCombo();
441}
442
443void UINameAndSystemEditor::prepareFamilyCombo()
444{
445 /* Acquire family IDs: */
446 m_familyIDs = vboxGlobal().vmGuestOSFamilyIDs();
447
448 /* For each known family ID: */
449 for (int i = 0; i < m_familyIDs.size(); ++i)
450 {
451 const QString &strFamilyId = m_familyIDs.at(i);
452
453 /* Append VM OS family combo: */
454 m_pComboFamily->insertItem(i, vboxGlobal().vmGuestOSFamilyDescription(strFamilyId));
455 m_pComboFamily->setItemData(i, strFamilyId, TypeID);
456
457 /* Fill in the type cache: */
458 m_types[strFamilyId] = QList<UIGuestOSType>();
459 foreach (const CGuestOSType &comType, vboxGlobal().vmGuestOSTypeList(strFamilyId))
460 {
461 UIGuestOSType guiType;
462 guiType.typeId = comType.GetId();
463 guiType.typeDescription = comType.GetDescription();
464 guiType.is64bit = comType.GetIs64Bit();
465 m_types[strFamilyId] << guiType;
466 }
467 }
468
469 /* Choose the 1st item to be the current: */
470 m_pComboFamily->setCurrentIndex(0);
471 /* And update the linked widgets accordingly: */
472 sltFamilyChanged(m_pComboFamily->currentIndex());
473}
474
475void UINameAndSystemEditor::prepareConnections()
476{
477 /* Prepare connections: */
478 connect(m_pNameLineEdit, &QILineEdit::textChanged,
479 this, &UINameAndSystemEditor::sigNameChanged);
480 if (m_pPathSelector)
481 connect(m_pPathSelector, &UIFilePathSelector::pathChanged,
482 this, &UINameAndSystemEditor::sigPathChanged);
483 connect(m_pComboFamily, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
484 this, &UINameAndSystemEditor::sltFamilyChanged);
485 connect(m_pComboType, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
486 this, &UINameAndSystemEditor::sltTypeChanged);
487}
488
489void UINameAndSystemEditor::setNameFieldValidator(const QString &strValidator)
490{
491 if (!m_pNameLineEdit)
492 return;
493 m_pNameLineEdit->setValidator(new QRegExpValidator(QRegExp(strValidator), this));
494}
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use