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