diff --git a/CHANGELOG.md b/CHANGELOG.md index f62f79d5404..d0389c10820 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,7 @@ Note that this project **does not** adhere to [Semantic Versioning](http://semve - We integrated two mail actions ("As Email" and "To Kindle") under a new "Send" option in the right-click & Tools menus. The Kindle option creates an email targeted to the user's Kindle email, which can be set in preferences under "External programs" [#6186](https://github.com/JabRef/jabref/issues/6186) - We added an option to clear recent libraries' history. [#10003](https://github.com/JabRef/jabref/issues/10003) - We added an option to encrypt and remember the proxy password. [#8055](https://github.com/JabRef/jabref/issues/8055)[#10044](https://github.com/JabRef/jabref/issues/10044) +- We added support for pushing citations to Sublime Text 3 [#10098](https://github.com/JabRef/jabref/issues/10098) ### Changed diff --git a/src/main/java/org/jabref/gui/icon/IconTheme.java b/src/main/java/org/jabref/gui/icon/IconTheme.java index c92fea5ac8e..6265cda1ef2 100644 --- a/src/main/java/org/jabref/gui/icon/IconTheme.java +++ b/src/main/java/org/jabref/gui/icon/IconTheme.java @@ -276,6 +276,7 @@ public enum JabRefIcons implements JabRefIcon { APPLICATION_TEXMAKER(JabRefMaterialDesignIcon.TEX_MAKER), APPLICATION_VIM(JabRefMaterialDesignIcon.VIM), APPLICATION_WINEDT(JabRefMaterialDesignIcon.WINEDT), + APPLICATION_SUBLIMETEXT(JabRefMaterialDesignIcon.SUBLIME_TEXT), KEY_BINDINGS(MaterialDesignK.KEYBOARD), FIND_DUPLICATES(MaterialDesignC.CODE_EQUAL), CONNECT_DB(MaterialDesignC.CLOUD_UPLOAD), diff --git a/src/main/java/org/jabref/gui/icon/JabRefMaterialDesignIcon.java b/src/main/java/org/jabref/gui/icon/JabRefMaterialDesignIcon.java index a5745132bbc..e6b63d609db 100644 --- a/src/main/java/org/jabref/gui/icon/JabRefMaterialDesignIcon.java +++ b/src/main/java/org/jabref/gui/icon/JabRefMaterialDesignIcon.java @@ -29,7 +29,8 @@ public enum JabRefMaterialDesignIcon implements Ikon { SET_CENTER("jab-setcenter", '\ue90b'), SET_ALL("jab-setall", '\ue90c'), VSCODE("jab-vsvode", '\ue90d'), - CANCEL("jab-cancel", '\ue90e'); + CANCEL("jab-cancel", '\ue90e'), + SUBLIME_TEXT("jab-sublime-text", '\ue90f'); private String description; private int code; diff --git a/src/main/java/org/jabref/gui/preferences/external/ExternalTabViewModel.java b/src/main/java/org/jabref/gui/preferences/external/ExternalTabViewModel.java index f5fe61cbce3..3700f93b5e4 100644 --- a/src/main/java/org/jabref/gui/preferences/external/ExternalTabViewModel.java +++ b/src/main/java/org/jabref/gui/preferences/external/ExternalTabViewModel.java @@ -86,6 +86,7 @@ public ExternalTabViewModel(DialogService dialogService, PreferencesService pref Localization.lang("Please specify a file browser.")))); } + @Override public void setValues() { eMailReferenceSubjectProperty.setValue(initialExternalApplicationPreferences.getEmailSubject()); autoOpenAttachedFoldersProperty.setValue(initialExternalApplicationPreferences.shouldAutoOpenEmailAttachmentsFolder()); @@ -104,6 +105,7 @@ public void setValues() { kindleEmailProperty.setValue(initialExternalApplicationPreferences.getKindleEmail()); } + @Override public void storeSettings() { ExternalApplicationsPreferences externalPreferences = preferences.getExternalApplicationsPreferences(); externalPreferences.setEMailSubject(eMailReferenceSubjectProperty.getValue()); @@ -130,6 +132,7 @@ public ValidationStatus fileBrowserCommandValidationStatus() { return fileBrowserCommandValidator.getValidationStatus(); } + @Override public boolean validateSettings() { CompositeValidator validator = new CompositeValidator(); diff --git a/src/main/java/org/jabref/gui/push/AbstractPushToApplication.java b/src/main/java/org/jabref/gui/push/AbstractPushToApplication.java index 8642082dbdd..5c3ceeac981 100644 --- a/src/main/java/org/jabref/gui/push/AbstractPushToApplication.java +++ b/src/main/java/org/jabref/gui/push/AbstractPushToApplication.java @@ -13,6 +13,7 @@ import org.jabref.logic.util.OS; import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.entry.BibEntry; +import org.jabref.model.strings.StringUtil; import org.jabref.preferences.PreferencesService; import org.jabref.preferences.PushToApplicationPreferences; @@ -64,7 +65,7 @@ public void pushEntries(BibDatabaseContext database, List entries, Str commandPath = preferencesService.getPushToApplicationPreferences().getCommandPaths().get(this.getDisplayName()); // Check if a path to the command has been specified - if ((commandPath == null) || commandPath.trim().isEmpty()) { + if (StringUtil.isNullOrEmpty(commandPath)) { notDefined = true; return; } @@ -145,6 +146,7 @@ protected String getCiteCommand() { return preferencesService.getExternalApplicationsPreferences().getCiteCommand(); } + @Override public PushToApplicationSettings getSettings(PushToApplication application, PushToApplicationPreferences preferences) { return new PushToApplicationSettings(application, dialogService, preferencesService.getFilePreferences(), preferences); } diff --git a/src/main/java/org/jabref/gui/push/PushToApplicationCommand.java b/src/main/java/org/jabref/gui/push/PushToApplicationCommand.java index 8209f1c509a..1c5f1ee5e10 100644 --- a/src/main/java/org/jabref/gui/push/PushToApplicationCommand.java +++ b/src/main/java/org/jabref/gui/push/PushToApplicationCommand.java @@ -72,7 +72,7 @@ public void registerReconfigurable(Object node) { } private void setApplication(String applicationName) { - final ActionFactory factory = new ActionFactory(Globals.getKeyPrefs()); + final ActionFactory factory = new ActionFactory(preferencesService.getKeyBindingRepository()); PushToApplication application = PushToApplications.getApplicationByName( applicationName, dialogService, diff --git a/src/main/java/org/jabref/gui/push/PushToApplications.java b/src/main/java/org/jabref/gui/push/PushToApplications.java index e53e55b304d..3550bbac28b 100644 --- a/src/main/java/org/jabref/gui/push/PushToApplications.java +++ b/src/main/java/org/jabref/gui/push/PushToApplications.java @@ -15,6 +15,7 @@ public class PushToApplications { public static final String TEXSTUDIO = "TeXstudio"; public static final String VIM = "Vim"; public static final String WIN_EDT = "WinEdt"; + public static final String SUBLIME_TEXT = "Sublime Text"; private static final List APPLICATIONS = new ArrayList<>(); @@ -29,6 +30,7 @@ public static List getAllApplications(DialogService dialogSer APPLICATIONS.addAll(List.of( new PushToEmacs(dialogService, preferencesService), new PushToLyx(dialogService, preferencesService), + new PushToSublimeText(dialogService, preferencesService), new PushToTexmaker(dialogService, preferencesService), new PushToTeXstudio(dialogService, preferencesService), new PushToVim(dialogService, preferencesService), diff --git a/src/main/java/org/jabref/gui/push/PushToSublimeText.java b/src/main/java/org/jabref/gui/push/PushToSublimeText.java new file mode 100644 index 00000000000..56567bf76b6 --- /dev/null +++ b/src/main/java/org/jabref/gui/push/PushToSublimeText.java @@ -0,0 +1,84 @@ +package org.jabref.gui.push; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.List; +import java.util.Map; + +import org.jabref.gui.DialogService; +import org.jabref.gui.JabRefExecutorService; +import org.jabref.gui.icon.IconTheme; +import org.jabref.gui.icon.JabRefIcon; +import org.jabref.gui.util.StreamGobbler; +import org.jabref.logic.util.OS; +import org.jabref.model.database.BibDatabaseContext; +import org.jabref.model.entry.BibEntry; +import org.jabref.model.strings.StringUtil; +import org.jabref.preferences.PreferencesService; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class PushToSublimeText extends AbstractPushToApplication { + + public static final String NAME = PushToApplications.SUBLIME_TEXT; + + private static final Logger LOGGER = LoggerFactory.getLogger(PushToSublimeText.class); + + public PushToSublimeText(DialogService dialogService, PreferencesService preferencesService) { + super(dialogService, preferencesService); + } + + @Override + public String getDisplayName() { + return NAME; + } + + @Override + public JabRefIcon getApplicationIcon() { + return IconTheme.JabRefIcons.APPLICATION_SUBLIMETEXT; + } + + @Override + public void pushEntries(BibDatabaseContext database, List entries, String keyString) { + couldNotConnect = false; + couldNotCall = false; + notDefined = false; + + commandPath = preferencesService.getPushToApplicationPreferences().getCommandPaths().get(this.getDisplayName()); + + // Check if a path to the command has been specified + if (StringUtil.isNullOrEmpty(commandPath)) { + notDefined = true; + return; + } + try { + + LOGGER.debug("Sublime string: {}", String.join(" ", getCommandLine(keyString))); + ProcessBuilder processBuilder = new ProcessBuilder(getCommandLine(keyString)); + processBuilder.inheritIO(); + Map envs = processBuilder.environment(); + envs.put("PATH", Path.of(commandPath).getParent().toString()); + + Process process = processBuilder.start(); + StreamGobbler streamGobblerInput = new StreamGobbler(process.getInputStream(), LOGGER::info); + StreamGobbler streamGobblerError = new StreamGobbler(process.getErrorStream(), LOGGER::info); + + JabRefExecutorService.INSTANCE.execute(streamGobblerInput); + JabRefExecutorService.INSTANCE.execute(streamGobblerError); + } catch (IOException excep) { + LOGGER.warn("Error: Could not call executable '{}'", commandPath, excep); + couldNotCall = true; + } + } + + @Override + protected String[] getCommandLine(String keyString) { + if (OS.WINDOWS) { + // TODO we might need to escape the inner double quotes with """ """ + return new String[] {"cmd.exe", "/c", "\"" + commandPath + "\"" + "--command \"insert {\\\"characters\\\": \"\\" + getCiteCommand() + "{" + keyString + "}\"}\""}; + } else { + return new String[] {"sh", "-c", "\"" + commandPath + "\"" + " --command 'insert {\"characters\": \"\\" + getCiteCommand() + "{" + keyString + "}\"}'"}; + } + } +} diff --git a/src/main/java/org/jabref/preferences/JabRefPreferences.java b/src/main/java/org/jabref/preferences/JabRefPreferences.java index f97680c67d7..f34f530032b 100644 --- a/src/main/java/org/jabref/preferences/JabRefPreferences.java +++ b/src/main/java/org/jabref/preferences/JabRefPreferences.java @@ -141,6 +141,7 @@ public class JabRefPreferences implements PreferencesService { public static final String PUSH_TEXMAKER_PATH = "texmakerPath"; public static final String PUSH_VIM_SERVER = "vimServer"; public static final String PUSH_VIM = "vim"; + public static final String PUSH_SUBLIME_TEXT_PATH = "sublimeTextPath"; /* contents of the defaults HashMap that are defined in this class. * There are more default parameters in this map which belong to separate preference classes. @@ -503,6 +504,7 @@ private JabRefPreferences() { defaults.put(PUSH_TEXMAKER_PATH, OS.getNativeDesktop().detectProgramPath("texmaker", "Texmaker")); defaults.put(PUSH_WINEDT_PATH, OS.getNativeDesktop().detectProgramPath("WinEdt", "WinEdt Team\\WinEdt")); defaults.put(PUSH_TEXSTUDIO_PATH, OS.getNativeDesktop().detectProgramPath("texstudio", "TeXstudio")); + defaults.put(PUSH_SUBLIME_TEXT_PATH, OS.getNativeDesktop().detectProgramPath("subl", "Sublime")); defaults.put(PUSH_LYXPIPE, USER_HOME + File.separator + ".lyx/lyxpipe"); defaults.put(PUSH_VIM, "vim"); defaults.put(PUSH_VIM_SERVER, "vim"); @@ -1722,6 +1724,7 @@ public PushToApplicationPreferences getPushToApplicationPreferences() { applicationCommands.put(PushToApplications.TEXSTUDIO, get(PUSH_TEXSTUDIO_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)); pushToApplicationPreferences = new PushToApplicationPreferences( get(PUSH_TO_APPLICATION), @@ -1753,6 +1756,8 @@ private void storePushToApplicationPath(Map commandPair) { put(PUSH_VIM, value); case PushToApplications.WIN_EDT -> put(PUSH_WINEDT_PATH, value); + case PushToApplications.SUBLIME_TEXT -> + put(PUSH_SUBLIME_TEXT_PATH, value); } }); } diff --git a/src/main/resources/fonts/JabRefMaterialDesign.ttf b/src/main/resources/fonts/JabRefMaterialDesign.ttf index f10dbdcd736..769fc1fe9e5 100644 Binary files a/src/main/resources/fonts/JabRefMaterialDesign.ttf and b/src/main/resources/fonts/JabRefMaterialDesign.ttf differ diff --git a/src/main/resources/images/Icons.properties b/src/main/resources/images/Icons.properties index 3618d8fb943..8caa86aa6ad 100644 --- a/src/main/resources/images/Icons.properties +++ b/src/main/resources/images/Icons.properties @@ -6,19 +6,3 @@ jabrefIcon40=JabRef-icon-40.png jabrefIcon48=JabRef-icon-48.png jabrefIcon64=JabRef-icon-64.png jabrefIcon128=JabRef-icon-128.png - - - -#external apps -texmaker=texmaker.png -texstudio=texstudio.png -winedt=winedt.png -vim=vim.png -lyx=lyx2.png -openoffice=openoffice.png -citeseer=wwwciteseer.png -arxiv=arxiv_32.png -emacs=emacs.png -mdl=mdl-icon.png -mdlloading=mdlloading.gif -mdlListIcon=mdlListIcon.png diff --git a/src/main/resources/images/external/arxiv_32.png b/src/main/resources/images/external/arxiv_32.png deleted file mode 100644 index d813cc665a3..00000000000 Binary files a/src/main/resources/images/external/arxiv_32.png and /dev/null differ diff --git a/src/main/resources/images/external/emacs.png b/src/main/resources/images/external/emacs.png deleted file mode 100644 index c86092f50ea..00000000000 Binary files a/src/main/resources/images/external/emacs.png and /dev/null differ diff --git a/src/main/resources/images/external/lyx2.png b/src/main/resources/images/external/lyx2.png deleted file mode 100644 index 4162b77745f..00000000000 Binary files a/src/main/resources/images/external/lyx2.png and /dev/null differ diff --git a/src/main/resources/images/external/mdl-icon.png b/src/main/resources/images/external/mdl-icon.png deleted file mode 100644 index 751e550c9e3..00000000000 Binary files a/src/main/resources/images/external/mdl-icon.png and /dev/null differ diff --git a/src/main/resources/images/external/mdlListIcon.png b/src/main/resources/images/external/mdlListIcon.png deleted file mode 100644 index fe876672aef..00000000000 Binary files a/src/main/resources/images/external/mdlListIcon.png and /dev/null differ diff --git a/src/main/resources/images/external/mdlloading.gif b/src/main/resources/images/external/mdlloading.gif deleted file mode 100644 index eea2948e08d..00000000000 Binary files a/src/main/resources/images/external/mdlloading.gif and /dev/null differ diff --git a/src/main/resources/images/external/openoffice.png b/src/main/resources/images/external/openoffice.png deleted file mode 100644 index d9cd9003da0..00000000000 Binary files a/src/main/resources/images/external/openoffice.png and /dev/null differ diff --git a/src/main/resources/images/external/texmaker.png b/src/main/resources/images/external/texmaker.png deleted file mode 100644 index 6c87386e8c2..00000000000 Binary files a/src/main/resources/images/external/texmaker.png and /dev/null differ diff --git a/src/main/resources/images/external/texstudio.png b/src/main/resources/images/external/texstudio.png deleted file mode 100644 index a010bee75da..00000000000 Binary files a/src/main/resources/images/external/texstudio.png and /dev/null differ diff --git a/src/main/resources/images/external/vim.png b/src/main/resources/images/external/vim.png deleted file mode 100644 index 0368ee4c24d..00000000000 Binary files a/src/main/resources/images/external/vim.png and /dev/null differ diff --git a/src/main/resources/images/external/winedt.png b/src/main/resources/images/external/winedt.png deleted file mode 100644 index 320320b4912..00000000000 Binary files a/src/main/resources/images/external/winedt.png and /dev/null differ diff --git a/src/main/resources/images/external/wwwciteseer.png b/src/main/resources/images/external/wwwciteseer.png deleted file mode 100644 index 82c8038f1b8..00000000000 Binary files a/src/main/resources/images/external/wwwciteseer.png and /dev/null differ