VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/wizards/newvm/UIWizardNewVMNameOSTypePage.cpp@ 104158

Last change on this file since 104158 was 103957, checked in by vboxsync, 10 months ago

FE/Qt. bugref:10622. Using new UITranslationEventListener in wizard page class hierarchy.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 52.5 KB
Line 
1/* $Id: UIWizardNewVMNameOSTypePage.cpp 103957 2024-03-20 13:41:59Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIWizardNewVMPageBasicNameOSStype class implementation.
4 */
5
6/*
7 * Copyright (C) 2006-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 <QCheckBox>
30#include <QDir>
31#include <QStyle>
32#include <QRegularExpression>
33#include <QVBoxLayout>
34
35/* GUI includes: */
36#include "QIRichTextLabel.h"
37#include "UICommon.h"
38#include "UIDesktopWidgetWatchdog.h"
39#include "UIGlobalSession.h"
40#include "UIIconPool.h"
41#include "UINameAndSystemEditor.h"
42#include "UINotificationCenter.h"
43#include "UIWizardNewVMNameOSTypePage.h"
44#include "UIWizardNewVM.h"
45
46/* COM includes: */
47#include "CHost.h"
48#include "CUnattended.h"
49#include <VBox/com/VirtualBox.h> /* Need GUEST_OS_ID_STR_X86 and friends. */
50
51/* Defines some patterns to guess the right OS type. Should be in sync with
52 * VirtualBox-settings-common.xsd in Main. The list is sorted by priority. The
53 * first matching string found, will be used. */
54struct osTypePattern
55{
56 QRegularExpression pattern;
57 const char *pcstId;
58};
59
60static const osTypePattern gs_OSTypePattern[] =
61{
62 /* DOS: */
63 { QRegularExpression("DOS", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("DOS") },
64
65 /* Windows: */
66 { QRegularExpression( "Wi.*98", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Windows98") },
67 { QRegularExpression( "Wi.*95", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Windows95") },
68 { QRegularExpression( "Wi.*Me", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("WindowsMe") },
69 { QRegularExpression( "(Wi.*NT)|(NT[-._v]*4)", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("WindowsNT4") },
70 { QRegularExpression( "NT[-._v]*3[.,]*[51x]", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("WindowsNT3x") },
71 { QRegularExpression("(Wi.*XP.*64)|(XP.*64)", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("WindowsXP") },
72 { QRegularExpression("(XP)", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("WindowsXP") },
73 { QRegularExpression("((Wi.*2003)|(W2K3)|(Win2K3)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Windows2003") },
74 { QRegularExpression("((Wi.*2003)|(W2K3)|(Win2K3)).*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Windows2003") },
75 { QRegularExpression("((Wi.*Vis)|(Vista)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("WindowsVista") },
76 { QRegularExpression("((Wi.*Vis)|(Vista)).*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("WindowsVista") },
77 { QRegularExpression( "(Wi.*2016)|(W2K16)|(Win2K16)", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Windows2016") },
78 { QRegularExpression( "(Wi.*2012)|(W2K12)|(Win2K12)", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Windows2012") },
79 { QRegularExpression("((Wi.*2008)|(W2K8)|(Win2k8)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Windows2008") },
80 { QRegularExpression("((Wi.*2008)|(W2K8)|(Win2K8)).*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Windows2008") },
81 { QRegularExpression( "(Wi.*2000)|(W2K)|(Win2K)", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Windows2000") },
82 { QRegularExpression( "(Wi.*7.*64)|(W7.*64)", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Windows7") },
83 { QRegularExpression( "(Wi.*7.*32)|(W7.*32)", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Windows7") },
84 { QRegularExpression( "(Wi.*8.*1.*64)|(W8.*64)", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Windows81") },
85 { QRegularExpression( "(Wi.*8.*1.*32)|(W8.*32)", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Windows81") },
86 { QRegularExpression( "(Wi.*8.*64)|(W8.*64)", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Windows8") },
87 { QRegularExpression( "(Wi.*8.*32)|(W8.*32)", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Windows8") },
88 { QRegularExpression( "(Wi.*10.*64)|(W10.*64)", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Windows10") },
89 { QRegularExpression( "(Wi.*10.*32)|(W10.*32)", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Windows10") },
90 { QRegularExpression( "(Wi.*11)|(W11)", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Windows11") },
91 { QRegularExpression( "Wi.*3.*1", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Windows31") },
92 /* Set Windows 10 as default for "Windows". */
93 { QRegularExpression( "Wi.*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Windows10") },
94 { QRegularExpression( "Wi.*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Windows10") },
95 /* ReactOS wants to be considered as Windows 2003 */
96 { QRegularExpression( "Reac.*", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Windows2003") },
97
98 /* Solaris: */
99 { QRegularExpression("((Op.*Sol)|(os20[01][0-9])|(India)|(Illum)|(Neva)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("OpenSolaris") },
100 { QRegularExpression("((Op.*Sol)|(os20[01][0-9])|(India)|(Illum)|(Neva)).*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("OpenSolaris") },
101 { QRegularExpression("(Sol.*10.*(10/09)|(9/10)|(8/11)|(1/13)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Solaris10U8_or_later") },
102 { QRegularExpression("(Sol.*10.*(10/09)|(9/10)|(8/11)|(1/13)).*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Solaris10U8_or_later") },
103 { QRegularExpression("(Sol.*10.*(U[89])|(U1[01])).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Solaris10U8_or_later") },
104 { QRegularExpression("(Sol.*10.*(U[89])|(U1[01])).*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Solaris10U8_or_later") },
105 { QRegularExpression("(Sol.*10.*(1/06)|(6/06)|(11/06)|(8/07)|(5/08)|(10/08)|(5/09)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Solaris") }, // Solaris 10U7 (5/09) or earlier
106 { QRegularExpression("(Sol.*10.*(1/06)|(6/06)|(11/06)|(8/07)|(5/08)|(10/08)|(5/09)).*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Solaris") }, // Solaris 10U7 (5/09) or earlier
107 { QRegularExpression("((Sol.*10.*U[1-7])|(Sol.*10)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Solaris") }, // Solaris 10U7 (5/09) or earlier
108 { QRegularExpression("((Sol.*10.*U[1-7])|(Sol.*10)).*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Solaris") }, // Solaris 10U7 (5/09) or earlier
109 { QRegularExpression("((Sol.*11)|(Sol.*)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Solaris11") },
110
111 /* OS/2: */
112 { QRegularExpression("OS[/|!-]{,1}2.*W.*4.?5", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("OS2Warp45") },
113 { QRegularExpression("OS[/|!-]{,1}2.*W.*4", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("OS2Warp4") },
114 { QRegularExpression("OS[/|!-]{,1}2.*W", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("OS2Warp3") },
115 { QRegularExpression("OS[/|!-]{,1}2.*e", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("OS2eCS") },
116 { QRegularExpression("OS[/|!-]{,1}2.*Ar.*", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("OS2ArcaOS") },
117 { QRegularExpression("OS[/|!-]{,1}2", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("OS2") },
118 { QRegularExpression("(eComS.*|eCS.*)", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("OS2eCS") },
119 { QRegularExpression("Arca.*", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("OS2ArcaOS") },
120
121 /* Other: Must come before Ubuntu/Maverick and before Linux??? */
122 { QRegularExpression("QN", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("QNX") },
123
124 /* Mac OS X: Must come before Ubuntu/Maverick and before Linux: */
125 { QRegularExpression("((mac.*10[.,]{0,1}4)|(os.*x.*10[.,]{0,1}4)|(mac.*ti)|(os.*x.*ti)|(Tig)).64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("MacOS") },
126 { QRegularExpression("((mac.*10[.,]{0,1}4)|(os.*x.*10[.,]{0,1}4)|(mac.*ti)|(os.*x.*ti)|(Tig)).32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("MacOS") },
127 { QRegularExpression("((mac.*10[.,]{0,1}5)|(os.*x.*10[.,]{0,1}5)|(mac.*leo)|(os.*x.*leo)|(Leop)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("MacOS") },
128 { QRegularExpression("((mac.*10[.,]{0,1}5)|(os.*x.*10[.,]{0,1}5)|(mac.*leo)|(os.*x.*leo)|(Leop)).*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("MacOS") },
129 { QRegularExpression("((mac.*10[.,]{0,1}6)|(os.*x.*10[.,]{0,1}6)|(mac.*SL)|(os.*x.*SL)|(Snow L)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("MacOS106") },
130 { QRegularExpression("((mac.*10[.,]{0,1}6)|(os.*x.*10[.,]{0,1}6)|(mac.*SL)|(os.*x.*SL)|(Snow L)).*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("MacOS106") },
131 { QRegularExpression( "(mac.*10[.,]{0,1}7)|(os.*x.*10[.,]{0,1}7)|(mac.*ML)|(os.*x.*ML)|(Mount)", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("MacOS107") },
132 { QRegularExpression( "(mac.*10[.,]{0,1}8)|(os.*x.*10[.,]{0,1}8)|(Lion)", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("MacOS108") },
133 { QRegularExpression( "(mac.*10[.,]{0,1}9)|(os.*x.*10[.,]{0,1}9)|(mac.*mav)|(os.*x.*mav)|(Mavericks)", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("MacOS109") },
134 { QRegularExpression( "(mac.*yos)|(os.*x.*yos)|(Yosemite)", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("MacOS1010") },
135 { QRegularExpression( "(mac.*cap)|(os.*x.*capit)|(Capitan)", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("MacOS1011") },
136 { QRegularExpression( "(mac.*hig)|(os.*x.*high.*sierr)|(High Sierra)", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("MacOS1013") },
137 { QRegularExpression( "(mac.*sie)|(os.*x.*sierr)|(Sierra)", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("MacOS1012") },
138 { QRegularExpression("((Mac)|(Tig)|(Leop)|(Yose)|(os[ ]*x)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("MacOS") },
139 { QRegularExpression("((Mac)|(Tig)|(Leop)|(Yose)|(os[ ]*x)).*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("MacOS") },
140
141 /* Code names for Linux distributions: */
142 { QRegularExpression("((bianca)|(cassandra)|(celena)|(daryna)|(elyssa)|(felicia)|(gloria)|(helena)|(isadora)|(julia)|(katya)|(lisa)|(maya)|(nadia)|(olivia)|(petra)|(qiana)|(rebecca)|(rafaela)|(rosa)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Ubuntu") },
143 { QRegularExpression("((bianca)|(cassandra)|(celena)|(daryna)|(elyssa)|(felicia)|(gloria)|(helena)|(isadora)|(julia)|(katya)|(lisa)|(maya)|(nadia)|(olivia)|(petra)|(qiana)|(rebecca)|(rafaela)|(rosa)).*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Ubuntu") },
144 { QRegularExpression("((edgy)|(feisty)|(gutsy)|(hardy)|(intrepid)|(jaunty)|(karmic)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Ubuntu") },
145 { QRegularExpression("((edgy)|(feisty)|(gutsy)|(hardy)|(intrepid)|(jaunty)|(karmic)).*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Ubuntu") },
146 { QRegularExpression("((eft)|(fawn)|(gibbon)|(heron)|(ibex)|(jackalope)|(koala)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Ubuntu") },
147 { QRegularExpression("((eft)|(fawn)|(gibbon)|(heron)|(ibex)|(jackalope)|(koala)).*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Ubuntu") },
148 { QRegularExpression("((lucid)|(lynx)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Ubuntu10_LTS") },
149 { QRegularExpression("((lucid)|(lynx)).*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Ubuntu10_LTS") },
150 { QRegularExpression("((maverick)|(meerkat)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Ubuntu10") },
151 { QRegularExpression("((maverick)|(meerkat)).*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Ubuntu10") },
152 { QRegularExpression("((natty)|(narwhal)|(oneiric)|(ocelot)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Ubuntu11") },
153 { QRegularExpression("((natty)|(narwhal)|(oneiric)|(ocelot)).*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Ubuntu11") },
154 { QRegularExpression("((precise)|(pangolin)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Ubuntu12_LTS") },
155 { QRegularExpression("((precise)|(pangolin)).*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Ubuntu12_LTS") },
156 { QRegularExpression("((quantal)|(quetzal)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Ubuntu12") },
157 { QRegularExpression("((quantal)|(quetzal)).*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Ubuntu12") },
158 { QRegularExpression("((raring)|(ringtail)|(saucy)|(salamander)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Ubuntu13") },
159 { QRegularExpression("((raring)|(ringtail)|(saucy)|(salamander)).*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Ubuntu13") },
160 { QRegularExpression("((trusty)|(tahr)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Ubuntu14_LTS") },
161 { QRegularExpression("((trusty)|(tahr)).*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Ubuntu14_LTS") },
162 { QRegularExpression("((utopic)|(unicorn)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Ubuntu14") },
163 { QRegularExpression("((utopic)|(unicorn)).*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Ubuntu14") },
164 { QRegularExpression("((vivid)|(vervet)|(wily)|(werewolf)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Ubuntu15") },
165 { QRegularExpression("((vivid)|(vervet)|(wily)|(werewolf)).*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Ubuntu15") },
166 { QRegularExpression("((xenial)|(xerus)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Ubuntu16_LTS") },
167 { QRegularExpression("((xenial)|(xerus)).*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Ubuntu16_LTS") },
168 { QRegularExpression("((yakkety)|(yak)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Ubuntu16") },
169 { QRegularExpression("((yakkety)|(yak)).*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Ubuntu16") },
170 { QRegularExpression("((zesty)|(zapus)|(artful)|(aardvark)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Ubuntu17") },
171 { QRegularExpression("((zesty)|(zapus)|(artful)|(aardvark)).*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Ubuntu17") },
172 { QRegularExpression("((bionic)|(beaver)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Ubuntu18_LTS") },
173 { QRegularExpression("((bionic)|(beaver)).*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Ubuntu18_LTS") },
174 { QRegularExpression("((cosmic)|(cuttlefish)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Ubuntu18") },
175 { QRegularExpression("((cosmic)|(cuttlefish)).*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Ubuntu18") },
176 { QRegularExpression("((disco)|(dingo)|(eoan)|(ermine)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Ubuntu19") },
177 { QRegularExpression("((disco)|(dingo)|(eoan)|(ermine)).*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Ubuntu19") },
178 { QRegularExpression("((focal)|(fossa)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Ubuntu20_LTS") },
179 { QRegularExpression("((groovy)|(gorilla)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Ubuntu20") },
180 { QRegularExpression("((hirsute)|(hippo)|(impish)|(indri)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Ubuntu21") },
181 { QRegularExpression("((jammy)|(jellyfish)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Ubuntu22_LTS") },
182 { QRegularExpression("((kinetic)|(kudu)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Ubuntu22") },
183 { QRegularExpression("((lunar)|(lobster)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Ubuntu23") },
184 { QRegularExpression("sarge.*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Debian31") },
185 { QRegularExpression("^etch.*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Debian4") },
186 { QRegularExpression("debian.*4.*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Debian4") },
187 { QRegularExpression("^etch.*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Debian4") },
188 { QRegularExpression("debian.*4.*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Debian4") },
189 { QRegularExpression("lenny.*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Debian5") },
190 { QRegularExpression("lenny.*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Debian5") },
191 { QRegularExpression("squeeze.*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Debian6") },
192 { QRegularExpression("debian.*6.*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Debian6") },
193 { QRegularExpression("squeeze.*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Debian6") },
194 { QRegularExpression("debian.*6.*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Debian6") },
195 { QRegularExpression("wheezy.*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Debian7") },
196 { QRegularExpression("debian.*7.*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Debian7") },
197 { QRegularExpression("wheezy.*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Debian7") },
198 { QRegularExpression("debian.*7.*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Debian7") },
199 { QRegularExpression("jessie.*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Debian8") },
200 { QRegularExpression("debian.*8.*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Debian8") },
201 { QRegularExpression("jessie.*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Debian8") },
202 { QRegularExpression("debian.*8*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Debian8") },
203 { QRegularExpression("stretch.*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Debian9") },
204 { QRegularExpression("debian.*9.*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Debian9") },
205 { QRegularExpression("debian.*9.*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Debian9") },
206 { QRegularExpression("stretch.*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Debian9") },
207 { QRegularExpression("buster.*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Debian10") },
208 { QRegularExpression("debian.*10.*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Debian10") },
209 { QRegularExpression("buster.*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Debian10") },
210 { QRegularExpression("debian.*10.*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Debian10") },
211 { QRegularExpression("bullseye.*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Debian11") },
212 { QRegularExpression("debian.*11.*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Debian11") },
213 { QRegularExpression("bullseye.*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Debian11") },
214 { QRegularExpression("debian.*11.*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Debian11") },
215 { QRegularExpression("bookworm.*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Debian12") },
216 { QRegularExpression("debian.*12.*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Debian12") },
217 { QRegularExpression("debian.*12", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Debian12") },
218 { QRegularExpression("bookworm.*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Debian12") },
219 { QRegularExpression("((trixie)|(sid)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Debian") },
220 { QRegularExpression("((trixie)|(sid)).*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Debian") },
221 { QRegularExpression("((moonshine)|(werewolf)|(sulphur)|(cambridge)|(leonidas)|(constantine)|(goddard)|(laughlin)|(lovelock)|(verne)|(beefy)|(spherical)|(schrodinger)|(heisenberg)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Fedora") },
222 { QRegularExpression("((moonshine)|(werewolf)|(sulphur)|(cambridge)|(leonidas)|(constantine)|(goddard)|(laughlin)|(lovelock)|(verne)|(beefy)|(spherical)|(schrodinger)|(heisenberg)).*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Fedora") },
223 { QRegularExpression("((basilisk)|(emerald)|(teal)|(celadon)|(asparagus)|(mantis)|(dartmouth)|(bottle)|(harlequin)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("OpenSUSE") },
224 { QRegularExpression("((basilisk)|(emerald)|(teal)|(celadon)|(asparagus)|(mantis)|(dartmouth)|(bottle)|(harlequin)).*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("OpenSUSE") },
225
226 /* Regular names of Linux distributions: */
227 { QRegularExpression("Arc.*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("ArchLinux") },
228 { QRegularExpression("Arc.*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("ArchLinux") },
229 { QRegularExpression("Deb.*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Debian") },
230 { QRegularExpression("Deb.*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Debian") },
231 { QRegularExpression("SU.*Leap.*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("OpenSUSE_Leap") },
232 { QRegularExpression("SU.*Tumble.*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("OpenSUSE_Tumbleweed") },
233 { QRegularExpression("SU.*Tumble.*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("OpenSUSE_Tumbleweed") },
234 { QRegularExpression("((SU)|(Nov)|(SLE)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("OpenSUSE") },
235 { QRegularExpression("((SU)|(Nov)|(SLE)).*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("OpenSUSE") },
236 { QRegularExpression("Fe.*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Fedora") },
237 { QRegularExpression("Fe.*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Fedora") },
238 { QRegularExpression("((Gen)|(Sab)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Gentoo") },
239 { QRegularExpression("((Gen)|(Sab)).*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Gentoo") },
240 { QRegularExpression("^Man.*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Mandriva") },
241 { QRegularExpression("^Man.*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Mandriva") },
242 { QRegularExpression("Op.*Man.*Lx.*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("OpenMandriva_Lx") },
243 { QRegularExpression("Op.*Man.*Lx.*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("OpenMandriva_Lx") },
244 { QRegularExpression("PCL.*OS.*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("PCLinuxOS") },
245 { QRegularExpression("PCL.*OS.*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("PCLinuxOS") },
246 { QRegularExpression("Mageia.*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Mageia") },
247 { QRegularExpression("Mageia.*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Mageia") },
248 { QRegularExpression("((Red)|(rhel)|(cen)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("RedHat") },
249 { QRegularExpression("((Red)|(rhel)|(cen)).*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("RedHat") },
250 { QRegularExpression("Tur.*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Turbolinux") },
251 { QRegularExpression("Tur.*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Turbolinux") },
252 { QRegularExpression("Lub.*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Lubuntu") },
253 { QRegularExpression("Lub.*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Lubuntu") },
254 { QRegularExpression("Xub.*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Xubuntu") },
255 { QRegularExpression("Xub.*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Xubuntu") },
256 { QRegularExpression("((Ub)|(Mint)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Ubuntu") },
257 { QRegularExpression("((Ub)|(Mint)).*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Ubuntu") },
258 { QRegularExpression("Xa.*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Xandros") },
259 { QRegularExpression("Xa.*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Xandros") },
260 { QRegularExpression("((Or)|(oel)|(^ol)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Oracle") },
261 { QRegularExpression("((Or)|(oel)|(^ol)).*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Oracle") },
262 { QRegularExpression("Knoppix", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Linux26") },
263 { QRegularExpression("Dsl", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Linux24") },
264 { QRegularExpression("((Lin)|(lnx)).*2.?2", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Linux22") },
265 { QRegularExpression("((Lin)|(lnx)).*2.?4.*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Linux24") },
266 { QRegularExpression("((Lin)|(lnx)).*2.?4.*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Linux24") },
267 { QRegularExpression("((((Lin)|(lnx)).*2.?6)|(LFS)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Linux26") },
268 { QRegularExpression("((((Lin)|(lnx)).*2.?6)|(LFS)).*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Linux26") },
269 { QRegularExpression("((Lin)|(lnx)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("Linux26") },
270 { QRegularExpression("((Lin)|(lnx)).*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Linux26") },
271
272 /* Other: */
273 { QRegularExpression("L4", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("L4") },
274 { QRegularExpression("((Fr.*B)|(fbsd)).*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("FreeBSD") },
275 { QRegularExpression("((Fr.*B)|(fbsd)).*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("FreeBSD") },
276 { QRegularExpression("Op.*B.*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("OpenBSD") },
277 { QRegularExpression("Op.*B.*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("OpenBSD") },
278 { QRegularExpression("Ne.*B.*64", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("NetBSD") },
279 { QRegularExpression("Ne.*B.*32", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("NetBSD") },
280 { QRegularExpression("Net", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Netware") },
281 { QRegularExpression("Rocki", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("JRockitVE") },
282 { QRegularExpression("bs[23]{0,1}-", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X64("VBoxBS") }, /* bootsector tests */
283 { QRegularExpression("Ot", QRegularExpression::CaseInsensitiveOption), GUEST_OS_ID_STR_X86("Other") },
284};
285
286static const QRegularExpression gs_Prefer32BitNamePatterns = QRegularExpression("(XP)", QRegularExpression::CaseInsensitiveOption);
287
288
289bool UIWizardNewVMNameOSTypeCommon::guessOSTypeFromName(UINameAndSystemEditor *pNameAndSystemEditor, QString strNewName)
290{
291 AssertReturn(pNameAndSystemEditor, false);
292
293 /* Append default architecture bit-count (64/32) if not already in the name, unless
294 it's XP or similar which is predominantly 32-bit: */
295 if (!strNewName.contains("32") && !strNewName.contains("64") && !strNewName.contains(gs_Prefer32BitNamePatterns))
296 strNewName += ARCH_BITS == 64 ? "64" : "32";
297
298 /* Search for a matching OS type based on the string the user typed already. */
299 for (size_t i = 0; i < RT_ELEMENTS(gs_OSTypePattern); ++i)
300 {
301 if (strNewName.contains(gs_OSTypePattern[i].pattern))
302 return pNameAndSystemEditor->setGuestOSTypeByTypeId(gs_OSTypePattern[i].pcstId);
303 }
304 return false;
305}
306
307bool UIWizardNewVMNameOSTypeCommon::guessOSTypeDetectedOSTypeString(UINameAndSystemEditor *pNameAndSystemEditor, QString strDetectedOSType)
308{
309 AssertReturn(pNameAndSystemEditor, false);
310 if (!strDetectedOSType.isEmpty())
311 {
312 if (!pNameAndSystemEditor->setGuestOSTypeByTypeId(strDetectedOSType))
313 {
314 pNameAndSystemEditor->setGuestOSTypeByTypeId(GUEST_OS_ID_STR_X86("Other"));
315 /* Return false to allow OS type guessing from name. See caller code: */
316 return false;
317 }
318 return true;
319 }
320 pNameAndSystemEditor->setGuestOSTypeByTypeId(GUEST_OS_ID_STR_X86("Other"));
321 return false;
322}
323
324void UIWizardNewVMNameOSTypeCommon::composeMachineFilePath(UINameAndSystemEditor *pNameAndSystemEditor,
325 UIWizardNewVM *pWizard)
326{
327 if (!pNameAndSystemEditor || !pWizard)
328 return;
329 if (pNameAndSystemEditor->name().isEmpty() || pNameAndSystemEditor->path().isEmpty())
330 return;
331 /* Get VBox: */
332 CVirtualBox vbox = gpGlobalSession->virtualBox();
333
334 /* Compose machine filename: */
335 pWizard->setMachineFilePath(vbox.ComposeMachineFilename(pNameAndSystemEditor->name(),
336 pWizard->machineGroup(),
337 QString(),
338 pNameAndSystemEditor->path()));
339 /* Compose machine folder/basename: */
340 const QFileInfo fileInfo(pWizard->machineFilePath());
341 pWizard->setMachineFolder(fileInfo.absolutePath());
342 pWizard->setMachineBaseName(pNameAndSystemEditor->name());
343}
344
345bool UIWizardNewVMNameOSTypeCommon::createMachineFolder(UINameAndSystemEditor *pNameAndSystemEditor,
346 UIWizardNewVM *pWizard)
347{
348 if (!pNameAndSystemEditor || !pWizard)
349 return false;
350 const QString &strMachineFolder = pWizard->machineFolder();
351 const QString &strCreatedFolder = pWizard->createdMachineFolder();
352
353 /* Cleanup previosly created folder if any: */
354 if (!cleanupMachineFolder(pWizard))
355 {
356 UINotificationMessage::cannotRemoveMachineFolder(strCreatedFolder, pWizard->notificationCenter());
357 return false;
358 }
359
360 /* Check if the folder already exists and check if it has been created by this wizard */
361 if (QDir(strMachineFolder).exists())
362 {
363 /* Looks like we have already created this folder for this run of the wizard. Just return */
364 if (strCreatedFolder == strMachineFolder)
365 return true;
366 /* The folder is there but not because of this wizard. Avoid overwriting a existing machine's folder */
367 else
368 {
369 UINotificationMessage::cannotOverwriteMachineFolder(strMachineFolder, pWizard->notificationCenter());
370 return false;
371 }
372 }
373
374 /* Try to create new folder (and it's predecessors): */
375 bool fMachineFolderCreated = QDir().mkpath(strMachineFolder);
376 if (!fMachineFolderCreated)
377 {
378 UINotificationMessage::cannotCreateMachineFolder(strMachineFolder, pWizard->notificationCenter());
379 return false;
380 }
381 pWizard->setCreatedMachineFolder(strMachineFolder);
382 return true;
383}
384
385bool UIWizardNewVMNameOSTypeCommon::cleanupMachineFolder(UIWizardNewVM *pWizard, bool fWizardCancel /* = false */)
386{
387 if (!pWizard)
388 return false;
389 const QString &strMachineFolder = pWizard->machineFolder();
390 const QString &strCreatedFolder = pWizard->createdMachineFolder();
391 /* Make sure folder was previosly created: */
392 if (strCreatedFolder.isEmpty())
393 return true;
394 /* Clean this folder if the machine folder has been changed by the user or we are cancelling the wizard: */
395 if (strCreatedFolder != strMachineFolder || fWizardCancel)
396 {
397 /* Try to cleanup folder (and it's predecessors): */
398 bool fMachineFolderRemoved = QDir(strCreatedFolder).removeRecursively();
399 /* Reset machine folder value: */
400 if (fMachineFolderRemoved)
401 pWizard->setCreatedMachineFolder(QString());
402 /* Return cleanup result: */
403 return fMachineFolderRemoved;
404 }
405 return true;
406}
407
408bool UIWizardNewVMNameOSTypeCommon::checkISOFile(UINameAndSystemEditor *pNameAndSystemEditor)
409{
410 if (!pNameAndSystemEditor)
411 return false;
412 const QString &strPath = pNameAndSystemEditor->ISOImagePath();
413 if (strPath.isNull() || strPath.isEmpty())
414 return true;
415 QFileInfo fileInfo(strPath);
416 if (!fileInfo.exists() || !fileInfo.isReadable())
417 return false;
418 return true;
419}
420
421UIWizardNewVMNameOSTypePage::UIWizardNewVMNameOSTypePage()
422 : m_pNameAndSystemLayout(0)
423 , m_pNameAndSystemEditor(0)
424 , m_pSkipUnattendedCheckBox(0)
425 , m_pNameOSTypeLabel(0)
426 , m_pInfoLabel(0)
427{
428 prepare();
429}
430
431void UIWizardNewVMNameOSTypePage::setISOFilePath(const QString &strISOFilePath)
432{
433 QFileInfo isoFileInfo(strISOFilePath);
434 if (isoFileInfo.exists() && m_pNameAndSystemEditor)
435 m_pNameAndSystemEditor->setISOImagePath(strISOFilePath);
436}
437
438void UIWizardNewVMNameOSTypePage::prepare()
439{
440 QVBoxLayout *pPageLayout = new QVBoxLayout(this);
441 if (pPageLayout)
442 {
443 m_pNameOSTypeLabel = new QIRichTextLabel(this);
444 if (m_pNameOSTypeLabel)
445 pPageLayout->addWidget(m_pNameOSTypeLabel);
446
447 /* Prepare Name and OS Type editor: */
448 pPageLayout->addWidget(createNameOSTypeWidgets());
449
450 pPageLayout->addStretch();
451 }
452
453 createConnections();
454}
455
456void UIWizardNewVMNameOSTypePage::createConnections()
457{
458 if (m_pNameAndSystemEditor)
459 {
460 connect(m_pNameAndSystemEditor, &UINameAndSystemEditor::sigNameChanged, this, &UIWizardNewVMNameOSTypePage::sltNameChanged);
461 connect(m_pNameAndSystemEditor, &UINameAndSystemEditor::sigPathChanged, this, &UIWizardNewVMNameOSTypePage::sltPathChanged);
462 connect(m_pNameAndSystemEditor, &UINameAndSystemEditor::sigOsTypeChanged, this, &UIWizardNewVMNameOSTypePage::sltOsTypeChanged);
463 connect(m_pNameAndSystemEditor, &UINameAndSystemEditor::sigImageChanged, this, &UIWizardNewVMNameOSTypePage::sltISOPathChanged);
464 connect(m_pNameAndSystemEditor, &UINameAndSystemEditor::sigOSFamilyChanged, this, &UIWizardNewVMNameOSTypePage::sltGuestOSFamilyChanged);
465 connect(m_pNameAndSystemEditor, &UINameAndSystemEditor::sigEditionChanged, this, &UIWizardNewVMNameOSTypePage::sltSelectedEditionChanged);
466 }
467 if (m_pSkipUnattendedCheckBox)
468 connect(m_pSkipUnattendedCheckBox, &QCheckBox::toggled, this, &UIWizardNewVMNameOSTypePage::sltSkipUnattendedInstallChanged);
469}
470
471bool UIWizardNewVMNameOSTypePage::isComplete() const
472{
473 markWidgets();
474 if (m_pNameAndSystemEditor->name().isEmpty())
475 return false;
476 return UIWizardNewVMNameOSTypeCommon::checkISOFile(m_pNameAndSystemEditor);
477}
478
479void UIWizardNewVMNameOSTypePage::sltNameChanged(const QString &strNewName)
480{
481 AssertReturnVoid(wizardWindow<UIWizardNewVM>());
482 if (!m_userModifiedParameters.contains("GuestOSTypeFromISO"))
483 {
484 m_pNameAndSystemEditor->blockSignals(true);
485 if (UIWizardNewVMNameOSTypeCommon::guessOSTypeFromName(m_pNameAndSystemEditor, strNewName))
486 {
487 wizardWindow<UIWizardNewVM>()->setGuestOSTypeId(m_pNameAndSystemEditor->typeId());
488 m_userModifiedParameters << "GuestOSTypeFromName";
489 }
490 m_pNameAndSystemEditor->blockSignals(false);
491 }
492 UIWizardNewVMNameOSTypeCommon::composeMachineFilePath(m_pNameAndSystemEditor, wizardWindow<UIWizardNewVM>());
493 emit completeChanged();
494}
495
496void UIWizardNewVMNameOSTypePage::sltPathChanged(const QString &strNewPath)
497{
498 Q_UNUSED(strNewPath);
499 UIWizardNewVMNameOSTypeCommon::composeMachineFilePath(m_pNameAndSystemEditor, wizardWindow<UIWizardNewVM>());
500}
501
502void UIWizardNewVMNameOSTypePage::sltOsTypeChanged()
503{
504 AssertReturnVoid(wizardWindow<UIWizardNewVM>());
505 //m_userModifiedParameters << "GuestOSType";
506 if (m_pNameAndSystemEditor)
507 wizardWindow<UIWizardNewVM>()->setGuestOSTypeId(m_pNameAndSystemEditor->typeId());
508}
509
510void UIWizardNewVMNameOSTypePage::sltRetranslateUI()
511{
512 setTitle(UIWizardNewVM::tr("Virtual machine Name and Operating System"));
513
514 if (m_pNameOSTypeLabel)
515 m_pNameOSTypeLabel->setText(UIWizardNewVM::tr("Please choose a descriptive name and destination folder for the new "
516 "virtual machine. The name you choose will be used throughout VirtualBox "
517 "to identify this machine. Additionally, you can select an ISO image which "
518 "may be used to install the guest operating system."));
519
520 if (m_pSkipUnattendedCheckBox)
521 {
522 m_pSkipUnattendedCheckBox->setText(UIWizardNewVM::tr("&Skip Unattended Installation"));
523 m_pSkipUnattendedCheckBox->setToolTip(UIWizardNewVM::tr("When checked, the unattended install is disabled and the selected ISO "
524 "is mounted on the vm."));
525 }
526
527 if (m_pNameAndSystemLayout && m_pNameAndSystemEditor)
528 m_pNameAndSystemLayout->setColumnMinimumWidth(0, m_pNameAndSystemEditor->firstColumnWidth());
529
530 updateInfoLabel();
531}
532
533void UIWizardNewVMNameOSTypePage::updateInfoLabel()
534{
535 UIWizardNewVM *pWizard = wizardWindow<UIWizardNewVM>();
536 AssertReturnVoid(pWizard);
537
538 if (!m_pInfoLabel)
539 return;
540
541 /*
542 * Here are the scenarios we consider while updating the info label:
543 * - No ISO selected,
544 * - Unattended cannot determine OS type from the ISO,
545 * - Unattended can determine the OS type from the ISO but cannot install it,
546 * - User has disabled unattended explicitly,
547 * - Unattended install will kick off.
548 */
549 QString strMessage;
550 if (m_pNameAndSystemEditor->ISOImagePath().isEmpty())
551 strMessage = UIWizardNewVM::tr("No ISO image is selected, the guest OS will need to be installed manually.");
552 else if (pWizard->detectedOSTypeId().isEmpty())
553 strMessage = UIWizardNewVM::tr("OS type cannot be determined from the selected ISO, "
554 "the guest OS will need to be installed manually.");
555 else if (!pWizard->detectedOSTypeId().isEmpty())
556 {
557 QString strType = gpGlobalSession->guestOSTypeManager().getDescription(pWizard->detectedOSTypeId());
558 if (!pWizard->isUnattendedInstallSupported())
559 strMessage = UIWizardNewVM::tr("Detected OS type: %1. %2")
560 .arg(strType)
561 .arg(UIWizardNewVM::tr("This OS type cannot be installed unattendedly. "
562 "The install needs to be started manually."));
563 else if (pWizard->skipUnattendedInstall())
564 strMessage = UIWizardNewVM::tr("You have selected to skip unattended guest OS install, "
565 "the guest OS will need to be installed manually.");
566 else
567 strMessage = UIWizardNewVM::tr("Detected OS type: %1. %2")
568 .arg(strType)
569 .arg(UIWizardNewVM::tr("This OS type can be installed unattendedly. "
570 "The install will start after this wizard is closed."));
571 }
572
573 const QIcon icon = UIIconPool::iconSet(":/session_info_16px.png");
574 const int iIconMetric = QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize);
575 const qreal fDevicePixelRatio = gpDesktop->devicePixelRatio(m_pInfoLabel);
576 m_pInfoLabel->registerPixmap(icon.pixmap(QSize(iIconMetric, iIconMetric), fDevicePixelRatio), "wizard://info");
577 m_pInfoLabel->setText(QString("<img src='wizard://info' style=\"vertical-align:top\"> %1").arg(strMessage));
578}
579
580void UIWizardNewVMNameOSTypePage::initializePage()
581{
582 UIWizardNewVM *pWizard = wizardWindow<UIWizardNewVM>();
583 AssertReturnVoid(pWizard);
584
585 sltRetranslateUI();
586
587 /* Initialize this page's widgets etc: */
588 {
589 if (m_pNameAndSystemEditor)
590 {
591 m_pNameAndSystemEditor->setFocus();
592 setEditionSelectorEnabled();
593 }
594 setSkipCheckBoxEnable();
595 }
596
597 /* Initialize some of the wizard's parameters: */
598 {
599 if (m_pNameAndSystemEditor)
600 {
601 pWizard->setGuestOSFamilyId(m_pNameAndSystemEditor->familyId());
602 pWizard->setGuestOSTypeId(m_pNameAndSystemEditor->typeId());
603 /* Vm name, folder, file path etc. will be initilized by composeMachineFilePath: */
604 }
605 }
606}
607
608bool UIWizardNewVMNameOSTypePage::validatePage()
609{
610 /* Try to create machine folder: */
611 return UIWizardNewVMNameOSTypeCommon::createMachineFolder(m_pNameAndSystemEditor, wizardWindow<UIWizardNewVM>());
612}
613
614void UIWizardNewVMNameOSTypePage::sltISOPathChanged(const QString &strPath)
615{
616 UIWizardNewVM *pWizard = qobject_cast<UIWizardNewVM*>(this->wizard());
617 AssertReturnVoid(pWizard);
618
619 pWizard->setISOFilePath(strPath);
620
621 bool const fOsTypeFixed = UIWizardNewVMNameOSTypeCommon::guessOSTypeDetectedOSTypeString(m_pNameAndSystemEditor,
622 pWizard->detectedOSTypeId());
623 if (fOsTypeFixed)
624 m_userModifiedParameters << "GuestOSTypeFromISO";
625 else /* Remove GuestOSTypeFromISO from the set if it is there: */
626 m_userModifiedParameters.remove("GuestOSTypeFromISO");
627
628 /* Update the global recent ISO path: */
629 QFileInfo fileInfo(strPath);
630 if (fileInfo.exists() && fileInfo.isReadable())
631 uiCommon().updateRecentlyUsedMediumListAndFolder(UIMediumDeviceType_DVD, strPath);
632
633 /* Populate the editions selector: */
634 if (m_pNameAndSystemEditor)
635 m_pNameAndSystemEditor->setEditionNameAndIndices(pWizard->detectedWindowsImageNames(),
636 pWizard->detectedWindowsImageIndices());
637
638 setSkipCheckBoxEnable();
639 setEditionSelectorEnabled();
640 updateInfoLabel();
641
642 /* Disable OS type selector(s) to prevent user from changing guest OS type manually: */
643 if (m_pNameAndSystemEditor)
644 {
645 m_pNameAndSystemEditor->setOSTypeStuffEnabled(!fOsTypeFixed);
646
647 /* Redetect the OS type using the name if detection or the step above failed: */
648 if (!fOsTypeFixed)
649 sltNameChanged(m_pNameAndSystemEditor->name());
650 }
651
652 emit completeChanged();
653}
654
655void UIWizardNewVMNameOSTypePage::sltGuestOSFamilyChanged(const QString &strGuestOSFamilyId)
656{
657 AssertReturnVoid(wizardWindow<UIWizardNewVM>());
658 wizardWindow<UIWizardNewVM>()->setGuestOSFamilyId(strGuestOSFamilyId);
659}
660
661void UIWizardNewVMNameOSTypePage::sltSelectedEditionChanged(ulong uEditionIndex)
662{
663 UIWizardNewVM *pWizard = wizardWindow<UIWizardNewVM>();
664 AssertReturnVoid(pWizard);
665 pWizard->setSelectedWindowImageIndex(uEditionIndex);
666 /* Update the OS type since IUnattended updates the detected OS type after edition (image index) changes: */
667 UIWizardNewVMNameOSTypeCommon::guessOSTypeDetectedOSTypeString(m_pNameAndSystemEditor, pWizard->detectedOSTypeId());
668}
669
670void UIWizardNewVMNameOSTypePage::sltSkipUnattendedInstallChanged(bool fSkip)
671{
672 AssertReturnVoid(wizardWindow<UIWizardNewVM>());
673 m_userModifiedParameters << "SkipUnattendedInstall";
674 wizardWindow<UIWizardNewVM>()->setSkipUnattendedInstall(fSkip);
675 setEditionSelectorEnabled();
676 updateInfoLabel();
677}
678
679QWidget *UIWizardNewVMNameOSTypePage::createNameOSTypeWidgets()
680{
681 /* Prepare container widget: */
682 QWidget *pContainerWidget = new QWidget;
683 if (pContainerWidget)
684 {
685 /* Prepare layout: */
686 m_pNameAndSystemLayout = new QGridLayout(pContainerWidget);
687 if (m_pNameAndSystemLayout)
688 {
689 m_pNameAndSystemLayout->setContentsMargins(0, 0, 0, 0);
690
691 /* Prepare Name and OS Type editor: */
692 m_pNameAndSystemEditor = new UINameAndSystemEditor(0,
693 true /* fChooseName? */,
694 true /* fChoosePath? */,
695 true /* fChooseImage? */,
696 true /* fChooseEdition? */,
697 true /* fChooseType? */);
698 if (m_pNameAndSystemEditor)
699 m_pNameAndSystemLayout->addWidget(m_pNameAndSystemEditor, 0, 0, 1, 2);
700
701 /* Prepare Skip Unattended checkbox: */
702 m_pSkipUnattendedCheckBox = new QCheckBox;
703 if (m_pSkipUnattendedCheckBox)
704 m_pNameAndSystemLayout->addWidget(m_pSkipUnattendedCheckBox, 1, 1);
705 m_pInfoLabel = new QIRichTextLabel;
706 if (m_pInfoLabel)
707 m_pNameAndSystemLayout->addWidget(m_pInfoLabel, 2, 1);
708 }
709 }
710
711 /* Return container widget: */
712 return pContainerWidget;
713}
714
715void UIWizardNewVMNameOSTypePage::markWidgets() const
716{
717 if (m_pNameAndSystemEditor)
718 {
719 m_pNameAndSystemEditor->markNameEditor(m_pNameAndSystemEditor->name().isEmpty());
720 m_pNameAndSystemEditor->markImageEditor(!UIWizardNewVMNameOSTypeCommon::checkISOFile(m_pNameAndSystemEditor),
721 UIWizardNewVM::tr("Invalid file path or unreadable file"));
722 }
723}
724
725void UIWizardNewVMNameOSTypePage::setSkipCheckBoxEnable()
726{
727 AssertReturnVoid(m_pSkipUnattendedCheckBox && m_pNameAndSystemEditor);
728 const QString &strPath = m_pNameAndSystemEditor->ISOImagePath();
729 if (strPath.isEmpty())
730 {
731 m_pSkipUnattendedCheckBox->setEnabled(false);
732 return;
733 }
734 if (!isUnattendedInstallSupported())
735 {
736 m_pSkipUnattendedCheckBox->setEnabled(false);
737 return;
738 }
739
740 m_pSkipUnattendedCheckBox->setEnabled(UIWizardNewVMNameOSTypeCommon::checkISOFile(m_pNameAndSystemEditor));
741}
742
743bool UIWizardNewVMNameOSTypePage::isUnattendedEnabled() const
744{
745 UIWizardNewVM *pWizard = wizardWindow<UIWizardNewVM>();
746 AssertReturn(pWizard, false);
747 return pWizard->isUnattendedEnabled();
748}
749
750bool UIWizardNewVMNameOSTypePage::isUnattendedInstallSupported() const
751{
752 UIWizardNewVM *pWizard = wizardWindow<UIWizardNewVM>();
753 AssertReturn(pWizard, false);
754 return pWizard->isUnattendedInstallSupported();
755}
756
757
758void UIWizardNewVMNameOSTypePage::setEditionSelectorEnabled()
759{
760 if (!m_pNameAndSystemEditor || !m_pSkipUnattendedCheckBox)
761 return;
762 m_pNameAndSystemEditor->setEditionSelectorEnabled( !m_pNameAndSystemEditor->isEditionsSelectorEmpty()
763 && !m_pSkipUnattendedCheckBox->isChecked());
764}
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