diff options
Diffstat (limited to 'application')
20 files changed, 361 insertions, 53 deletions
diff --git a/application/CMakeLists.txt b/application/CMakeLists.txt index 38bd586b..1a3bd1c3 100644 --- a/application/CMakeLists.txt +++ b/application/CMakeLists.txt @@ -124,8 +124,10 @@ SET(MULTIMC_SOURCES # GUI - platform pages pages/modplatform/VanillaPage.cpp pages/modplatform/VanillaPage.h - pages/modplatform/ftb/FtbModel.cpp - pages/modplatform/ftb/FtbModel.h + pages/modplatform/ftb/FtbFilterModel.cpp + pages/modplatform/ftb/FtbFilterModel.h + pages/modplatform/ftb/FtbListModel.cpp + pages/modplatform/ftb/FtbListModel.h pages/modplatform/ftb/FtbPage.cpp pages/modplatform/ftb/FtbPage.h pages/modplatform/legacy_ftb/Page.cpp diff --git a/application/package/rpm/MultiMC5.spec b/application/package/rpm/MultiMC5.spec new file mode 100644 index 00000000..5b72c781 --- /dev/null +++ b/application/package/rpm/MultiMC5.spec @@ -0,0 +1,45 @@ +Name: MultiMC5 +Version: 1.4 +Release: 1%{?dist} +Summary: A local install wrapper for MultiMC + +License: ASL 2.0 +URL: https://multimc.org +BuildArch: x86_64 + +Requires: zenity qt5-qtbase wget +Provides: multimc MultiMC multimc5 + +%description +A local install wrapper for MultiMC + +%prep + + +%build + + +%install +mkdir -p %{buildroot}/opt/multimc +install -m 0644 ../ubuntu/multimc/opt/multimc/icon.svg %{buildroot}/opt/multimc/icon.svg +install -m 0755 ../ubuntu/multimc/opt/multimc/run.sh %{buildroot}/opt/multimc/run.sh +mkdir -p %{buildroot}/%{_datadir}/applications +install -m 0644 ../ubuntu/multimc/usr/share/applications/multimc.desktop %{buildroot}/%{_datadir}/applications/multimc.desktop +mkdir -p %{buildroot}/%{_metainfodir} +install -m 0644 ../ubuntu/multimc/usr/share/metainfo/multimc.metainfo.xml %{buildroot}/%{_metainfodir}/multimc.metainfo.xml + +%files +%dir /opt/multimc +/opt/multimc/icon.svg +/opt/multimc/run.sh +%{_datadir}/applications/multimc.desktop +%{_metainfodir}/multimc.metainfo.xml + + +%changelog + +* Tue Dec 08 00:34:35 CET 2020 joshua-stone <joshua.gage.stone@gmail.com> +- Add metainfo.xml for improving package metadata + +* Wed Nov 25 22:53:59 CET 2020 kb1000 <fedora@kb1000.de> +- Initial version of the RPM package, based on the Ubuntu package diff --git a/application/package/rpm/README.md b/application/package/rpm/README.md new file mode 100644 index 00000000..0c2b1e49 --- /dev/null +++ b/application/package/rpm/README.md @@ -0,0 +1,12 @@ +# What is this? +A simple RPM package for MultiMC that contains a script that downloads and installs real MultiMC on Red Hat based systems. + +It contains a `.desktop` file, a `.metainfo.xml` file, an icon, and a simple script that does the heavy lifting. + +# How to build this? +You need the `rpm-build` package. Switch into this directory, then run: +``` +rpmbuild --build-in-place -bb MultiMC5.spec +``` + +Replace the version with whatever is appropriate. diff --git a/application/package/ubuntu/readme.md b/application/package/ubuntu/README.md index 5b0d6b27..5c0f4eeb 100644 --- a/application/package/ubuntu/readme.md +++ b/application/package/ubuntu/README.md @@ -1,8 +1,10 @@ # What is this? -A simple ubuntu package for MultiMC that wraps the contains a script that downloads and installs real MultiMC on ubuntu based systems. +A simple Ubuntu package for MultiMC that contains a script that downloads and installs real MultiMC on Ubuntu based systems. It contains a `.desktop` file, an icon, and a simple script that does the heavy lifting. +This is also the source for the files in the [RPM package](../rpm). If you rename, create or delete files here, you'll likely also have to update the RPM spec file there. + # How to build this? You need dpkg utils. Rename the `multimc` folder to `multimc_1.3-1` and then run: ``` diff --git a/application/package/ubuntu/multimc/usr/share/metainfo/multimc.metainfo.xml b/application/package/ubuntu/multimc/usr/share/metainfo/multimc.metainfo.xml new file mode 100644 index 00000000..64b2f44d --- /dev/null +++ b/application/package/ubuntu/multimc/usr/share/metainfo/multimc.metainfo.xml @@ -0,0 +1,61 @@ +<?xml version="1.0" encoding="UTF-8"?> +<component type="desktop"> + <id>multimc</id> + <launchable type="desktop-id">multimc.desktop</launchable> + <name>MultiMC</name> + <summary>Manage Minecraft instances with ease</summary> + <description> + <p>Overview</p> + <p>MultiMC is a free, open source launcher for Minecraft. It allows you to have multiple, cleanly separated instances of Minecraft (each with their own mods, texture packs, saves, etc) and helps you manage them and their associated options with a simple and powerful interface.</p> + <p>Features</p> + <ul> + <li>Manage multiple instances of Minecraft at once</li> + <li>Start Minecraft with a custom resolution</li> + <li>Change Java's runtime options (including memory options)</li> + <li>Shows Minecraft's console output in a colour coded window</li> + <li>Kill Minecraft easily if it crashes / freezes</li> + <li>Custom icons and groups for instances</li> + <li>Forge integration (automatic installation, version downloads, mod management)</li> + <li>Minecraft world management</li> + <li>Import and export Minecraft instances to share them with anyone</li> + <li>Supports every version of Minecraft that the vanilla launcher does</li> + </ul> + </description> + <screenshots> + <screenshot type="default"> + <image type="source" width="936" height="921">https://multimc.org/images/screenshots/main.png</image> + </screenshot> + <screenshot> + <image type="source" width="936" height="998">https://multimc.org/images/screenshots/editmods.png</image> + </screenshot> + <screenshot> + <image type="source" width="936" height="998">https://multimc.org/images/screenshots/version.png</image> + </screenshot> + <screenshot> + <image type="source" width="936" height="998">https://multimc.org/images/screenshots/console.png</image> + </screenshot> + <screenshot> + <image type="source" width="936" height="921">https://multimc.org/images/screenshots/settings.png</image> + </screenshot> + </screenshots> + <releases> + <release date="2020-03-28" version="0.6.11"/> + </releases> + <url type="homepage">https://multimc.org/</url> + <url type="help">https://discord.com/invite/0k2zsXGNHs0fE4Wm</url> + <url type="faq">https://github.com/MultiMC/MultiMC5/wiki/FAQ</url> + <url type="bugtracker">https://github.com/flathub/multimc/issues</url> + <url type="translate">https://translate.multimc.org/</url> + <url type="donation">https://www.patreon.com/multimc</url> + <developer_name>The MultiMC Team</developer_name> + <metadata_license>CC0-1.0</metadata_license> + <project_license>Apache-2.0</project_license> + <content_rating type="oars-1.1"> + <content_attribute id="language-humor">mild</content_attribute> + <content_attribute id="language-discrimination">mild</content_attribute> + <content_attribute id="social-chat">mild</content_attribute> + <content_attribute id="social-info">mild</content_attribute> + <content_attribute id="money-purchasing">mild</content_attribute> + </content_rating> + <update_contact>peterix_at_gmail.com</update_contact> +</component> diff --git a/application/pages/instance/WorldListPage.cpp b/application/pages/instance/WorldListPage.cpp index 75741d22..4d737025 100644 --- a/application/pages/instance/WorldListPage.cpp +++ b/application/pages/instance/WorldListPage.cpp @@ -170,6 +170,24 @@ void WorldListPage::on_actionView_Folder_triggered() DesktopServices::openDirectory(m_worlds->dir().absolutePath(), true); } +void WorldListPage::on_actionDatapacks_triggered() +{ + QModelIndex index = getSelectedWorld(); + + if (!index.isValid()) + { + return; + } + + if(!worldSafetyNagQuestion()) + return; + + auto fullPath = m_worlds->data(index, WorldList::FolderRole).toString(); + + DesktopServices::openDirectory(FS::PathCombine(fullPath, "datapacks"), true); +} + + void WorldListPage::on_actionReset_Icon_triggered() { auto proxiedIndex = getSelectedWorld(); diff --git a/application/pages/instance/WorldListPage.h b/application/pages/instance/WorldListPage.h index 8ff14819..d19f4937 100644 --- a/application/pages/instance/WorldListPage.h +++ b/application/pages/instance/WorldListPage.h @@ -90,6 +90,7 @@ private slots: void on_actionRename_triggered(); void on_actionRefresh_triggered(); void on_actionView_Folder_triggered(); + void on_actionDatapacks_triggered(); void on_actionReset_Icon_triggered(); void worldChanged(const QModelIndex ¤t, const QModelIndex &previous); void mceditState(LoggedProcess::State state); diff --git a/application/pages/instance/WorldListPage.ui b/application/pages/instance/WorldListPage.ui index 8d00f8f4..ed078d94 100644 --- a/application/pages/instance/WorldListPage.ui +++ b/application/pages/instance/WorldListPage.ui @@ -85,6 +85,7 @@ <addaction name="actionCopy"/> <addaction name="actionRemove"/> <addaction name="actionMCEdit"/> + <addaction name="actionDatapacks"/> <addaction name="actionReset_Icon"/> <addaction name="separator"/> <addaction name="actionCopy_Seed"/> @@ -139,6 +140,14 @@ <string>Remove world icon to make the game re-generate it on next load.</string> </property> </action> + <action name="actionDatapacks"> + <property name="text"> + <string>Datapacks</string> + </property> + <property name="toolTip"> + <string>Manage datapacks inside the world.</string> + </property> + </action> </widget> <customwidgets> <customwidget> diff --git a/application/pages/modplatform/ftb/FtbFilterModel.cpp b/application/pages/modplatform/ftb/FtbFilterModel.cpp new file mode 100644 index 00000000..dec3a017 --- /dev/null +++ b/application/pages/modplatform/ftb/FtbFilterModel.cpp @@ -0,0 +1,64 @@ +#include "FtbFilterModel.h" + +#include <QDebug> + +#include "modplatform/modpacksch/FTBPackManifest.h" +#include <MMCStrings.h> + +namespace Ftb { + +FilterModel::FilterModel(QObject *parent) : QSortFilterProxyModel(parent) +{ + currentSorting = Sorting::ByPlays; + sortings.insert(tr("Sort by plays"), Sorting::ByPlays); + sortings.insert(tr("Sort by installs"), Sorting::ByInstalls); + sortings.insert(tr("Sort by name"), Sorting::ByName); +} + +const QMap<QString, FilterModel::Sorting> FilterModel::getAvailableSortings() +{ + return sortings; +} + +QString FilterModel::translateCurrentSorting() +{ + return sortings.key(currentSorting); +} + +void FilterModel::setSorting(Sorting sorting) +{ + currentSorting = sorting; + invalidate(); +} + +FilterModel::Sorting FilterModel::getCurrentSorting() +{ + return currentSorting; +} + +bool FilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const +{ + return true; +} + +bool FilterModel::lessThan(const QModelIndex &left, const QModelIndex &right) const +{ + ModpacksCH::Modpack leftPack = sourceModel()->data(left, Qt::UserRole).value<ModpacksCH::Modpack>(); + ModpacksCH::Modpack rightPack = sourceModel()->data(right, Qt::UserRole).value<ModpacksCH::Modpack>(); + + if (currentSorting == ByPlays) { + return leftPack.plays < rightPack.plays; + } + else if (currentSorting == ByInstalls) { + return leftPack.installs < rightPack.installs; + } + else if (currentSorting == ByName) { + return Strings::naturalCompare(leftPack.name, rightPack.name, Qt::CaseSensitive) >= 0; + } + + // Invalid sorting set, somehow... + qWarning() << "Invalid sorting set!"; + return true; +} + +} diff --git a/application/pages/modplatform/ftb/FtbFilterModel.h b/application/pages/modplatform/ftb/FtbFilterModel.h new file mode 100644 index 00000000..4fe2a274 --- /dev/null +++ b/application/pages/modplatform/ftb/FtbFilterModel.h @@ -0,0 +1,33 @@ +#pragma once + +#include <QtCore/QSortFilterProxyModel> + +namespace Ftb { + +class FilterModel : public QSortFilterProxyModel +{ + Q_OBJECT + +public: + FilterModel(QObject* parent = Q_NULLPTR); + enum Sorting { + ByPlays, + ByInstalls, + ByName, + }; + const QMap<QString, Sorting> getAvailableSortings(); + QString translateCurrentSorting(); + void setSorting(Sorting sorting); + Sorting getCurrentSorting(); + +protected: + bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override; + bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; + +private: + QMap<QString, Sorting> sortings; + Sorting currentSorting; + +}; + +} diff --git a/application/pages/modplatform/ftb/FtbModel.cpp b/application/pages/modplatform/ftb/FtbListModel.cpp index ecdcb00b..63236827 100644 --- a/application/pages/modplatform/ftb/FtbModel.cpp +++ b/application/pages/modplatform/ftb/FtbListModel.cpp @@ -1,4 +1,4 @@ -#include "FtbModel.h" +#include "FtbListModel.h" #include "BuildConfig.h" #include "Env.h" @@ -79,7 +79,7 @@ void ListModel::performSearch() auto *netJob = new NetJob("Ftb::Search"); QString searchUrl; if(currentSearchTerm.isEmpty()) { - searchUrl = BuildConfig.MODPACKSCH_API_BASE_URL + "public/modpack/popular/plays/100"; + searchUrl = BuildConfig.MODPACKSCH_API_BASE_URL + "public/modpack/all"; } else { searchUrl = QString(BuildConfig.MODPACKSCH_API_BASE_URL + "public/modpack/search/25?term=%1") @@ -206,9 +206,18 @@ void ListModel::packRequestFinished() return; } - beginInsertRows(QModelIndex(), modpacks.size(), modpacks.size()); - modpacks.append(pack); - endInsertRows(); + // Since there is no guarantee that packs have a version, this will just + // ignore those "dud" packs. + if (pack.versions.empty()) + { + qWarning() << "FTB Pack " << pack.id << " ignored. reason: lacking any versions"; + } + else + { + beginInsertRows(QModelIndex(), modpacks.size(), modpacks.size()); + modpacks.append(pack); + endInsertRows(); + } if(!remainingPacks.isEmpty()) { currentPack = remainingPacks.at(0); diff --git a/application/pages/modplatform/ftb/FtbModel.h b/application/pages/modplatform/ftb/FtbListModel.h index 9c057d73..9c057d73 100644 --- a/application/pages/modplatform/ftb/FtbModel.h +++ b/application/pages/modplatform/ftb/FtbListModel.h diff --git a/application/pages/modplatform/ftb/FtbPage.cpp b/application/pages/modplatform/ftb/FtbPage.cpp index c82508b3..60294de0 100644 --- a/application/pages/modplatform/ftb/FtbPage.cpp +++ b/application/pages/modplatform/ftb/FtbPage.cpp @@ -10,12 +10,26 @@ FtbPage::FtbPage(NewInstanceDialog* dialog, QWidget *parent) : QWidget(parent), ui(new Ui::FtbPage), dialog(dialog) { ui->setupUi(this); - connect(ui->searchButton, &QPushButton::clicked, this, &FtbPage::triggerSearch); + + filterModel = new Ftb::FilterModel(this); + listModel = new Ftb::ListModel(this); + filterModel->setSourceModel(listModel); + ui->packView->setModel(filterModel); + ui->packView->setSortingEnabled(true); + ui->packView->header()->hide(); + ui->packView->setIndentation(0); + ui->searchEdit->installEventFilter(this); - model = new Ftb::ListModel(this); - ui->packView->setModel(model); - connect(ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, this, &FtbPage::onSelectionChanged); + for(int i = 0; i < filterModel->getAvailableSortings().size(); i++) + { + ui->sortByBox->addItem(filterModel->getAvailableSortings().keys().at(i)); + } + ui->sortByBox->setCurrentText(filterModel->translateCurrentSorting()); + + connect(ui->searchButton, &QPushButton::clicked, this, &FtbPage::triggerSearch); + connect(ui->sortByBox, &QComboBox::currentTextChanged, this, &FtbPage::onSortingSelectionChanged); + connect(ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, this, &FtbPage::onSelectionChanged); connect(ui->versionSelectionBox, &QComboBox::currentTextChanged, this, &FtbPage::onVersionSelectionChanged); } @@ -59,7 +73,7 @@ void FtbPage::suggestCurrent() QString editedLogoName; editedLogoName = selected.name; - model->getLogo(selected.name, art.url, [this, editedLogoName](QString logo) + listModel->getLogo(selected.name, art.url, [this, editedLogoName](QString logo) { dialog->setSuggestedIconFromFile(logo + ".small", editedLogoName); }); @@ -70,7 +84,13 @@ void FtbPage::suggestCurrent() void FtbPage::triggerSearch() { - model->searchWithTerm(ui->searchEdit->text()); + listModel->searchWithTerm(ui->searchEdit->text()); +} + +void FtbPage::onSortingSelectionChanged(QString data) +{ + auto toSet = filterModel->getAvailableSortings().value(data); + filterModel->setSorting(toSet); } void FtbPage::onSelectionChanged(QModelIndex first, QModelIndex second) @@ -86,7 +106,7 @@ void FtbPage::onSelectionChanged(QModelIndex first, QModelIndex second) return; } - selected = model->data(first, Qt::UserRole).value<ModpacksCH::Modpack>(); + selected = filterModel->data(first, Qt::UserRole).value<ModpacksCH::Modpack>(); // reverse foreach, so that the newest versions are first for (auto i = selected.versions.size(); i--;) { diff --git a/application/pages/modplatform/ftb/FtbPage.h b/application/pages/modplatform/ftb/FtbPage.h index 80f152c6..b31e1c9e 100644 --- a/application/pages/modplatform/ftb/FtbPage.h +++ b/application/pages/modplatform/ftb/FtbPage.h @@ -15,7 +15,8 @@ #pragma once -#include "FtbModel.h" +#include "FtbFilterModel.h" +#include "FtbListModel.h" #include <QWidget> @@ -64,13 +65,15 @@ private: private slots: void triggerSearch(); + void onSortingSelectionChanged(QString data); void onSelectionChanged(QModelIndex first, QModelIndex second); void onVersionSelectionChanged(QString data); private: Ui::FtbPage *ui = nullptr; NewInstanceDialog* dialog = nullptr; - Ftb::ListModel* model = nullptr; + Ftb::ListModel* listModel = nullptr; + Ftb::FilterModel* filterModel = nullptr; ModpacksCH::Modpack selected; QString selectedVersion; diff --git a/application/pages/modplatform/ftb/FtbPage.ui b/application/pages/modplatform/ftb/FtbPage.ui index 772b0276..3a2203db 100644 --- a/application/pages/modplatform/ftb/FtbPage.ui +++ b/application/pages/modplatform/ftb/FtbPage.ui @@ -11,22 +11,6 @@ </rect> </property> <layout class="QGridLayout" name="gridLayout"> - <item row="1" column="0" colspan="2"> - <widget class="QListView" name="packView"> - <property name="alternatingRowColors"> - <bool>true</bool> - </property> - <property name="iconSize"> - <size> - <width>48</width> - <height>48</height> - </size> - </property> - <property name="uniformItemSizes"> - <bool>true</bool> - </property> - </widget> - </item> <item row="0" column="1"> <widget class="QPushButton" name="searchButton"> <property name="text"> @@ -38,19 +22,38 @@ <widget class="QLineEdit" name="searchEdit"/> </item> <item row="2" column="0" colspan="2"> - <layout class="QGridLayout" name="gridLayout_4" columnstretch="0,0" rowminimumheight="0" columnminimumwidth="0,0"> - <item row="0" column="1"> + <layout class="QGridLayout" name="gridLayout_4" columnstretch="0,0,0" rowminimumheight="0" columnminimumwidth="0,0,0"> + <item row="0" column="2"> <widget class="QComboBox" name="versionSelectionBox"/> </item> - <item row="0" column="0"> + <item row="0" column="1"> <widget class="QLabel" name="label"> <property name="text"> <string>Version selected:</string> </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> </widget> </item> + <item row="0" column="0"> + <widget class="QComboBox" name="sortByBox"/> + </item> </layout> </item> + <item row="1" column="0" colspan="2"> + <widget class="QTreeView" name="packView"> + <property name="alternatingRowColors"> + <bool>true</bool> + </property> + <property name="iconSize"> + <size> + <width>48</width> + <height>48</height> + </size> + </property> + </widget> + </item> </layout> </widget> <tabstops> diff --git a/application/pages/modplatform/technic/TechnicData.h b/application/pages/modplatform/technic/TechnicData.h index 5c746619..c7ddd9ce 100644 --- a/application/pages/modplatform/technic/TechnicData.h +++ b/application/pages/modplatform/technic/TechnicData.h @@ -18,7 +18,6 @@ #include <QList> #include <QString> - namespace Technic { struct Modpack { QString slug; @@ -34,6 +33,9 @@ struct Modpack { QString minecraftVersion; bool metadataLoaded = false; + QString websiteUrl; + QString author; + QString description; }; } diff --git a/application/pages/modplatform/technic/TechnicModel.cpp b/application/pages/modplatform/technic/TechnicModel.cpp index bdc411c3..e1294554 100644 --- a/application/pages/modplatform/technic/TechnicModel.cpp +++ b/application/pages/modplatform/technic/TechnicModel.cpp @@ -20,7 +20,6 @@ #include <QIcon> - Technic::ListModel::ListModel(QObject *parent) : QAbstractListModel(parent) { } diff --git a/application/pages/modplatform/technic/TechnicPage.cpp b/application/pages/modplatform/technic/TechnicPage.cpp index 75efd3ed..f6facd57 100644 --- a/application/pages/modplatform/technic/TechnicPage.cpp +++ b/application/pages/modplatform/technic/TechnicPage.cpp @@ -13,7 +13,6 @@ * limitations under the License. */ - #include "TechnicPage.h" #include "ui_TechnicPage.h" @@ -159,6 +158,9 @@ void TechnicPage::suggestCurrent() } current.minecraftVersion = Json::ensureString(obj, "minecraft", QString(), "__placeholder__"); + current.websiteUrl = Json::ensureString(obj, "platformUrl", QString(), "__placeholder__"); + current.author = Json::ensureString(obj, "user", QString(), "__placeholder__"); + current.description = Json::ensureString(obj, "description", QString(), "__placeholder__"); current.metadataLoaded = true; metadataLoaded(); }); @@ -169,29 +171,22 @@ void TechnicPage::suggestCurrent() // expects current.metadataLoaded to be true void TechnicPage::metadataLoaded() { - /*QString text = ""; + QString text = ""; QString name = current.name; if (current.websiteUrl.isEmpty()) + // This allows injecting HTML here. text = name; else + // URL not properly escaped for inclusion in HTML. The name allows for injecting HTML. text = "<a href=\"" + current.websiteUrl + "\">" + name + "</a>"; - if (!current.authors.empty()) { - auto authorToStr = [](Technic::ModpackAuthor & author) { - if(author.url.isEmpty()) { - return author.name; - } - return QString("<a href=\"%1\">%2</a>").arg(author.url, author.name); - }; - QStringList authorStrs; - for(auto & author: current.authors) { - authorStrs.push_back(authorToStr(author)); - } - text += tr(" by ") + authorStrs.join(", "); + if (!current.author.isEmpty()) { + // This allows injecting HTML here + text += tr(" by ") + current.author; } ui->frame->setModText(text); - ui->frame->setModDescription(current.description);*/ + ui->frame->setModDescription(current.description); if (!current.isSolder) { dialog->setSuggestedPack(current.name, new Technic::SingleZipPackInstallTask(current.url, current.minecraftVersion)); diff --git a/application/pages/modplatform/technic/TechnicPage.ui b/application/pages/modplatform/technic/TechnicPage.ui index be56fa82..36ce2ecf 100644 --- a/application/pages/modplatform/technic/TechnicPage.ui +++ b/application/pages/modplatform/technic/TechnicPage.ui @@ -55,8 +55,37 @@ </property> </widget> </item> + <item> + <widget class="MCModInfoFrame" name="frame"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Minimum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="frameShape"> + <enum>QFrame::StyledPanel</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Raised</enum> + </property> + </widget> + </item> </layout> </widget> + <customwidgets> + <customwidget> + <class>MCModInfoFrame</class> + <extends>QFrame</extends> + <header>widgets/MCModInfoFrame.h</header> + <container>1</container> + </customwidget> + </customwidgets> + <tabstops> + <tabstop>searchEdit</tabstop> + <tabstop>searchButton</tabstop> + <tabstop>packView</tabstop> + </tabstops> <resources/> <connections/> </ui> diff --git a/application/widgets/MCModInfoFrame.cpp b/application/widgets/MCModInfoFrame.cpp index 577b32a7..89bb90fd 100644 --- a/application/widgets/MCModInfoFrame.cpp +++ b/application/widgets/MCModInfoFrame.cpp @@ -135,6 +135,7 @@ void MCModInfoFrame::setModDescription(QString text) ui->label_ModDescription->setOpenExternalLinks(false); ui->label_ModDescription->setTextFormat(Qt::TextFormat::RichText); desc = text; + // This allows injecting HTML here. labeltext.append("<html><body>" + finaltext.left(287) + "<a href=\"#mod_desc\">...</a></body></html>"); QObject::connect(ui->label_ModDescription, &QLabel::linkActivated, this, &MCModInfoFrame::modDescEllipsisHandler); } |