From 67dcd900584cd56f9ac0f97b2321379efbca16d9 Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Sun, 8 Oct 2023 20:01:17 -0400 Subject: [PATCH] Overhaul initial setup flow, again This improves the flow drastically, first by porting it from MobileForm to FormCard. Next, it fixes some of the annoying bugs such as the profile not switching properly when adding a new profile. Selecting an existing game path is now possible, and it's less likely you can enter in invalid account credentials. The overall look and behavior of some of the pages is improved. --- launcher/CMakeLists.txt | 10 ++ launcher/include/accountmanager.h | 2 + launcher/include/profilemanager.h | 2 + launcher/src/accountmanager.cpp | 5 + launcher/src/launchercore.cpp | 2 +- launcher/src/profile.cpp | 4 +- launcher/src/profilemanager.cpp | 13 +- launcher/ui/Components/FormFileDelegate.qml | 4 +- launcher/ui/Settings/GeneralSettings.qml | 1 - launcher/ui/Setup/AccountSetup.qml | 110 +++++++------ launcher/ui/Setup/AddSapphire.qml | 81 +++++----- launcher/ui/Setup/AddSquareEnix.qml | 103 ++++++------ launcher/ui/Setup/DownloadSetup.qml | 48 +++--- launcher/ui/Setup/ExistingSetup.qml | 55 +++++-- launcher/ui/Setup/InstallProgress.qml | 1 - launcher/ui/Setup/SetupPage.qml | 164 +++++++++++--------- 16 files changed, 344 insertions(+), 261 deletions(-) diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 8b34ca4..8d5d6e4 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -109,6 +109,16 @@ qt_target_qml_sources(astra ui/Main.qml ) +set_source_files_properties(../zone.xiv.astra.svg PROPERTIES + QT_RESOURCE_ALIAS /zone.xiv.astra.svg +) + +qt_target_qml_sources(astra + PREFIX / + RESOURCES + ../zone.xiv.astra.svg +) + kconfig_add_kcfg_files(astra GENERATE_MOC config.kcfgc accountconfig.kcfgc profileconfig.kcfgc) target_include_directories(astra PRIVATE include ${CMAKE_BINARY_DIR}) target_link_libraries(astra PRIVATE diff --git a/launcher/include/accountmanager.h b/launcher/include/accountmanager.h index 2a8889c..8be1502 100644 --- a/launcher/include/accountmanager.h +++ b/launcher/include/accountmanager.h @@ -37,6 +37,8 @@ public: Q_INVOKABLE bool canDelete(Account *account) const; Q_INVOKABLE void deleteAccount(Account *account); + Q_INVOKABLE bool hasAnyAccounts() const; + private: void insertAccount(Account *account); diff --git a/launcher/include/profilemanager.h b/launcher/include/profilemanager.h index e9b435e..dfd5208 100644 --- a/launcher/include/profilemanager.h +++ b/launcher/include/profilemanager.h @@ -40,6 +40,8 @@ public: Q_INVOKABLE bool canDelete(Profile *account) const; + Q_INVOKABLE bool hasAnyExistingInstallations() const; + static QString getDefaultGamePath(const QString &uuid); static QString getDefaultWinePrefixPath(const QString &uuid); diff --git a/launcher/src/accountmanager.cpp b/launcher/src/accountmanager.cpp index fa7d160..7428887 100644 --- a/launcher/src/accountmanager.cpp +++ b/launcher/src/accountmanager.cpp @@ -111,3 +111,8 @@ void AccountManager::insertAccount(Account *account) m_accounts.append(account); endInsertRows(); } + +bool AccountManager::hasAnyAccounts() const +{ + return !m_accounts.empty(); +} diff --git a/launcher/src/launchercore.cpp b/launcher/src/launchercore.cpp index 9ab02e1..da67a63 100755 --- a/launcher/src/launchercore.cpp +++ b/launcher/src/launchercore.cpp @@ -794,7 +794,7 @@ void LauncherCore::setCurrentProfile(Profile *profile) { Q_ASSERT(profile != nullptr); - const int newIndex = m_profileManager->getProfileIndex(profile->name()); + const int newIndex = m_profileManager->getProfileIndex(profile->uuid()); if (newIndex != m_currentProfileIndex) { m_currentProfileIndex = newIndex; Q_EMIT currentProfileChanged(); diff --git a/launcher/src/profile.cpp b/launcher/src/profile.cpp index 0b90a07..8db4c6a 100644 --- a/launcher/src/profile.cpp +++ b/launcher/src/profile.cpp @@ -510,13 +510,13 @@ QString Profile::bootVersion() const QString Profile::baseGameVersion() const { - Q_ASSERT(m_repositories.repositories_count > 1); + Q_ASSERT(m_repositories.repositories_count >= 1); return m_repositories.repositories[0].version; } int Profile::numInstalledExpansions() const { - Q_ASSERT(m_repositories.repositories_count > 1); + Q_ASSERT(m_repositories.repositories_count >= 1); return m_repositories.repositories_count - 1; } diff --git a/launcher/src/profilemanager.cpp b/launcher/src/profilemanager.cpp index 26f704e..e505455 100644 --- a/launcher/src/profilemanager.cpp +++ b/launcher/src/profilemanager.cpp @@ -22,7 +22,7 @@ Profile *ProfileManager::getProfile(const int index) int ProfileManager::getProfileIndex(const QString &name) { for (int i = 0; i < m_profiles.size(); i++) { - if (m_profiles[i]->name() == name) + if (m_profiles[i]->uuid() == name) return i; } @@ -147,3 +147,14 @@ bool ProfileManager::canDelete(Profile *account) const Q_UNUSED(account) return m_profiles.size() != 1; } + +bool ProfileManager::hasAnyExistingInstallations() const +{ + for (auto &profile : m_profiles) { + if (profile->isGameInstalled()) { + return true; + } + } + + return false; +} diff --git a/launcher/ui/Components/FormFileDelegate.qml b/launcher/ui/Components/FormFileDelegate.qml index cf4f626..57b2395 100644 --- a/launcher/ui/Components/FormFileDelegate.qml +++ b/launcher/ui/Components/FormFileDelegate.qml @@ -4,9 +4,9 @@ import QtCore import QtQuick.Dialogs -import org.kde.kirigamiaddons.labs.mobileform as MobileForm +import org.kde.kirigamiaddons.formcard as FormCard -MobileForm.FormButtonDelegate { +FormCard.FormButtonDelegate { id: control property string file diff --git a/launcher/ui/Settings/GeneralSettings.qml b/launcher/ui/Settings/GeneralSettings.qml index df56732..7fe3d53 100644 --- a/launcher/ui/Settings/GeneralSettings.qml +++ b/launcher/ui/Settings/GeneralSettings.qml @@ -88,7 +88,6 @@ FormCard.FormCardPage { } } - FormCard.FormCard { Layout.topMargin: Kirigami.Units.largeSpacing Layout.fillWidth: true diff --git a/launcher/ui/Setup/AccountSetup.qml b/launcher/ui/Setup/AccountSetup.qml index 3840484..a6c3c91 100644 --- a/launcher/ui/Setup/AccountSetup.qml +++ b/launcher/ui/Setup/AccountSetup.qml @@ -5,75 +5,91 @@ import QtQuick import QtQuick.Layouts import org.kde.kirigami as Kirigami -import org.kde.kirigamiaddons.labs.mobileform as MobileForm +import org.kde.kirigamiaddons.formcard as FormCard import zone.xiv.astra -Kirigami.Page { +FormCard.FormCardPage { id: page property var profile title: i18n("Account Setup") - ColumnLayout { - width: parent.width - MobileForm.FormCard { - Layout.topMargin: Kirigami.Units.largeSpacing - Layout.fillWidth: true - contentItem: ColumnLayout { - spacing: 0 + FormCard.FormCard { + Layout.topMargin: Kirigami.Units.largeSpacing + Layout.fillWidth: true - MobileForm.FormCardHeader { - title: i18n("Accounts") - } + FormCard.FormTextDelegate { + id: helpTextDelegate - MobileForm.FormTextDelegate { - text: i18n("Select an account below to use for profile '%1'.", LauncherCore.currentProfile.name) - } + text: i18n("Select an account to use for '%1'", LauncherCore.currentProfile.name) + } + } - Repeater { - model: LauncherCore.accountManager + FormCard.FormHeader { + title: i18n("Existing Accounts") + visible: LauncherCore.accountManager.hasAnyAccounts() + } - MobileForm.FormButtonDelegate { - required property var account + FormCard.FormCard { + visible: LauncherCore.accountManager.hasAnyAccounts() - text: account.name + Layout.fillWidth: true - onClicked: { - page.profile.account = account - applicationWindow().checkSetup() - } - } - } - } + FormCard.FormTextDelegate { + id: existingHelpDelegate + + text: i18n("You can select an existing account.") } - MobileForm.FormCard { - Layout.topMargin: Kirigami.Units.largeSpacing - Layout.fillWidth: true - contentItem: ColumnLayout { - spacing: 0 + FormCard.FormDelegateSeparator { + above: existingHelpDelegate + } - MobileForm.FormButtonDelegate { - text: i18n("Add Square Enix Account") - icon.name: "list-add-symbolic" - onClicked: pageStack.layers.push(Qt.createComponent("zone.xiv.astra", "AddSquareEnix"), { - profile: page.profile - }) - } + Repeater { + model: LauncherCore.accountManager - MobileForm.FormDelegateSeparator { - } + FormCard.FormButtonDelegate { + required property var account - MobileForm.FormButtonDelegate { - text: i18n("Add Sapphire Account") - icon.name: "list-add-symbolic" - onClicked: pageStack.layers.push(Qt.createComponent("zone.xiv.astra", "AddSapphire"), { - profile: page.profile - }) + text: account.name + + onClicked: { + page.profile.account = account + applicationWindow().checkSetup() } } } } + + FormCard.FormCard { + Layout.topMargin: Kirigami.Units.largeSpacing + Layout.fillWidth: true + + FormCard.FormButtonDelegate { + id: addSquareEnixButton + + text: i18n("Add Square Enix Account") + icon.name: "list-add-symbolic" + onClicked: pageStack.layers.push(Qt.createComponent("zone.xiv.astra", "AddSquareEnix"), { + profile: page.profile + }) + } + + FormCard.FormDelegateSeparator { + above: addSquareEnixButton + below: addSapphireButton + } + + FormCard.FormButtonDelegate { + id: addSapphireButton + + text: i18n("Add Sapphire Account") + icon.name: "list-add-symbolic" + onClicked: pageStack.layers.push(Qt.createComponent("zone.xiv.astra", "AddSapphire"), { + profile: page.profile + }) + } + } } \ No newline at end of file diff --git a/launcher/ui/Setup/AddSapphire.qml b/launcher/ui/Setup/AddSapphire.qml index 182e4e6..b35d8ce 100644 --- a/launcher/ui/Setup/AddSapphire.qml +++ b/launcher/ui/Setup/AddSapphire.qml @@ -6,60 +6,65 @@ import QtQuick.Layouts import QtQuick.Window import org.kde.kirigami as Kirigami -import org.kde.kirigamiaddons.labs.mobileform as MobileForm +import org.kde.kirigamiaddons.formcard as FormCard import zone.xiv.astra -Kirigami.Page { +FormCard.FormCardPage { id: page property var profile title: i18n("Add Sapphire Account") - ColumnLayout { - width: parent.width - MobileForm.FormCard { - Layout.topMargin: Kirigami.Units.largeSpacing - Layout.fillWidth: true - contentItem: ColumnLayout { - spacing: 0 + readonly property bool isValid: usernameField.text.length !== 0 && lobbyUrlField.text.length !== 0 - MobileForm.FormTextDelegate { - description: i18n("Passwords will be entered on the login page. The username will be associated with this profile but can be changed later.") - } + FormCard.FormCard { + Layout.topMargin: Kirigami.Units.largeSpacing + Layout.fillWidth: true - MobileForm.FormDelegateSeparator { - } + FormCard.FormTextDelegate { + id: helpTextDelegate + description: i18n("The password will be entered on the login page. A username will be associated with this account but can always be changed later.") + } - MobileForm.FormTextFieldDelegate { - id: lobbyUrlField - label: i18n("Lobby URL") - } + FormCard.FormDelegateSeparator { + above: helpTextDelegate + below: usernameField + } - MobileForm.FormDelegateSeparator { - } + FormCard.FormTextFieldDelegate { + id: usernameField + label: i18n("Username") + } - MobileForm.FormTextFieldDelegate { - id: usernameField - label: i18n("Username") - } + FormCard.FormDelegateSeparator { + above: usernameField + below: lobbyUrlField + } - MobileForm.FormDelegateSeparator { - } + FormCard.FormTextFieldDelegate { + id: lobbyUrlField + label: i18n("Lobby URL") + } - MobileForm.FormButtonDelegate { - text: i18n("Add Account") - icon.name: "list-add-symbolic" - onClicked: { - let account = LauncherCore.accountManager.createSapphireAccount(lobbyUrlField.text, usernameField.text) - if (page.profile) { - page.profile.account = account - applicationWindow().checkSetup() - } else { - page.Window.window.pageStack.layers.pop() - } - } + FormCard.FormDelegateSeparator { + above: lobbyUrlField + below: buttonDelegate + } + + FormCard.FormButtonDelegate { + id: buttonDelegate + text: i18n("Add Account") + icon.name: "list-add-symbolic" + enabled: page.isValid + onClicked: { + let account = LauncherCore.accountManager.createSapphireAccount(lobbyUrlField.text, usernameField.text) + if (page.profile) { + page.profile.account = account + applicationWindow().checkSetup() + } else { + page.Window.window.pageStack.layers.pop() } } } diff --git a/launcher/ui/Setup/AddSquareEnix.qml b/launcher/ui/Setup/AddSquareEnix.qml index 38c199d..709e0d0 100644 --- a/launcher/ui/Setup/AddSquareEnix.qml +++ b/launcher/ui/Setup/AddSquareEnix.qml @@ -6,72 +6,79 @@ import QtQuick.Layouts import QtQuick.Window import org.kde.kirigami as Kirigami -import org.kde.kirigamiaddons.labs.mobileform as MobileForm +import org.kde.kirigamiaddons.formcard as FormCard import zone.xiv.astra -Kirigami.Page { +FormCard.FormCardPage { id: page property var profile title: i18n("Add Square Enix Account") - ColumnLayout { - width: parent.width - MobileForm.FormCard { - Layout.topMargin: Kirigami.Units.largeSpacing - Layout.fillWidth: true - contentItem: ColumnLayout { - spacing: 0 + readonly property bool isValid: usernameField.text.length !== 0 - MobileForm.FormTextDelegate { - description: i18n("Passwords will be entered on the login page. The username will be associated with this profile but can be changed later.") - } + FormCard.FormCard { + Layout.topMargin: Kirigami.Units.largeSpacing + Layout.fillWidth: true - MobileForm.FormDelegateSeparator { - } + FormCard.FormTextDelegate { + id: helpTextDelegate + description: i18n("The password will be entered on the login page. A username will be associated with this account but can always be changed later.") + } - MobileForm.FormTextFieldDelegate { - id: usernameField - label: i18n("Username") - } + FormCard.FormDelegateSeparator { + above: helpTextDelegate + below: usernameField + } - MobileForm.FormDelegateSeparator { - } + FormCard.FormTextFieldDelegate { + id: usernameField + label: i18n("Username") + } - MobileForm.FormComboBoxDelegate { - id: licenseField - text: i18n("License") - description: i18n("If the account holds multiple licenses, choose the preferred one.") - model: ["Windows", "Steam", "macOS"] - currentIndex: 0 - } + FormCard.FormDelegateSeparator { + above: usernameField + below: licenseField + } - MobileForm.FormDelegateSeparator { - } + FormCard.FormComboBoxDelegate { + id: licenseField + text: i18n("License") + description: i18n("If the account holds multiple licenses, choose the preferred one.") + model: ["Windows", "Steam", "macOS"] + currentIndex: 0 + } - MobileForm.FormCheckDelegate { - id: freeTrialField - text: i18n("Free Trial") - description: i18n("Check if the account is currently on free trial.") - } + FormCard.FormDelegateSeparator { + above: licenseField + below: freeTrialField + } - MobileForm.FormDelegateSeparator { - } + FormCard.FormCheckDelegate { + id: freeTrialField + text: i18n("Free Trial") + description: i18n("Check if the account is currently on free trial.") + } - MobileForm.FormButtonDelegate { - text: i18n("Add Account") - icon.name: "list-add-symbolic" - onClicked: { - let account = LauncherCore.accountManager.createSquareEnixAccount(usernameField.text, licenseField.currentIndex, freeTrialField.checkState === Qt.Checked) - if (page.profile) { - page.profile.account = account - applicationWindow().checkSetup() - } else { - page.Window.window.pageStack.layers.pop() - } - } + FormCard.FormDelegateSeparator { + above: freeTrialField + below: buttonDelegate + } + + FormCard.FormButtonDelegate { + id: buttonDelegate + text: i18n("Add Account") + icon.name: "list-add-symbolic" + enabled: page.isValid + onClicked: { + let account = LauncherCore.accountManager.createSquareEnixAccount(usernameField.text, licenseField.currentIndex, freeTrialField.checkState === Qt.Checked) + if (page.profile) { + page.profile.account = account + applicationWindow().checkSetup() + } else { + page.Window.window.pageStack.layers.pop() } } } diff --git a/launcher/ui/Setup/DownloadSetup.qml b/launcher/ui/Setup/DownloadSetup.qml index a14b6b6..e54b83f 100644 --- a/launcher/ui/Setup/DownloadSetup.qml +++ b/launcher/ui/Setup/DownloadSetup.qml @@ -5,45 +5,41 @@ import QtQuick import QtQuick.Layouts import org.kde.kirigami as Kirigami -import org.kde.kirigamiaddons.labs.mobileform as MobileForm +import org.kde.kirigamiaddons.formcard as FormCard import zone.xiv.astra -Kirigami.Page { +FormCard.FormCardPage { id: page property var profile title: i18n("Download Game") - ColumnLayout { - width: parent.width - MobileForm.FormCard { - Layout.topMargin: Kirigami.Units.largeSpacing - Layout.fillWidth: true - contentItem: ColumnLayout { - spacing: 0 + FormCard.FormCard { + Layout.topMargin: Kirigami.Units.largeSpacing + Layout.fillWidth: true - MobileForm.FormCardHeader { - title: i18n("Download Game") - } + FormCard.FormTextDelegate { + id: helpTextDelegate - MobileForm.FormTextDelegate { - text: i18n("Press the button below to download and setup the game.") - description: i18n("This is for the base files required for start-up, only when logged in will Astra begin downloading the full game.") - } + text: i18n("Press the button below to download and setup the game.") + description: i18n("This only installs the base files required for the initial update. Astra can only download patches with a legitimate Square Enix account.") + } - MobileForm.FormDelegateSeparator { - } + FormCard.FormDelegateSeparator { + above: helpTextDelegate + below: buttonDelegate + } - MobileForm.FormButtonDelegate { - text: i18n("Begin installation") - icon.name: "cloud-download" - onClicked: pageStack.layers.push(Qt.createComponent("zone.xiv.astra", "InstallProgress"), { - gameInstaller: LauncherCore.createInstaller(page.profile) - }) - } - } + FormCard.FormButtonDelegate { + id: buttonDelegate + + text: i18n("Begin installation") + icon.name: "cloud-download" + onClicked: pageStack.layers.push(Qt.createComponent("zone.xiv.astra", "InstallProgress"), { + gameInstaller: LauncherCore.createInstaller(page.profile) + }) } } } \ No newline at end of file diff --git a/launcher/ui/Setup/ExistingSetup.qml b/launcher/ui/Setup/ExistingSetup.qml index 61f5b2e..dfa65c8 100644 --- a/launcher/ui/Setup/ExistingSetup.qml +++ b/launcher/ui/Setup/ExistingSetup.qml @@ -3,31 +3,52 @@ import QtQuick import QtQuick.Layouts +import QtQuick.Dialogs import org.kde.kirigami as Kirigami -import org.kde.kirigamiaddons.labs.mobileform as MobileForm +import org.kde.kirigamiaddons.formcard as FormCard import zone.xiv.astra -Kirigami.Page { - title: i18n("Find Game Installation") +import "../Components" - ColumnLayout { - width: parent.width - MobileForm.FormCard { - Layout.topMargin: Kirigami.Units.largeSpacing - Layout.fillWidth: true - contentItem: ColumnLayout { - spacing: 0 +FormCard.FormCardPage { + id: page - MobileForm.FormCardHeader { - title: i18n("Find an existing installation") - } + property var profile - MobileForm.FormTextDelegate { - text: i18n("Please select the path to your existing installation.") - } - } + title: i18n("Find Existing Installation") + + FormCard.FormCard { + Layout.topMargin: Kirigami.Units.largeSpacing + Layout.fillWidth: true + + FormCard.FormTextDelegate { + id: helpTextDelegate + + text: i18n("Please select the path to your existing installation.") + } + + FormCard.FormDelegateSeparator { + above: helpTextDelegate + below: selectDelegate + } + + FormCard.FormButtonDelegate { + id: selectDelegate + + text: i18n("Select Existing Path") + icon.name: "document-open-folder" + onClicked: dialog.open() + } + } + + data: FolderDialog { + id: dialog + + onAccepted: { + page.profile.gamePath = decodeURIComponent(selectedFolder.toString().replace("file://", "")); + applicationWindow().checkSetup(); } } } \ No newline at end of file diff --git a/launcher/ui/Setup/InstallProgress.qml b/launcher/ui/Setup/InstallProgress.qml index 72345be..ddb0d7e 100644 --- a/launcher/ui/Setup/InstallProgress.qml +++ b/launcher/ui/Setup/InstallProgress.qml @@ -5,7 +5,6 @@ import QtQuick import QtQuick.Layouts import org.kde.kirigami as Kirigami -import org.kde.kirigamiaddons.labs.mobileform as MobileForm import zone.xiv.astra diff --git a/launcher/ui/Setup/SetupPage.qml b/launcher/ui/Setup/SetupPage.qml index 74e3b62..ff1ca5a 100644 --- a/launcher/ui/Setup/SetupPage.qml +++ b/launcher/ui/Setup/SetupPage.qml @@ -5,97 +5,107 @@ import QtQuick import QtQuick.Layouts import org.kde.kirigami as Kirigami -import org.kde.kirigamiaddons.labs.mobileform as MobileForm +import org.kde.kirigamiaddons.formcard as FormCard import zone.xiv.astra -Kirigami.Page { +FormCard.FormCardPage { id: page property var profile + readonly property bool isInitialSetup: !LauncherCore.profileManager.hasAnyExistingInstallations() - title: i18n("Game Setup") + title: isInitialSetup ? i18n("Initial Setup") : i18n("Profile Setup") - ColumnLayout { - width: parent.width - MobileForm.FormCard { - Layout.topMargin: Kirigami.Units.largeSpacing - Layout.fillWidth: true - contentItem: ColumnLayout { - spacing: 0 + Image { + source: "qrc:/zone.xiv.astra.svg" - MobileForm.FormCardHeader { - title: i18n("Welcome to Astra") - } + fillMode: Image.PreserveAspectFit - MobileForm.FormTextDelegate { - text: i18n("The profile '%1' must be set up before first.", LauncherCore.currentProfile.name) - } + Layout.fillWidth: true + Layout.fillHeight: true + Layout.margins: Kirigami.Units.largeSpacing * 3 + } - MobileForm.FormTextDelegate { - text: i18n("A copy of the game must be located or installed.") - description: i18n("A valid game account will be required at the end of installation.") - } - } - } + FormCard.FormCard { + Layout.fillWidth: true - MobileForm.FormCard { - Layout.topMargin: Kirigami.Units.largeSpacing - Layout.fillWidth: true - contentItem: ColumnLayout { - spacing: 0 - - MobileForm.FormCardHeader { - title: i18n("Existing Installations") - } - - MobileForm.FormTextDelegate { - text: i18n("Select an existing installation from another profile below.") - } - - Repeater { - model: LauncherCore.profileManager - - MobileForm.FormButtonDelegate { - required property var profile - - text: profile.name - description: profile.gamePath - - onClicked: { - LauncherCore.currentProfile.gamePath = profile.gamePath; - applicationWindow().checkSetup(); - } - } - } - } - } - - MobileForm.FormCard { - Layout.topMargin: Kirigami.Units.largeSpacing - Layout.fillWidth: true - contentItem: ColumnLayout { - spacing: 0 - - MobileForm.FormButtonDelegate { - text: i18n("Find Existing Installation") - icon.name: "edit-find" - onClicked: pageStack.layers.push(Qt.createComponent("zone.xiv.astra", "ExistingSetup"), { - profile: page.profile - }) - } - - MobileForm.FormDelegateSeparator { - } - - MobileForm.FormButtonDelegate { - text: i18n("Download Game") - icon.name: "cloud-download" - onClicked: pageStack.layers.push(Qt.createComponent("zone.xiv.astra", "DownloadSetup"), { - profile: page.profile - }) + FormCard.FormTextDelegate { + text: { + if (isInitialSetup) { + return i18n("You must have a legitimate installation of the FFXIV to continue."); + } else { + return i18n("You must select a legitimate installation of FFXIV for '%1'", page.profile.name); } } } } + + FormCard.FormHeader { + title: i18n("Existing Installations") + visible: LauncherCore.profileManager.hasAnyExistingInstallations() + } + + FormCard.FormCard { + visible: LauncherCore.profileManager.hasAnyExistingInstallations() + + Layout.fillWidth: true + + FormCard.FormTextDelegate { + id: existingHelpDelegate + + text: i18n("You can select an existing installation from another profile.") + } + + FormCard.FormDelegateSeparator { + above: existingHelpDelegate + } + + Repeater { + model: LauncherCore.profileManager + + FormCard.FormButtonDelegate { + required property var profile + + text: profile.name + description: profile.gamePath + visible: profile.isGameInstalled + + onClicked: { + LauncherCore.currentProfile.gamePath = profile.gamePath; + applicationWindow().checkSetup(); + } + } + } + } + + FormCard.FormCard { + Layout.topMargin: Kirigami.Units.largeSpacing + Layout.fillWidth: true + + FormCard.FormButtonDelegate { + id: findExistingDelegate + + text: i18n("Find Existing Installation") + icon.name: "edit-find" + onClicked: pageStack.layers.push(Qt.createComponent("zone.xiv.astra", "ExistingSetup"), { + profile: page.profile + }) + } + + FormCard.FormDelegateSeparator { + above: findExistingDelegate + below: downloadDelegate + } + + FormCard.FormButtonDelegate { + id: downloadDelegate + + text: i18n("Download Game") + icon.name: "cloud-download" + onClicked: pageStack.layers.push(Qt.createComponent("zone.xiv.astra", "DownloadSetup"), { + profile: page.profile + }) + } + } } \ No newline at end of file