diff --git a/src/airplaywindow.cpp b/src/airplaywindow.cpp index 010a0a0..35106c3 100644 --- a/src/airplaywindow.cpp +++ b/src/airplaywindow.cpp @@ -69,8 +69,9 @@ QStringList AirPlaySettings::toArgs() const // FPS args << "-fps" << QString::number(fps); + // FIXME: causes seg fault on Windows ? // Allow new connections to take over - args << "-nohold"; + // args << "-nohold"; return args; } @@ -80,7 +81,7 @@ AirPlaySettingsDialog::AirPlaySettingsDialog(QWidget *parent) { setupUI(); setWindowTitle("AirPlay Settings"); - resize(500, 600); + resize(300, 300); } void AirPlaySettingsDialog::setupUI() @@ -167,16 +168,17 @@ void AirPlayWindow::setupUI() m_loadingIndicator = new QProcessIndicator(); m_loadingIndicator->setType(QProcessIndicator::line_rotate); - m_loadingIndicator->setFixedSize(64, 32); + m_loadingIndicator->setFixedSize(24, 24); m_loadingIndicator->start(); QHBoxLayout *loadingLayout = new QHBoxLayout(); - loadingLayout->setSpacing(1); m_loadingLabel = new QLabel("Starting AirPlay Server..."); - m_loadingLabel->setAlignment(Qt::AlignCenter); + loadingLayout->addStretch(); loadingLayout->addWidget(m_loadingLabel); + loadingLayout->addSpacing(5); loadingLayout->addWidget(m_loadingIndicator); + loadingLayout->addStretch(); m_tutorialLayout->addLayout(loadingLayout); m_tutorialLayout->addSpacing(1); @@ -319,8 +321,6 @@ void AirPlayWindow::startAirPlayServer() void AirPlayWindow::stopAirPlayServer() { if (m_serverThread) { - // m_serverThread->stopServer(); - // m_serverThread->wait(3000); m_serverThread->quit(); m_serverThread->deleteLater(); m_serverThread = nullptr; @@ -364,7 +364,7 @@ void AirPlayWindow::onServerStatusChanged(bool running) if (running) { // Server started successfully, hide loading indicator and show tutorial // video - m_loadingLabel->setText("Waiting for device connection..."); + m_loadingLabel->setText("Waiting for device connection"); // Show tutorial video and instructions m_tutorialVideoWidget->setVisible(true); @@ -460,7 +460,6 @@ AirPlayServerThread::AirPlayServerThread(QObject *parent) AirPlayServerThread::~AirPlayServerThread() { - // stopServer(); uxplay_cleanup(); wait(); } diff --git a/src/devicesidebarwidget.cpp b/src/devicesidebarwidget.cpp index d3afda0..a77dc88 100644 --- a/src/devicesidebarwidget.cpp +++ b/src/devicesidebarwidget.cpp @@ -283,7 +283,7 @@ DeviceSidebarWidget::DeviceSidebarWidget(QWidget *parent) // Set minimum width setMinimumWidth(200); - setMaximumWidth(250); + setMaximumWidth(200); // Listen to AppContext selection changes connect(AppContext::sharedInstance(), diff --git a/src/infolabel.cpp b/src/infolabel.cpp index 4c604b2..ef5f411 100644 --- a/src/infolabel.cpp +++ b/src/infolabel.cpp @@ -20,10 +20,13 @@ #include "infolabel.h" #include #include +#include #include -InfoLabel::InfoLabel(const QString &text, QWidget *parent) - : QLabel(text, parent), m_originalText(text) +InfoLabel::InfoLabel(const QString &text, const QString &textToCopy, + QWidget *parent) + : QLabel(text, parent), m_originalText(text), + m_textToCopy(!textToCopy.isEmpty() ? textToCopy : text) { setCursor(Qt::PointingHandCursor); setStyleSheet("QLabel:hover { background-color: rgba(255, 255, 255, 0.1); " @@ -38,9 +41,13 @@ InfoLabel::InfoLabel(const QString &text, QWidget *parent) void InfoLabel::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) { - QClipboard *clipboard = QApplication::clipboard(); - clipboard->setText(m_originalText); + int originalWidth = width(); + QClipboard *clipboard = QApplication::clipboard(); + clipboard->setText(m_textToCopy); + + // prevent layout shifts + setMinimumWidth(originalWidth); setText("Copied!"); setStyleSheet("QLabel { color: #4CAF50; font-weight: bold; } " "QLabel:hover { background-color: rgba(255, 255, 255, " @@ -72,8 +79,14 @@ void InfoLabel::leaveEvent(QEvent *event) void InfoLabel::restoreOriginalText() { setText(m_originalText); + setMinimumWidth(0); setStyleSheet("QLabel:hover { background-color: rgba(255, 255, 255, 0.1); " "border-radius: 2px; }"); } void InfoLabel::setOriginalText(const QString &text) { m_originalText = text; } + +void InfoLabel::setTextToCopy(const QString &textToCopy) +{ + m_textToCopy = textToCopy; +} \ No newline at end of file diff --git a/src/infolabel.h b/src/infolabel.h index 6a6d723..18e55d9 100644 --- a/src/infolabel.h +++ b/src/infolabel.h @@ -29,10 +29,11 @@ class InfoLabel : public QLabel public: explicit InfoLabel(const QString &text = QString(), + const QString &textToCopy = QString(), QWidget *parent = nullptr); - // Allow updating the original text (useful for PrivateInfoLabel) void setOriginalText(const QString &text); + void setTextToCopy(const QString &textToCopy); protected: void mousePressEvent(QMouseEvent *event) override; @@ -44,6 +45,7 @@ private slots: private: QString m_originalText; + QString m_textToCopy; QTimer *m_restoreTimer; }; diff --git a/src/main.cpp b/src/main.cpp index 7cb2815..2723eea 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -77,9 +77,6 @@ int main(int argc, char *argv[]) setenv("GST_PLUGIN_PATH", gstPluginPath.toUtf8().constData(), 1); setenv("GST_PLUGIN_SYSTEM_PATH", gstPluginPath.toUtf8().constData(), 1); setenv("GST_PLUGIN_SCANNER", gstPluginScannerPath.toUtf8().constData(), 1); -#endif -#ifndef __APPLE__ - QApplication::setStyle(QStyleFactory::create("Fusion")); #endif MainWindow *w = MainWindow::sharedInstance(); w->show(); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 9a36264..ae53251 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -201,6 +201,10 @@ MainWindow::MainWindow(QWidget *parent) ui->statusbar->addPermanentWidget(appVersionLabel); ui->statusbar->addPermanentWidget(githubButton); ui->statusbar->addPermanentWidget(settingsButton); +#ifdef WIN32 + ui->statusbar->setStyleSheet( + "QStatusBar { border-top: 1px solid #dcdcdc; }"); +#endif #ifdef __linux__ QList mounted_iFusePaths = iFuseManager::getMountPoints(); diff --git a/src/privateinfolabel.cpp b/src/privateinfolabel.cpp index dcc188f..4a92719 100644 --- a/src/privateinfolabel.cpp +++ b/src/privateinfolabel.cpp @@ -28,7 +28,7 @@ PrivateInfoLabel::PrivateInfoLabel(const QString &fullText, QWidget *parent) layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(5); - m_textLabel = new InfoLabel(m_maskedText, this); + m_textLabel = new InfoLabel(m_maskedText, m_fullText, this); layout->addWidget(m_textLabel); m_toggleButton = new ZIconWidget( @@ -55,12 +55,10 @@ void PrivateInfoLabel::toggleVisibility() m_isVisible = !m_isVisible; if (m_isVisible) { m_textLabel->setText(m_fullText); - m_textLabel->setOriginalText(m_fullText); m_toggleButton->setIcon(QIcon(":/resources/icons/ClarityEyeLine.png")); m_toggleButton->setToolTip("Hide"); } else { m_textLabel->setText(m_maskedText); - m_textLabel->setOriginalText(m_fullText); m_toggleButton->setIcon( QIcon(":/resources/icons/ClarityEyeHideLine.png")); m_toggleButton->setToolTip("Show"); diff --git a/src/settingswidget.cpp b/src/settingswidget.cpp index 5fa66cc..b04e85d 100644 --- a/src/settingswidget.cpp +++ b/src/settingswidget.cpp @@ -42,6 +42,10 @@ SettingsWidget::SettingsWidget(QWidget *parent) : QDialog{parent} setupUI(); loadSettings(); connectSignals(); + // due to scrollbar add 10px on windows +#ifdef WIN32 + resize(sizeHint().width() + 10, sizeHint().height()); +#endif } void SettingsWidget::setupUI() @@ -54,6 +58,7 @@ void SettingsWidget::setupUI() auto *scrollArea = new QScrollArea(); auto *scrollWidget = new QWidget(); auto *scrollLayout = new QVBoxLayout(scrollWidget); + scrollLayout->setContentsMargins(10, 10, 10, 10); // === GENERAL SETTINGS === auto *generalGroup = new QGroupBox("General"); @@ -207,7 +212,7 @@ void SettingsWidget::setupUI() QString( "iDescriptor v%1\n" "A free, open-source, and cross-platform iDevice management tool.\n" - "© 2025 See AUTHORS for details. Licensed under AGPLv3.") + "© 2026 See AUTHORS for details. Licensed under AGPLv3.") .arg(APP_VERSION)); footerLabel->setAlignment(Qt::AlignCenter); footerLabel->setStyleSheet("color: gray; font-size: 8pt;"); @@ -348,13 +353,25 @@ void SettingsWidget::onCheckUpdatesClicked() m_checkUpdatesButton->setText("Checking..."); m_checkUpdatesButton->setEnabled(false); - MainWindow::sharedInstance()->m_updater->checkForUpdates(); + connect( + MainWindow::sharedInstance()->m_updater, &ZUpdater::dataAvailable, this, + [this](const QJsonDocument data, bool isUpdateAvailable) { + if (isUpdateAvailable) { + QMessageBox::information( + this, "Update Available", + "A new version of iDescriptor is available. Please " + "update to the latest version."); + } else { + QMessageBox::information(this, "No Updates", + "You are using the latest version of " + "iDescriptor."); + } + m_checkUpdatesButton->setText("Check for Updates"); + m_checkUpdatesButton->setEnabled(true); + }, + Qt::SingleShotConnection); - // Simulate check (replace with actual update check) - QTimer::singleShot(2000, this, [this]() { - m_checkUpdatesButton->setText("Check for Updates"); - m_checkUpdatesButton->setEnabled(true); - }); + MainWindow::sharedInstance()->m_updater->checkForUpdates(); } void SettingsWidget::onResetToDefaultsClicked() diff --git a/src/welcomewidget.cpp b/src/welcomewidget.cpp index 57bb706..05764ba 100644 --- a/src/welcomewidget.cpp +++ b/src/welcomewidget.cpp @@ -79,15 +79,11 @@ void WelcomeWidget::setupUI() connect(m_githubLabel, &ZLabel::clicked, this, []() { QDesktopServices::openUrl(QUrl(REPO_URL)); }); - // Make it look like a link QPalette githubPalette = m_githubLabel->palette(); githubPalette.setColor(QPalette::WindowText, QColor(0, 122, 255)); // Apple blue m_githubLabel->setPalette(githubPalette); - // Connect click functionality using installEventFilter - m_githubLabel->installEventFilter(this); - m_mainLayout->addWidget(m_githubLabel, 0, Qt::AlignCenter); // no additional deps needed on macOS