Skip to content

Commit

Permalink
Merge branch 'master' into issue-120
Browse files Browse the repository at this point in the history
  • Loading branch information
Oliver-Loeffler authored Oct 1, 2024
2 parents cb6e16e + f0c5860 commit eed9eb8
Show file tree
Hide file tree
Showing 23 changed files with 487 additions and 99 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/bundles-mac.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ on:
required: true
jobs:
build:
runs-on: macos-latest
runs-on: macos-13
steps:
- uses: actions/checkout@v4

Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ See the [documentation](http://docs.gluonhq.com/scenebuilder/) about the new fea

For community support, go to [StackOverflow](https://stackoverflow.com/questions/tagged/scenebuilder).

### Requirements on Linux ###

On Linux systems, Scene Builder uses the `xdg-open` command to reveal files in the system's default file system browser or to open URLs in the default web browser. Most modern Linux Desktop Environments already provide the [xdg-utils](https://freedesktop.org/wiki/Software/xdg-utils/) package. If it is missing, it can be installed using the respective Linux package management tool such as `yum`, `apt-get`, `dnf` or `pacman`. The `xdg-utils` package is usually available on KDE based systems, some Arch based systems may require manual installations.

## Issues and Contributions ##

Issues can be reported to the [Issue tracker](https://github.com/gluonhq/scenebuilder/issues/)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
import com.oracle.javafx.scenebuilder.kit.editor.EditorController.ControlAction;
import com.oracle.javafx.scenebuilder.kit.editor.EditorController.EditAction;
import com.oracle.javafx.scenebuilder.kit.editor.EditorPlatform;
import com.oracle.javafx.scenebuilder.kit.editor.FileBrowserRevealException;
import com.oracle.javafx.scenebuilder.kit.editor.job.Job;
import com.oracle.javafx.scenebuilder.kit.editor.panel.content.ContentPanelController;
import com.oracle.javafx.scenebuilder.kit.editor.panel.css.CssPanelController;
Expand Down Expand Up @@ -191,6 +192,8 @@ public enum ActionStatus {
DONE
}

private static final Logger LOGGER = Logger.getLogger(DocumentWindowController.class.getName());

private final EditorController editorController = new EditorController();
private final MenuBarController menuBarController = new MenuBarController(this);
private final ContentPanelController contentPanelController = new ContentPanelController(editorController);
Expand Down Expand Up @@ -1478,14 +1481,13 @@ void onLibraryImportSelection(ActionEvent event) {
@FXML
void onLibraryRevealCustomFolder(ActionEvent event) {
String userLibraryPath = ((UserLibrary) getEditorController().getLibrary()).getPath();

// ensure that there is no mixup of forward and backward slashes.
File libraryPath = Paths.get(userLibraryPath).normalize().toFile();
try {
EditorPlatform.revealInFileBrowser(new File(userLibraryPath));
} catch(IOException x) {
final ErrorDialog errorDialog = new ErrorDialog(null);
errorDialog.setMessage(I18N.getString("alert.reveal.failure.message", getStage().getTitle()));
errorDialog.setDetails(I18N.getString("alert.reveal.failure.details"));
errorDialog.setDebugInfoWithThrowable(x);
errorDialog.showAndWait();
EditorPlatform.revealInFileBrowser(libraryPath);
} catch (Exception revealError) {
handleRevealFolderException(revealError, String.valueOf(libraryPath));
}
}

Expand Down Expand Up @@ -2196,26 +2198,33 @@ ActionStatus performCloseAction() {
return closeConfirmed ? ActionStatus.DONE : ActionStatus.CANCELLED;
}


private void performRevealAction() {
assert editorController.getFxomDocument() != null;
assert editorController.getFxomDocument().getLocation() != null;

final URL location = editorController.getFxomDocument().getLocation();


File fxmlFile = null;
try {
/*
* Using Path.normalize().toAbsolutePath() ensures that forward and backward slashes are not mixed
* and the path matches the platform requirements. It also ensures, that the file:/ prefix is
* removed from paths and users can directly use the path in their attempt to investigate the error.
*/
fxmlFile = Path.of(location.toURI()).normalize().toAbsolutePath().toFile();
} catch (URISyntaxException e) {
handleRevealResourceException(e, String.valueOf(location));
}

try {
final File fxmlFile = new File(location.toURI());
EditorPlatform.revealInFileBrowser(fxmlFile);
} catch(IOException | URISyntaxException x) {
final ErrorDialog errorDialog = new ErrorDialog(null);
errorDialog.setMessage(I18N.getString("alert.reveal.failure.message", getStage().getTitle()));
errorDialog.setDetails(I18N.getString("alert.reveal.failure.details"));
errorDialog.setDebugInfoWithThrowable(x);
errorDialog.showAndWait();
} catch (FileBrowserRevealException re) {
handleRevealFileException(re, String.valueOf(fxmlFile));
} catch (IOException x) {
handleRevealResourceException(x, String.valueOf(fxmlFile));
}
}


private void updateLoadFileTime() {

final URL fxmlURL = editorController.getFxmlLocation();
Expand Down Expand Up @@ -2286,17 +2295,64 @@ private void performHelp() {

private void openURL(String url) {
try {
LOGGER.log(Level.FINE, "Attempting to open URL: {0}", url);
EditorPlatform.open(url);
} catch (IOException ioe) {
handleErrorWhenOpeningURL(ioe, url);
LOGGER.log(Level.WARNING, "Error during attempt to open URL!", ioe);
handleRevealResourceException(ioe, url);
}
}

private void handleErrorWhenOpeningURL(IOException ioe, String url) {
final ErrorDialog errorDialog = new ErrorDialog(null);
errorDialog.setMessage(I18N.getString("alert.help.failure.message", url));
errorDialog.setDetails(I18N.getString("alert.messagebox.failure.details"));
errorDialog.setDebugInfoWithThrowable(ioe);
/**
* When an FXML file is to be revealed and an error occurs, the file and the error are displayed in this dialog.
* The error type and its details are displayed within the details window. The dialog itself only
* notifies that there was an error.
*
* @param fileRevealException {@link FileBrowserRevealException}
* @param locationToBeRevealed {@link String}
*/
private void handleRevealFileException(FileBrowserRevealException fileRevealException, String locationToBeRevealed) {
final ErrorDialog errorDialog = new ErrorDialog(this.getStage());
errorDialog.setTitle(I18N.getString("alert.error.file.reveal.title"));
errorDialog.setMessage(I18N.getString("alert.error.file.reveal.message"));
errorDialog.setDetails(I18N.getString("alert.error.file.reveal.details", locationToBeRevealed));
errorDialog.setDetailsTitle(I18N.getString("alert.error.file.reveal.details.title"));
errorDialog.setDebugInfoWithThrowable(fileRevealException);
errorDialog.showAndWait();
}

/**
*
* Resources may be related to files included with Scene Builder or with arbitrary files (e.g. CSS sheets)
* co-located to a given FXML file. In case of an error opening a resource, a custom dialog is shown.
*
* @param revealException {@link Exception}
* @param locationToBeRevealed {@link String}
*/
private void handleRevealResourceException(Exception revealException, String locationToBeRevealed) {
final ErrorDialog errorDialog = new ErrorDialog(this.getStage());
errorDialog.setTitle(I18N.getString("alert.error.resource.reveal.title"));
errorDialog.setMessage(I18N.getString("alert.error.resource.reveal.message"));
errorDialog.setDetails(I18N.getString("alert.error.resource.reveal.details", locationToBeRevealed));
errorDialog.setDetailsTitle(I18N.getString("alert.error.resource.reveal.details.title"));
errorDialog.setDebugInfoWithThrowable(revealException);
errorDialog.showAndWait();
}

/**
*
* In some cases the resource to be revealed or opened is a directory. Hence the UI dialog should reflect this.
*
* @param revealException {@link Exception}
* @param directoryToBeRevealed {@link String}
*/
private void handleRevealFolderException(Exception revealException, String directoryToBeRevealed) {
final ErrorDialog errorDialog = new ErrorDialog(this.getStage());
errorDialog.setTitle(I18N.getString("alert.error.directory.reveal.title"));
errorDialog.setMessage(I18N.getString("alert.error.directory.reveal.message"));
errorDialog.setDetails(I18N.getString("alert.error.directory.reveal.details", directoryToBeRevealed));
errorDialog.setDetailsTitle(I18N.getString("alert.error.directory.reveal.details.title"));
errorDialog.setDebugInfoWithThrowable(revealException);
errorDialog.showAndWait();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import com.oracle.javafx.scenebuilder.app.i18n.I18N;
import com.oracle.javafx.scenebuilder.kit.editor.EditorController;
import com.oracle.javafx.scenebuilder.kit.editor.EditorPlatform;
import com.oracle.javafx.scenebuilder.kit.editor.FileBrowserRevealException;
import com.oracle.javafx.scenebuilder.kit.editor.panel.util.dialog.ErrorDialog;
import javafx.stage.FileChooser;

Expand Down Expand Up @@ -97,10 +98,11 @@ public void performRevealResource() {
try {
EditorPlatform.revealInFileBrowser(resourceFile);
} catch (IOException ioe) {
final ErrorDialog errorDialog = new ErrorDialog(null);
errorDialog.setTitle(I18N.getString("error.file.reveal.title"));
errorDialog.setMessage(I18N.getString("error.file.reveal.message"));
errorDialog.setDetails(I18N.getString("error.filesystem.details"));
final ErrorDialog errorDialog = new ErrorDialog(documentWindowController.getStage());
errorDialog.setTitle(I18N.getString("alert.error.file.reveal.title"));
errorDialog.setMessage(I18N.getString("alert.error.file.reveal.message"));
errorDialog.setDetails(I18N.getString("alert.error.file.reveal.details", resourceFile));
errorDialog.setDetailsTitle(I18N.getString("alert.error.file.reveal.details.title"));
errorDialog.setDebugInfoWithThrowable(ioe);
errorDialog.showAndWait();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/*
* Copyright (c) 2024, Gluon and/or its affiliates.
* Copyright (c) 2012, 2014, Oracle and/or its affiliates.
* All rights reserved. Use is subject to license terms.
*
Expand Down Expand Up @@ -102,10 +103,11 @@ public void performOpenSceneStyleSheet(File toOpen) {
try {
EditorPlatform.open(toOpen.getPath());
} catch (IOException ioe) {
final ErrorDialog errorDialog = new ErrorDialog(null);
final ErrorDialog errorDialog = new ErrorDialog(documentWindowController.getStage());
errorDialog.setTitle(I18N.getString("error.file.open.title"));
errorDialog.setMessage(I18N.getString("error.file.open.message"));
errorDialog.setMessage(I18N.getString("error.file.open.message", toOpen));
errorDialog.setDetails(I18N.getString("error.filesystem.details"));
errorDialog.setDetailsTitle(I18N.getString("error.file.open.title"));
errorDialog.setDebugInfoWithThrowable(ioe);
errorDialog.showAndWait();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -418,8 +418,6 @@ alert.messagebox.failure.message = Could not process open request
alert.messagebox.failure.details = An unexpected failure happened during open operation. Please report this failure to support.
alert.revert.question.message = Do you want to revert to the last saved version of ''{0}'' ?
alert.revert.question.details = Your current changes will be lost.
alert.reveal.failure.message = Could not reveal ''{0}''
alert.reveal.failure.details = Reveal operation has failed. Check logs of the operating system.
alert.copy.failure.message = Could not copy ''{0}''
alert.help.failure.message = Could not access to ''{0}''
alert.delete.fxid1of1.message = This component has an fx:id. Do you really want to delete it ?
Expand Down Expand Up @@ -474,11 +472,29 @@ file.filter.label.image = Image Document
file.filter.label.media = Media Document
file.filter.label.video = Video Document
error.file.open.title = File opening failed
error.file.open.details.title = File opening failed - Details
# {0} is a file path
error.file.open.message = File {0} cannot be opened
error.filesystem.details = Please check your file system.
error.file.reveal.title = File locating failed
error.file.reveal.message = File {0} cannot be found
error.filesystem.details = File: {0}

# File Reveal Error Dialog
alert.error.file.reveal.title = Failed to reveal file ...
alert.error.file.reveal.message = Cannot reveal file in file system viewer due to an error.
alert.error.file.reveal.details = ''{0}''
alert.error.file.reveal.details.title = File Reveal Error Details

# Directory Reveal Error Dialog
alert.error.directory.reveal.title = Failed to reveal folder ...
alert.error.directory.reveal.message = Cannot reveal folder in file system viewer due to an error.
alert.error.directory.reveal.details = ''{0}''
alert.error.directory.reveal.details.title = Folder Reveal Error Details

# Resource Reveal Error Dialog
alert.error.resource.reveal.title = Failed to reveal resource ...
alert.error.resource.reveal.message = Cannot reveal resource in file system viewer due to an error.
alert.error.resource.reveal.details = ''{0}''
alert.error.resource.reveal.details.title = Resource Reveal Error Details

#
log.start = JavaFX Scene Builder started
log.stop = JavaFX Scene Builder stopped
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -410,8 +410,6 @@ alert.messagebox.failure.message = 開く操作を処理できませんでした
alert.messagebox.failure.details = 開く操作中に予期しない問題が起きました。この問題をサポートに報告してください。
alert.revert.question.message = 最後に保存した''{0}''に戻しますか。
alert.revert.question.details = 現在の変更は失われます。
alert.reveal.failure.message = ''{0}''を表示できませんでした
alert.reveal.failure.details = 元に戻すのに失敗しました。オペレーティング・システムのログを確認してください。
alert.copy.failure.message = コピー
alert.help.failure.message = ''{0}''にアクセスできませんでした
alert.delete.fxid1of1.message = このコンポーネントにはfx:idがあります。このコンポーネントを削除しますか。
Expand Down Expand Up @@ -457,7 +455,7 @@ file.filter.label.fxml = FXMLドキュメント
file.filter.label.image = イメージ・ドキュメント
file.filter.label.media = メディア・ドキュメント
file.filter.label.video = ビデオ・ドキュメント
error.file.open.title = ファイルを開くのに失敗しました

# {0} is a file path
error.file.open.message = ファイル{0}を開けません
error.filesystem.details = ファイル・システムを確認してください。
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -416,8 +416,6 @@ alert.messagebox.failure.message = 无法处理打开的请求
alert.messagebox.failure.details = 打开操作期间发生意外故障。请向支持部门报告此故障。
alert.revert.question.message = 是否要恢复到上次保存的 ''{0}'' 版本?
alert.revert.question.details = 您当前的更改将丢失。
alert.reveal.failure.message = 无法显示 ''{0}''
alert.reveal.failure.details = 显示操作失败。检查操作系统的日志。
alert.copy.failure.message = 无法复制 ''{0}''
alert.help.failure.message = 无法访问 ''{0}''
alert.delete.fxid1of1.message = 此组件具有 fx:id,你真的要删除它吗?
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright (c) 2024, Gluon and/or its affiliates.
* All rights reserved. Use is subject to license terms.
*
* This file is available and licensed under the following license:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the distribution.
* - Neither the name of Oracle Corporation and Gluon nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.oracle.javafx.scenebuilder.kit.editor;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
* Cmd allows the execution of a given command line in a defined working directory. The execution is
* aborted after the timeout.
*/
final class Cmd {

/**
* Executes a given command line using the working directory and timeout.
*
* @param cmd The command line to be executed defined as a {@link List} of {@link String}
* @param wDir The working directory, where the process shall be executed within.
* @param timeoutSec Duration in in seconds after which the execution should be stopped.
* @return exit code of the command line as an Integer
*
* @throws IOException - if the command was not found or the program execution exceeds the given timeout duration.
* @throws InterruptedException - if the current thread is interrupted while waiting
*/
public final Integer exec(List<String> cmd, File wDir, long timeoutSec) throws IOException,
InterruptedException {
ProcessBuilder builder = new ProcessBuilder(cmd);
builder = builder.directory(wDir);
Process proc = builder.start();
boolean completed = proc.waitFor(timeoutSec, TimeUnit.SECONDS);
if (completed) {
return proc.exitValue();
}
throw new IOException("Process timed out after %s seconds!".formatted(timeoutSec));
}

}
Loading

0 comments on commit eed9eb8

Please sign in to comment.