package org.jabref.gui.openoffice; import java.awt.BorderLayout; import java.io.File; import java.nio.file.Path; import java.util.List; import java.util.Optional; import javax.swing.BorderFactory; import javax.swing.DefaultListModel; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JOptionPane; import javax.swing.JProgressBar; import javax.swing.ListSelectionModel; import javax.swing.SwingConstants; import org.jabref.gui.DialogService; import org.jabref.gui.FXDialogService; import org.jabref.gui.desktop.JabRefDesktop; import org.jabref.gui.desktop.os.NativeDesktop; import org.jabref.gui.util.DefaultTaskExecutor; import org.jabref.gui.util.DirectoryDialogConfiguration; import org.jabref.gui.worker.AbstractWorker; import org.jabref.logic.l10n.Localization; import org.jabref.logic.openoffice.OpenOfficeFileSearch; import org.jabref.logic.openoffice.OpenOfficePreferences; import org.jabref.logic.util.OS; import org.jabref.logic.util.io.FileUtil; import com.jgoodies.forms.builder.FormBuilder; import com.jgoodies.forms.layout.FormLayout; /** * Tools for automatically detecting OpenOffice or LibreOffice installations. */ public class DetectOpenOfficeInstallation extends AbstractWorker { private final OpenOfficePreferences preferences; private final JDialog parent; private boolean foundPaths; private JDialog progressDialog; public DetectOpenOfficeInstallation(JDialog parent, OpenOfficePreferences preferences) { this.parent = parent; this.preferences = preferences; } public boolean isInstalled() { foundPaths = false; if (preferences.checkAutoDetectedPaths()) { return true; } init(); getWorker().run(); update(); return foundPaths; } @Override public void run() { foundPaths = autoDetectPaths(); } @Override public void init() { progressDialog = showProgressDialog(parent, Localization.lang("Autodetecting paths..."), Localization.lang("Please wait...")); } @Override public void update() { progressDialog.dispose(); } private Optional<Path> selectInstallationPath() { final NativeDesktop nativeDesktop = JabRefDesktop.getNativeDesktop(); JOptionPane.showMessageDialog(parent, Localization.lang("Unable to autodetect OpenOffice/LibreOffice installation. Please choose the installation directory manually."), Localization.lang("Could not find OpenOffice/LibreOffice installation"), JOptionPane.INFORMATION_MESSAGE); DialogService ds = new FXDialogService(); DirectoryDialogConfiguration dirDialogConfiguration = new DirectoryDialogConfiguration.Builder() .withInitialDirectory(nativeDesktop.getApplicationDirectory()).build(); Optional<Path> path = DefaultTaskExecutor.runInJavaFXThread(() -> ds.showDirectorySelectionDialog(dirDialogConfiguration)); if (path.isPresent()) { return path; } return Optional.empty(); } private boolean autoDetectPaths() { List<Path> installations = OpenOfficeFileSearch.detectInstallations(); // manually add installation path if (installations.isEmpty()) { selectInstallationPath().ifPresent(installations::add); } // select among multiple installations Optional<Path> actualFile = chooseAmongInstallations(installations); if (actualFile.isPresent()) { return setOpenOfficePreferences(actualFile.get()); } return false; } private boolean setOpenOfficePreferences(Path installDir) { Optional<Path> execPath = Optional.empty(); if (OS.WINDOWS) { execPath = FileUtil.find(OpenOfficePreferences.WINDOWS_EXECUTABLE, installDir); } else if (OS.OS_X) { execPath = FileUtil.find(OpenOfficePreferences.OSX_EXECUTABLE, installDir); } else if (OS.LINUX) { execPath = FileUtil.find(OpenOfficePreferences.LINUX_EXECUTABLE, installDir); } Optional<Path> jarFilePath = FileUtil.find(OpenOfficePreferences.OO_JARS.get(0), installDir); if (execPath.isPresent() && jarFilePath.isPresent()) { preferences.setOOPath(installDir.toString()); preferences.setExecutablePath(execPath.get().toString()); preferences.setJarsPath(jarFilePath.get().getParent().toString()); return true; } return false; } private Optional<Path> chooseAmongInstallations(List<Path> installDirs) { if (installDirs.isEmpty()) { return Optional.empty(); } if (installDirs.size() == 1) { return Optional.of(installDirs.get(0).toAbsolutePath()); } // Otherwise more than one installation was found, select among them DefaultListModel<File> mod = new DefaultListModel<>(); for (Path tmpfile : installDirs) { mod.addElement(tmpfile.toFile()); } JList<File> fileList = new JList<>(mod); fileList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); fileList.setSelectedIndex(0); FormBuilder builder = FormBuilder.create().layout(new FormLayout("pref:grow", "pref, 2dlu, pref, 4dlu, pref")); builder.add(Localization.lang("Found more than one OpenOffice/LibreOffice executable.")).xy(1, 1); builder.add(Localization.lang("Please choose which one to connect to:")).xy(1, 3); builder.add(fileList).xy(1, 5); int answer = JOptionPane.showConfirmDialog(null, builder.getPanel(), Localization.lang("Choose OpenOffice/LibreOffice executable"), JOptionPane.OK_CANCEL_OPTION); if (answer == JOptionPane.CANCEL_OPTION) { return Optional.empty(); } else { return Optional.of(fileList.getSelectedValue().toPath()); } } public JDialog showProgressDialog(JDialog progressParent, String title, String message) { JProgressBar bar = new JProgressBar(SwingConstants.HORIZONTAL); final JDialog progressDialog = new JDialog(progressParent, title, false); bar.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); bar.setIndeterminate(true); progressDialog.add(new JLabel(message), BorderLayout.NORTH); progressDialog.add(bar, BorderLayout.CENTER); progressDialog.pack(); progressDialog.setLocationRelativeTo(null); progressDialog.setVisible(true); return progressDialog; } }