mirror of
https://invent.kde.org/system/dolphin
synced 2024-07-04 17:30:55 +00:00
Merge branch 'improve_filelight_installation_ux' into 'master'
Improve Filelight installation UX See merge request system/dolphin!783
This commit is contained in:
commit
d71304ec5a
|
@ -103,7 +103,7 @@ find_package(Phonon4Qt6 CONFIG REQUIRED)
|
||||||
find_package(PackageKitQt6)
|
find_package(PackageKitQt6)
|
||||||
set_package_properties(PackageKitQt6
|
set_package_properties(PackageKitQt6
|
||||||
PROPERTIES DESCRIPTION "Software Manager integration"
|
PROPERTIES DESCRIPTION "Software Manager integration"
|
||||||
TYPE OPTIONAL
|
TYPE RECOMMENDED
|
||||||
PURPOSE "Used in the service menu installer"
|
PURPOSE "Used in the service menu installer"
|
||||||
)
|
)
|
||||||
if(PackageKitQt6_FOUND)
|
if(PackageKitQt6_FOUND)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
include(ECMAddAppIcon)
|
include(ECMAddAppIcon)
|
||||||
|
|
||||||
|
set(FILELIGHT_PACKAGE_NAME "filelight")
|
||||||
configure_file(config-dolphin.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-dolphin.h)
|
configure_file(config-dolphin.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-dolphin.h)
|
||||||
|
|
||||||
add_definitions(
|
add_definitions(
|
||||||
|
@ -273,6 +274,7 @@ target_sources(dolphinstatic PRIVATE
|
||||||
dolphincontextmenu.cpp
|
dolphincontextmenu.cpp
|
||||||
dolphinnavigatorswidgetaction.cpp
|
dolphinnavigatorswidgetaction.cpp
|
||||||
dolphintabbar.cpp
|
dolphintabbar.cpp
|
||||||
|
dolphinpackageinstaller.cpp
|
||||||
dolphinplacesmodelsingleton.cpp
|
dolphinplacesmodelsingleton.cpp
|
||||||
dolphinrecenttabsmenu.cpp
|
dolphinrecenttabsmenu.cpp
|
||||||
dolphintabpage.cpp
|
dolphintabpage.cpp
|
||||||
|
@ -333,6 +335,7 @@ target_sources(dolphinstatic PRIVATE
|
||||||
dolphincontextmenu.h
|
dolphincontextmenu.h
|
||||||
dolphinnavigatorswidgetaction.h
|
dolphinnavigatorswidgetaction.h
|
||||||
dolphintabbar.h
|
dolphintabbar.h
|
||||||
|
dolphinpackageinstaller.h
|
||||||
dolphinplacesmodelsingleton.h
|
dolphinplacesmodelsingleton.h
|
||||||
dolphinrecenttabsmenu.h
|
dolphinrecenttabsmenu.h
|
||||||
dolphintabpage.h
|
dolphintabpage.h
|
||||||
|
@ -458,6 +461,13 @@ if (HAVE_PLASMA_ACTIVITIES)
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(HAVE_PACKAGEKIT)
|
||||||
|
target_link_libraries(
|
||||||
|
dolphinstatic
|
||||||
|
PK::packagekitqt6
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
if (HAVE_KUSERFEEDBACK)
|
if (HAVE_KUSERFEEDBACK)
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
dolphinstatic
|
dolphinstatic
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
|
/** Set whether to build Dolphin with support for these technologies or not. */
|
||||||
#cmakedefine01 HAVE_BALOO
|
#cmakedefine01 HAVE_BALOO
|
||||||
#cmakedefine01 HAVE_PLASMA_ACTIVITIES
|
#cmakedefine01 HAVE_PLASMA_ACTIVITIES
|
||||||
#cmakedefine01 HAVE_KUSERFEEDBACK
|
#cmakedefine01 HAVE_KUSERFEEDBACK
|
||||||
#cmakedefine01 HAVE_PACKAGEKIT
|
#cmakedefine01 HAVE_PACKAGEKIT
|
||||||
#cmakedefine01 HAVE_TERMINAL
|
#cmakedefine01 HAVE_TERMINAL
|
||||||
#cmakedefine01 HAVE_X11
|
#cmakedefine01 HAVE_X11
|
||||||
|
|
||||||
|
/** The name of the KDE Filelight package. */
|
||||||
|
#cmakedefine FILELIGHT_PACKAGE_NAME "@FILELIGHT_PACKAGE_NAME@"
|
||||||
|
|
110
src/dolphinpackageinstaller.cpp
Normal file
110
src/dolphinpackageinstaller.cpp
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
/*
|
||||||
|
This file is part of the KDE project
|
||||||
|
SPDX-FileCopyrightText: 2024 Felix Ernst <felixernst@kde.org>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dolphinpackageinstaller.h"
|
||||||
|
|
||||||
|
#include <KLocalizedString>
|
||||||
|
|
||||||
|
#if HAVE_PACKAGEKIT
|
||||||
|
#include <PackageKit/Daemon>
|
||||||
|
#else
|
||||||
|
#include <QDesktopServices>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QtAssert>
|
||||||
|
|
||||||
|
DolphinPackageInstaller::DolphinPackageInstaller(const QString &packageName,
|
||||||
|
const QUrl &fallBackInstallationPageUrl,
|
||||||
|
std::function<bool()> isPackageInstalledCheck,
|
||||||
|
QObject *parent)
|
||||||
|
: KJob(parent)
|
||||||
|
, m_packageName{packageName}
|
||||||
|
, m_fallBackInstallationPageUrl{fallBackInstallationPageUrl}
|
||||||
|
, m_isPackageInstalledCheck{isPackageInstalledCheck}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void DolphinPackageInstaller::start()
|
||||||
|
{
|
||||||
|
if (m_isPackageInstalledCheck()) {
|
||||||
|
emitResult();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if HAVE_PACKAGEKIT
|
||||||
|
PackageKit::Daemon::setHints(PackageKit::Daemon::hints() + QStringList{QStringLiteral("interactive=true")});
|
||||||
|
const PackageKit::Transaction *resolveTransaction = PackageKit::Daemon::resolve(m_packageName);
|
||||||
|
|
||||||
|
connect(resolveTransaction, &PackageKit::Transaction::errorCode, this, &DolphinPackageInstaller::slotInstallationFailed);
|
||||||
|
connect(resolveTransaction, &PackageKit::Transaction::finished, this, [this]() { // Will be disconnected if we find a package.
|
||||||
|
slotInstallationFailed(PackageKit::Transaction::ErrorPackageNotFound,
|
||||||
|
i18nc("@info:shell about system packages", "Could not find package %1.", m_packageName));
|
||||||
|
});
|
||||||
|
connect(resolveTransaction,
|
||||||
|
&PackageKit::Transaction::package,
|
||||||
|
this,
|
||||||
|
[this, resolveTransaction](PackageKit::Transaction::Info /* info */, const QString &packageId) {
|
||||||
|
disconnect(resolveTransaction, nullptr, this, nullptr); // We only care about the first package.
|
||||||
|
const PackageKit::Transaction *installTransaction = PackageKit::Daemon::installPackage(packageId);
|
||||||
|
connectTransactionToJobProgress(*installTransaction);
|
||||||
|
connect(installTransaction,
|
||||||
|
&PackageKit::Transaction::errorCode,
|
||||||
|
this,
|
||||||
|
[installTransaction, this](PackageKit::Transaction::Error error, const QString &details) {
|
||||||
|
disconnect(installTransaction, nullptr, this, nullptr); // We only want to emit a result once.
|
||||||
|
slotInstallationFailed(error, details);
|
||||||
|
});
|
||||||
|
connect(installTransaction,
|
||||||
|
&PackageKit::Transaction::finished,
|
||||||
|
this,
|
||||||
|
[installTransaction, this](const PackageKit::Transaction::Exit status, uint /* runtime */) {
|
||||||
|
disconnect(installTransaction, nullptr, this, nullptr); // We only want to emit a result once.
|
||||||
|
if (status == PackageKit::Transaction::ExitSuccess) {
|
||||||
|
emitResult();
|
||||||
|
} else {
|
||||||
|
slotInstallationFailed(PackageKit::Transaction::ErrorUnknown,
|
||||||
|
i18nc("@info %1 is error code",
|
||||||
|
"Installation exited without reporting success. (%1)",
|
||||||
|
QMetaEnum::fromType<PackageKit::Transaction::Exit>().valueToKey(status)));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
#else
|
||||||
|
QDesktopServices::openUrl(m_fallBackInstallationPageUrl);
|
||||||
|
auto waitForSuccess = new QTimer(this);
|
||||||
|
connect(waitForSuccess, &QTimer::timeout, this, [this]() {
|
||||||
|
if (m_isPackageInstalledCheck()) {
|
||||||
|
emitResult();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
waitForSuccess->start(3000);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if HAVE_PACKAGEKIT
|
||||||
|
void DolphinPackageInstaller::connectTransactionToJobProgress(const PackageKit::Transaction &transaction)
|
||||||
|
{
|
||||||
|
connect(&transaction, &PackageKit::Transaction::speedChanged, this, [this, &transaction]() {
|
||||||
|
emitSpeed(transaction.speed());
|
||||||
|
});
|
||||||
|
connect(&transaction, &PackageKit::Transaction::percentageChanged, this, [this, &transaction]() {
|
||||||
|
setPercent(transaction.percentage());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void DolphinPackageInstaller::slotInstallationFailed(PackageKit::Transaction::Error error, const QString &details)
|
||||||
|
{
|
||||||
|
setErrorString(xi18nc("@info:shell %1 is package name, %2 is error message, %3 is error e.g. 'ErrorNoNetwork'",
|
||||||
|
"Installing <application>%1</application> failed: %2 (%3)<nl/>Please try installing <application>%1</application> manually instead.",
|
||||||
|
m_packageName,
|
||||||
|
details,
|
||||||
|
QMetaEnum::fromType<PackageKit::Transaction::Error>().valueToKey(error)));
|
||||||
|
setError(error);
|
||||||
|
emitResult();
|
||||||
|
}
|
||||||
|
#endif
|
85
src/dolphinpackageinstaller.h
Normal file
85
src/dolphinpackageinstaller.h
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
/*
|
||||||
|
This file is part of the KDE project
|
||||||
|
SPDX-FileCopyrightText: 2024 Felix Ernst <felixernst@kde.org>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef dolphinpackageinstaller_H
|
||||||
|
#define dolphinpackageinstaller_H
|
||||||
|
|
||||||
|
#include "config-dolphin.h"
|
||||||
|
|
||||||
|
#if HAVE_PACKAGEKIT
|
||||||
|
#include <PackageKit/Transaction>
|
||||||
|
#endif
|
||||||
|
#include <KJob>
|
||||||
|
|
||||||
|
#include <QUrl>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A KJob providing simple means to install a package.
|
||||||
|
*/
|
||||||
|
class DolphinPackageInstaller : public KJob
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Installs a system package.
|
||||||
|
*
|
||||||
|
* @param packageName A name that can be resolved to a package.
|
||||||
|
* @param fallBackInstallationPageUrl This url will be opened if Dolphin was installed without the PackageKit library. A good choice for this parameter
|
||||||
|
* is an appstream url that will be opened in a software store like Discover
|
||||||
|
* e.g. "appstream://org.kde.filelight.desktop". The user is then expected to install the package themselves and
|
||||||
|
* KJob::result() will be emitted when it is detected that the installation finished successfully.
|
||||||
|
* @param isPackageInstalledCheck A function that can be regularly checked to determine if the installation was already successful.
|
||||||
|
*/
|
||||||
|
explicit DolphinPackageInstaller(const QString &packageName,
|
||||||
|
const QUrl &fallBackInstallationPageUrl,
|
||||||
|
std::function<bool()> isPackageInstalledCheck,
|
||||||
|
QObject *parent = nullptr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see KJob::start().
|
||||||
|
* Make sure to connect to the KJob::result() signal and show the KJob::errorString() to users there before calling this.
|
||||||
|
*/
|
||||||
|
void start() override;
|
||||||
|
|
||||||
|
/** @see KJob::errorString(). */
|
||||||
|
inline QString errorString() const override
|
||||||
|
{
|
||||||
|
return m_errorString;
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
/** @see KJob::errorString(). */
|
||||||
|
inline void setErrorString(const QString &errorString)
|
||||||
|
{
|
||||||
|
m_errorString = errorString;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if HAVE_PACKAGEKIT
|
||||||
|
/**
|
||||||
|
* Makes sure progress signals of @p transaction are forwarded to KJob's progress signals.
|
||||||
|
*/
|
||||||
|
void connectTransactionToJobProgress(const PackageKit::Transaction &transaction);
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
/** Creates a nice user-facing error message from its parameters and then finishes this job with an @p error. */
|
||||||
|
void slotInstallationFailed(PackageKit::Transaction::Error error, const QString &details);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
/** The name of the package that is supposed to be installed. */
|
||||||
|
const QString m_packageName;
|
||||||
|
|
||||||
|
/** @see DolphinPackageInstaller::DolphinPackageInstaller(). */
|
||||||
|
const QUrl m_fallBackInstallationPageUrl;
|
||||||
|
|
||||||
|
/** @see DolphinPackageInstaller::DolphinPackageInstaller(). */
|
||||||
|
const std::function<bool()> m_isPackageInstalledCheck;
|
||||||
|
|
||||||
|
/** @see KJob::errorString(). */
|
||||||
|
QString m_errorString;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // dolphinpackageinstaller_H
|
|
@ -168,6 +168,7 @@ DolphinViewContainer::DolphinViewContainer(const QUrl &url, QWidget *parent)
|
||||||
});
|
});
|
||||||
connect(m_statusBar, &DolphinStatusBar::stopPressed, this, &DolphinViewContainer::stopDirectoryLoading);
|
connect(m_statusBar, &DolphinStatusBar::stopPressed, this, &DolphinViewContainer::stopDirectoryLoading);
|
||||||
connect(m_statusBar, &DolphinStatusBar::zoomLevelChanged, this, &DolphinViewContainer::slotStatusBarZoomLevelChanged);
|
connect(m_statusBar, &DolphinStatusBar::zoomLevelChanged, this, &DolphinViewContainer::slotStatusBarZoomLevelChanged);
|
||||||
|
connect(m_statusBar, &DolphinStatusBar::showMessage, this, &DolphinViewContainer::showMessage);
|
||||||
|
|
||||||
m_statusBarTimer = new QTimer(this);
|
m_statusBarTimer = new QTimer(this);
|
||||||
m_statusBarTimer->setSingleShot(true);
|
m_statusBarTimer->setSingleShot(true);
|
||||||
|
|
|
@ -49,8 +49,8 @@ QPair<QString, Qt::SortOrder> sortOrderForUrl(QUrl &url);
|
||||||
/**
|
/**
|
||||||
* TODO: Move this somewhere global to all KDE apps, not just Dolphin
|
* TODO: Move this somewhere global to all KDE apps, not just Dolphin
|
||||||
*/
|
*/
|
||||||
const int VERTICAL_SPACER_HEIGHT = 12;
|
constexpr int VERTICAL_SPACER_HEIGHT = 12;
|
||||||
const int LAYOUT_SPACING_SMALL = 2;
|
constexpr int LAYOUT_SPACING_SMALL = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Animated { WithAnimation, WithoutAnimation };
|
enum Animated { WithAnimation, WithoutAnimation };
|
||||||
|
|
|
@ -70,6 +70,13 @@ DolphinStatusBar::DolphinStatusBar(QWidget *parent)
|
||||||
|
|
||||||
// Initialize space information
|
// Initialize space information
|
||||||
m_spaceInfo = new StatusBarSpaceInfo(contentsContainer);
|
m_spaceInfo = new StatusBarSpaceInfo(contentsContainer);
|
||||||
|
connect(m_spaceInfo, &StatusBarSpaceInfo::showMessage, this, &DolphinStatusBar::showMessage);
|
||||||
|
connect(m_spaceInfo,
|
||||||
|
&StatusBarSpaceInfo::showInstallationProgress,
|
||||||
|
this,
|
||||||
|
[this](const QString ¤tlyRunningTaskTitle, int installationProgressPercent) {
|
||||||
|
showProgress(currentlyRunningTaskTitle, installationProgressPercent, CancelLoading::Disallowed);
|
||||||
|
});
|
||||||
|
|
||||||
// Initialize progress information
|
// Initialize progress information
|
||||||
m_stopButton = new QToolButton(contentsContainer);
|
m_stopButton = new QToolButton(contentsContainer);
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
|
|
||||||
#include "animatedheightwidget.h"
|
#include "animatedheightwidget.h"
|
||||||
|
|
||||||
|
#include <KMessageWidget>
|
||||||
|
|
||||||
#include <QTime>
|
#include <QTime>
|
||||||
|
|
||||||
class QUrl;
|
class QUrl;
|
||||||
|
@ -96,6 +98,11 @@ Q_SIGNALS:
|
||||||
|
|
||||||
void zoomLevelChanged(int zoomLevel);
|
void zoomLevelChanged(int zoomLevel);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requests for @p message with the given @p messageType to be shown to the user in a non-modal way.
|
||||||
|
*/
|
||||||
|
void showMessage(const QString &message, KMessageWidget::MessageType messageType);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void contextMenuEvent(QContextMenuEvent *event) override;
|
void contextMenuEvent(QContextMenuEvent *event) override;
|
||||||
void paintEvent(QPaintEvent *paintEvent) override;
|
void paintEvent(QPaintEvent *paintEvent) override;
|
||||||
|
|
|
@ -6,6 +6,9 @@
|
||||||
|
|
||||||
#include "statusbarspaceinfo.h"
|
#include "statusbarspaceinfo.h"
|
||||||
|
|
||||||
|
#include "config-dolphin.h"
|
||||||
|
#include "dolphinpackageinstaller.h"
|
||||||
|
#include "global.h"
|
||||||
#include "spaceinfoobserver.h"
|
#include "spaceinfoobserver.h"
|
||||||
|
|
||||||
#include <KCapacityBar>
|
#include <KCapacityBar>
|
||||||
|
@ -16,14 +19,19 @@
|
||||||
|
|
||||||
#include <QDesktopServices>
|
#include <QDesktopServices>
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
|
#include <QLabel>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
|
#include <QPushButton>
|
||||||
#include <QStorageInfo>
|
#include <QStorageInfo>
|
||||||
#include <QToolButton>
|
#include <QToolButton>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QWidgetAction>
|
||||||
|
|
||||||
StatusBarSpaceInfo::StatusBarSpaceInfo(QWidget *parent)
|
StatusBarSpaceInfo::StatusBarSpaceInfo(QWidget *parent)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
, m_observer(nullptr)
|
, m_observer(nullptr)
|
||||||
|
, m_installFilelightWidgetAction{nullptr}
|
||||||
{
|
{
|
||||||
m_capacityBar = new KCapacityBar(KCapacityBar::DrawTextInline, this);
|
m_capacityBar = new KCapacityBar(KCapacityBar::DrawTextInline, this);
|
||||||
m_textInfoButton = new QToolButton(this);
|
m_textInfoButton = new QToolButton(this);
|
||||||
|
@ -116,17 +124,87 @@ void StatusBarSpaceInfo::updateMenu()
|
||||||
const KService::Ptr kdiskfree = KService::serviceByDesktopName(QStringLiteral("org.kde.kdf"));
|
const KService::Ptr kdiskfree = KService::serviceByDesktopName(QStringLiteral("org.kde.kdf"));
|
||||||
|
|
||||||
if (!filelight && !kdiskfree) {
|
if (!filelight && !kdiskfree) {
|
||||||
QAction *installFilelight =
|
// Show an UI to install a tool to free up disk space because this is what a user pressing on a "free space" button would want.
|
||||||
m_buttonMenu->addAction(QIcon::fromTheme(QStringLiteral("filelight")), i18n("Install Filelight to View Disk Usage Statistics…"));
|
if (!m_installFilelightWidgetAction) {
|
||||||
|
auto containerWidget = new QWidget{this};
|
||||||
|
containerWidget->setContentsMargins(Dolphin::VERTICAL_SPACER_HEIGHT,
|
||||||
|
Dolphin::VERTICAL_SPACER_HEIGHT,
|
||||||
|
Dolphin::VERTICAL_SPACER_HEIGHT,
|
||||||
|
Dolphin::VERTICAL_SPACER_HEIGHT);
|
||||||
|
auto vLayout = new QVBoxLayout(containerWidget);
|
||||||
|
|
||||||
connect(installFilelight, &QAction::triggered, this, [] {
|
auto installFilelightTitle = new QLabel(i18nc("@title", "Free Up Disk Space"), containerWidget);
|
||||||
|
installFilelightTitle->setAlignment(Qt::AlignCenter);
|
||||||
|
installFilelightTitle->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard | Qt::LinksAccessibleByKeyboard);
|
||||||
|
QFont titleFont{installFilelightTitle->font()};
|
||||||
|
titleFont.setPointSize(titleFont.pointSize() + 2);
|
||||||
|
installFilelightTitle->setFont(titleFont);
|
||||||
|
vLayout->addWidget(installFilelightTitle);
|
||||||
|
|
||||||
|
vLayout->addSpacing(Dolphin::VERTICAL_SPACER_HEIGHT);
|
||||||
|
|
||||||
|
auto installFilelightBody =
|
||||||
|
// i18n: The new line ("<nl/>") tag is only there to format this text visually pleasing, i.e. to avoid having one very long line.
|
||||||
|
new QLabel(xi18nc("@title", "<para>Install additional software to view disk usage statistics<nl/>and identify big files and folders.</para>"),
|
||||||
|
containerWidget);
|
||||||
|
installFilelightBody->setAlignment(Qt::AlignCenter);
|
||||||
|
installFilelightBody->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard | Qt::LinksAccessibleByKeyboard);
|
||||||
|
vLayout->addWidget(installFilelightBody);
|
||||||
|
|
||||||
|
vLayout->addSpacing(Dolphin::VERTICAL_SPACER_HEIGHT);
|
||||||
|
|
||||||
|
auto installFilelightButton =
|
||||||
|
new QPushButton(QIcon::fromTheme(QStringLiteral("filelight")), i18nc("@action:button", "Install Filelight…"), containerWidget);
|
||||||
|
installFilelightButton->setMinimumWidth(std::max(installFilelightButton->sizeHint().width(), installFilelightTitle->sizeHint().width()));
|
||||||
|
auto buttonLayout = new QHBoxLayout{containerWidget};
|
||||||
|
buttonLayout->addWidget(installFilelightButton, 0, Qt::AlignHCenter);
|
||||||
|
vLayout->addLayout(buttonLayout);
|
||||||
|
|
||||||
|
// Make sure one Tab press focuses the button after the UI opened.
|
||||||
|
m_buttonMenu->setFocusProxy(installFilelightButton);
|
||||||
|
containerWidget->setFocusPolicy(Qt::TabFocus);
|
||||||
|
containerWidget->setFocusProxy(installFilelightButton);
|
||||||
|
installFilelightButton->setAccessibleDescription(installFilelightBody->text());
|
||||||
|
|
||||||
|
connect(installFilelightButton, &QAbstractButton::clicked, this, [this] {
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
QDesktopServices::openUrl(QUrl("https://apps.kde.org/filelight"));
|
QDesktopServices::openUrl(QUrl("https://apps.kde.org/filelight"));
|
||||||
#else
|
#else
|
||||||
QDesktopServices::openUrl(QUrl("appstream://org.kde.filelight.desktop"));
|
auto packageInstaller = new DolphinPackageInstaller(
|
||||||
|
FILELIGHT_PACKAGE_NAME,
|
||||||
|
QUrl("appstream://org.kde.filelight.desktop"),
|
||||||
|
[]() {
|
||||||
|
return KService::serviceByDesktopName(QStringLiteral("org.kde.filelight"));
|
||||||
|
},
|
||||||
|
this);
|
||||||
|
connect(packageInstaller, &KJob::result, this, [this](KJob *job) {
|
||||||
|
Q_EMIT showInstallationProgress(QString(), 100); // Hides the progress information in the status bar.
|
||||||
|
if (job->error()) {
|
||||||
|
Q_EMIT showMessage(job->errorString(), KMessageWidget::Error);
|
||||||
|
} else {
|
||||||
|
Q_EMIT showMessage(xi18nc("@info", "<application>Filelight</application> installed successfully."), KMessageWidget::Positive);
|
||||||
|
if (m_textInfoButton->menu()->isVisible()) {
|
||||||
|
m_textInfoButton->menu()->hide();
|
||||||
|
updateMenu();
|
||||||
|
m_textInfoButton->menu()->show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const auto installationTaskText{i18nc("@info:status", "Installing Filelight…")};
|
||||||
|
Q_EMIT showInstallationProgress(installationTaskText, -1);
|
||||||
|
connect(packageInstaller, &KJob::percentChanged, this, [this, installationTaskText](KJob */* job */, long unsigned int percent) {
|
||||||
|
if (percent < 100) { // Ignore some weird reported values.
|
||||||
|
Q_EMIT showInstallationProgress(installationTaskText, percent);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
packageInstaller->start();
|
||||||
#endif
|
#endif
|
||||||
});
|
});
|
||||||
|
|
||||||
|
m_installFilelightWidgetAction = new QWidgetAction{this};
|
||||||
|
m_installFilelightWidgetAction->setDefaultWidget(containerWidget); // transfers ownership of containerWidget
|
||||||
|
}
|
||||||
|
m_buttonMenu->addAction(m_installFilelightWidgetAction);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
#ifndef STATUSBARSPACEINFO_H
|
#ifndef STATUSBARSPACEINFO_H
|
||||||
#define STATUSBARSPACEINFO_H
|
#define STATUSBARSPACEINFO_H
|
||||||
|
|
||||||
|
#include <KMessageWidget>
|
||||||
|
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
|
@ -14,6 +16,7 @@ class QShowEvent;
|
||||||
class QMenu;
|
class QMenu;
|
||||||
class QMouseEvent;
|
class QMouseEvent;
|
||||||
class QToolButton;
|
class QToolButton;
|
||||||
|
class QWidgetAction;
|
||||||
|
|
||||||
class KCapacityBar;
|
class KCapacityBar;
|
||||||
|
|
||||||
|
@ -40,6 +43,14 @@ public:
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
/**
|
||||||
|
* Requests for @p message with the given @p messageType to be shown to the user in a non-modal way.
|
||||||
|
*/
|
||||||
|
void showMessage(const QString &message, KMessageWidget::MessageType messageType);
|
||||||
|
|
||||||
|
void showInstallationProgress(const QString ¤tlyRunningTaskTitle, int installationProgressPercent);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void showEvent(QShowEvent *event) override;
|
void showEvent(QShowEvent *event) override;
|
||||||
void hideEvent(QHideEvent *event) override;
|
void hideEvent(QHideEvent *event) override;
|
||||||
|
@ -55,6 +66,7 @@ private:
|
||||||
KCapacityBar *m_capacityBar;
|
KCapacityBar *m_capacityBar;
|
||||||
QToolButton *m_textInfoButton;
|
QToolButton *m_textInfoButton;
|
||||||
QMenu *m_buttonMenu;
|
QMenu *m_buttonMenu;
|
||||||
|
QWidgetAction *m_installFilelightWidgetAction;
|
||||||
QUrl m_url;
|
QUrl m_url;
|
||||||
bool m_ready;
|
bool m_ready;
|
||||||
bool m_shown;
|
bool m_shown;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user