diff --git a/annotations/idea/java/lang/annotations.xml b/annotations/idea/java/lang/annotations.xml
index 484821018..3170cefa6 100644
--- a/annotations/idea/java/lang/annotations.xml
+++ b/annotations/idea/java/lang/annotations.xml
@@ -5,6 +5,9 @@
-
+ -
+
+
-
diff --git a/weasis-base/weasis-base-ui/pom.xml b/weasis-base/weasis-base-ui/pom.xml
index 2b1dfa3a5..5037e7a21 100644
--- a/weasis-base/weasis-base-ui/pom.xml
+++ b/weasis-base/weasis-base-ui/pom.xml
@@ -44,5 +44,10 @@
${weasis.core.img.version}
provided
+
+ org.glassfish
+ jakarta.json
+ provided
+
diff --git a/weasis-base/weasis-base-ui/src/main/java/org/weasis/base/ui/gui/WeasisWin.java b/weasis-base/weasis-base-ui/src/main/java/org/weasis/base/ui/gui/WeasisWin.java
index 48d23d995..6e16d29ab 100644
--- a/weasis-base/weasis-base-ui/src/main/java/org/weasis/base/ui/gui/WeasisWin.java
+++ b/weasis-base/weasis-base-ui/src/main/java/org/weasis/base/ui/gui/WeasisWin.java
@@ -9,6 +9,8 @@
*/
package org.weasis.base.ui.gui;
+import static java.time.temporal.ChronoUnit.SECONDS;
+
import bibliothek.extension.gui.dock.theme.EclipseTheme;
import bibliothek.extension.gui.dock.theme.eclipse.EclipseTabDockActionLocation;
import bibliothek.extension.gui.dock.theme.eclipse.EclipseTabStateInfo;
@@ -52,26 +54,41 @@
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
+import java.io.IOException;
import java.io.PrintStream;
+import java.io.StringReader;
import java.lang.management.ManagementFactory;
import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.net.URL;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+import java.net.http.HttpResponse.BodyHandlers;
+import java.time.Duration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
+import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
+import javax.json.Json;
+import javax.json.JsonObject;
+import javax.json.JsonReader;
import javax.management.InstanceNotFoundException;
import javax.management.JMException;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.swing.Action;
import javax.swing.Icon;
+import javax.swing.JCheckBox;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComponent;
import javax.swing.JFrame;
+import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
@@ -84,6 +101,7 @@
import javax.swing.TransferHandler;
import javax.swing.TransferHandler.DropLocation;
import javax.swing.WindowConstants;
+import org.osgi.framework.Version;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.weasis.base.ui.Messages;
@@ -313,6 +331,14 @@ public void createMainPanel() {
UIManager.MAIN_AREA.getComponent().setTransferHandler(new SequenceHandler());
UIManager.MAIN_AREA.setLocation(CLocation.base().normalRectangle(0, 0, 1, 1));
UIManager.MAIN_AREA.setVisible(true);
+
+ boolean updateRelease =
+ BundleTools.SYSTEM_PREFERENCES.getBooleanProperty("weasis.update.release", true);
+ boolean showDownloadRelease =
+ BundleTools.SYSTEM_PREFERENCES.getBooleanProperty("weasis.show.update.next.release", true);
+ if (updateRelease && showDownloadRelease) {
+ CompletableFuture.runAsync(() -> checkReleaseUpdate(frame));
+ }
}
HashMap>> getSeriesByEntry(
@@ -712,6 +738,37 @@ private JMenuBar createMenuBar() {
openBrowser(
websiteMenuItem, BundleTools.SYSTEM_PREFERENCES.getProperty("weasis.help.online")));
helpMenuItem.add(websiteMenuItem);
+ helpMenuItem.add(new JSeparator());
+
+ final JMenuItem updateMenuItem = new JMenuItem("Check for Updates...");
+ updateMenuItem.addActionListener(
+ e -> {
+ JsonObject object = getLastRelease();
+ if (object != null) {
+ Version vOld = AppProperties.getVersion(AppProperties.WEASIS_VERSION);
+ Version vNew = AppProperties.getVersion(object.getString("version"));
+ if (vNew.compareTo(vOld) > 0) {
+ openBrowser(updateMenuItem, object.getString("url"));
+ } else {
+ GuiExecutor.instance()
+ .execute(
+ () ->
+ JOptionPane.showMessageDialog(
+ updateMenuItem,
+ "The current release is already the latest release available.",
+ "Update",
+ JOptionPane.INFORMATION_MESSAGE));
+ }
+ }
+ });
+ helpMenuItem.add(updateMenuItem);
+
+ final JMenuItem reportMenuItem = new JMenuItem("Submit a Bug Report");
+ reportMenuItem.addActionListener(
+ e -> openBrowser(reportMenuItem, "https://github.com/nroduit/Weasis/issues"));
+ helpMenuItem.add(reportMenuItem);
+ helpMenuItem.add(new JSeparator());
+
final JMenuItem aboutMenuItem =
new JMenuItem(
String.format(Messages.getString("WeasisAboutBox.about"), AppProperties.WEASIS_NAME));
@@ -726,6 +783,63 @@ private JMenuBar createMenuBar() {
return menuBar;
}
+ private JsonObject getLastRelease() {
+ try {
+ HttpRequest request =
+ HttpRequest.newBuilder()
+ .uri(new URI("https://nroduit.github.io/en/api/release/api.json"))
+ .timeout(Duration.of(10, SECONDS))
+ .GET()
+ .build();
+
+ HttpResponse response =
+ HttpClient.newBuilder()
+ .followRedirects(HttpClient.Redirect.ALWAYS)
+ .build()
+ .send(request, BodyHandlers.ofString());
+
+ try (JsonReader jsonReader = Json.createReader(new StringReader(response.body()))) {
+ return jsonReader.readObject();
+ }
+ } catch (IOException | URISyntaxException ex) {
+ LOGGER.error("Cannot check release update", ex);
+ } catch (InterruptedException ex2) {
+ Thread.currentThread().interrupt();
+ }
+ return null;
+ }
+
+ private void checkReleaseUpdate(Component parent) {
+ JsonObject object = getLastRelease();
+ if (object != null) {
+ Version vOld = AppProperties.getVersion(AppProperties.WEASIS_VERSION);
+ // Version vNew = AppProperties.getVersion(object.getString("version"));
+ Version vNew = AppProperties.getVersion("4.0.2");
+ if (vNew.compareTo(vOld) > 0) {
+ GuiExecutor.instance()
+ .execute(
+ () -> {
+ JLabel label =
+ new JLabel("A new release is available. Do you want to download it?");
+ label.setAlignmentX(JLabel.RIGHT_ALIGNMENT);
+ JCheckBox dontAskMeAgain = new JCheckBox("Don't ask me again");
+ dontAskMeAgain.setAlignmentX(JLabel.RIGHT_ALIGNMENT);
+ JPanel panel = GuiUtils.getVerticalBoxLayoutPanel(label, dontAskMeAgain);
+ int confirm =
+ JOptionPane.showConfirmDialog(
+ parent, panel, "Update", JOptionPane.YES_NO_OPTION);
+ if (confirm == 0) {
+ openBrowser(parent, object.getString("url"));
+ }
+ if (dontAskMeAgain.isSelected()) {
+ BundleTools.SYSTEM_PREFERENCES.putBooleanProperty(
+ "weasis.show.update.next.release", false);
+ }
+ });
+ }
+ }
+ }
+
private void openBrowser(Component c, String ref) {
try {
URL url = new URL(ref);
diff --git a/weasis-core/weasis-core-api/src/main/java/org/weasis/core/api/gui/util/AppProperties.java b/weasis-core/weasis-core-api/src/main/java/org/weasis/core/api/gui/util/AppProperties.java
index e177f7ce9..d9d8887dd 100644
--- a/weasis-core/weasis-core-api/src/main/java/org/weasis/core/api/gui/util/AppProperties.java
+++ b/weasis-core/weasis-core-api/src/main/java/org/weasis/core/api/gui/util/AppProperties.java
@@ -14,6 +14,7 @@
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceReference;
+import org.osgi.framework.Version;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.weasis.core.util.FileUtil;
@@ -129,4 +130,14 @@ public static File buildAccessibleTempDirectory(String... subFolderName) {
}
return AppProperties.APP_TEMP_DIR;
}
+
+ public static Version getVersion(String version) {
+ String v = "";
+ if (version != null) {
+ int start = version.startsWith("v") ? 1 : 0;
+ int end = version.indexOf('-');
+ v = end > 0 ? version.substring(start, end) : version;
+ }
+ return new Version(v);
+ }
}
diff --git a/weasis-dicom/weasis-dicom-qr/src/main/java/org/weasis/dicom/qr/RsQuery.java b/weasis-dicom/weasis-dicom-qr/src/main/java/org/weasis/dicom/qr/RsQuery.java
index 2a62d175c..06a835f76 100644
--- a/weasis-dicom/weasis-dicom-qr/src/main/java/org/weasis/dicom/qr/RsQuery.java
+++ b/weasis-dicom/weasis-dicom-qr/src/main/java/org/weasis/dicom/qr/RsQuery.java
@@ -170,14 +170,13 @@ static void populateDicomModel(DicomModel dicomModel, Attributes item) {
TagW.PatientPseudoUID, patientPseudoUID, DicomModel.patient.tagView()) {
@Override
public String toString() {
- StringBuilder buf = new StringBuilder(getDisplayValue(this, Tag.PatientName));
- buf.append(" [");
- buf.append(getDisplayValue(this, Tag.PatientID));
- buf.append("] ");
- buf.append(getDisplayValue(this, Tag.PatientBirthDate));
- buf.append(" ");
- buf.append(getDisplayValue(this, Tag.PatientSex));
- return buf.toString();
+ return getDisplayValue(this, Tag.PatientName)
+ + " ["
+ + getDisplayValue(this, Tag.PatientID)
+ + "] "
+ + getDisplayValue(this, Tag.PatientBirthDate)
+ + " "
+ + getDisplayValue(this, Tag.PatientSex);
}
};
DicomMediaUtils.writeMetaData(patient, item);
diff --git a/weasis-dicom/weasis-dicom-sr/src/main/java/org/weasis/dicom/sr/SRView.java b/weasis-dicom/weasis-dicom-sr/src/main/java/org/weasis/dicom/sr/SRView.java
index 856e8d299..787df965c 100644
--- a/weasis-dicom/weasis-dicom-sr/src/main/java/org/weasis/dicom/sr/SRView.java
+++ b/weasis-dicom/weasis-dicom-sr/src/main/java/org/weasis/dicom/sr/SRView.java
@@ -23,7 +23,6 @@
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
-import javax.swing.border.EmptyBorder;
import javax.swing.event.HyperlinkEvent;
import org.dcm4che3.data.Attributes;
import org.dcm4che3.data.Tag;
@@ -82,7 +81,7 @@ public SRView(Series> series) {
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
- htmlPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
+ htmlPanel.setBorder(GuiUtils.getEmptyBorder(5, 5, 5, 5));
htmlPanel.setContentType("text/html");
htmlPanel.setEditable(false);
htmlPanel.addHyperlinkListener(
diff --git a/weasis-launcher/conf/ext-config.properties b/weasis-launcher/conf/ext-config.properties
index d32aa6b40..2142c8f7e 100644
--- a/weasis-launcher/conf/ext-config.properties
+++ b/weasis-launcher/conf/ext-config.properties
@@ -61,6 +61,8 @@ org.apache.sling.commons.log.stack.limit=-1
weasis.show.disclaimer=false
##### Show a message when the release has changed
weasis.show.release=false
+##### Show a message when a new release is available
+weasis.update.release=true
##### Allows exporting DICOM files. Default value is true.
#weasis.export.dicom=false
##### Allows DICOM send. Is always false when weasis.export.dicom=false.
diff --git a/weasis-launcher/src/main/java/org/weasis/launcher/WeasisLauncher.java b/weasis-launcher/src/main/java/org/weasis/launcher/WeasisLauncher.java
index 2d48c16a7..43792b52e 100644
--- a/weasis-launcher/src/main/java/org/weasis/launcher/WeasisLauncher.java
+++ b/weasis-launcher/src/main/java/org/weasis/launcher/WeasisLauncher.java
@@ -996,6 +996,8 @@ else if (cleanCache && versionNew != null && !versionNew.equals(versionOld)) {
if (update) {
FileUtil.storeProperties(sourceIDProps, localSourceProp, null);
+ // Reset message when deploying a new release
+ currentProps.setProperty("weasis.show.update.next.release", Boolean.TRUE.toString());
}
// Transmit weasis.properties