From 8e553385ab268c216a99b03d15783c563ce748dc Mon Sep 17 00:00:00 2001 From: Jakob Heher Date: Thu, 1 Sep 2022 12:50:50 +0200 Subject: add update check status to about config panel, cf. #119 --- .../composites/configuration/AboutComposite.java | 30 +++++- .../asit/pdfover/gui/utils/UpdateCheckManager.java | 113 ++++++++++++++------- .../at/asit/pdfover/gui/messages.properties | 5 + .../at/asit/pdfover/gui/messages_de.properties | 7 +- 4 files changed, 115 insertions(+), 40 deletions(-) diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/configuration/AboutComposite.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/configuration/AboutComposite.java index 825a6187..35b73e7b 100644 --- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/configuration/AboutComposite.java +++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/configuration/AboutComposite.java @@ -21,6 +21,7 @@ import org.slf4j.LoggerFactory; import at.asit.pdfover.commons.Constants; import at.asit.pdfover.commons.Messages; import at.asit.pdfover.gui.utils.SWTUtils; +import at.asit.pdfover.gui.utils.UpdateCheckManager; import at.asit.pdfover.gui.workflow.config.ConfigurationDataInMemory; import at.asit.pdfover.gui.workflow.config.ConfigurationManager; import at.asit.pdfover.gui.workflow.states.State; @@ -30,8 +31,10 @@ public class AboutComposite extends ConfigurationCompositeBase { private Link lnkAbout; private Link lnkDataProtection; private Label lblDataProtection; + private Link lnkUpdateCheckStatus; private Button btnUpdateCheck; private Button btnOpenLogDirectory; + private UpdateCheckManager.Status latestUpdateStatus; /** * @param parent * @param style @@ -54,15 +57,33 @@ public class AboutComposite extends ConfigurationCompositeBase { SWTUtils.anchor(lnkDataProtection).top(lblDataProtection,10).left(0,5).right(100,-5); SWTUtils.setFontHeight(lnkDataProtection, Constants.TEXT_SIZE_NORMAL); + this.lnkUpdateCheckStatus = new Link(this, SWT.NONE); + SWTUtils.anchor(lnkUpdateCheckStatus).bottom(100, -5).left(0,5); + SWTUtils.setFontHeight(lnkUpdateCheckStatus, Constants.TEXT_SIZE_BUTTON); + UpdateCheckManager.registerStatusCallback((s) -> { latestUpdateStatus = s; getDisplay().asyncExec(() -> { RefreshUpdateStatusText(); }); }); + SWTUtils.addSelectionListener(lnkUpdateCheckStatus, (e) -> { + if (latestUpdateStatus == UpdateCheckManager.Status.OUTDATED) + Program.launch(Constants.UPDATE_URL); + else + UpdateCheckManager.checkNow(getShell()); + }); + this.btnUpdateCheck = new Button(this, SWT.CHECK); - SWTUtils.anchor(btnUpdateCheck).bottom(100,-5).left(0,5); + SWTUtils.anchor(btnUpdateCheck).bottom(lnkUpdateCheckStatus,-5).left(0,5); SWTUtils.setFontHeight(btnUpdateCheck, Constants.TEXT_SIZE_BUTTON); - SWTUtils.addSelectionListener(btnUpdateCheck, e -> { this.configurationContainer.updateCheck = btnUpdateCheck.getSelection(); }); + SWTUtils.addSelectionListener(btnUpdateCheck, (e) -> { + boolean enabled = btnUpdateCheck.getSelection(); + this.configurationContainer.updateCheck = enabled; + if (enabled) + UpdateCheckManager.checkNow(getShell()); + }); this.btnOpenLogDirectory = new Button(this, SWT.NONE); SWTUtils.anchor(btnOpenLogDirectory).bottom(100, -5).right(100, -5); SWTUtils.setFontHeight(btnOpenLogDirectory, Constants.TEXT_SIZE_BUTTON); + SWTUtils.reanchor(lnkDataProtection).bottom(btnUpdateCheck,-5); + this.lnkAbout.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { @@ -129,6 +150,10 @@ public class AboutComposite extends ConfigurationCompositeBase { // Nothing to do here } + private void RefreshUpdateStatusText() { + SWTUtils.setLocalizedText(lnkUpdateCheckStatus, "config.UpdateStatus." + latestUpdateStatus.name()); + } + /* (non-Javadoc) * @see at.asit.pdfover.gui.composites.StateComposite#reloadResources() */ @@ -140,6 +165,7 @@ public class AboutComposite extends ConfigurationCompositeBase { SWTUtils.setLocalizedText(btnUpdateCheck, "advanced_config.UpdateCheck"); SWTUtils.setLocalizedToolTipText(btnUpdateCheck, "advanced_config.UpdateCheck_ToolTip"); SWTUtils.setLocalizedText(btnOpenLogDirectory, "config.ShowLogDirectory"); + RefreshUpdateStatusText(); } @Override diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/utils/UpdateCheckManager.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/utils/UpdateCheckManager.java index d6e650ba..92104176 100644 --- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/utils/UpdateCheckManager.java +++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/utils/UpdateCheckManager.java @@ -2,6 +2,8 @@ package at.asit.pdfover.gui.utils; import java.awt.Desktop; import java.net.URI; +import java.util.ArrayList; +import java.util.function.Consumer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -24,6 +26,72 @@ public final class UpdateCheckManager { private static Thread updateCheckThread = null; private static boolean needsCheck = false; + public enum Status { NOT_CHECKED, CHECKING, OUTDATED, UP_TO_DATE, FAILED }; + private static Status currentStatus = Status.NOT_CHECKED; + public static Status getCurrentStatus() { + synchronized (UpdateCheckManager.class) { + return currentStatus; + } + } + + private static ArrayList> statusCallbacks = new ArrayList<>(); + public static void registerStatusCallback(Consumer f) { + synchronized (UpdateCheckManager.class) { + statusCallbacks.add(f); + f.accept(currentStatus); + } + } + + private static void setStatus(Status status) { + synchronized(UpdateCheckManager.class) { + currentStatus = status; + for (Consumer f : statusCallbacks) + f.accept(status); + } + } + + private static String latestVersionNotified = null; + private static Status runCheck(Shell shell) { + HttpClient client = (HttpClient) BKUHelper.getHttpClient(); + GetMethod method = new GetMethod(Constants.CURRENT_RELEASE_URL); + try { + client.executeMethod(method); + final String version = method.getResponseBodyAsString().trim(); + if (!VersionComparator.before(Constants.APP_VERSION, version)) + return Status.UP_TO_DATE; + + if ((latestVersionNotified == null) || VersionComparator.before(latestVersionNotified, version)) { + latestVersionNotified = version; + // invoke GUI message in main thread + shell.getDisplay().asyncExec(() -> { + Dialog info = new Dialog(shell, + Messages.getString("version_check.UpdateTitle"), + String.format(Messages.getString("version_check.UpdateText"), version), + BUTTONS.OK_CANCEL, ICON.INFORMATION); + + if (info.open() == SWT.OK) + { + if (Desktop.isDesktopSupported()) { + try { + Desktop.getDesktop().browse(new URI(Constants.UPDATE_URL)); + } catch (Exception e) { + log.error("Error opening update location ", e); + } + } else { + log.info("SWT Desktop is not supported on this platform"); + Program.launch(Constants.UPDATE_URL); + } + } + }); + } + + return Status.OUTDATED; + } catch (Exception e) { + log.error("Error downloading update information: ", e); + return Status.FAILED; + } + } + public static void checkNow(Shell shell) { if (Constants.APP_VERSION == null) return; @@ -34,48 +102,19 @@ public final class UpdateCheckManager { needsCheck = true; updateCheckThread = new Thread(() -> { + synchronized(UpdateCheckManager.class) { + setStatus(Status.CHECKING); + } while (true) { + Status status = runCheck(shell); synchronized (UpdateCheckManager.class) { - if (!needsCheck) { + if (!UpdateCheckManager.needsCheck) { + setStatus(status); UpdateCheckManager.updateCheckThread = null; return; } - needsCheck = false; - } - HttpClient client = (HttpClient) BKUHelper.getHttpClient(); - GetMethod method = new GetMethod(Constants.CURRENT_RELEASE_URL); - try { - client.executeMethod(method); - final String version = method.getResponseBodyAsString().trim(); - if (!VersionComparator.before(Constants.APP_VERSION, version)) - return; - - // wait 500ms before invoke the GUI message, because GUI had to be started from - // main thread - try { Thread.sleep(500); } catch (InterruptedException e1) { } - // invoke GUI message in main thread - shell.getDisplay().asyncExec(() -> { - Dialog info = new Dialog(shell, - Messages.getString("version_check.UpdateTitle"), - String.format(Messages.getString("version_check.UpdateText"), version), - BUTTONS.OK_CANCEL, ICON.INFORMATION); - - if (info.open() == SWT.OK) - { - if (Desktop.isDesktopSupported()) { - try { - Desktop.getDesktop().browse(new URI(Constants.UPDATE_URL)); - } catch (Exception e) { - log.error("Error opening update location ", e); - } - } else { - log.info("SWT Desktop is not supported on this platform"); - Program.launch(Constants.UPDATE_URL); - } - } - }); - } catch (Exception e) { - log.error("Error downloading update information: ", e); + UpdateCheckManager.needsCheck = false; + setStatus(Status.CHECKING); } } }); diff --git a/pdf-over-gui/src/main/resources/at/asit/pdfover/gui/messages.properties b/pdf-over-gui/src/main/resources/at/asit/pdfover/gui/messages.properties index d8f0657e..65e353a1 100644 --- a/pdf-over-gui/src/main/resources/at/asit/pdfover/gui/messages.properties +++ b/pdf-over-gui/src/main/resources/at/asit/pdfover/gui/messages.properties @@ -260,3 +260,8 @@ version_check.UpdateText=Version %s is available.\nOpen download page now? version_check.UpdateTitle=New version available\! waiting.message=Signature creation in progress... waiting_for_app.message=Please open Signature-App\! +config.UpdateStatus.NOT_CHECKED=Update check not done. Check now? +config.UpdateStatus.CHECKING=Checking for updates... +config.UpdateStatus.OUTDATED=New version available. Update now? +config.UpdateStatus.UP_TO_DATE=PDF-Over is up to date. Check again? +config.UpdateStatus.FAILED=Update check failed. Retry? diff --git a/pdf-over-gui/src/main/resources/at/asit/pdfover/gui/messages_de.properties b/pdf-over-gui/src/main/resources/at/asit/pdfover/gui/messages_de.properties index ba82ea3e..a2afff03 100644 --- a/pdf-over-gui/src/main/resources/at/asit/pdfover/gui/messages_de.properties +++ b/pdf-over-gui/src/main/resources/at/asit/pdfover/gui/messages_de.properties @@ -114,7 +114,7 @@ config.DataProtectionURL=https://www.a-trust.at/MediaProvider/2357/datenschutzer config.Advanced=Er&weitert config.Keystore=&Keystore config.Simple=&Einfach -config.ShowLogDirectory=Logverzeichnis anzeigen +config.ShowLogDirectory=Logs anzeigen dataSourceSelection.DropLabel=Dokument hierher ziehen dataSourceSelection.DropLabel2=oder... dataSourceSelection.browse=&Durchsuchen um ein Dokument zu wählen @@ -252,3 +252,8 @@ version_check.UpdateText=Version %s ist verfügbar\nJetzt Download-Seite öffnen version_check.UpdateTitle=Neue Version verfügbar\! waiting.message=Signaturerstellung läuft... waiting_for_app.message=Bitte öffnen Sie die Handy-Signatur App! +config.UpdateStatus.NOT_CHECKED=Keine Versions-Infos. Jetzt abfragen? +config.UpdateStatus.CHECKING=Versions-Infos werden abgefragt... +config.UpdateStatus.OUTDATED=Neue Version verfügbar. Herunterladen? +config.UpdateStatus.UP_TO_DATE=Ihre Version ist aktuell. Nochmals prüfen? +config.UpdateStatus.FAILED=Versions-Check fehlgeschlagen. Nochmal versuchen? -- cgit v1.2.3