diff options
Diffstat (limited to 'launcher/ui/pages')
-rw-r--r-- | launcher/ui/pages/global/APIPage.ui | 4 | ||||
-rw-r--r-- | launcher/ui/pages/global/AccountListPage.ui | 18 | ||||
-rw-r--r-- | launcher/ui/pages/global/ExternalToolsPage.ui | 8 | ||||
-rw-r--r-- | launcher/ui/pages/global/JavaPage.ui | 16 | ||||
-rw-r--r-- | launcher/ui/pages/global/LauncherPage.ui | 18 | ||||
-rw-r--r-- | launcher/ui/pages/global/MinecraftPage.ui | 20 | ||||
-rw-r--r-- | launcher/ui/pages/global/ProxyPage.ui | 10 | ||||
-rw-r--r-- | launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp | 150 | ||||
-rw-r--r-- | launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.h | 50 | ||||
-rw-r--r-- | launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.ui | 16 |
10 files changed, 229 insertions, 81 deletions
diff --git a/launcher/ui/pages/global/APIPage.ui b/launcher/ui/pages/global/APIPage.ui index 7a9088d1..acde9aef 100644 --- a/launcher/ui/pages/global/APIPage.ui +++ b/launcher/ui/pages/global/APIPage.ui @@ -36,7 +36,7 @@ <item> <widget class="QGroupBox" name="groupBox_paste"> <property name="title"> - <string>Pastebin URL</string> + <string>&Pastebin URL</string> </property> <layout class="QVBoxLayout" name="verticalLayout_3"> <item> @@ -98,7 +98,7 @@ <item> <widget class="QGroupBox" name="groupBox_msa"> <property name="title"> - <string>Microsoft Authentication</string> + <string>&Microsoft Authentication</string> </property> <layout class="QVBoxLayout" name="verticalLayout_4"> <item> diff --git a/launcher/ui/pages/global/AccountListPage.ui b/launcher/ui/pages/global/AccountListPage.ui index d21a92e2..469955b5 100644 --- a/launcher/ui/pages/global/AccountListPage.ui +++ b/launcher/ui/pages/global/AccountListPage.ui @@ -65,17 +65,17 @@ </widget> <action name="actionAddMojang"> <property name="text"> - <string>Add Mojang</string> + <string>Add &Mojang</string> </property> </action> <action name="actionRemove"> <property name="text"> - <string>Remove</string> + <string>Remo&ve</string> </property> </action> <action name="actionSetDefault"> <property name="text"> - <string>Set Default</string> + <string>&Set Default</string> </property> </action> <action name="actionNoDefault"> @@ -83,17 +83,17 @@ <bool>true</bool> </property> <property name="text"> - <string>No Default</string> + <string>&No Default</string> </property> </action> <action name="actionUploadSkin"> <property name="text"> - <string>Upload Skin</string> + <string>&Upload Skin</string> </property> </action> <action name="actionDeleteSkin"> <property name="text"> - <string>Delete Skin</string> + <string>&Delete Skin</string> </property> <property name="toolTip"> <string>Delete the currently active skin and go back to the default one</string> @@ -101,17 +101,17 @@ </action> <action name="actionAddMicrosoft"> <property name="text"> - <string>Add Microsoft</string> + <string>&Add Microsoft</string> </property> </action> <action name="actionAddOffline"> <property name="text"> - <string>Add Offline</string> + <string>Add &Offline</string> </property> </action> <action name="actionRefresh"> <property name="text"> - <string>Refresh</string> + <string>&Refresh</string> </property> <property name="toolTip"> <string>Refresh the account tokens</string> diff --git a/launcher/ui/pages/global/ExternalToolsPage.ui b/launcher/ui/pages/global/ExternalToolsPage.ui index e79e9388..8609d469 100644 --- a/launcher/ui/pages/global/ExternalToolsPage.ui +++ b/launcher/ui/pages/global/ExternalToolsPage.ui @@ -36,7 +36,7 @@ <item> <widget class="QGroupBox" name="groupBox_2"> <property name="title"> - <string notr="true">JProfiler</string> + <string notr="true">J&Profiler</string> </property> <layout class="QVBoxLayout" name="verticalLayout_10"> <item> @@ -73,7 +73,7 @@ <item> <widget class="QGroupBox" name="groupBox_3"> <property name="title"> - <string notr="true">JVisualVM</string> + <string notr="true">J&VisualVM</string> </property> <layout class="QVBoxLayout" name="verticalLayout_11"> <item> @@ -110,7 +110,7 @@ <item> <widget class="QGroupBox" name="groupBox_4"> <property name="title"> - <string notr="true">MCEdit</string> + <string notr="true">&MCEdit</string> </property> <layout class="QVBoxLayout" name="verticalLayout_12"> <item> @@ -156,7 +156,7 @@ <item row="0" column="0"> <widget class="QLabel" name="labelJsonEditor"> <property name="text"> - <string>Text Editor:</string> + <string>&Text Editor:</string> </property> </widget> </item> diff --git a/launcher/ui/pages/global/JavaPage.ui b/launcher/ui/pages/global/JavaPage.ui index d27b200f..bb195770 100644 --- a/launcher/ui/pages/global/JavaPage.ui +++ b/launcher/ui/pages/global/JavaPage.ui @@ -70,14 +70,14 @@ <item row="0" column="0"> <widget class="QLabel" name="labelMinMem"> <property name="text"> - <string>Minimum memory allocation:</string> + <string>&Minimum memory allocation:</string> </property> </widget> </item> <item row="1" column="0"> <widget class="QLabel" name="labelMaxMem"> <property name="text"> - <string>Maximum memory allocation:</string> + <string>Ma&ximum memory allocation:</string> </property> </widget> </item> @@ -106,7 +106,7 @@ <item row="2" column="0"> <widget class="QLabel" name="labelPermGen"> <property name="text"> - <string notr="true">PermGen:</string> + <string notr="true">&PermGen:</string> </property> </widget> </item> @@ -150,7 +150,7 @@ </sizepolicy> </property> <property name="text"> - <string>Java path:</string> + <string>&Java path:</string> </property> </widget> </item> @@ -192,7 +192,7 @@ </sizepolicy> </property> <property name="text"> - <string>JVM arguments:</string> + <string>J&VM arguments:</string> </property> </widget> </item> @@ -205,7 +205,7 @@ </sizepolicy> </property> <property name="text"> - <string>Auto-detect...</string> + <string>&Auto-detect...</string> </property> </widget> </item> @@ -218,7 +218,7 @@ </sizepolicy> </property> <property name="text"> - <string>Test</string> + <string>&Test</string> </property> </widget> </item> @@ -234,7 +234,7 @@ <string>If enabled, the launcher will not check if an instance is compatible with the selected Java version.</string> </property> <property name="text"> - <string>Skip Java compatibility checks</string> + <string>&Skip Java compatibility checks</string> </property> </widget> </item> diff --git a/launcher/ui/pages/global/LauncherPage.ui b/launcher/ui/pages/global/LauncherPage.ui index 4cc2a113..086de17b 100644 --- a/launcher/ui/pages/global/LauncherPage.ui +++ b/launcher/ui/pages/global/LauncherPage.ui @@ -196,7 +196,7 @@ <item> <widget class="QRadioButton" name="sortLastLaunchedBtn"> <property name="text"> - <string>By &last launched</string> + <string>&By last launched</string> </property> <attribute name="buttonGroup"> <string notr="true">sortingModeGroup</string> @@ -293,7 +293,7 @@ <item row="1" column="0"> <widget class="QLabel" name="label_4"> <property name="text"> - <string>Colors</string> + <string>&Colors</string> </property> <property name="buddy"> <cstring>themeComboBoxColors</cstring> @@ -334,7 +334,7 @@ <string>The menubar is more friendly for keyboard-driven interaction.</string> </property> <property name="text"> - <string>Replace toolbar with menubar</string> + <string>&Replace toolbar with menubar</string> </property> </widget> </item> @@ -370,21 +370,21 @@ <item> <widget class="QCheckBox" name="showConsoleCheck"> <property name="text"> - <string>Show console while the game is running?</string> + <string>Show console while the game is &running?</string> </property> </widget> </item> <item> <widget class="QCheckBox" name="autoCloseConsoleCheck"> <property name="text"> - <string>Automatically close console when the game quits?</string> + <string>&Automatically close console when the game quits?</string> </property> </widget> </item> <item> <widget class="QCheckBox" name="showConsoleErrorCheck"> <property name="text"> - <string>Show console when the game crashes?</string> + <string>Show console when the game &crashes?</string> </property> </widget> </item> @@ -394,13 +394,13 @@ <item> <widget class="QGroupBox" name="groupBox_4"> <property name="title"> - <string>History limit</string> + <string>&History limit</string> </property> <layout class="QGridLayout" name="gridLayout_3"> <item row="1" column="0"> <widget class="QCheckBox" name="checkStopLogging"> <property name="text"> - <string>Stop logging when log overflows</string> + <string>&Stop logging when log overflows</string> </property> </widget> </item> @@ -441,7 +441,7 @@ </sizepolicy> </property> <property name="title"> - <string>Console font</string> + <string>Console &font</string> </property> <layout class="QGridLayout" name="gridLayout_2"> <item row="1" column="0" colspan="2"> diff --git a/launcher/ui/pages/global/MinecraftPage.ui b/launcher/ui/pages/global/MinecraftPage.ui index c18ab34b..353390bd 100644 --- a/launcher/ui/pages/global/MinecraftPage.ui +++ b/launcher/ui/pages/global/MinecraftPage.ui @@ -51,7 +51,7 @@ <item> <widget class="QCheckBox" name="maximizedCheckBox"> <property name="text"> - <string>Start Minecraft maximized?</string> + <string>Start Minecraft &maximized?</string> </property> </widget> </item> @@ -60,7 +60,7 @@ <item row="1" column="0"> <widget class="QLabel" name="labelWindowHeight"> <property name="text"> - <string>Window hei&ght:</string> + <string>Window &height:</string> </property> <property name="buddy"> <cstring>windowHeightSpinBox</cstring> @@ -70,7 +70,7 @@ <item row="0" column="0"> <widget class="QLabel" name="labelWindowWidth"> <property name="text"> - <string>W&indow width:</string> + <string>Window &width:</string> </property> <property name="buddy"> <cstring>windowWidthSpinBox</cstring> @@ -120,14 +120,14 @@ <item> <widget class="QCheckBox" name="useNativeGLFWCheck"> <property name="text"> - <string>Use system installation of GLFW</string> + <string>Use system installation of &GLFW</string> </property> </widget> </item> <item> <widget class="QCheckBox" name="useNativeOpenALCheck"> <property name="text"> - <string>Use system installation of OpenAL</string> + <string>Use system installation of &OpenAL</string> </property> </widget> </item> @@ -143,21 +143,21 @@ <item> <widget class="QCheckBox" name="showGameTime"> <property name="text"> - <string>Show time spent playing instances</string> + <string>Show time spent &playing instances</string> </property> </widget> </item> <item> <widget class="QCheckBox" name="showGlobalGameTime"> <property name="text"> - <string>Show time spent playing across all instances</string> + <string>Show time spent playing across &all instances</string> </property> </widget> </item> <item> <widget class="QCheckBox" name="recordGameTime"> <property name="text"> - <string>Record time spent playing instances</string> + <string>&Record time spent playing instances</string> </property> </widget> </item> @@ -176,7 +176,7 @@ <string><html><head/><body><p>The launcher will automatically reopen when the game crashes or exits.</p></body></html></string> </property> <property name="text"> - <string>Close the launcher after game window opens</string> + <string>&Close the launcher after game window opens</string> </property> </widget> </item> @@ -186,7 +186,7 @@ <string><html><head/><body><p>The launcher will automatically quit after the game exits or crashes.</p></body></html></string> </property> <property name="text"> - <string>Quit the launcher after game window closes</string> + <string>&Quit the launcher after game window closes</string> </property> </widget> </item> diff --git a/launcher/ui/pages/global/ProxyPage.ui b/launcher/ui/pages/global/ProxyPage.ui index 347fa86c..5a2fc73d 100644 --- a/launcher/ui/pages/global/ProxyPage.ui +++ b/launcher/ui/pages/global/ProxyPage.ui @@ -81,7 +81,7 @@ <item> <widget class="QRadioButton" name="proxySOCKS5Btn"> <property name="text"> - <string>SOC&KS5</string> + <string>&SOCKS5</string> </property> <attribute name="buttonGroup"> <string notr="true">proxyGroup</string> @@ -91,7 +91,7 @@ <item> <widget class="QRadioButton" name="proxyHTTPBtn"> <property name="text"> - <string>H&TTP</string> + <string>&HTTP</string> </property> <attribute name="buttonGroup"> <string notr="true">proxyGroup</string> @@ -104,7 +104,7 @@ <item> <widget class="QGroupBox" name="proxyAddrBox"> <property name="title"> - <string>Address and Port</string> + <string>&Address and Port</string> </property> <layout class="QHBoxLayout" name="horizontalLayout_2"> <item> @@ -145,14 +145,14 @@ <item row="0" column="0"> <widget class="QLabel" name="proxyUsernameLabel"> <property name="text"> - <string>Username:</string> + <string>&Username:</string> </property> </widget> </item> <item row="1" column="0"> <widget class="QLabel" name="proxyPasswordLabel"> <property name="text"> - <string>Password:</string> + <string>&Password:</string> </property> </widget> </item> diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp b/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp index ac3869dc..26aa60af 100644 --- a/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp +++ b/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp @@ -1,30 +1,56 @@ +// SPDX-License-Identifier: GPL-3.0-only /* - * Copyright 2021 Jamie Mansfield <jmansfield@cadixdev.org> + * PolyMC - Minecraft Launcher + * Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org> * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. * - * http://www.apache.org/licenses/LICENSE-2.0 + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * Copyright 2021 Jamie Mansfield <jmansfield@cadixdev.org> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ #include "AtlOptionalModDialog.h" #include "ui_AtlOptionalModDialog.h" +#include <QInputDialog> +#include <QMessageBox> +#include "BuildConfig.h" +#include "Json.h" +#include "modplatform/atlauncher/ATLShareCode.h" +#include "Application.h" + AtlOptionalModListModel::AtlOptionalModListModel(QWidget *parent, QVector<ATLauncher::VersionMod> mods) : QAbstractListModel(parent), m_mods(mods) { - // fill mod index for (int i = 0; i < m_mods.size(); i++) { auto mod = m_mods.at(i); m_index[mod.name] = i; } + // set initial state for (int i = 0; i < m_mods.size(); i++) { auto mod = m_mods.at(i); @@ -77,7 +103,7 @@ QVariant AtlOptionalModListModel::data(const QModelIndex &index, int role) const } } - return QVariant(); + return {}; } bool AtlOptionalModListModel::setData(const QModelIndex &index, const QVariant &value, int role) { @@ -104,7 +130,7 @@ QVariant AtlOptionalModListModel::headerData(int section, Qt::Orientation orient } } - return QVariant(); + return {}; } Qt::ItemFlags AtlOptionalModListModel::flags(const QModelIndex &index) const { @@ -115,6 +141,69 @@ Qt::ItemFlags AtlOptionalModListModel::flags(const QModelIndex &index) const { return flags; } +void AtlOptionalModListModel::useShareCode(const QString& code) { + m_jobPtr.reset(new NetJob("Atl::Request", APPLICATION->network())); + auto url = QString(BuildConfig.ATL_API_BASE_URL + "share-codes/" + code); + m_jobPtr->addNetAction(Net::Download::makeByteArray(QUrl(url), &m_response)); + + connect(m_jobPtr.get(), &NetJob::succeeded, + this, &AtlOptionalModListModel::shareCodeSuccess); + connect(m_jobPtr.get(), &NetJob::failed, + this, &AtlOptionalModListModel::shareCodeFailure); + + m_jobPtr->start(); +} + +void AtlOptionalModListModel::shareCodeSuccess() { + m_jobPtr.reset(); + + QJsonParseError parse_error {}; + auto doc = QJsonDocument::fromJson(m_response, &parse_error); + if (parse_error.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response from ATL at " << parse_error.offset << " reason: " << parse_error.errorString(); + qWarning() << m_response; + return; + } + auto obj = doc.object(); + + ATLauncher::ShareCodeResponse response; + try { + ATLauncher::loadShareCodeResponse(response, obj); + } + catch (const JSONValidationError& e) { + qDebug() << QString::fromUtf8(m_response); + qWarning() << "Error while reading response from ATLauncher: " << e.cause(); + return; + } + + if (response.error) { + // fixme: plumb in an error message + qWarning() << "ATLauncher API Response Error" << response.message; + return; + } + + // FIXME: verify pack and version, error if not matching. + + // Clear the current selection + for (const auto& mod : m_mods) { + m_selection[mod.name] = false; + } + + // Make the selections, as per the share code. + for (const auto& mod : response.data.mods) { + m_selection[mod.name] = mod.selected; + } + + emit dataChanged(AtlOptionalModListModel::index(0, EnabledColumn), + AtlOptionalModListModel::index(m_mods.size() - 1, EnabledColumn)); +} + +void AtlOptionalModListModel::shareCodeFailure(const QString& reason) { + m_jobPtr.reset(); + + // fixme: plumb in an error message +} + void AtlOptionalModListModel::selectRecommended() { for (const auto& mod : m_mods) { m_selection[mod.name] = mod.recommended; @@ -212,14 +301,43 @@ AtlOptionalModDialog::AtlOptionalModDialog(QWidget *parent, QVector<ATLauncher:: ui->treeView->header()->setSectionResizeMode( AtlOptionalModListModel::DescriptionColumn, QHeaderView::Stretch); - connect(ui->selectRecommendedButton, &QPushButton::pressed, + connect(ui->shareCodeButton, &QPushButton::clicked, + this, &AtlOptionalModDialog::useShareCode); + connect(ui->selectRecommendedButton, &QPushButton::clicked, listModel, &AtlOptionalModListModel::selectRecommended); - connect(ui->clearAllButton, &QPushButton::pressed, + connect(ui->clearAllButton, &QPushButton::clicked, listModel, &AtlOptionalModListModel::clearAll); - connect(ui->installButton, &QPushButton::pressed, + connect(ui->installButton, &QPushButton::clicked, this, &QDialog::close); } AtlOptionalModDialog::~AtlOptionalModDialog() { delete ui; } + +void AtlOptionalModDialog::useShareCode() { + bool ok; + auto shareCode = QInputDialog::getText( + this, + tr("Select a share code"), + tr("Share code:"), + QLineEdit::Normal, + "", + &ok + ); + + if (!ok) { + // If the user cancels the dialog, we don't need to show any error dialogs. + return; + } + + if (shareCode.isEmpty()) { + QMessageBox box; + box.setIcon(QMessageBox::Warning); + box.setText(tr("No share code specified!")); + box.exec(); + return; + } + + listModel->useShareCode(shareCode); +} diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.h b/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.h index 9832014c..953b288e 100644 --- a/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.h +++ b/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.h @@ -1,17 +1,36 @@ +// SPDX-License-Identifier: GPL-3.0-only /* - * Copyright 2021 Jamie Mansfield <jmansfield@cadixdev.org> + * PolyMC - Minecraft Launcher + * Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org> * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. * - * http://www.apache.org/licenses/LICENSE-2.0 + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * Copyright 2021 Jamie Mansfield <jmansfield@cadixdev.org> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ #pragma once @@ -20,6 +39,7 @@ #include <QAbstractListModel> #include "modplatform/atlauncher/ATLPackIndex.h" +#include "net/NetJob.h" namespace Ui { class AtlOptionalModDialog; @@ -49,7 +69,12 @@ public: Qt::ItemFlags flags(const QModelIndex &index) const override; + void useShareCode(const QString& code); + public slots: + void shareCodeSuccess(); + void shareCodeFailure(const QString& reason); + void selectRecommended(); void clearAll(); @@ -58,6 +83,9 @@ private: void setMod(ATLauncher::VersionMod mod, int index, bool enable, bool shouldEmit = true); private: + NetJob::Ptr m_jobPtr; + QByteArray m_response; + QVector<ATLauncher::VersionMod> m_mods; QMap<QString, bool> m_selection; QMap<QString, int> m_index; @@ -75,6 +103,8 @@ public: return listModel->getResult(); } + void useShareCode(); + private: Ui::AtlOptionalModDialog *ui; diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.ui b/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.ui index 4c5c2ec5..d9496142 100644 --- a/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.ui +++ b/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.ui @@ -24,23 +24,23 @@ </property> </widget> </item> - <item row="1" column="1"> - <widget class="QPushButton" name="selectRecommendedButton"> - <property name="text"> - <string>Select Recommended</string> - </property> - </widget> - </item> <item row="1" column="0"> <widget class="QPushButton" name="shareCodeButton"> <property name="enabled"> - <bool>false</bool> + <bool>true</bool> </property> <property name="text"> <string>Use Share Code</string> </property> </widget> </item> + <item row="1" column="1"> + <widget class="QPushButton" name="selectRecommendedButton"> + <property name="text"> + <string>Select Recommended</string> + </property> + </widget> + </item> <item row="1" column="2"> <widget class="QPushButton" name="clearAllButton"> <property name="text"> |