mirror of
https://github.com/iDescriptor/iDescriptor.git
synced 2026-06-21 19:35:49 +08:00
bug fixes
- update app icon fetching to use QNetworkAccessManager - fix App icon label dangling pointer - check updates if autocheckupdates is enabled
This commit is contained in:
@@ -86,7 +86,8 @@ void AppDownloadBaseDialog::startDownloadProcess(const QString &bundleId,
|
||||
|
||||
manager->downloadApp(
|
||||
bundleId, outputDir, "", acquireLicense,
|
||||
[this, outputDir, promptToOpenDir](int result) {
|
||||
[this, promptToOpenDir, outputDir](int result) {
|
||||
m_operationInProgress = false;
|
||||
if (result == 0) { // Success
|
||||
emit downloadFinished(true, "Success");
|
||||
m_progressBar->setValue(100);
|
||||
|
||||
@@ -83,6 +83,7 @@ void AppDownloadDialog::onDownloadClicked()
|
||||
int buttonIndex = m_layout->indexOf(m_actionButton);
|
||||
layout()->removeWidget(m_actionButton);
|
||||
m_actionButton->deleteLater();
|
||||
|
||||
qDebug() << "Starting download to" << m_outputDir;
|
||||
qDebug() << "Bundle ID:" << m_bundleId;
|
||||
startDownloadProcess(m_bundleId, m_outputDir, buttonIndex);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <QFutureWatcher>
|
||||
#include <QLabel>
|
||||
#include <QMessageBox>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QPainter>
|
||||
#include <QPainterPath>
|
||||
#include <QPushButton>
|
||||
@@ -24,14 +25,13 @@ AppInstallDialog::AppInstallDialog(const QString &appName,
|
||||
setWindowTitle("Install " + appName + " - iDescriptor");
|
||||
setModal(true);
|
||||
setFixedWidth(500);
|
||||
|
||||
m_manager = new QNetworkAccessManager(this);
|
||||
QVBoxLayout *layout = qobject_cast<QVBoxLayout *>(this->layout());
|
||||
// App info section
|
||||
QHBoxLayout *appInfoLayout = new QHBoxLayout();
|
||||
QLabel *iconLabel = new QLabel();
|
||||
fetchAppIconFromApple(
|
||||
bundleId,
|
||||
[iconLabel](const QPixmap &pixmap) {
|
||||
::fetchAppIconFromApple(
|
||||
m_manager, bundleId, [iconLabel](const QPixmap &pixmap) {
|
||||
if (!pixmap.isNull()) {
|
||||
QPixmap scaled =
|
||||
pixmap.scaled(64, 64, Qt::KeepAspectRatioByExpanding,
|
||||
@@ -49,8 +49,7 @@ AppInstallDialog::AppInstallDialog(const QString &appName,
|
||||
|
||||
iconLabel->setPixmap(rounded);
|
||||
}
|
||||
},
|
||||
this);
|
||||
});
|
||||
QPixmap icon = QApplication::style()
|
||||
->standardIcon(QStyle::SP_ComputerIcon)
|
||||
.pixmap(64, 64);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <QFutureWatcher>
|
||||
#include <QLabel>
|
||||
#include <QTemporaryDir>
|
||||
#include <QNetworkAccessManager>
|
||||
|
||||
class AppInstallDialog : public AppDownloadBaseDialog
|
||||
{
|
||||
@@ -30,6 +31,7 @@ private:
|
||||
QLabel *m_statusLabel;
|
||||
QFutureWatcher<int> *m_installWatcher;
|
||||
QTemporaryDir *m_tempDir = nullptr;
|
||||
QNetworkAccessManager *m_manager = nullptr;
|
||||
void updateDeviceList();
|
||||
void performInstallation(const QString &ipaPath, const QString &deviceUdid);
|
||||
};
|
||||
|
||||
+12
-11
@@ -160,8 +160,9 @@ void AppStoreManager::searchApps(
|
||||
}
|
||||
|
||||
void AppStoreManager::downloadApp(
|
||||
const QString &bundleId, const QString &outputDir, const QString &country,
|
||||
bool acquireLicense, std::function<void(int result)> callback,
|
||||
const QString &bundleId, const QString &outputDir,
|
||||
const QString &externalVersionId, bool acquireLicense,
|
||||
std::function<void(int result)> callback,
|
||||
std::function<void(long long current, long long total)> progressCallback)
|
||||
{
|
||||
if (!m_initialized) {
|
||||
@@ -189,15 +190,15 @@ void AppStoreManager::downloadApp(
|
||||
};
|
||||
}
|
||||
|
||||
QFuture<int> future = QtConcurrent::run([bundleId, outputDir, country,
|
||||
acquireLicense, cProgressCallback,
|
||||
progressUserData]() {
|
||||
int result = IpaToolDownloadApp(bundleId.toUtf8().data(),
|
||||
outputDir.toUtf8().data(),
|
||||
country.toUtf8().data(), acquireLicense,
|
||||
cProgressCallback, progressUserData);
|
||||
return result;
|
||||
});
|
||||
QFuture<int> future = QtConcurrent::run(
|
||||
[bundleId, outputDir, externalVersionId, acquireLicense,
|
||||
cProgressCallback, progressUserData]() {
|
||||
int result = IpaToolDownloadApp(
|
||||
bundleId.toUtf8().data(), outputDir.toUtf8().data(),
|
||||
externalVersionId.toUtf8().data(), acquireLicense,
|
||||
cProgressCallback, progressUserData);
|
||||
return result;
|
||||
});
|
||||
|
||||
QFutureWatcher<int> *watcher = new QFutureWatcher<int>(this);
|
||||
connect(
|
||||
|
||||
@@ -25,7 +25,7 @@ public:
|
||||
const QString &searchTerm, int limit,
|
||||
std::function<void(bool success, const QString &results)> callback);
|
||||
void downloadApp(const QString &bundleId, const QString &outputDir,
|
||||
const QString &country, bool acquireLicense,
|
||||
const QString &externalVersionId, bool acquireLicense,
|
||||
std::function<void(int result)> callback,
|
||||
std::function<void(long long current, long long total)>
|
||||
progressCallback = nullptr);
|
||||
|
||||
+60
-46
@@ -118,11 +118,11 @@ QJsonObject getVersionedConfig(const QJsonObject &rootObj)
|
||||
}
|
||||
}
|
||||
|
||||
// watch for login and logout events
|
||||
// TODO: watch for login and logout events
|
||||
AppsWidget *AppsWidget::sharedInstance()
|
||||
{
|
||||
static AppsWidget instance;
|
||||
return &instance;
|
||||
static AppsWidget *instance = new AppsWidget();
|
||||
return instance;
|
||||
}
|
||||
|
||||
AppsWidget::AppsWidget(QWidget *parent) : QWidget(parent), m_isLoggedIn(false)
|
||||
@@ -406,9 +406,11 @@ void AppsWidget::populateDefaultApps()
|
||||
QString logoUrl = sponsorObj.value("logo").toString();
|
||||
QString description = sponsorObj.value("description").toString();
|
||||
QString url = sponsorObj.value("url").toString();
|
||||
|
||||
bool useBundleIdForIcon =
|
||||
sponsorObj.value("useBundleIdForIcon").toBool(true);
|
||||
createAppCard(name, bundleId, description, logoUrl, url, gridLayout,
|
||||
row, col, SponsorType(SponsorType::Platinum));
|
||||
row, col, useBundleIdForIcon,
|
||||
SponsorType(SponsorType::Platinum));
|
||||
advanceGridPos();
|
||||
}
|
||||
|
||||
@@ -419,8 +421,11 @@ void AppsWidget::populateDefaultApps()
|
||||
QString description = sponsorObj.value("description").toString();
|
||||
QString logoUrl = sponsorObj.value("logo").toString();
|
||||
QString url = sponsorObj.value("url").toString();
|
||||
bool useBundleIdForIcon =
|
||||
sponsorObj.value("useBundleIdForIcon").toBool(true);
|
||||
createAppCard(name, bundleId, description, logoUrl, url, gridLayout,
|
||||
row, col, SponsorType(SponsorType::Gold));
|
||||
row, col, useBundleIdForIcon,
|
||||
SponsorType(SponsorType::Gold));
|
||||
advanceGridPos();
|
||||
}
|
||||
|
||||
@@ -466,9 +471,13 @@ void AppsWidget::populateDefaultApps()
|
||||
QString bundleId = sponsorObj.value("bundleId").toString();
|
||||
QString description = sponsorObj.value("description").toString();
|
||||
QString url = sponsorObj.value("url").toString();
|
||||
QString logoUrl = sponsorObj.value("logo").toString();
|
||||
bool useBundleIdForIcon =
|
||||
sponsorObj.value("useBundleIdForIcon").toBool(true);
|
||||
|
||||
createAppCard(name, bundleId, description, "", url, gridLayout, row,
|
||||
col, SponsorType(SponsorType::Silver));
|
||||
createAppCard(name, bundleId, description, logoUrl, url, gridLayout,
|
||||
row, col, useBundleIdForIcon,
|
||||
SponsorType(SponsorType::Silver));
|
||||
advanceGridPos();
|
||||
}
|
||||
|
||||
@@ -478,8 +487,13 @@ void AppsWidget::populateDefaultApps()
|
||||
QString bundleId = sponsorObj.value("bundleId").toString();
|
||||
QString description = sponsorObj.value("description").toString();
|
||||
QString url = sponsorObj.value("url").toString();
|
||||
createAppCard(name, bundleId, description, "", url, gridLayout, row,
|
||||
col, SponsorType(SponsorType::Bronze));
|
||||
QString logoUrl = sponsorObj.value("logo").toString();
|
||||
|
||||
bool useBundleIdForIcon =
|
||||
sponsorObj.value("useBundleIdForIcon").toBool(true);
|
||||
createAppCard(name, bundleId, description, logoUrl, url, gridLayout,
|
||||
row, col, useBundleIdForIcon,
|
||||
SponsorType(SponsorType::Bronze));
|
||||
advanceGridPos();
|
||||
}
|
||||
gridLayout->setRowStretch(gridLayout->rowCount(), 1);
|
||||
@@ -526,12 +540,10 @@ void AppsWidget::createSponsorCard(QGridLayout *gridLayout, int row, int col)
|
||||
gridLayout->addWidget(sponsorCard, row, col);
|
||||
}
|
||||
|
||||
void AppsWidget::createAppCard(const QString &name, const QString &bundleId,
|
||||
const QString &description,
|
||||
const QString &logoUrl,
|
||||
const QString &websiteUrl,
|
||||
QGridLayout *gridLayout, int row, int col,
|
||||
const SponsorType &sponsorType)
|
||||
void AppsWidget::createAppCard(
|
||||
const QString &name, const QString &bundleId, const QString &description,
|
||||
const QString &logoUrl, const QString &websiteUrl, QGridLayout *gridLayout,
|
||||
int row, int col, bool useBundleIdForIcon, const SponsorType &sponsorType)
|
||||
{
|
||||
QWidget *cardWidget = new QWidget();
|
||||
|
||||
@@ -541,6 +553,7 @@ void AppsWidget::createAppCard(const QString &name, const QString &bundleId,
|
||||
|
||||
// App icon
|
||||
QLabel *iconLabel = new QLabel();
|
||||
QPointer<QLabel> safeIconLabel = iconLabel;
|
||||
QPixmap placeholderIcon = QApplication::style()
|
||||
->standardIcon(QStyle::SP_ComputerIcon)
|
||||
.pixmap(64, 64);
|
||||
@@ -548,41 +561,43 @@ void AppsWidget::createAppCard(const QString &name, const QString &bundleId,
|
||||
iconLabel->setAlignment(Qt::AlignCenter);
|
||||
cardLayout->addWidget(iconLabel);
|
||||
|
||||
// If logoUrl is provided and bundleId is empty, use the logo directly
|
||||
if (!logoUrl.isEmpty()) {
|
||||
if (!logoUrl.isEmpty() && !useBundleIdForIcon) {
|
||||
QUrl url(logoUrl);
|
||||
QNetworkRequest request(url);
|
||||
QNetworkReply *reply = m_networkManager->get(request);
|
||||
connect(reply, &QNetworkReply::finished, [reply, iconLabel]() {
|
||||
if (reply->error() == QNetworkReply::NoError) {
|
||||
QByteArray data = reply->readAll();
|
||||
QPixmap pixmap;
|
||||
if (pixmap.loadFromData(data)) {
|
||||
QPixmap scaled =
|
||||
pixmap.scaled(64, 64, Qt::KeepAspectRatioByExpanding,
|
||||
Qt::SmoothTransformation);
|
||||
QPixmap rounded(64, 64);
|
||||
rounded.fill(Qt::transparent);
|
||||
// Use Qt's parent-child relationship to auto-cleanup
|
||||
connect(
|
||||
reply, &QNetworkReply::finished, this, [reply, safeIconLabel]() {
|
||||
if (reply->error() == QNetworkReply::NoError && safeIconLabel) {
|
||||
QByteArray data = reply->readAll();
|
||||
QPixmap pixmap;
|
||||
if (pixmap.loadFromData(data)) {
|
||||
QPixmap scaled = pixmap.scaled(
|
||||
64, 64, Qt::KeepAspectRatioByExpanding,
|
||||
Qt::SmoothTransformation);
|
||||
QPixmap rounded(64, 64);
|
||||
rounded.fill(Qt::transparent);
|
||||
|
||||
QPainter painter(&rounded);
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
QPainterPath path;
|
||||
path.addRoundedRect(QRectF(0, 0, 64, 64), 16, 16);
|
||||
painter.setClipPath(path);
|
||||
painter.drawPixmap(0, 0, scaled);
|
||||
painter.end();
|
||||
QPainter painter(&rounded);
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
QPainterPath path;
|
||||
path.addRoundedRect(QRectF(0, 0, 64, 64), 16, 16);
|
||||
painter.setClipPath(path);
|
||||
painter.drawPixmap(0, 0, scaled);
|
||||
painter.end();
|
||||
|
||||
iconLabel->setPixmap(rounded);
|
||||
safeIconLabel->setPixmap(rounded);
|
||||
}
|
||||
}
|
||||
}
|
||||
reply->deleteLater();
|
||||
});
|
||||
reply->deleteLater();
|
||||
});
|
||||
// Ensure reply is deleted if iconLabel is destroyed
|
||||
connect(iconLabel, &QObject::destroyed, reply, &QNetworkReply::abort);
|
||||
} else if (!bundleId.isEmpty()) {
|
||||
// Use Apple's API for app icons
|
||||
fetchAppIconFromApple(
|
||||
bundleId,
|
||||
[iconLabel](const QPixmap &pixmap) {
|
||||
if (!pixmap.isNull()) {
|
||||
m_networkManager, bundleId, [safeIconLabel](const QPixmap &pixmap) {
|
||||
// Check if iconLabel still exists
|
||||
if (safeIconLabel && !pixmap.isNull()) {
|
||||
QPixmap scaled =
|
||||
pixmap.scaled(64, 64, Qt::KeepAspectRatioByExpanding,
|
||||
Qt::SmoothTransformation);
|
||||
@@ -597,10 +612,9 @@ void AppsWidget::createAppCard(const QString &name, const QString &bundleId,
|
||||
painter.drawPixmap(0, 0, scaled);
|
||||
painter.end();
|
||||
|
||||
iconLabel->setPixmap(rounded);
|
||||
safeIconLabel->setPixmap(rounded);
|
||||
}
|
||||
},
|
||||
cardWidget);
|
||||
});
|
||||
}
|
||||
|
||||
// Vertical layout for name and description
|
||||
|
||||
+1
-1
@@ -79,7 +79,7 @@ private:
|
||||
void createAppCard(const QString &name, const QString &bundleId,
|
||||
const QString &description, const QString &logoUrl,
|
||||
const QString &websiteUrl, QGridLayout *gridLayout,
|
||||
int row, int col,
|
||||
int row, int col, bool useBundleIdForIcon = true,
|
||||
const SponsorType &sponsorType = SponsorType());
|
||||
void setupDefaultAppsPage();
|
||||
void setupLoadingPage();
|
||||
|
||||
@@ -1,23 +1,19 @@
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
#include <QPixmap>
|
||||
#include <QtConcurrent/QtConcurrent>
|
||||
|
||||
void fetchAppIconFromApple(const QString &bundleId,
|
||||
std::function<void(const QPixmap &)> callback,
|
||||
QObject *context)
|
||||
void fetchAppIconFromApple(QNetworkAccessManager *manager,
|
||||
const QString &bundleId,
|
||||
std::function<void(const QPixmap &)> callback)
|
||||
{
|
||||
QNetworkAccessManager *manager = new QNetworkAccessManager(context);
|
||||
QString url =
|
||||
QString("https://itunes.apple.com/lookup?bundleId=%1").arg(bundleId);
|
||||
|
||||
QNetworkReply *reply = manager->get(QNetworkRequest(QUrl(url)));
|
||||
QObject::connect(
|
||||
reply, &QNetworkReply::finished, context,
|
||||
[reply, callback, manager, context]() {
|
||||
reply, &QNetworkReply::finished, [reply, callback, manager]() {
|
||||
QByteArray data = reply->readAll();
|
||||
reply->deleteLater();
|
||||
|
||||
@@ -25,7 +21,6 @@ void fetchAppIconFromApple(const QString &bundleId,
|
||||
QJsonDocument doc = QJsonDocument::fromJson(data, &parseError);
|
||||
if (parseError.error != QJsonParseError::NoError) {
|
||||
callback(QPixmap());
|
||||
manager->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -33,7 +28,6 @@ void fetchAppIconFromApple(const QString &bundleId,
|
||||
QJsonArray results = obj.value("results").toArray();
|
||||
if (results.isEmpty()) {
|
||||
callback(QPixmap());
|
||||
manager->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -41,21 +35,19 @@ void fetchAppIconFromApple(const QString &bundleId,
|
||||
QString iconUrl = appInfo.value("artworkUrl100").toString();
|
||||
if (iconUrl.isEmpty()) {
|
||||
callback(QPixmap());
|
||||
manager->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
// Fetch the icon image
|
||||
QNetworkReply *iconReply =
|
||||
manager->get(QNetworkRequest(QUrl(iconUrl)));
|
||||
QObject::connect(iconReply, &QNetworkReply::finished, context,
|
||||
[iconReply, callback, manager]() {
|
||||
QObject::connect(iconReply, &QNetworkReply::finished,
|
||||
[iconReply, callback]() {
|
||||
QByteArray iconData = iconReply->readAll();
|
||||
iconReply->deleteLater();
|
||||
QPixmap pixmap;
|
||||
pixmap.loadFromData(iconData);
|
||||
callback(pixmap);
|
||||
manager->deleteLater();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
+4
-3
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
#include <QDebug>
|
||||
#include <QImage>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QtCore/QObject>
|
||||
#include <libimobiledevice/afc.h>
|
||||
#include <libimobiledevice/installation_proxy.h>
|
||||
@@ -375,9 +376,9 @@ void get_battery_info(std::string productType, idevice_t idevice,
|
||||
void parseOldDeviceBattery(PlistNavigator &ioreg, DeviceInfo &d);
|
||||
void parseDeviceBattery(PlistNavigator &ioreg, DeviceInfo &d);
|
||||
|
||||
void fetchAppIconFromApple(const QString &bundleId,
|
||||
std::function<void(const QPixmap &)> callback,
|
||||
QObject *context);
|
||||
void fetchAppIconFromApple(QNetworkAccessManager *manager,
|
||||
const QString &bundleId,
|
||||
std::function<void(const QPixmap &)> callback);
|
||||
|
||||
afc_error_t afc2_client_new(idevice_t device, afc_client_t *afc);
|
||||
|
||||
|
||||
@@ -36,9 +36,8 @@ AppTabWidget::AppTabWidget(const QString &appName, const QString &bundleId,
|
||||
|
||||
void AppTabWidget::fetchAppIcon()
|
||||
{
|
||||
fetchAppIconFromApple(
|
||||
m_bundleId,
|
||||
[this](const QPixmap &pixmap) {
|
||||
::fetchAppIconFromApple(
|
||||
m_networkManager, m_bundleId, [this](const QPixmap &pixmap) {
|
||||
if (!pixmap.isNull()) {
|
||||
QPixmap scaled =
|
||||
pixmap.scaled(32, 32, Qt::KeepAspectRatioByExpanding,
|
||||
@@ -56,8 +55,7 @@ void AppTabWidget::fetchAppIcon()
|
||||
|
||||
m_iconLabel->setPixmap(rounded);
|
||||
}
|
||||
},
|
||||
this);
|
||||
});
|
||||
}
|
||||
|
||||
void AppTabWidget::setSelected(bool selected)
|
||||
|
||||
@@ -61,6 +61,7 @@ private:
|
||||
QLabel *m_nameLabel;
|
||||
QLabel *m_versionLabel;
|
||||
QList<AppTabWidget *> m_appTabs;
|
||||
QNetworkAccessManager *m_networkManager = new QNetworkAccessManager(this);
|
||||
};
|
||||
|
||||
class InstalledAppsWidget : public QWidget
|
||||
|
||||
+3
-1
@@ -265,7 +265,9 @@ MainWindow::MainWindow(QWidget *parent)
|
||||
// installed via package manager on Linux
|
||||
this);
|
||||
qDebug() << "Checking for updates...";
|
||||
m_updater->checkForUpdates();
|
||||
SettingsManager::sharedInstance()->doIfEnabled(
|
||||
SettingsManager::Setting::AutoCheckUpdates,
|
||||
[this]() { m_updater->checkForUpdates(); });
|
||||
}
|
||||
|
||||
void MainWindow::createMenus()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// https://github.com/raythorn/QProcessIndicator/blob/master/QProcessIndicator/QProcessIndicator.cpp
|
||||
#include "qprocessindicator.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDebug>
|
||||
#include <QPoint>
|
||||
#include <QtGlobal>
|
||||
@@ -16,6 +16,13 @@ QProcessIndicator::QProcessIndicator(QWidget *parent)
|
||||
|
||||
m_timer = new QTimer();
|
||||
connect(m_timer, SIGNAL(timeout()), this, SLOT(onTimeout()));
|
||||
connect(qApp, &QApplication::paletteChanged, this,
|
||||
&QProcessIndicator::updateStyle);
|
||||
}
|
||||
void QProcessIndicator::updateStyle()
|
||||
{
|
||||
m_color = palette().color(QPalette::Highlight);
|
||||
update();
|
||||
}
|
||||
|
||||
QProcessIndicator::~QProcessIndicator()
|
||||
|
||||
@@ -47,6 +47,7 @@ private:
|
||||
void drawRotateLine(QPainter *painter);
|
||||
void drawScaleLine(QPainter *painter);
|
||||
void drawRotateBall(QPainter *painter);
|
||||
void updateStyle();
|
||||
|
||||
private:
|
||||
int m_type;
|
||||
|
||||
@@ -39,9 +39,8 @@ SponsorAppCard::SponsorAppCard(QWidget *parent) : QWidget{parent}
|
||||
"Create an online store within minutes and start selling.";
|
||||
QString websiteUrl = "https://www.shopify.com";
|
||||
|
||||
fetchAppIconFromApple(
|
||||
bundleId,
|
||||
[iconLabel](const QPixmap &pixmap) {
|
||||
::fetchAppIconFromApple(
|
||||
m_networkManager, bundleId, [iconLabel](const QPixmap &pixmap) {
|
||||
if (!pixmap.isNull()) {
|
||||
QPixmap scaled =
|
||||
pixmap.scaled(64, 64, Qt::KeepAspectRatioByExpanding,
|
||||
@@ -59,8 +58,7 @@ SponsorAppCard::SponsorAppCard(QWidget *parent) : QWidget{parent}
|
||||
|
||||
iconLabel->setPixmap(rounded);
|
||||
}
|
||||
},
|
||||
this);
|
||||
});
|
||||
|
||||
// Vertical layout for name and description
|
||||
QVBoxLayout *textLayout = new QVBoxLayout();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#ifndef SPONSORAPPCARD_H
|
||||
#define SPONSORAPPCARD_H
|
||||
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QWidget>
|
||||
|
||||
class SponsorAppCard : public QWidget
|
||||
@@ -9,6 +9,9 @@ class SponsorAppCard : public QWidget
|
||||
public:
|
||||
explicit SponsorAppCard(QWidget *parent = nullptr);
|
||||
|
||||
private:
|
||||
QNetworkAccessManager *m_networkManager = new QNetworkAccessManager(this);
|
||||
|
||||
signals:
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user