Skip to content

Commit

Permalink
Restructured OO/LO auto-detection for Windows and OS X
Browse files Browse the repository at this point in the history
  • Loading branch information
oscargus committed Mar 28, 2016
1 parent c4c779d commit 17e998d
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 97 deletions.
154 changes: 61 additions & 93 deletions src/main/java/net/sf/jabref/openoffice/AutoDetectPaths.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (C) 2003-2015 JabRef contributors.
/* Copyright (C) 2003-2016 JabRef contributors.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
Expand Down Expand Up @@ -37,6 +37,8 @@
*/
public class AutoDetectPaths extends AbstractWorker {

private static final String SOFFICE_EXE = "soffice.exe";

private static final String SOFFICE = "soffice";

private static final String SOFFICE_BIN = "soffice.bin";
Expand All @@ -51,6 +53,9 @@ public class AutoDetectPaths extends AbstractWorker {
private final JDialog parent;


private final OpenOfficeFileSearch fileSearch = new OpenOfficeFileSearch();


public AutoDetectPaths(JDialog parent, OpenOfficePreferences preferences) {
this.parent = parent;
this.preferences = preferences;
Expand Down Expand Up @@ -92,21 +97,14 @@ public void update() {
}

private boolean autoDetectPaths() {

fileSearch.resetFileSearch();
if (OS.WINDOWS) {
List<File> progFiles = new OpenOfficeFileSearch().findWindowsProgramFilesDir();
File sOffice = null;
List<File> sofficeFiles = new ArrayList<>();
for (File dir : progFiles) {
if (fileSearchCancelled) {
return false;
}
sOffice = findFileDir(dir, "soffice.exe");
if (sOffice != null) {
sofficeFiles.add(sOffice);
}
List<File> progFiles = fileSearch.findWindowsProgramFilesDir();
List<File> sofficeFiles = new ArrayList<>(fileSearch.findFileDir(progFiles, SOFFICE_EXE));
if (fileSearchCancelled) {
return false;
}
if (sOffice == null) {
if (sofficeFiles.isEmpty()) {
JOptionPane.showMessageDialog(parent,
Localization
.lang("Unable to autodetect OpenOffice/LibreOffice installation. Please choose the installation directory manually."),
Expand All @@ -132,67 +130,39 @@ public String getDescription() {
sofficeFiles.add(fileChooser.getSelectedFile());
}
}
if (sOffice == null) {
return false;
}

if (sofficeFiles.size() > 1) {
// More than one file found
DefaultListModel<File> mod = new DefaultListModel<>();
for (File tmpfile : sofficeFiles) {
mod.addElement(tmpfile);
}
JList<File> fileList = new JList<>(mod);
fileList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
fileList.setSelectedIndex(0);
FormBuilder builder = FormBuilder.create()
.layout(new FormLayout("left:pref", "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 false;
} else {
sOffice = fileList.getSelectedValue();
}

Optional<File> actualFile = checkAndSelectAmongMultipleInstalls(sofficeFiles);
if (actualFile.isPresent()) {
setupPreferencesForOO(actualFile.get().getParentFile(), actualFile.get(), SOFFICE_EXE);
} else {
sOffice = sofficeFiles.get(0);
return false;
}
return setupPreferencesForOO(sOffice.getParentFile(), sOffice, "soffice.exe");
} else if (OS.OS_X) {
File rootDir = new File("/Applications");
File[] files = rootDir.listFiles();
if (files != null) {
for (File file : files) {
if (file.isDirectory() && ("OpenOffice.org.app".equals(file.getName())
|| "LibreOffice.app".equals(file.getName()))) {
rootDir = file;
break;
}
}
}
File sOffice = findFileDir(rootDir, SOFFICE_BIN);
List<File> dirList = fileSearch.findOSXProgramFilesDir();
List<File> sofficeFiles = new ArrayList<>(fileSearch.findFileDir(dirList, SOFFICE_BIN));

if (fileSearchCancelled) {
return false;
}
if (sOffice == null) {
Optional<File> actualFile = checkAndSelectAmongMultipleInstalls(sofficeFiles);
if (actualFile.isPresent()) {
for (File rootdir : dirList) {
if (actualFile.get().getPath().startsWith(rootdir.getPath())) {
return setupPreferencesForOO(rootdir, actualFile.get(), SOFFICE_BIN);
}
}
return false;
} else {
return setupPreferencesForOO(rootDir, sOffice, SOFFICE_BIN);
return false;
}
} else {
// Linux:
String usrRoot = "/usr/lib";
File inUsr = findFileDir(new File(usrRoot), SOFFICE);
File inUsr = fileSearch.findFileInDir(new File(usrRoot), SOFFICE);
if (fileSearchCancelled) {
return false;
}
if (inUsr == null) {
inUsr = findFileDir(new File("/usr/lib64"), SOFFICE);
inUsr = fileSearch.findFileInDir(new File("/usr/lib64"), SOFFICE);
if (inUsr != null) {
usrRoot = "/usr/lib64";
}
Expand All @@ -201,7 +171,7 @@ public String getDescription() {
if (fileSearchCancelled) {
return false;
}
File inOpt = findFileDir(new File("/opt"), SOFFICE);
File inOpt = fileSearch.findFileInDir(new File("/opt"), SOFFICE);
if (fileSearchCancelled) {
return false;
}
Expand Down Expand Up @@ -246,7 +216,7 @@ private boolean setupPreferencesForOO(String usrRoot, File inUsr, String soffice

private boolean setupPreferencesForOO(File rootDir, File inUsr, String sofficeName) {
preferences.setExecutablePath(new File(inUsr, sofficeName).getPath());
File jurt = findFileDir(rootDir, "jurt.jar");
File jurt = fileSearch.findFileInDir(rootDir, "jurt.jar");
if (fileSearchCancelled) {
return false;
}
Expand All @@ -258,50 +228,48 @@ private boolean setupPreferencesForOO(File rootDir, File inUsr, String sofficeNa
}
}

/**
* Search for a file, starting at the given directory.
* @param startDir The starting point.
* @param filename The name of the file to search for.
* @return The directory where the file was first found, or null if not found.
*/
private File findFileDir(File startDir, String filename) {
if (fileSearchCancelled) {
return null;
private Optional<File> checkAndSelectAmongMultipleInstalls(List<File> sofficeFiles) {
if (sofficeFiles.isEmpty()) {
return Optional.empty();
} else if (sofficeFiles.size() == 1) {
return Optional.of(sofficeFiles.get(0));
}
File[] files = startDir.listFiles();
if (files == null) {
return null;
// Otherwise more than one file found, select among them
DefaultListModel<File> mod = new DefaultListModel<>();
for (File tmpfile : sofficeFiles) {
mod.addElement(tmpfile);
}
File result = null;
for (File file : files) {
if (fileSearchCancelled) {
return null;
}
if (file.isDirectory()) {
result = findFileDir(file, filename);
if (result != null) {
break;
}
} else if (file.getName().equals(filename)) {
result = startDir;
break;
}
JList<File> fileList = new JList<>(mod);
fileList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
fileList.setSelectedIndex(0);
FormBuilder builder = FormBuilder.create().layout(new FormLayout("left:pref", "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());
}
return result;

}


public JDialog showProgressDialog(JDialog progressParent, String title, String message, boolean includeCancelButton) {
fileSearchCancelled = false;
JProgressBar bar = new JProgressBar(SwingConstants.HORIZONTAL);
JButton cancel = new JButton(Localization.lang("Cancel"));
cancel.addActionListener(event -> {
fileSearchCancelled = true;
((JButton) event.getSource()).setEnabled(false);
});
final JDialog progressDialog = new JDialog(progressParent, title, false);
bar.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
bar.setIndeterminate(true);
if (includeCancelButton) {
JButton cancel = new JButton(Localization.lang("Cancel"));
cancel.addActionListener(event -> {
fileSearchCancelled = true;
fileSearch.cancelFileSearch();
((JButton) event.getSource()).setEnabled(false);
});
progressDialog.add(cancel, BorderLayout.SOUTH);
}
progressDialog.add(new JLabel(message), BorderLayout.NORTH);
Expand Down
91 changes: 87 additions & 4 deletions src/main/java/net/sf/jabref/openoffice/OpenOfficeFileSearch.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class OpenOfficeFileSearch {

private boolean fileSearchCancelled;


/**
* Search for Program files directory.
* @return the File pointing to the Program files directory, or null if not found.
Expand All @@ -17,13 +19,13 @@ public List<File> findWindowsProgramFilesDir() {
List<String> sourceList = new ArrayList<>();
List<File> dirList = new ArrayList<>();

// 64-bits first
// Check default 64-bits program directory
String progFiles = System.getenv("ProgramFiles");
if (progFiles != null) {
sourceList.add(progFiles);
}

// Then 32-bits
// Check default 64-bits program directory
progFiles = System.getenv("ProgramFiles(x86)");
if (progFiles != null) {
sourceList.add(progFiles);
Expand All @@ -33,9 +35,90 @@ public List<File> findWindowsProgramFilesDir() {
File root = new File(rootPath);
File[] dirs = root.listFiles(File::isDirectory);
if (dirs != null) {
Collections.addAll(dirList, dirs);
for (File dir : dirs) {
if (dir.getPath().contains("OpenOffice") || dir.getPath().contains("LibreOffice")) {
dirList.add(dir);
}
}
}
}
return dirList;
}

/**
* Search for Program files directory.
* @return the File pointing to the Program files directory, or null if not found.
* Since we are not including a library for Windows integration, this method can't
* find the Program files dir in localized Windows installations.
*/
public List<File> findOSXProgramFilesDir() {
List<File> dirList = new ArrayList<>();

File rootDir = new File("/Applications");
File[] files = rootDir.listFiles();
if (files != null) {
for (File file : files) {
if (file.isDirectory() && ("OpenOffice.org.app".equals(file.getName())
|| "LibreOffice.app".equals(file.getName()))) {
dirList.add(file);
}
}
}

return dirList;
}

public void resetFileSearch() {
fileSearchCancelled = false;
}

public void cancelFileSearch() {
fileSearchCancelled = true;
}

public List<File> findFileDir(List<File> dirList, String filename) {
List<File> sofficeFiles = new ArrayList<>();
for (File dir : dirList) {
if (fileSearchCancelled) {
break;
}
File sOffice = findFileInDir(dir, filename);
if (sOffice != null) {
sofficeFiles.add(sOffice);
}
}
return sofficeFiles;
}
/**
* Search for a file, starting at the given directory.
* @param startDir The starting point.
* @param filename The name of the file to search for.
* @return The directory where the file was first found, or null if not found.
*/
public File findFileInDir(File startDir, String filename) {
if (fileSearchCancelled) {
return null;
}
File[] files = startDir.listFiles();
if (files == null) {
return null;
}
File result = null;
for (File file : files) {
if (fileSearchCancelled) {
return null;
}
if (file.isDirectory()) {
result = findFileInDir(file, filename);
if (result != null) {
break;
}
} else if (file.getName().equals(filename)) {
result = startDir;
break;
}
}
return result;
}

}
2 changes: 2 additions & 0 deletions src/main/java/net/sf/jabref/openoffice/OpenOfficePanel.java
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,8 @@ private void connect(boolean auto) {
} else if (!adp.cancelled()) {
JOptionPane.showMessageDialog(diag, Localization.lang("Autodetection failed"),
Localization.lang("Autodetection failed"), JOptionPane.ERROR_MESSAGE);
} else {
frame.setStatus(Localization.lang("Operation canceled."));
}
if (!autoDetected) {
return;
Expand Down

0 comments on commit 17e998d

Please sign in to comment.