diff --git a/z.ex.search/build.properties b/z.ex.search/build.properties index e9863e2..6c480f3 100644 --- a/z.ex.search/build.properties +++ b/z.ex.search/build.properties @@ -2,4 +2,5 @@ source.. = src/ output.. = bin/ bin.includes = META-INF/,\ .,\ - plugin.xml + plugin.xml,\ + icons/ diff --git a/z.ex.search/icons/pdf.svg b/z.ex.search/icons/pdf.svg new file mode 100644 index 0000000..56e57fc --- /dev/null +++ b/z.ex.search/icons/pdf.svg @@ -0,0 +1,3 @@ + + + diff --git a/z.ex.search/plugin.xml b/z.ex.search/plugin.xml index 50b9208..72defc6 100644 --- a/z.ex.search/plugin.xml +++ b/z.ex.search/plugin.xml @@ -15,6 +15,11 @@ id="z.ex.search.prevSearchEntry" name="Previous Search Entry"> + + @@ -31,5 +36,35 @@ sequence="ALT+,"> + + + + + + + + + + + + + + + + diff --git a/z.ex.search/src/z/ex/search/BuildRCPScriptHandler.java b/z.ex.search/src/z/ex/search/BuildRCPScriptHandler.java new file mode 100644 index 0000000..d8699c2 --- /dev/null +++ b/z.ex.search/src/z/ex/search/BuildRCPScriptHandler.java @@ -0,0 +1,154 @@ +package z.ex.search; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.swt.program.Program; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.preferences.ScopedPreferenceStore; + +public class BuildRCPScriptHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + // Read paths from preferences + IPreferenceStore store = new ScopedPreferenceStore(InstanceScope.INSTANCE, "z.ex.search"); + String scriptPath = store.getString(PreferenceConstants.SCRIPT_PATH); + String pdfOutputPath = store.getString(PreferenceConstants.PDF_OUTPUT_PATH); + + File scriptFile = new File(scriptPath); + + if (!scriptFile.exists()) { + showError("Script not found at: " + scriptPath); + return null; + } + + if (!scriptFile.canExecute()) { + showError("Script is not executable: " + scriptPath); + return null; + } + + // Execute the script using Eclipse Jobs API + Job job = new Job("Building RCP") { + @Override + protected IStatus run(IProgressMonitor monitor) { + monitor.beginTask("Executing RCP build script", IProgressMonitor.UNKNOWN); + + try { + ProcessBuilder pb = new ProcessBuilder(scriptPath); + pb.directory(scriptFile.getParentFile()); + pb.redirectErrorStream(true); + + Process process = pb.start(); + + // Read and collect output + StringBuilder output = new StringBuilder(); + try (BufferedReader reader = new BufferedReader( + new InputStreamReader(process.getInputStream()))) { + String line; + while ((line = reader.readLine()) != null) { + output.append(line).append("\n"); + if (monitor.isCanceled()) { + process.destroyForcibly(); + return Status.CANCEL_STATUS; + } + } + } + + int exitCode = process.waitFor(); + final boolean success = exitCode == 0; + + if (success) { + showSuccessDialog(); + } else { + String message = "Build failed with exit code: " + exitCode + + "\n\n" + output.toString(); + showErrorDialog(message); + } + + return Status.OK_STATUS; + + } catch (IOException e) { + return new Status(IStatus.ERROR, "z.ex.search", + "Error executing script: " + e.getMessage(), e); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + return Status.CANCEL_STATUS; + } finally { + monitor.done(); + } + } + }; + + job.setUser(true); // Shows the job in the UI + job.schedule(); + + return null; + } + + private void showError(String message) { + Display.getDefault().asyncExec(() -> { + MessageDialog.openError( + Display.getDefault().getActiveShell(), + "Build RCP Script Error", + message + ); + }); + } + + private void showSuccessDialog() { + Display.getDefault().asyncExec(() -> { + boolean openPdf = MessageDialog.openQuestion( + Display.getDefault().getActiveShell(), + "Build RCP Script", + "RCP build script executed successfully.\n\nDo you want to open the PDF file?" + ); + + if (openPdf) { + openPdfFile(); + } + }); + } + + private void showErrorDialog(String message) { + Display.getDefault().asyncExec(() -> { + MessageDialog.openError( + Display.getDefault().getActiveShell(), + "Build RCP Script Error", + message + ); + }); + } + + private void openPdfFile() { + // Read PDF path from preferences + IPreferenceStore store = new ScopedPreferenceStore(InstanceScope.INSTANCE, "z.ex.search"); + String pdfOutputPath = store.getString(PreferenceConstants.PDF_OUTPUT_PATH); + + File pdfFile = new File(pdfOutputPath); + + if (!pdfFile.exists()) { + showError("PDF file not found at: " + pdfOutputPath); + return; + } + + // Use SWT Program to launch the PDF with system default application + boolean launched = Program.launch(pdfFile.getAbsolutePath()); + + if (!launched) { + showError("Failed to open PDF file. No application is associated with PDF files."); + } + } +} diff --git a/z.ex.search/src/z/ex/search/BuildScriptPreferencePage.java b/z.ex.search/src/z/ex/search/BuildScriptPreferencePage.java new file mode 100644 index 0000000..77f9509 --- /dev/null +++ b/z.ex.search/src/z/ex/search/BuildScriptPreferencePage.java @@ -0,0 +1,36 @@ +package z.ex.search; + +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.jface.preference.FieldEditorPreferencePage; +import org.eclipse.jface.preference.FileFieldEditor; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; +import org.eclipse.ui.preferences.ScopedPreferenceStore; + +/** + * Preference page for configuring build script paths. + */ +public class BuildScriptPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage { + + public BuildScriptPreferencePage() { + super(GRID); + } + + @Override + public void createFieldEditors() { + addField(new FileFieldEditor(PreferenceConstants.SCRIPT_PATH, + "&Build Script Path:", + getFieldEditorParent())); + + addField(new FileFieldEditor(PreferenceConstants.PDF_OUTPUT_PATH, + "&PDF Output Path:", + getFieldEditorParent())); + } + + @Override + public void init(IWorkbench workbench) { + setPreferenceStore(new ScopedPreferenceStore(InstanceScope.INSTANCE, "z.ex.search")); + setDescription("Configure paths for the RCP build script and PDF output."); + } + +} diff --git a/z.ex.search/src/z/ex/search/PreferenceConstants.java b/z.ex.search/src/z/ex/search/PreferenceConstants.java new file mode 100644 index 0000000..1e49ec5 --- /dev/null +++ b/z.ex.search/src/z/ex/search/PreferenceConstants.java @@ -0,0 +1,19 @@ +package z.ex.search; + +import java.nio.file.Paths; + +/** + * Constant definitions for plug-in preferences + */ +public class PreferenceConstants { + + public static final String SCRIPT_PATH = "scriptPath"; + public static final String PDF_OUTPUT_PATH = "pdfOutputPath"; + + // Default values + public static final String DEFAULT_SCRIPT_PATH = Paths.get(System.getProperty("user.home"), + "git", "content", "_scripts", "buildRCPScript.sh").toString(); + public static final String DEFAULT_PDF_OUTPUT_PATH = Paths.get(System.getProperty("user.home"), + "git", "content", "output.pdf").toString(); + +} diff --git a/z.ex.search/src/z/ex/search/PreferenceInitializer.java b/z.ex.search/src/z/ex/search/PreferenceInitializer.java new file mode 100644 index 0000000..a51f9a4 --- /dev/null +++ b/z.ex.search/src/z/ex/search/PreferenceInitializer.java @@ -0,0 +1,19 @@ +package z.ex.search; + +import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.ui.preferences.ScopedPreferenceStore; + +/** + * Initializes default preference values. + */ +public class PreferenceInitializer extends AbstractPreferenceInitializer { + + @Override + public void initializeDefaultPreferences() { + ScopedPreferenceStore store = new ScopedPreferenceStore(InstanceScope.INSTANCE, "z.ex.search"); + store.setDefault(PreferenceConstants.SCRIPT_PATH, PreferenceConstants.DEFAULT_SCRIPT_PATH); + store.setDefault(PreferenceConstants.PDF_OUTPUT_PATH, PreferenceConstants.DEFAULT_PDF_OUTPUT_PATH); + } + +}