diff --git a/CHANGELOG.md b/CHANGELOG.md index a27e119b67f..3b86c76bc5b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -77,6 +77,7 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv - We fixed an issue where JabRef could not parse absolute file paths from Zotero exports. [#10959](https://github.com/JabRef/jabref/issues/10959) - We fixed an issue where an exception occured when toggling between "Live" or "Locked" in the internal Document Viewer. [#10935](https://github.com/JabRef/jabref/issues/10935) - Fixed an issue on Windows where the browser extension reported failure to send an entry to JabRef even though it was sent properly. [JabRef-Browser-Extension#493](https://github.com/JabRef/JabRef-Browser-Extension/issues/493) +- Fixed an issue on Windows where TeXworks path was not resolved if it was installed with MiKTeX. [#10977](https://github.com/JabRef/jabref/issues/10977) - We fixed an issue with where JabRef would throw an error when using MathSciNet search, as it was unable to parse the fetched JSON coreectly. [10996](https://github.com/JabRef/jabref/issues/10996) ### Removed diff --git a/build.gradle b/build.gradle index 3a7b4b17cea..996cf18442d 100644 --- a/build.gradle +++ b/build.gradle @@ -252,6 +252,9 @@ dependencies { // parse plist files implementation 'com.googlecode.plist:dd-plist:1.28' + // Parse lnk files + implementation 'com.github.vatbub:mslinks:1.0.6.2' + // YAML formatting implementation 'org.yaml:snakeyaml:2.2' diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index f10bafc0d4b..98d60718c2c 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -145,5 +145,6 @@ requires de.saxsys.mvvmfx.validation; requires com.jthemedetector; requires dd.plist; + requires mslinks; requires org.yaml.snakeyaml; } diff --git a/src/main/java/org/jabref/gui/desktop/os/Windows.java b/src/main/java/org/jabref/gui/desktop/os/Windows.java index 2fa119208f0..fd1d7b40789 100644 --- a/src/main/java/org/jabref/gui/desktop/os/Windows.java +++ b/src/main/java/org/jabref/gui/desktop/os/Windows.java @@ -4,7 +4,10 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.util.Objects; import java.util.Optional; +import java.util.logging.Level; +import java.util.logging.Logger; import org.jabref.Launcher; import org.jabref.gui.DialogService; @@ -16,6 +19,8 @@ import com.sun.jna.platform.win32.Shell32Util; import com.sun.jna.platform.win32.ShlObj; import com.sun.jna.platform.win32.Win32Exception; +import mslinks.ShellLink; +import mslinks.ShellLinkException; import org.slf4j.LoggerFactory; /** @@ -43,6 +48,20 @@ public void openFile(String filePath, String fileType, FilePreferences filePrefe @Override public String detectProgramPath(String programName, String directoryName) { + if (Objects.equals(programName, "texworks")) { + Path texworksLinkPath = Path.of(System.getenv("APPDATA") + "\\Microsoft\\Windows\\Start Menu\\Programs\\MiKTeX\\TeXworks.lnk"); + if (Files.exists(texworksLinkPath)) { + try { + ShellLink link = new ShellLink(texworksLinkPath); + return link.resolveTarget(); + } catch (IOException | ShellLinkException e) { + // Static logger instance cannot be used. See the class comment. + Logger logger = Logger.getLogger(Windows.class.getName()); + logger.log(Level.WARNING, "Had an error while reading .lnk file for TeXworks", e); + } + } + } + String progFiles = System.getenv("ProgramFiles(x86)"); String programPath; if (progFiles != null) { diff --git a/src/main/java/org/jabref/preferences/JabRefPreferences.java b/src/main/java/org/jabref/preferences/JabRefPreferences.java index 88d5582eeb4..836a724225a 100644 --- a/src/main/java/org/jabref/preferences/JabRefPreferences.java +++ b/src/main/java/org/jabref/preferences/JabRefPreferences.java @@ -939,6 +939,15 @@ public String get(String key) { return prefs.get(key, (String) defaults.get(key)); } + public String getEmptyIsDefault(String key) { + String defaultValue = (String) defaults.get(key); + String result = prefs.get(key, defaultValue); + if ("".equals(result)) { + return defaultValue; + } + return result; + } + public Optional getAsOptional(String key) { return Optional.ofNullable(prefs.get(key, (String) defaults.get(key))); } @@ -1774,14 +1783,16 @@ public PushToApplicationPreferences getPushToApplicationPreferences() { } Map applicationCommands = new HashMap<>(); - applicationCommands.put(PushToApplications.EMACS, get(PUSH_EMACS_PATH)); - applicationCommands.put(PushToApplications.LYX, get(PUSH_LYXPIPE)); - applicationCommands.put(PushToApplications.TEXMAKER, get(PUSH_TEXMAKER_PATH)); - applicationCommands.put(PushToApplications.TEXSTUDIO, get(PUSH_TEXSTUDIO_PATH)); - applicationCommands.put(PushToApplications.TEXWORKS, get(PUSH_TEXWORKS_PATH)); - applicationCommands.put(PushToApplications.VIM, get(PUSH_VIM)); - applicationCommands.put(PushToApplications.WIN_EDT, get(PUSH_WINEDT_PATH)); - applicationCommands.put(PushToApplications.SUBLIME_TEXT, get(PUSH_SUBLIME_TEXT_PATH)); + // getEmptyIsDefault is used to ensure that an installation of a tool leads to the new path (instead of leaving the empty one) + // Reason: empty string is returned by org.jabref.gui.desktop.os.Windows.detectProgramPath if program is not found. That path is stored in the preferences. + applicationCommands.put(PushToApplications.EMACS, getEmptyIsDefault(PUSH_EMACS_PATH)); + applicationCommands.put(PushToApplications.LYX, getEmptyIsDefault(PUSH_LYXPIPE)); + applicationCommands.put(PushToApplications.TEXMAKER, getEmptyIsDefault(PUSH_TEXMAKER_PATH)); + applicationCommands.put(PushToApplications.TEXSTUDIO, getEmptyIsDefault(PUSH_TEXSTUDIO_PATH)); + applicationCommands.put(PushToApplications.TEXWORKS, getEmptyIsDefault(PUSH_TEXWORKS_PATH)); + applicationCommands.put(PushToApplications.VIM, getEmptyIsDefault(PUSH_VIM)); + applicationCommands.put(PushToApplications.WIN_EDT, getEmptyIsDefault(PUSH_WINEDT_PATH)); + applicationCommands.put(PushToApplications.SUBLIME_TEXT, getEmptyIsDefault(PUSH_SUBLIME_TEXT_PATH)); pushToApplicationPreferences = new PushToApplicationPreferences( get(PUSH_TO_APPLICATION),