/**************************************************************************** ** ** Copyright (C) 2024 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the release tools of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3 as published by the Free Software ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT ** included in the packaging of this file. Please review the following ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ // constructor function Component() { if (installer.isOfflineOnly()) { component.setValue("Virtual", "false") component.setValue("Default", "true"); var ifwVersion = installer.value("FrameworkVersion"); if (installer.versionMatches(ifwVersion, ">=4.1.1")) { var childComponents = installer.components("^" + component.name); // "Default" cannot be set to component which has child items. // Select the component's child items instead. if (childComponents.length > 1) { for (j = 0; j < childComponents.length; j++) { var childName = childComponents[j].name; if (childName == component.name) continue; else installer.selectComponent(childName); } } } // skip component selection in the offline installer except when user has created the offline installer // as user might have other components in the same offline installer if (!installer.fileExists(":/generated-offline.ini")) installer.setDefaultPageVisible(QInstaller.ComponentSelection, false); if (!installer.isCommandLineInstance()) component.userInterface("LaunchQtDesignStudioCheckBoxForm").launchQtDesignStudioCheckBox.setChecked(true) } component.loaded.connect(this, Component.prototype.loaded); installer.installationFinished.connect(this, Component.prototype.installationFinishedPageIsShown); installer.finishButtonClicked.connect(this, Component.prototype.installationFinished); installer.valueChanged.connect(this, Component.prototype.reactOnTargetDirChange); if (installer.value("os") == "win") { var vcredist_component = "qt.tools.vcredist_msvc2019_x64"; if (installer.componentByName(vcredist_component)) { component.addDependency(vcredist_component); } } // set the default values to SDKToolBinary Component.prototype.reactOnTargetDirChange("TargetDir", installer.value("TargetDir")); if (!isEditionCommercial()) component.addDependency("qt.license.gplv3except"); // add dependency to licenseservice if component is available // add dependency only to commercial online installations if (isEditionCommercial() && !installer.isOfflineOnly()) { if (installer.componentByName("tools.licenseservice")) component.addDependency("tools.licenseservice"); } } Component.prototype.loaded = function() { try { if (installer.isOfflineOnly()) { if (installer.value("os") == "win" && installer.isInstaller()) { var ifwVersion = installer.value("FrameworkVersion"); if (installer.versionMatches(ifwVersion, "<4.9.0")) installer.addWizardPageItem(component, "AssociateCommonFiletypesForm", QInstaller.TargetDirectory); else installer.addWizardPageItem(component, "AssociateCommonFiletypesForm", QInstaller.ReadyForInstallation); } } } catch(e) { print(e); } } Component.prototype.beginInstallation = function() { if (installer.value("os") === "win") component.addStopProcessForUpdateRequest(component.qtDesignStudioBinaryPath); } Component.prototype.reactOnTargetDirChange = function(key, value) { if (key == "TargetDir") { if (installer.value("os") == "win") { // TODO: rename if binary name changed component.qtDesignStudioBinaryPath = value + "\\/Tools/QtDesignStudio\\bin\\qtdesignstudio.exe"; component.qtDesignStudioBinaryPath = component.qtDesignStudioBinaryPath.replace(/\//g, "\\"); component.sdktoolBinaryPath = value + "\\/Tools/QtDesignStudio\\bin\\sdktool.exe"; component.sdktoolBinaryPath = component.sdktoolBinaryPath.replace(/\//g, "\\"); if (installer.isOfflineOnly()) { component.qtDesignStudioUninstallPath = value + "\\QtDesignStudioUninstaller.exe"; component.qtDesignStudioUninstallPath = component.qtDesignStudioUninstallPath.replace(/\//g, "\\"); } installer.setValue("DesignStudioResourcePath", value + "//Tools/QtDesignStudio/share/qtcreator/"); installer.setValue("DesignStudioResourceRegisterPath", "//Tools/QtDesignStudio/share/qtcreator/"); installer.setValue("DesignStudioDocumentationPath", value + "//Tools/QtDesignStudio/share/doc/qtcreator"); installer.setValue("DesignStudioDocumentationRegisterPath", "//Tools/QtDesignStudio/share/doc/qtcreator"); } else if (installer.value("os") == "mac") { component.qtDesignStudioBinaryPath = value + "/Tools/QtDesignStudio/Qt Design Studio.app/Contents/MacOS/Qt Design Studio"; // fix duplicate forward slashes in path component.qtDesignStudioBinaryPath = component.qtDesignStudioBinaryPath.replace(/\/+/g, "/"); component.sdktoolBinaryPath = value + "/Tools/QtDesignStudio/Tools/sdktool"; installer.setValue("DesignStudioResourcePath", value + "/Tools/QtDesignStudio/Qt Design Studio.app/Contents/Resources/"); installer.setValue("DesignStudioResourceRegisterPath", "/Tools/QtDesignStudio/Qt Design Studio.app/Contents/Resources/"); installer.setValue("DesignStudioDocumentationPath", value + "/Tools/QtDesignStudio/Qt Design Studio.app/Contents/Resources/doc"); installer.setValue("DesignStudioDocumentationRegisterPath", "/Tools/QtDesignStudio/Qt Design Studio.app/Contents/Resources/doc"); } else { component.qtDesignStudioBinaryPath = value + "//Tools/QtDesignStudio/bin/qtdesignstudio"; component.qtDesignStudioBinaryPath = component.qtDesignStudioBinaryPath.replace(/\/+/g, "/"); component.sdktoolBinaryPath = value + "//Tools/QtDesignStudio/bin/sdktool"; installer.setValue("DesignStudioResourcePath", value + "//Tools/QtDesignStudio/share/qtcreator/"); installer.setValue("DesignStudioResourceRegisterPath", "//Tools/QtDesignStudio/share/qtcreator/"); installer.setValue("DesignStudioDocumentationPath", value + "//Tools/QtDesignStudio/share/doc/qtcreator"); installer.setValue("DesignStudioDocumentationRegisterPath", "//Tools/QtDesignStudio/share/doc/qtcreator"); } } } function registerWindowsFileTypeExtensions() { try { component.addOperation("RegisterFileType", "qmlproject", component.qtDesignStudioBinaryPath + " -client \"%1\"", "QML Project file", "text/plain", component.qtDesignStudioBinaryPath + ",7", "ProgId=QtProject.QtDesignStudio.qmlproject"); } catch (e) { console.log(e); } } function registerInQtCreator() { try { // if qtcreator is in the same installer register documentation and examples if (installer.value("QtCreatorInstallerSettingsFile")) { registerQtCreatorDocumentation(component, "@DesignStudioDocumentationRegisterPath@") registerQtCreatorExampleSet(component, "Qt Design Studio", "@DesignStudioDocumentationRegisterPath@", "@DesignStudioResourceRegisterPath@/examples") var settingsFile = installer.value("QtCreatorInstallerSettingsFile"); component.addOperation("Settings", "path=" + settingsFile, "method=set", "key=QML/Designer/DesignStudioInstallation", "value=" + component.qtDesignStudioBinaryPath); } } catch (e) { console.log(e) } } Component.prototype.createOperations = function() { try { // call the base create operations function component.createOperations(); registerInQtCreator(); //since we use bundles, nothing to do for mac here if (installer.value("os") == "mac") return if (installer.value("os") === "win") { var windir = installer.environmentVariable("WINDIR"); if (installer.environmentVariable("WINDIR") == "") { QMessageBox["warning"]( "Error" , qsTranslate("installscript", "Error"), qsTranslate("installscript", "Could not find Windows installation directory")); return; } } if (installer.value("os") == "win") { maintenanceToolPath = installer.value("TargetDir") + "/MaintenanceTool.exe"; } if (installer.value("os") == "x11") { maintenanceToolPath = installer.value("TargetDir") + "/MaintenanceTool"; } var settingsFile = installer.value("DesignStudioResourcePath") + "QtProject/QtDesignStudio.ini"; if (!installer.isOfflineOnly()) { // Configure UpdateInfo plugin component.addOperation("Settings", "path="+settingsFile, "method=set", "key=Updater/MaintenanceTool", "value="+maintenanceToolPath); component.addOperation("Settings", "path="+settingsFile, "method=add_array_value", "key=Plugins/ForceEnabled", "value=UpdateInfo"); } var sdkPath = installer.value("DesignStudioResourcePath") + "/QtProject/qtdesignstudio"; var qt5Path = "@TargetDir@" + "/Tools/QtDesignStudio/qt5_design_studio_reduced_version"; var qmake5Binary = qt5Path + "/bin/qmake"; var qt6Path = "@TargetDir@" + "/Tools/QtDesignStudio/qt6_design_studio_reduced_version"; var qmake6Binary = qt6Path + "/bin/qmake"; if (installer.value("os") == "win" && isEditionCommercial()) { // TODO: we should use qdb from b2qt var qdb = "@TargetDir@" + "/Tools/QtDesignStudio/qdb/bin/qdb.exe"; component.addOperation("Settings", "path="+settingsFile, "method=set", "key=Boot2Qt/qdbFilePath", "value=" + qdb); component.addOperation("Settings", "path="+settingsFile, "method=add_array_value", "key=Plugins/ForceEnabled", "value=Boot2QtQdb"); component.addOperation("Execute", qdb + "", "-v", "UNDOEXECUTE", "{0,1}", qdb + "", "stop-server"); } var abi = "" if (installer.value("os") == "win") { abi = "x86-windows-msvc2019-pe-64bit"; // TODO: Fix QTDS-524 Associate file type checkboxes having too much space // For now hide the issue and register Windows file type extensions // if (component.userInterface("AssociateCommonFiletypesForm").AssociateCommonFiletypesCheckBox.checked) registerWindowsFileTypeExtensions(); component.addOperation("CreateShortcut", component.qtDesignStudioBinaryPath + "", "@StartMenuDir@\\Qt Design Studio.lnk", "workingDirectory=@TargetDir@\\bin", "iconPath=" + component.qtDesignStudioBinaryPath, "iconId=0"); component.addOperation("CreateShortcut", component.qtDesignStudioUninstallPath + "", "@StartMenuDir@\\Uninstall Qt Design Studio.lnk", "workingDirectory=@TargetDir@", "iconPath=" + component.qtDesignStudioUninstallPath, "iconId=0"); sdkPath = sdkPath.replace(/\//g, "\\"); qmake5Binary = qmake5Binary + ".exe"; qmake6Binary = qmake6Binary + ".exe"; } else if (installer.value("os") == "x11") { abi = "x86-linux-generic-elf-64bit"; } // with QtCreator 4.14 it is not possible to select the no compiler option anymore, // so adding a mock compiler and using that one for the kits var toolchain_c_id = "ProjectExplorer.ToolChain.Custom:{9799e31f-e3d0-47cb-8bc1-1d0806d0ed23}"; var toolchain_cpp_id = "ProjectExplorer.ToolChain.Custom:{c702c2f1-69f7-41b6-a4b1-77569d527e28}"; component.addOperation("Execute", [component.sdktoolBinaryPath, "-s", sdkPath, "addTC", "--id", toolchain_c_id + "", "--language", "C", "--name", "mock C compiler", "--abi", abi + "", "--path", "not_existing", "ProjectExplorer.CustomToolChain.TargetAbi", "QString:" + abi, "UNDOEXECUTE", "{0,2}", component.sdktoolBinaryPath + "", "-s", sdkPath + "", "rmTC", "--id", toolchain_c_id + ""] ); component.addOperation("Execute", [component.sdktoolBinaryPath, "-s", sdkPath, "addTC", "--id", toolchain_cpp_id + "", "--language", "Cxx", "--name", "mock C++ compiler", "--abi", abi + "", "--path", "not_existing", "ProjectExplorer.CustomToolChain.TargetAbi", "QString:" + abi, "UNDOEXECUTE", "{0,2}", component.sdktoolBinaryPath + "", "-s", sdkPath + "", "rmTC", "--id", toolchain_cpp_id + ""] ); if (component.archives.toString().includes("qt6_design_studio_reduced_version.7z")) { var qt6_name = component.name + "_qt6"; component.addOperation("Execute", [component.sdktoolBinaryPath + "", "-s", sdkPath, "addQt", "--id", qt6_name + "", "--name", "Designer specialized Qt %{Qt:Version}", "--type", "Qt4ProjectManager.QtVersion.Desktop", "--qmake", qmake6Binary + "", "overrideFeatures", "QString:QtStudio", "UNDOEXECUTE", "{0,2}", component.sdktoolBinaryPath + "", "-s", sdkPath + "", "rmQt", "--id", qt6_name + ""] ); // first kit will be the default one var desktopKitName = "{63f87550-2541-4163-9631-08b7fea781da}"; component.addOperation("Execute", [component.sdktoolBinaryPath + "", "-s", sdkPath + "", "addKit", "--id", desktopKitName + "", "--name", "Desktop Qt %{Qt:Version}", "--devicetype", "Desktop", "--qt", qt6_name + "", "--Ctoolchain", toolchain_c_id + "", "--Cxxtoolchain", toolchain_cpp_id + "", "UNDOEXECUTE", "{0,2}", component.sdktoolBinaryPath + "", "-s", sdkPath + "", "rmKit", "--id", desktopKitName + ""] ); // qdb does not exist for mac so we only register it at linux and windows if (installer.value("os") != "mac" && isEditionCommercial()) { var boot2QtKitName = "{56ba0f6c-7274-447b-b1f5-38a7aa5db139}"; component.addOperation("Execute", [component.sdktoolBinaryPath + "", "-s", sdkPath, "addKit", "--id", boot2QtKitName + "", "--name", "Boot2Qt device", "--devicetype", "QdbLinuxOsType", "--qt", qt6_name + "", "--Ctoolchain", toolchain_c_id + "", "--Cxxtoolchain", toolchain_cpp_id + "", "UNDOEXECUTE", "{0,2}", component.sdktoolBinaryPath + "", "-s", sdkPath + "", "rmKit", "--id", boot2QtKitName + ""] ); } var androidKitName = "{fcfcb7a6-2c80-4785-b1a9-02d08953be61}"; component.addOperation("Execute", [component.sdktoolBinaryPath + "", "-s", sdkPath, "addKit", "--id", androidKitName + "", "--name", "Android device", //"--device", "Android Device:QtAVD", "--devicetype", "Android.Device.Type", "--qt", qt6_name + "", "--Ctoolchain", toolchain_c_id + "", "--Cxxtoolchain", toolchain_cpp_id + "", "UNDOEXECUTE", "{0,2}", component.sdktoolBinaryPath + "", "-s", sdkPath + "", "rmKit", "--id", androidKitName + ""] ); } // if component.archives.toString().includes("qt6_design_studio_reduced_version.7z") if (component.archives.toString().includes("qt5_design_studio_reduced_version.7z")) { var qt5_name = component.name + "_qt5"; component.addOperation("Execute", [component.sdktoolBinaryPath + "", "-s", sdkPath, "addQt", "--id", qt5_name + "", "--name", "Designer specialized Qt %{Qt:Version}", "--type", "Qt4ProjectManager.QtVersion.Desktop", "--qmake", qmake5Binary + "", "overrideFeatures", "QString:QtStudio", "UNDOEXECUTE", "{0,2}", component.sdktoolBinaryPath + "", "-s", sdkPath + "", "rmQt", "--id", qt5_name + ""] ); var desktopKitName = "{8994bd34-5ed9-4c45-8c0a-94c8f33eca4a}"; component.addOperation("Execute", [component.sdktoolBinaryPath + "", "-s", sdkPath + "", "addKit", "--id", desktopKitName + "", "--name", "Desktop Qt %{Qt:Version}", "--devicetype", "Desktop", "--qt", qt5_name + "", "--Ctoolchain", toolchain_c_id + "", "--Cxxtoolchain", toolchain_cpp_id + "", "UNDOEXECUTE", "{0,2}", component.sdktoolBinaryPath + "", "-s", sdkPath + "", "rmKit", "--id", desktopKitName + ""] ); } // if component.archives.toString().includes("qt5_design_studio_reduced_version.7z") if (!installer.isOfflineOnly()) { // if /Tools/QtDesignStudio is defined to be '/' SimpleMoveFile fails if ("/Tools/QtDesignStudio" != "/") { // move README.txt file from install root to preview folder var readme_file_location = "@TargetDir@" + "/README.txt"; var readme_file_new_location = "@TargetDir@" + "/Tools/QtDesignStudio/README.txt"; component.addOperation("SimpleMoveFile", readme_file_location + "", readme_file_new_location + "") } } } catch (e) { console.log(e); } } function isRoot() { if (installer.value("os") == "x11" || installer.value("os") == "mac") { var id = installer.execute("/usr/bin/id", new Array("-u"))[0]; id = id.replace(/(\r\n|\n|\r)/gm,""); if (id === "0") { return true; } } return false; } isEditionCommercial = function() { var isOpenSource = "false"; // check if OPENSOURCE flag is set to 'false' or not defined if (['false', 'no', '0', "", null].indexOf(isOpenSource) >= 0) return true return false } addDependency = function(newDependency) { var dependencies = component.value("Dependencies"); if (dependencies) { component.setValue("Dependencies", dependencies + "," + newDependency) } else { component.setValue("Dependencies", newDependency) } } Component.prototype.installationFinishedPageIsShown = function() { // newer macos versions do a malewarecheck on new binaries, that takes up to 5 seconds, with calling the puppets here // we avoid the wait time when we start QtDesignStudio the first time if (installer.value("os") == "mac") { var qt6_qmlpuppet_path = installer.value("TargetDir") + "//Tools/QtDesignStudio/qt6_design_studio_reduced_version/bin/qmlpuppet-" + "4.7.1"; if (installer.fileExists(qt6_qmlpuppet_path)) installer.executeDetached(qt6_qmlpuppet_path, new Array(), "@homeDir@"); else print("qt6_qmlpuppet_path does not exist: " + qt6_qmlpuppet_path); } isroot = isRoot(); try { if (component.installed && installer.isInstaller() && installer.status == QInstaller.Success && !isroot) { // FIX ME: splash screen causes issues on macOS with QtDS and QtC starting simultaneously // after online installation. Hide check box from macOS (checkbox selection false for other hosts) if (installer.isOfflineOnly() || installer.value("os") != "mac") { installer.addWizardPageItem( component, "LaunchQtDesignStudioCheckBoxForm", QInstaller.InstallationFinished ); } installer.addWizardPageItem( component, "ReadmeCheckBoxForm", QInstaller.InstallationFinished ); } } catch(e) { print(e); } } Component.prototype.installationFinished = function() { try { if (component.installed && installer.isInstaller() && installer.status == QInstaller.Success && !isroot && !installer.isCommandLineInstance()) { var isLaunchQtDesignStudioBoxChecked = component.userInterface("LaunchQtDesignStudioCheckBoxForm").launchQtDesignStudioCheckBox.checked; if (isLaunchQtDesignStudioBoxChecked) { if (installer.value("os") == "mac") { // Start via open so that we run with the native architecture app_bundle_path = component.qtDesignStudioBinaryPath; app_bundle_path = app_bundle_path.replace("/Contents/MacOS/Qt Design Studio", ""); installer.executeDetached("/usr/bin/open", new Array(app_bundle_path), "@homeDir@"); } else { installer.executeDetached(component.qtDesignStudioBinaryPath, new Array(), "@homeDir@"); } } var isDemoVideoCheckBoxChecked = component.userInterface("ReadmeCheckBoxForm").checkBox.checked; if (isDemoVideoCheckBoxChecked) QDesktopServices.openUrl(installer.value("TargetDir") + "/Tools/QtDesignStudio/README.txt"); } } catch(e) { print(e); } }