Compare commits
13 Commits
ubuntu/1.0
...
ubuntu/plu
Author | SHA1 | Date | |
---|---|---|---|
|
217d71ba43 | ||
|
fed35d17a8 | ||
|
d418d68a29 | ||
978e9bfa5f | |||
953908831e | |||
9a2b5b6450 | |||
|
7daa5ffbb7 | ||
64ba4f8a12 | |||
9a41afd011 | |||
|
86c512a2ff | ||
|
d71a36f0ef | ||
|
1821373141 | ||
|
2a7548e4ce |
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +1,2 @@
|
||||
CMakeLists.txt.user
|
||||
build
|
||||
|
@ -9,8 +9,7 @@ set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets LinguistTools)
|
||||
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets LinguistTools)
|
||||
find_package(Qt6 REQUIRED COMPONENTS Widgets DBus LinguistTools)
|
||||
|
||||
set(TS_FILES
|
||||
src/translations/lubuntu-update_en_US.ts
|
||||
@ -36,16 +35,22 @@ set(PROJECT_SOURCES
|
||||
src/conffilehandlerdialog.h
|
||||
src/conffilehandlerdialog.cpp
|
||||
src/conffilehandlerdialog.ui
|
||||
src/ipcfilewatcher.h
|
||||
src/ipcfilewatcher.cpp
|
||||
src/releaseupgradewindow.h
|
||||
src/releaseupgradewindow.cpp
|
||||
src/releaseupgradewindow.ui
|
||||
src/upgradedelaywindow.h
|
||||
src/upgradedelaywindow.cpp
|
||||
src/upgradedelaywindow.ui
|
||||
src/windowshowwatcher.h
|
||||
src/windowshowwatcher.cpp
|
||||
${TS_FILES}
|
||||
)
|
||||
|
||||
set(TRANSLATION_RESOURCES "src/translations.qrc")
|
||||
|
||||
configure_file(${TRANSLATION_RESOURCES} translations.qrc COPYONLY)
|
||||
qt5_add_translation(QM_FILES ${TS_FILES})
|
||||
qt5_add_resources(QM_RESOURCES ${CMAKE_CURRENT_BINARY_DIR}/translations.qrc)
|
||||
qt6_add_translation(QM_FILES ${TS_FILES})
|
||||
qt6_add_resources(QM_RESOURCES ${CMAKE_CURRENT_BINARY_DIR}/translations.qrc)
|
||||
|
||||
add_custom_target(translations ALL DEPENDS ${QM_FILES})
|
||||
|
||||
@ -57,7 +62,9 @@ add_executable(lubuntu-update
|
||||
|
||||
add_dependencies(lubuntu-update translations)
|
||||
|
||||
target_link_libraries(lubuntu-update PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)
|
||||
target_link_libraries(lubuntu-update PRIVATE
|
||||
Qt6::Widgets
|
||||
Qt6::DBus)
|
||||
|
||||
install(TARGETS lubuntu-update
|
||||
BUNDLE DESTINATION .
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
Copyright (c) 2023-2024 Lubuntu Contributors. Licensed under the GNU General Public License version 2, or (at your option) any later version.
|
||||
|
||||
Build dependencies are Qt 5.15 and cmake, runtime dependencies are apt, apt-get, and diff.
|
||||
Build dependencies are Qt 5.15 and cmake, runtime dependencies are apt, apt-get, curl, and diff.
|
||||
|
||||
To build:
|
||||
|
||||
@ -20,6 +20,11 @@ It is highly recommended that you use a Lubuntu virtual machine for testing and
|
||||
|
||||
Qt Creator is recommended for editing the code. It is present in Ubuntu's official repos and can be installed using `sudo apt install qtcreator`.
|
||||
|
||||
## Config file format:
|
||||
There's only one field here:
|
||||
|
||||
* nextDoReleaseUpgradeNotify=123456789 - Value is number of seconds since the UNIX epoch. Used to determine when to offer the user an upgrade.
|
||||
|
||||
## Missing features
|
||||
|
||||
* Double-clicking on a package doesn't show detailed information for it yet.
|
||||
|
43
debian/changelog
vendored
43
debian/changelog
vendored
@ -1,3 +1,46 @@
|
||||
lubuntu-update-notifier (1.1.1) plucky; urgency=medium
|
||||
|
||||
* Switch debconf frontend to noninteractive. (LP: #2091704)
|
||||
|
||||
-- Aaron Rainbolt <arraybolt3@ubuntu.com> Tue, 24 Dec 2024 13:51:28 -0600
|
||||
|
||||
lubuntu-update-notifier (1.1.0) oracular; urgency=medium
|
||||
|
||||
* Port to Qt6.
|
||||
|
||||
-- Aaron Rainbolt <arraybolt3@ubuntu.com> Thu, 15 Aug 2024 16:58:41 -0500
|
||||
|
||||
lubuntu-update-notifier (1.0.0) noble; urgency=medium
|
||||
|
||||
* Change from beta to final release.
|
||||
* Use D-Bus as a window show trigger rather than clunky drop files, this
|
||||
will prevent issues if multiple users are logged in at once.
|
||||
|
||||
-- Aaron Rainbolt <arraybolt3@ubuntu.com> Mon, 25 Mar 2024 16:15:49 -0500
|
||||
|
||||
lubuntu-update-notifier (1.0.0~beta1) noble; urgency=medium
|
||||
|
||||
* Change from alpha to beta testing phase, this has been tested for a while
|
||||
and looks pretty stable so far.
|
||||
* Wait to start until lxqt-notificationd is present. (LP: #2056379)
|
||||
|
||||
-- Aaron Rainbolt <arraybolt3@ubuntu.com> Thu, 07 Mar 2024 04:06:13 +0000
|
||||
|
||||
lubuntu-update-notifier (1.0.0~alpha4) noble; urgency=medium
|
||||
|
||||
* Fix infinite loop when no eligible new release is available.
|
||||
* Fix a bug where only the first eligible new release would be considered.
|
||||
|
||||
-- Aaron Rainbolt <arraybolt3@ubuntu.com> Fri, 09 Feb 2024 22:26:59 +0000
|
||||
|
||||
lubuntu-update-notifier (1.0.0~alpha3) noble; urgency=medium
|
||||
|
||||
* New feature release. Notable additions:
|
||||
- do-release-upgrade support
|
||||
* Updated runtime dependencies.
|
||||
|
||||
-- Aaron Rainbolt <arraybolt3@ubuntu.com> Fri, 02 Feb 2024 11:37:36 -0600
|
||||
|
||||
lubuntu-update-notifier (1.0.0~alpha2) noble; urgency=medium
|
||||
|
||||
* New feature release. Notable additions:
|
||||
|
7
debian/control
vendored
7
debian/control
vendored
@ -5,14 +5,15 @@ Maintainer: Lubuntu Developers <lubuntu-devel@lists.ubuntu.com>
|
||||
Build-Depends: cmake,
|
||||
debhelper-compat (= 13),
|
||||
lxqt-sudo (>= 1.4.0-0ubuntu2),
|
||||
qtbase5-dev,
|
||||
qttools5-dev
|
||||
qt6-base-dev,
|
||||
qt6-tools-dev
|
||||
Standards-Version: 4.6.2
|
||||
Rules-Requires-Root: no
|
||||
|
||||
Package: lubuntu-update-notifier
|
||||
Architecture: any
|
||||
Depends: ${misc:Depends},
|
||||
Depends: curl,
|
||||
${misc:Depends},
|
||||
${shlibs:Depends}
|
||||
Description: Lubuntu's update installer
|
||||
Lubuntu Update is an enhanced, modern update installer for the Lubuntu
|
||||
|
1
debian/files
vendored
Normal file
1
debian/files
vendored
Normal file
@ -0,0 +1 @@
|
||||
lubuntu-update-notifier_1.1.0~ppa1_source.buildinfo admin optional
|
@ -88,10 +88,10 @@ void AptManager::handleUpdateProcessBuffer()
|
||||
// yes, this gave me a headache also
|
||||
if (dlLineMatch.hasMatch()) { // Increments the progress counter for each package downloaded
|
||||
internalUpdateProgress++;
|
||||
} else if (line.count() >= 25 && line.left(24) == "Preparing to unpack .../" && numPackagesToPrep != 0) {
|
||||
} else if (line.length() >= 25 && line.left(24) == "Preparing to unpack .../" && numPackagesToPrep != 0) {
|
||||
internalUpdateProgress++; // Increments the progress counter for each package that is "prepared to unpack"
|
||||
numPackagesToPrep--;
|
||||
} else if (line.count() >= 10 && line.left(9) == "Unpacking") {
|
||||
} else if (line.length() >= 10 && line.left(9) == "Unpacking") {
|
||||
/*
|
||||
* Increments the progress counter for each package that is unpacked
|
||||
* The package name may be suffixed with ":amd64" or some other
|
||||
@ -109,7 +109,7 @@ void AptManager::handleUpdateProcessBuffer()
|
||||
internalUpdateProgress++;
|
||||
}
|
||||
}
|
||||
} else if (line.count() >= 11 && line.left(10) == "Setting up") {
|
||||
} else if (line.length() >= 11 && line.left(10) == "Setting up") {
|
||||
QStringList parts = line.split(' ');
|
||||
QString packageName;
|
||||
if (parts.count() >= 3) {
|
||||
@ -118,7 +118,7 @@ void AptManager::handleUpdateProcessBuffer()
|
||||
internalUpdateProgress++;
|
||||
}
|
||||
}
|
||||
} else if (line.count() >= 9 && line.left(8) == "Removing") {
|
||||
} else if (line.length() >= 9 && line.left(8) == "Removing") {
|
||||
QStringList parts = line.split(' ');
|
||||
QString packageName;
|
||||
if (parts.count() >= 2) {
|
||||
@ -136,7 +136,7 @@ void AptManager::handleUpdateProcessBuffer()
|
||||
}
|
||||
aptProcess->readLine(lineBuf, 2048);
|
||||
QString confLine = QString(lineBuf);
|
||||
confLine = confLine.left(confLine.count() - 2);
|
||||
confLine = confLine.left(confLine.length() - 2);
|
||||
if (confLine == "Lubuntu Update !!! CONFIGURATION FILE LIST END") {
|
||||
emit conffileListReady(conffileList); // this triggers the main window to show the conffile handler window
|
||||
break;
|
||||
@ -144,6 +144,15 @@ void AptManager::handleUpdateProcessBuffer()
|
||||
conffileList.append(confLine);
|
||||
}
|
||||
}
|
||||
} else if (line == "Lubuntu Update !!! NEW RELEASE\r\n") {
|
||||
// Same busy-wait technique, but here we're just getting one extra line, the release code.
|
||||
while (!aptProcess->canReadLine()) {
|
||||
QThread::msleep(20);
|
||||
}
|
||||
aptProcess->readLine(lineBuf, 2048);
|
||||
QString releaseCode = QString(lineBuf);
|
||||
releaseCode = releaseCode.left(releaseCode.length() - 2);
|
||||
emit newRelease(releaseCode);
|
||||
}
|
||||
|
||||
double percentageDone = (static_cast<double>(internalUpdateProgress) / (((internalUpdateInfo[0].count() + internalUpdateInfo[1].count()) * 4) + internalUpdateInfo[2].count())) * 100;
|
||||
@ -237,7 +246,7 @@ QList<QStringList> AptManager::getUpdateInfo()
|
||||
* spaces, we know we're no longer reading a package list.
|
||||
*/
|
||||
|
||||
if (stdoutLine.count() < 3 || stdoutLine.left(2) != " ") {
|
||||
if (stdoutLine.length() < 3 || stdoutLine.left(2) != " ") {
|
||||
gettingInstallPackages = false;
|
||||
gettingUpgradePackages = false;
|
||||
gettingUninstallPackages = false;
|
||||
@ -308,7 +317,7 @@ QStringList AptManager::getSecurityUpdateList()
|
||||
QString distroLine;
|
||||
while (distroFinder.readLineInto(&distroLine)) {
|
||||
// The line has to be at least 18 characters long - 16 for the string "DISTRIB_CODENAME", one for the = sign, and one for a codename with a length of at least one.
|
||||
if (distroLine.count() >= 18 && distroLine.left(16) == "DISTRIB_CODENAME") {
|
||||
if (distroLine.length() >= 18 && distroLine.left(16) == "DISTRIB_CODENAME") {
|
||||
QStringList distroParts = distroLine.split('=');
|
||||
if (distroParts.count() >= 2) {
|
||||
distroName = distroParts[1];
|
||||
|
@ -28,6 +28,7 @@ signals:
|
||||
void progressUpdated(int progress);
|
||||
void logLineReady(QString logLine);
|
||||
void conffileListReady(QStringList conffileList);
|
||||
void newRelease(QString code);
|
||||
|
||||
private slots:
|
||||
void handleUpdateProcessBuffer();
|
||||
|
@ -1,38 +0,0 @@
|
||||
#include "ipcfilewatcher.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QFileSystemWatcher>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
IPCFileWatcher::IPCFileWatcher(QObject *parent)
|
||||
: QObject{parent}
|
||||
{
|
||||
QDir targetDir("/dev/shm/lubuntu-update");
|
||||
bool couldRemove = targetDir.removeRecursively();
|
||||
if (!couldRemove) {
|
||||
qCritical() << "Could not clear IPC directory. Ensure that /dev/shm and /dev/shm/lubuntu-update are world-readable and world-writable.";
|
||||
initFailed = true;
|
||||
return;
|
||||
}
|
||||
targetDir.mkdir("/dev/shm/lubuntu-update");
|
||||
QFileSystemWatcher *watcher = new QFileSystemWatcher(QStringList() << "/dev/shm/lubuntu-update");
|
||||
connect(watcher, &QFileSystemWatcher::directoryChanged, this, &IPCFileWatcher::checkForShowWindowFile);
|
||||
initFailed = false;
|
||||
}
|
||||
|
||||
bool IPCFileWatcher::didInitFail()
|
||||
{
|
||||
return initFailed;
|
||||
}
|
||||
|
||||
void IPCFileWatcher::checkForShowWindowFile()
|
||||
{
|
||||
QFile flagFile("/dev/shm/lubuntu-update/lubuntu-update-show-win");
|
||||
if (flagFile.exists()) {
|
||||
flagFile.remove();
|
||||
emit showWindowFlagDetected();
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
#ifndef IPCFILEWATCHER_H
|
||||
#define IPCFILEWATCHER_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class IPCFileWatcher : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit IPCFileWatcher(QObject *parent = nullptr);
|
||||
bool didInitFail();
|
||||
|
||||
signals:
|
||||
void showWindowFlagDetected();
|
||||
|
||||
private:
|
||||
bool initFailed;
|
||||
|
||||
void checkForShowWindowFile();
|
||||
};
|
||||
|
||||
#endif // IPCFILEWATCHER_H
|
@ -4,6 +4,43 @@
|
||||
set -e
|
||||
export LC_ALL='C'
|
||||
|
||||
# Returns 0 if the release is supported, 1 if unsupported, 2 if if didn't exist at all, and 3 if something went wrong.
|
||||
isReleaseSupported () {
|
||||
releaseYear="${1:-}";
|
||||
releaseMonth="${2:-}";
|
||||
metaReleaseStr="${3:-}";
|
||||
|
||||
if [ -z "$releaseYear" ]; then
|
||||
echo '! ! ! releaseYear is blank';
|
||||
return 3;
|
||||
elif [ -z "$releaseMonth" ]; then
|
||||
echo '! ! ! releaseMonth is blank';
|
||||
return 3;
|
||||
elif [ -z "$metaReleaseStr" ]; then
|
||||
echo '! ! ! metaReleaseStr is blank';
|
||||
return 3;
|
||||
fi
|
||||
|
||||
releaseCode="$releaseYear.$releaseMonth";
|
||||
scanForSupported='n';
|
||||
|
||||
while IFS= read -r line || [[ -n $line ]]; do
|
||||
if [[ "$line" =~ $releaseCode ]]; then
|
||||
scanForSupported='y';
|
||||
fi
|
||||
if [ "$scanForSupported" = 'y' ]; then
|
||||
if [[ "$line" =~ Supported ]]; then
|
||||
if [ "$(echo "$line" | cut -d':' -f2 | tail -c+2)" = '0' ]; then
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done < <(printf '%s' "$metaReleaseStr")
|
||||
return 2;
|
||||
}
|
||||
|
||||
if [ "$1" = 'pkgver' ]; then
|
||||
shift
|
||||
while [ "$1" != '' ]; do
|
||||
@ -29,66 +66,128 @@ elif [ "$1" = 'doupdate' ]; then
|
||||
dpkg --configure -a
|
||||
|
||||
# Run the real update
|
||||
DEBIAN_FRONTEND='kde' apt-get -o Dpkg::Options::='--force-confdef' -o Dpkg::Options::='--force-confold' -o Apt::Color='0' -o Dpkg::Use-Pty='0' -y dist-upgrade |& tee /run/lubuntu-update-apt-log
|
||||
DEBIAN_FRONTEND='noninteractive' apt-get -o Dpkg::Options::='--force-confdef' -o Dpkg::Options::='--force-confold' -o Apt::Color='0' -o Dpkg::Use-Pty='0' -y dist-upgrade |& tee /run/lubuntu-update-apt-log
|
||||
|
||||
# Find all the conffiles
|
||||
doConffiles='y';
|
||||
mapfile conffileRawList <<< "$(grep -P "^Configuration file \'.*\'$" '/run/lubuntu-update-apt-log')"
|
||||
if [ "$(echo "${conffileRawList[0]}" | head -c1)" != 'C' ]; then # Empty or invalid list, we're done
|
||||
exit 0
|
||||
doConffiles='n';
|
||||
fi
|
||||
|
||||
conffileList=()
|
||||
counter=0
|
||||
while [ "$counter" -lt "${#conffileRawList[@]}" ]; do
|
||||
# Cut off "Configuration file '" from the start and "'" plus a couple trailing characters from the end
|
||||
conffileList[counter]="$(echo "${conffileRawList[$counter]}" | tail -c+21 | head -c-3)"
|
||||
counter=$((counter+1))
|
||||
done
|
||||
if [ "$doConffiles" = 'y' ]; then
|
||||
conffileList=()
|
||||
counter=0
|
||||
while [ "$counter" -lt "${#conffileRawList[@]}" ]; do
|
||||
# Cut off "Configuration file '" from the start and "'" plus a couple trailing characters from the end
|
||||
conffileList[counter]="$(echo "${conffileRawList[$counter]}" | tail -c+21 | head -c-3)"
|
||||
counter=$((counter+1))
|
||||
done
|
||||
|
||||
echo "Lubuntu Update !!! CONFIGURATION FILE LIST START";
|
||||
counter=0
|
||||
while [ "$counter" -lt "${#conffileList[@]}" ]; do
|
||||
echo "${conffileList[$counter]}"
|
||||
counter=$((counter+1))
|
||||
done
|
||||
echo "Lubuntu Update !!! CONFIGURATION FILE LIST END";
|
||||
echo "Lubuntu Update !!! CONFIGURATION FILE LIST START";
|
||||
counter=0
|
||||
while [ "$counter" -lt "${#conffileList[@]}" ]; do
|
||||
echo "${conffileList[$counter]}"
|
||||
counter=$((counter+1))
|
||||
done
|
||||
echo "Lubuntu Update !!! CONFIGURATION FILE LIST END";
|
||||
|
||||
# If we make it this far, there were conffiles to deal with
|
||||
breakLoop='no'
|
||||
gotCommand='no'
|
||||
commandName=''
|
||||
while [ "$breakLoop" = 'no' ]; do
|
||||
read -r inputVal
|
||||
if [ "$gotCommand" = 'no' ]; then
|
||||
if [ "$inputVal" = 'done' ]; then
|
||||
breakLoop='yes'
|
||||
# If we make it this far, there were conffiles to deal with
|
||||
breakLoop='no'
|
||||
gotCommand='no'
|
||||
commandName=''
|
||||
while [ "$breakLoop" = 'no' ]; do
|
||||
read -r inputVal
|
||||
if [ "$gotCommand" = 'no' ]; then
|
||||
if [ "$inputVal" = 'done' ]; then
|
||||
breakLoop='yes'
|
||||
else
|
||||
commandName="$inputVal"
|
||||
gotCommand='yes'
|
||||
fi
|
||||
else
|
||||
commandName="$inputVal"
|
||||
gotCommand='yes'
|
||||
if [ "$commandName" = 'replace' ]; then # Replace an existing file
|
||||
counter=0
|
||||
while [ "$counter" -lt "${#conffileList[@]}" ]; do
|
||||
if [ "$inputVal" = "${conffileList[$counter]}" ]; then
|
||||
mv "$inputVal.dpkg-dist" "$inputVal"
|
||||
break
|
||||
fi
|
||||
counter=$((counter+1))
|
||||
done
|
||||
elif [ "$commandName" = 'keep' ]; then # Keep an existing file
|
||||
counter=0
|
||||
while [ "$counter" -lt "${#conffileList[@]}" ]; do
|
||||
if [ "$inputVal" = "${conffileList[$counter]}" ]; then
|
||||
rm "$inputVal.dpkg-dist"
|
||||
break
|
||||
fi
|
||||
counter=$((counter+1))
|
||||
done
|
||||
fi
|
||||
gotCommand='no'
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
echo 'Checking release status...'
|
||||
|
||||
releaseCode="$(cat /etc/lsb-release | grep "DISTRIB_RELEASE" | cut -d'=' -f2)";
|
||||
releaseYear="$(cut -d'.' -f1 <<< "$releaseCode")";
|
||||
releaseMonth="$(cut -d'.' -f2 <<< "$releaseCode")";
|
||||
metaReleaseData="$(curl https://changelogs.ubuntu.com/meta-release)";
|
||||
#nextReleaseMonth='';
|
||||
#nextReleaseYear='';
|
||||
#nextLTSReleaseMonth='';
|
||||
#nextLTSReleaseYear='';
|
||||
|
||||
while true; do
|
||||
if ((releaseMonth == 4)); then
|
||||
releaseMonth='10';
|
||||
else
|
||||
if [ "$commandName" = 'replace' ]; then # Replace an existing file
|
||||
counter=0
|
||||
while [ "$counter" -lt "${#conffileList[@]}" ]; do
|
||||
if [ "$inputVal" = "${conffileList[$counter]}" ]; then
|
||||
mv "$inputVal.dpkg-dist" "$inputVal"
|
||||
break
|
||||
fi
|
||||
counter=$((counter+1))
|
||||
done
|
||||
elif [ "$commandName" = 'keep' ]; then # Keep an existing file
|
||||
counter=0
|
||||
while [ "$counter" -lt "${#conffileList[@]}" ]; do
|
||||
if [ "$inputVal" = "${conffileList[$counter]}" ]; then
|
||||
rm "$inputVal.dpkg-dist"
|
||||
break
|
||||
fi
|
||||
counter=$((counter+1))
|
||||
done
|
||||
fi
|
||||
gotCommand='no'
|
||||
releaseMonth='04';
|
||||
((releaseYear++));
|
||||
fi
|
||||
releaseSupportedResult="$(isReleaseSupported "$releaseYear" "$releaseMonth" "$metaReleaseData"; echo "$?")";
|
||||
if [ "$releaseSupportedResult" = '0' ]; then
|
||||
echo 'Lubuntu Update !!! NEW RELEASE';
|
||||
echo "$releaseYear.$releaseMonth";
|
||||
elif [ "$releaseSupportedResult" = '2' ]; then
|
||||
break;
|
||||
fi
|
||||
done
|
||||
|
||||
# if ((releaseMonth == 4)); then
|
||||
# nextReleaseMonth=$((releaseMonth + 6));
|
||||
# nextReleaseYear="$releaseYear";
|
||||
# if (((releaseYear % 2) == 0)); then
|
||||
# nextLTSReleaseMonth='04';
|
||||
# nextLTSReleaseYear=$((releaseYear + 2));
|
||||
# fi
|
||||
# else
|
||||
# nextReleaseMonth="$releaseMonth";
|
||||
# nextReleaseYear=$((releaseYear + 1));
|
||||
# fi
|
||||
#
|
||||
# if [ -n "$nextLTSReleaseYear" ]; then
|
||||
# if isReleaseSupported "$nextLTSReleaseYear" "$nextLTSReleaseMonth" "$metaReleaseData"; then
|
||||
# echo 'Lubuntu Update !!! NEW RELEASE';
|
||||
# echo "$nextLTSReleaseYear.$nextLTSReleaseMonth";
|
||||
# fi
|
||||
# fi
|
||||
#
|
||||
# if ! (((nextReleaseYear == nextLTSReleaseYear) && (nextReleaseMonth == nextLTSReleaseMonth))); then
|
||||
# if isReleaseSupported "$nextReleaseYear" "$nextReleaseMonth" "$metaReleaseData"; then
|
||||
# echo 'Lubuntu Update !!! NEW RELEASE';
|
||||
# echo "$nextReleaseYear.$nextReleaseMonth";
|
||||
# else
|
||||
# echo "Unsupported release: $nextReleaseYear.$nextReleaseMonth";
|
||||
# fi
|
||||
# fi
|
||||
|
||||
echo 'Update installation complete.'
|
||||
elif [ "$1" = 'doReleaseUpgrade' ]; then
|
||||
do-release-upgrade -m desktop -f DistUpgradeViewKDE;
|
||||
elif [ "$1" = 'declineReleaseUpgrade' ]; then
|
||||
sed -i -E 's/^Prompt=(never|lts|normal)$/Prompt=never/' /etc/update-manager/release-upgrades;
|
||||
fi
|
||||
|
90
src/main.cpp
90
src/main.cpp
@ -1,14 +1,38 @@
|
||||
#include "ipcfilewatcher.h"
|
||||
#include "windowshowwatcher.h"
|
||||
#include "orchestrator.h"
|
||||
#include "mainwindow.h"
|
||||
#include "conffilehandlerdialog.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusError>
|
||||
#include <QDBusInterface>
|
||||
#include <QDebug>
|
||||
#include <QDialog>
|
||||
#include <QLocale>
|
||||
#include <QProcess>
|
||||
#include <QThread>
|
||||
#include <QTranslator>
|
||||
|
||||
/*
|
||||
* Detects if at least `count` processes that match `procName` are running.
|
||||
*/
|
||||
bool detectProc(QString procName, int count)
|
||||
{
|
||||
QProcess procDetector;
|
||||
procDetector.setProgram("/usr/bin/bash");
|
||||
procDetector.setArguments(QStringList() << "-c" << "ps axo comm | grep " + procName);
|
||||
procDetector.start();
|
||||
procDetector.waitForFinished();
|
||||
QString procDetectResult = procDetector.readAllStandardOutput();
|
||||
procDetectResult = procDetectResult.trimmed();
|
||||
QStringList procDetectResultList = procDetectResult.split('\n');
|
||||
if (procDetectResultList.count() >= count) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
@ -23,40 +47,53 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If Lubuntu Update is already running, create
|
||||
* /dev/shm/lubuntu-update/lubuntu-update-show-win and exit. This will
|
||||
* trigger the existing process to pop up a window.
|
||||
*/
|
||||
// Connect to D-Bus.
|
||||
auto dbusConnection = QDBusConnection::sessionBus();
|
||||
|
||||
QProcess procDetector;
|
||||
procDetector.setProgram("/usr/bin/bash");
|
||||
procDetector.setArguments(QStringList() << "-c" << "ps axo comm | grep lubuntu-update");
|
||||
procDetector.start();
|
||||
procDetector.waitForFinished();
|
||||
QString procDetectResult = procDetector.readAllStandardOutput();
|
||||
procDetectResult = procDetectResult.trimmed();
|
||||
QStringList procDetectResultList = procDetectResult.split('\n');
|
||||
if (procDetectResultList.count() > 1) {
|
||||
QFile flagFile("/dev/shm/lubuntu-update/lubuntu-update-show-win");
|
||||
flagFile.open(QFile::WriteOnly);
|
||||
flagFile.close();
|
||||
/*
|
||||
* If Lubuntu Update is already running, instruct the running instance to
|
||||
* display its window via the D-Bus connection.
|
||||
*/
|
||||
if (detectProc("lubuntu-update", 2)) {
|
||||
auto iface = new QDBusInterface("me.lubuntu.LubuntuUpdate.window", "/", "me.lubuntu.LubuntuUpdate.window", dbusConnection);
|
||||
if (!iface->isValid()) {
|
||||
qWarning().noquote() << dbusConnection.lastError().message();
|
||||
return 1;
|
||||
}
|
||||
iface->call("showWindow");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait to run until lxqt-notificationd is running. This avoids a bug that
|
||||
* causes notifications to show up in the entirely wrong spot. If it takes
|
||||
* longer than about 30 seconds to show up, we continue on without it for
|
||||
* the sake of getting security updates.
|
||||
*/
|
||||
for (int i = 0;i < 30;i++) {
|
||||
// "lxqt-notificati" is intentionally truncated here since that's how it shows up in the output of `ps axo comm`.
|
||||
if (detectProc("lxqt-notificati", 1)) {
|
||||
// Wait for it to initialize fully - 3 seconds should be way more than enough
|
||||
QThread::sleep(3);
|
||||
break;
|
||||
} else {
|
||||
QThread::sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Don't want the updater to stop just because the user closed it :P
|
||||
a.setQuitOnLastWindowClosed(false);
|
||||
|
||||
/*
|
||||
* IPCFileWatcher just watches the /dev/shm/lubuntu-update folder for the
|
||||
* creation of a lubuntu-update-show-win file. If it detects it, it
|
||||
* immediately deletes it and emits a signal. This is then used later to
|
||||
* cause the updater window to pop up.
|
||||
* WindowShowWatcher is a very simple D-Bus service that allow triggering
|
||||
* the Lubuntu Update window to be shown. If anything calls "showWindow"
|
||||
* on this service, Lubuntu Update's window will pop up.
|
||||
*/
|
||||
QObject obj;
|
||||
auto *wsw = new WindowShowWatcher(&obj);
|
||||
dbusConnection.registerObject("/", &obj);
|
||||
|
||||
IPCFileWatcher *p = new IPCFileWatcher();
|
||||
|
||||
if (p->didInitFail()) {
|
||||
if (!dbusConnection.registerService("me.lubuntu.LubuntuUpdate.window")) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -71,10 +108,9 @@ int main(int argc, char *argv[])
|
||||
* there's no need to do anything with this except create it and then
|
||||
* start the event loop.
|
||||
*/
|
||||
|
||||
Orchestrator *o = new Orchestrator();
|
||||
|
||||
QObject::connect(p, &IPCFileWatcher::showWindowFlagDetected, o, &Orchestrator::displayUpdater);
|
||||
QObject::connect(wsw, &WindowShowWatcher::showWindowTriggered, o, &Orchestrator::displayUpdater);
|
||||
|
||||
/*
|
||||
* This is an artifact from testing the conffile handler window. You can
|
||||
|
@ -25,6 +25,7 @@ MainWindow::MainWindow(QWidget *parent)
|
||||
connect(aptManager, &AptManager::progressUpdated, this, &MainWindow::onProgressUpdate);
|
||||
connect(aptManager, &AptManager::logLineReady, this, &MainWindow::onLogLineReady);
|
||||
connect(aptManager, &AptManager::conffileListReady, this, &MainWindow::onConffileListReady);
|
||||
connect(aptManager, &AptManager::newRelease, this, &MainWindow::onNewRelease);
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
@ -143,6 +144,9 @@ void MainWindow::onUpdateCompleted()
|
||||
ui->progressBar->setVisible(false);
|
||||
ui->statLabel->setText(tr("Update installation complete."));
|
||||
emit updatesInstalled(); // this tells the orchestrator to hide the tray icon
|
||||
if (releaseCodes.count() > 0) {
|
||||
handleNewReleases();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::onCheckUpdatesCompleted()
|
||||
@ -175,3 +179,14 @@ void MainWindow::onConffileListReady(QStringList conffileList)
|
||||
}
|
||||
aptManager->doneWithConffiles();
|
||||
}
|
||||
|
||||
void MainWindow::onNewRelease(QString code)
|
||||
{
|
||||
releaseCodes.append(code);
|
||||
}
|
||||
|
||||
void MainWindow::handleNewReleases()
|
||||
{
|
||||
emit newReleaseAvailable(releaseCodes);
|
||||
releaseCodes.clear();
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ public:
|
||||
signals:
|
||||
void updatesInstalled();
|
||||
void updatesRefreshed();
|
||||
void newReleaseAvailable(QStringList releaseCodes);
|
||||
|
||||
protected slots:
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
@ -39,9 +40,13 @@ private slots:
|
||||
void onProgressUpdate(int progress);
|
||||
void onLogLineReady(QString logLine);
|
||||
void onConffileListReady(QStringList conffileList);
|
||||
void onNewRelease(QString code);
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
AptManager *aptManager;
|
||||
QStringList releaseCodes;
|
||||
|
||||
void handleNewReleases();
|
||||
};
|
||||
#endif // MAINWINDOW_H
|
||||
|
@ -6,7 +6,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>462</width>
|
||||
<width>473</width>
|
||||
<height>600</height>
|
||||
</rect>
|
||||
</property>
|
||||
@ -37,6 +37,9 @@
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QProgressBar" name="progressBar">
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>0</number>
|
||||
</property>
|
||||
|
@ -1,8 +1,13 @@
|
||||
#include "orchestrator.h"
|
||||
#include "mainwindow.h"
|
||||
#include "aptmanager.h"
|
||||
#include "releaseupgradewindow.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QIcon>
|
||||
#include <QProcess>
|
||||
#include <QSystemTrayIcon>
|
||||
#include <QTimer>
|
||||
|
||||
@ -12,10 +17,38 @@ Orchestrator::Orchestrator(QObject *parent)
|
||||
checkTimer = new QTimer(); // every time this triggers, the apt database is checked for new updates
|
||||
trayIcon = new QSystemTrayIcon(); // this is shown to the user to offer updates
|
||||
|
||||
/*
|
||||
* Parse the Lubuntu Update config file. It contains two critical pieces
|
||||
* of info - when the system last offered the user a release upgrade,
|
||||
* and whether the user has disabled release upgrade notifications.
|
||||
*/
|
||||
QFile configFile(QDir::homePath() + "/.config/lubuntu-update.conf");
|
||||
bool success = configFile.open(QFile::ReadOnly);
|
||||
if (success) {
|
||||
char lineBuf[2048];
|
||||
while (!configFile.atEnd()) {
|
||||
configFile.readLine(lineBuf, 2048);
|
||||
QString line(lineBuf);
|
||||
line = line.trimmed();
|
||||
QStringList lineParts = line.split("=");
|
||||
if (lineParts.count() == 2) {
|
||||
if (lineParts[0] == "nextDoReleaseUpgradeNotify") {
|
||||
nextUpgradeCheck = QDateTime::fromSecsSinceEpoch(lineParts[1].toLongLong());
|
||||
} else {
|
||||
qWarning() << "Unrecognized config line: " << line;
|
||||
}
|
||||
} else {
|
||||
qWarning() << "Wrong number of fields in line: " << line;
|
||||
}
|
||||
}
|
||||
}
|
||||
configFile.close();
|
||||
|
||||
connect(checkTimer, &QTimer::timeout, this, &Orchestrator::checkForUpdates);
|
||||
connect(trayIcon, &QSystemTrayIcon::activated, this, &Orchestrator::displayUpdater);
|
||||
connect(&updaterWindow, &MainWindow::updatesInstalled, this, &Orchestrator::handleUpdatesInstalled);
|
||||
connect(&updaterWindow, &MainWindow::updatesRefreshed, this, &Orchestrator::handleUpdatesRefreshed);
|
||||
connect(&updaterWindow, &MainWindow::newReleaseAvailable, this, &Orchestrator::onNewReleaseAvailable);
|
||||
|
||||
checkTimer->start(21600000); // check four times a day, at least one of those times unattended-upgrades should have refreshed the apt database
|
||||
|
||||
@ -65,3 +98,91 @@ void Orchestrator::handleUpdatesRefreshed()
|
||||
checkForUpdates();
|
||||
displayUpdater();
|
||||
}
|
||||
|
||||
void Orchestrator::onNewReleaseAvailable(QStringList releaseCodes)
|
||||
{
|
||||
// First, determine what kinds of releases the user wants to see.
|
||||
QFile druTypeFile("/etc/update-manager/release-upgrades");
|
||||
bool success = druTypeFile.open(QFile::ReadOnly);
|
||||
QString druType;
|
||||
if (success) {
|
||||
char lineBuf[2048];
|
||||
while (!druTypeFile.atEnd()) {
|
||||
druTypeFile.readLine(lineBuf, 2048);
|
||||
QString line(lineBuf);
|
||||
line = line.trimmed();
|
||||
if (line == "Prompt=lts") {
|
||||
druType="lts";
|
||||
druTypeFile.close();
|
||||
break;
|
||||
} else if (line == "Prompt=none") {
|
||||
// The user has disabled all upgrade prompts.
|
||||
druTypeFile.close();
|
||||
return;
|
||||
} else if (line == "Prompt=normal") {
|
||||
druType="normal";
|
||||
druTypeFile.close();
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
druType="normal";
|
||||
druTypeFile.close();
|
||||
}
|
||||
|
||||
for (int i = 0;i < releaseCodes.count();i++) {
|
||||
QStringList releaseCodeParts = releaseCodes[i].split('.');
|
||||
if (releaseCodeParts.count() >= 2) {
|
||||
int releaseYear = releaseCodeParts[0].toInt();
|
||||
int releaseMonth = releaseCodeParts[1].toInt();
|
||||
if (((releaseYear % 2 == 0) && (releaseMonth == 4)) || druType == "normal") {
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
if (nextUpgradeCheck < now) {
|
||||
ReleaseUpgradeWindow upgradeWindow(releaseCodes[i]);
|
||||
upgradeWindow.exec();
|
||||
if (upgradeWindow.getUpgradeAccepted()) {
|
||||
doReleaseUpgrade();
|
||||
} else if (upgradeWindow.getUpgradeDelayStamp() > 0) {
|
||||
delayReleaseUpgrade(upgradeWindow.getUpgradeDelayStamp());
|
||||
} else {
|
||||
declineReleaseUpgrade();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Orchestrator::doReleaseUpgrade()
|
||||
{
|
||||
QProcess druProcess;
|
||||
druProcess.setProgram("/usr/bin/lxqt-sudo");
|
||||
druProcess.setArguments(QStringList() << "/usr/libexec/lubuntu-update-backend" << "doReleaseUpgrade");
|
||||
druProcess.start();
|
||||
druProcess.waitForFinished(-1);
|
||||
}
|
||||
|
||||
void Orchestrator::delayReleaseUpgrade(qint64 timestamp)
|
||||
{
|
||||
QFile configFile(QDir::homePath() + "/.config/lubuntu-update.conf");
|
||||
bool success = configFile.open(QFile::WriteOnly);
|
||||
if (success) {
|
||||
configFile.write("nextDoReleaseUpgradeNotify=");
|
||||
configFile.write(QString::number(timestamp).toUtf8());
|
||||
configFile.write("\n");
|
||||
} else {
|
||||
qWarning() << "Could not write to " + QDir::homePath() + "/.config/lubuntu-update.conf, check permissions";
|
||||
}
|
||||
configFile.close();
|
||||
nextUpgradeCheck = QDateTime::fromSecsSinceEpoch(timestamp);
|
||||
}
|
||||
|
||||
void Orchestrator::declineReleaseUpgrade()
|
||||
{
|
||||
QProcess druProcess;
|
||||
druProcess.setProgram("/usr/bin/lxqt-sudo");
|
||||
druProcess.setArguments(QStringList() << "/usr/libexec/lubuntu-update-backend" << "declineReleaseUpgrade");
|
||||
druProcess.start();
|
||||
druProcess.waitForFinished(-1);
|
||||
}
|
||||
|
@ -3,11 +3,13 @@
|
||||
|
||||
#include "mainwindow.h"
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QObject>
|
||||
#include <QStringList>
|
||||
|
||||
class QTimer;
|
||||
class QSystemTrayIcon;
|
||||
class ReleaseUpgradeWindow;
|
||||
|
||||
class Orchestrator : public QObject
|
||||
{
|
||||
@ -22,12 +24,17 @@ private slots:
|
||||
void checkForUpdates();
|
||||
void handleUpdatesInstalled();
|
||||
void handleUpdatesRefreshed();
|
||||
void onNewReleaseAvailable(QStringList releaseCodes);
|
||||
|
||||
private:
|
||||
QTimer *checkTimer;
|
||||
QSystemTrayIcon *trayIcon;
|
||||
QList<QStringList> updateInfo;
|
||||
MainWindow updaterWindow;
|
||||
QDateTime nextUpgradeCheck;
|
||||
void doReleaseUpgrade();
|
||||
void delayReleaseUpgrade(qint64 timestamp);
|
||||
void declineReleaseUpgrade();
|
||||
};
|
||||
|
||||
#endif // ORCHESTRATOR_H
|
||||
|
67
src/releaseupgradewindow.cpp
Normal file
67
src/releaseupgradewindow.cpp
Normal file
@ -0,0 +1,67 @@
|
||||
#include "releaseupgradewindow.h"
|
||||
#include "ui_releaseupgradewindow.h"
|
||||
|
||||
#include "upgradedelaywindow.h"
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QMessageBox>
|
||||
|
||||
ReleaseUpgradeWindow::ReleaseUpgradeWindow(QString releaseCode, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::ReleaseUpgradeWindow)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->upgradeLabel->setText(tr("An upgrade to Lubuntu %1 is available! Would you like to install this upgrade now?").arg(releaseCode));
|
||||
code=releaseCode;
|
||||
connect(ui->upgradeButton, &QPushButton::clicked, this, &ReleaseUpgradeWindow::onUpgradeClicked);
|
||||
connect(ui->remindButton, &QPushButton::clicked, this, &ReleaseUpgradeWindow::onRemindClicked);
|
||||
connect(ui->declineButton, &QPushButton::clicked, this, &ReleaseUpgradeWindow::onDeclineClicked);
|
||||
}
|
||||
|
||||
ReleaseUpgradeWindow::~ReleaseUpgradeWindow()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
bool ReleaseUpgradeWindow::getUpgradeAccepted()
|
||||
{
|
||||
return upgradeAccepted;
|
||||
}
|
||||
|
||||
qint64 ReleaseUpgradeWindow::getUpgradeDelayStamp()
|
||||
{
|
||||
return upgradeDelayStamp;
|
||||
}
|
||||
|
||||
void ReleaseUpgradeWindow::onUpgradeClicked()
|
||||
{
|
||||
upgradeAccepted = true;
|
||||
this->done(0);
|
||||
}
|
||||
|
||||
void ReleaseUpgradeWindow::onRemindClicked()
|
||||
{
|
||||
UpgradeDelayWindow delayWindow;
|
||||
delayWindow.exec();
|
||||
if (delayWindow.getDelayDays() > 0) {
|
||||
QDateTime delayDateTime = QDateTime::currentDateTime();
|
||||
delayDateTime = delayDateTime.addDays(delayWindow.getDelayDays());
|
||||
upgradeAccepted = false;
|
||||
upgradeDelayStamp = delayDateTime.toSecsSinceEpoch();
|
||||
this->done(0);
|
||||
}
|
||||
}
|
||||
|
||||
void ReleaseUpgradeWindow::onDeclineClicked()
|
||||
{
|
||||
QMessageBox confirmDialog;
|
||||
confirmDialog.setWindowTitle(tr("Lubuntu Update"));
|
||||
confirmDialog.setText(tr("You have declined the upgrade to Lubuntu %1.\nYou can upgrade manually by following the directions at https://manual.lubuntu.me/stable/D/upgrading.html.").arg(code));
|
||||
confirmDialog.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
|
||||
int result = confirmDialog.exec();
|
||||
if (result == QMessageBox::Ok) {
|
||||
upgradeDelayStamp = 0;
|
||||
upgradeAccepted = false;
|
||||
this->done(0);
|
||||
}
|
||||
}
|
32
src/releaseupgradewindow.h
Normal file
32
src/releaseupgradewindow.h
Normal file
@ -0,0 +1,32 @@
|
||||
#ifndef RELEASEUPGRADEWINDOW_H
|
||||
#define RELEASEUPGRADEWINDOW_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui {
|
||||
class ReleaseUpgradeWindow;
|
||||
}
|
||||
|
||||
class ReleaseUpgradeWindow : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ReleaseUpgradeWindow(QString releaseCode, QWidget *parent = nullptr);
|
||||
~ReleaseUpgradeWindow();
|
||||
bool getUpgradeAccepted();
|
||||
qint64 getUpgradeDelayStamp();
|
||||
|
||||
private slots:
|
||||
void onUpgradeClicked();
|
||||
void onRemindClicked();
|
||||
void onDeclineClicked();
|
||||
|
||||
private:
|
||||
Ui::ReleaseUpgradeWindow *ui;
|
||||
QString code;
|
||||
bool upgradeAccepted = false;
|
||||
qint64 upgradeDelayStamp = 0;
|
||||
};
|
||||
|
||||
#endif // RELEASEUPGRADEWINDOW_H
|
69
src/releaseupgradewindow.ui
Normal file
69
src/releaseupgradewindow.ui
Normal file
@ -0,0 +1,69 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ReleaseUpgradeWindow</class>
|
||||
<widget class="QDialog" name="ReleaseUpgradeWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>393</width>
|
||||
<height>116</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Lubuntu Update</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="upgradeLabel">
|
||||
<property name="text">
|
||||
<string>upgrade available</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>6</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="upgradeButton">
|
||||
<property name="text">
|
||||
<string>Upgrade Now</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="remindButton">
|
||||
<property name="text">
|
||||
<string>Remind me later</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="declineButton">
|
||||
<property name="text">
|
||||
<string>Decline Upgrade</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
42
src/upgradedelaywindow.cpp
Normal file
42
src/upgradedelaywindow.cpp
Normal file
@ -0,0 +1,42 @@
|
||||
#include "upgradedelaywindow.h"
|
||||
#include "ui_upgradedelaywindow.h"
|
||||
|
||||
UpgradeDelayWindow::UpgradeDelayWindow(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::UpgradeDelayWindow)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
connect(ui->okButton, &QPushButton::clicked, this, &UpgradeDelayWindow::onOkClicked);
|
||||
connect(ui->cancelButton, &QPushButton::clicked, this, &UpgradeDelayWindow::onCancelClicked);
|
||||
}
|
||||
|
||||
UpgradeDelayWindow::~UpgradeDelayWindow()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
qint64 UpgradeDelayWindow::getDelayDays()
|
||||
{
|
||||
return delayDays;
|
||||
}
|
||||
|
||||
void UpgradeDelayWindow::onOkClicked()
|
||||
{
|
||||
switch (ui->timeTypeComboBox->currentIndex()) {
|
||||
case 0: // days
|
||||
delayDays = ui->timeSpinBox->value();
|
||||
break;
|
||||
case 1: // weeks
|
||||
delayDays = ui->timeSpinBox->value() * 7;
|
||||
break;
|
||||
case 2: // months
|
||||
delayDays = ui->timeSpinBox->value() * 28;
|
||||
break;
|
||||
}
|
||||
this->done(0);
|
||||
}
|
||||
|
||||
void UpgradeDelayWindow::onCancelClicked()
|
||||
{
|
||||
this->done(0);
|
||||
}
|
28
src/upgradedelaywindow.h
Normal file
28
src/upgradedelaywindow.h
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef UPGRADEDELAYWINDOW_H
|
||||
#define UPGRADEDELAYWINDOW_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui {
|
||||
class UpgradeDelayWindow;
|
||||
}
|
||||
|
||||
class UpgradeDelayWindow : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit UpgradeDelayWindow(QWidget *parent = nullptr);
|
||||
~UpgradeDelayWindow();
|
||||
qint64 getDelayDays();
|
||||
|
||||
private slots:
|
||||
void onOkClicked();
|
||||
void onCancelClicked();
|
||||
|
||||
private:
|
||||
Ui::UpgradeDelayWindow *ui;
|
||||
qint64 delayDays;
|
||||
};
|
||||
|
||||
#endif // UPGRADEDELAYWINDOW_H
|
97
src/upgradedelaywindow.ui
Normal file
97
src/upgradedelaywindow.ui
Normal file
@ -0,0 +1,97 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>UpgradeDelayWindow</class>
|
||||
<widget class="QDialog" name="UpgradeDelayWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>242</width>
|
||||
<height>137</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Lubuntu Update</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p>How long would you like to wait before being reminded of the upgrade again?</p></body></html></string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="1">
|
||||
<widget class="QSpinBox" name="timeSpinBox"/>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QPushButton" name="okButton">
|
||||
<property name="text">
|
||||
<string>OK</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QPushButton" name="cancelButton">
|
||||
<property name="text">
|
||||
<string>Cancel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QComboBox" name="timeTypeComboBox">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Days</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Weeks</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Months</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
6
src/windowshowwatcher.cpp
Normal file
6
src/windowshowwatcher.cpp
Normal file
@ -0,0 +1,6 @@
|
||||
#include "windowshowwatcher.h"
|
||||
|
||||
void WindowShowWatcher::showWindow()
|
||||
{
|
||||
emit showWindowTriggered();
|
||||
}
|
23
src/windowshowwatcher.h
Normal file
23
src/windowshowwatcher.h
Normal file
@ -0,0 +1,23 @@
|
||||
#ifndef WINDOWSHOWWATCHER_H
|
||||
#define WINDOWSHOWWATCHER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QDBusAbstractAdaptor>
|
||||
#include <QDBusVariant>
|
||||
|
||||
class WindowShowWatcher : public QDBusAbstractAdaptor
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_CLASSINFO("D-Bus Interface", "me.lubuntu.LubuntuUpdate.window")
|
||||
|
||||
public:
|
||||
explicit WindowShowWatcher(QObject *obj) : QDBusAbstractAdaptor(obj) {}
|
||||
|
||||
public slots:
|
||||
void showWindow();
|
||||
|
||||
signals:
|
||||
void showWindowTriggered();
|
||||
};
|
||||
|
||||
#endif // WINDOWSHOWWATCHER_H
|
Loading…
x
Reference in New Issue
Block a user