Commit f56281e7 authored by Alexander Weigl's avatar Alexander Weigl

Merge branch 'master' of git.scc.kit.edu:xt9634/ProofScriptParser

* 'master' of git.scc.kit.edu:xt9634/ProofScriptParser:
  New Script Tabs loadable and concept for loading a file again is implementend: if file is already laoded and loaded again, it is overwritten (Decision for the beginning); part for right side is coming in the next days ;-)
  New Tabs loadable and concept for loading a file again is implementend: if file is already laoded and loaded again, it is overwritten (Decision for the beginning)
  small improvements
  Better StatusBar, little refactoring in contract chooser
  Empty tab pane has buttons now, need to add the appropriate Action
  Empty TabPane (not final yet)
  Fixed issue back
  Initial Tab for scriptArea
  Added tabbedpane in fxml for scriptarea and model skelett for inspectionviewmodel
  CodeArea's syntax highlightning
  added first part of parser testcases
parents 30833094 b03739c9
Pipeline #11076 failed with stage
in 2 minutes and 21 seconds
......@@ -99,6 +99,26 @@
</configuration>
</plugin>
<plugin>
<groupId>org.lesscss</groupId>
<artifactId>lesscss-maven-plugin</artifactId>
<version>1.7.0.1.1</version>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<outputDirectory>${project.build.outputDirectory}</outputDirectory>
<sourceDirectory>${project.build.sourceDirectory}/../resources</sourceDirectory>
<compress>false</compress>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.antlr</groupId>
<artifactId>antlr4-maven-plugin</artifactId>
......@@ -283,6 +303,20 @@
<version>0.9.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.8</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.8</version>
</dependency>
</dependencies>
......
......@@ -7,23 +7,23 @@ package edu.kit.formal.gui;
*/
import de.uka.ilkd.key.util.KeYConstants;
import edu.kit.formal.gui.controller.DebuggerMainWindowController;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.SceneBuilder;
import javafx.stage.Stage;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.IOException;
import java.util.logging.Logger;
import java.util.Locale;
public class ProofScriptDebugger extends Application {
public static final String NAME = "Proof Script Debugger";
public static final String VERSION = "0.1";
public static final String KEY_VERSION = KeYConstants.VERSION;
private Logger logger = Logger.getLogger("psdbg");
private Logger logger = LogManager.getLogger("psdbg");
public static void main(String[] args) {
launch(args);
......@@ -31,11 +31,9 @@ public class ProofScriptDebugger extends Application {
@Override
public void start(Stage primaryStage) {
logger.info("Start: " + NAME);
logger.info("Version: " + VERSION);
logger.info("KeY: " + KeYConstants.COPYRIGHT);
logger.info("KeY Version: " + KeYConstants.VERSION);
logger.info("KeY Internal: " + KeYConstants.INTERNAL_VERSION);
Locale.setDefault(Locale.ENGLISH);
try {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/DebuggerMain.fxml"));
......@@ -43,11 +41,20 @@ public class ProofScriptDebugger extends Application {
//DebuggerMainWindowController controller = fxmlLoader.<DebuggerMainWindowController>getController();
Scene scene = new Scene(root);
scene.getStylesheets().addAll(
"/proofscriptdebugger.css"
getClass().getResource("debugger-ui.css").toExternalForm()
);
primaryStage.setTitle(NAME + " (" + VERSION + ") with KeY:" + KEY_VERSION);
primaryStage.setScene(scene);
primaryStage.show();
logger.info("Start: " + NAME);
logger.info("Version: " + VERSION);
logger.info("KeY: " + KeYConstants.COPYRIGHT);
logger.info("KeY Version: " + KeYConstants.VERSION);
logger.info("KeY Internal: " + KeYConstants.INTERNAL_VERSION);
logger.error("sfklsajflksajfsdajfsdalfjsdaf", new IllegalAccessError("dlfsdalfjsadflj"));
} catch (IOException e) {
e.printStackTrace();
}
......
......@@ -5,37 +5,59 @@ import de.uka.ilkd.key.speclang.Contract;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleListProperty;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.stage.Modality;
import lombok.Getter;
import java.awt.event.KeyEvent;
/**
* WozardPane to dosplay all available contracts
* A Contract Chooser is a modal dialog, which shows a list of contracts and lets the user select one.
* <p>
* <p>
* <p>
* <p>
* WizardPane to display all available contracts
*
* @author S. Grebing
* @author A. Weigl
*/
public class ContractChooser extends Dialog<Contract> {
@Getter
private final MultipleSelectionModel<Contract> selectionModel;
private final ObjectProperty<ObservableList<Contract>> items;
private final ListView<Contract> listOfContractsView;
private final ListView<Contract> listOfContractsView = new ListView<>();
private final Services services;
public ContractChooser(Services services) {
super();
this.services = services;
setTitle("Key Contract Chooser");
setHeaderText("Please select a contract");
this.services = services;
listOfContractsView = new ListView<>();
setResizable(true);
initModality(Modality.APPLICATION_MODAL);
selectionModel = listOfContractsView.getSelectionModel();
items = listOfContractsView.itemsProperty();
DialogPane dpane = new DialogPane();
dpane.setContent(listOfContractsView);
dpane.setPrefSize(680, 320);
setDialogPane(dpane);
listOfContractsView.setCellFactory(ContractListCell::new);
setResizable(true);
dpane.setPrefSize(680, 320);
setResultConverter((value) -> value == ButtonType.OK ? listOfContractsView.getSelectionModel().getSelectedItem() : null);
dpane.getButtonTypes().addAll(ButtonType.OK, ButtonType.CANCEL);
final Button okButton = (Button) dpane.lookupButton(ButtonType.OK);
okButton.setDefaultButton(true);
listOfContractsView.setOnKeyPressed(event -> okButton.fire());
}
public ContractChooser(Services services,
......@@ -52,14 +74,14 @@ public class ContractChooser extends Dialog<Contract> {
return items.get();
}
public ObjectProperty<ObservableList<Contract>> itemsProperty() {
return items;
}
public void setItems(ObservableList<Contract> items) {
this.items.set(items);
}
public ObjectProperty<ObservableList<Contract>> itemsProperty() {
return items;
}
private class ContractListCell extends ListCell<Contract> {
ContractListCell(ListView<Contract> contractListView) {
itemProperty().addListener((observable, oldValue, newValue) -> render());
......@@ -226,10 +248,16 @@ public class ContractChooser extends Dialog<Contract> {
return;
}
VBox box = new VBox();
Label head = new Label(getItem().getDisplayName() + "\n");
head.setWrapText(true);
head.setStyle("-fx-font-weight: bold; -fx-font-size: 120%");
setGraphic(new VBox(head, new Label(getItem().getPlainText(services))));
head.getStyleClass().add("title");
Label contract = new Label(getItem().getPlainText(services));
contract.getStyleClass().add("contract");
setGraphic(
new VBox(head, contract)
);
}
}
}
......@@ -10,6 +10,7 @@ import edu.kit.formal.proofscriptparser.ast.*;
import javafx.application.Platform;
import javafx.beans.property.SimpleObjectProperty;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentSkipListSet;
......@@ -22,17 +23,13 @@ import java.util.concurrent.locks.ReentrantLock;
* Created by weigl on 21.05.2017.
*/
public class PuppetMaster {
private Interpreter<KeyData> puppet;
private AtomicInteger stepUntilBlock = new AtomicInteger(-1);
private Set<Integer> brkpnts = new ConcurrentSkipListSet<>();
private final Lock lock = new ReentrantLock();
private final Condition block = lock.newCondition();
private final SimpleObjectProperty<List<GoalNode<KeyData>>> currentGoals = new SimpleObjectProperty<>();
private final SimpleObjectProperty<GoalNode<KeyData>> currentSelectedGoal = new SimpleObjectProperty<>();
private Interpreter<KeyData> puppet;
private AtomicInteger stepUntilBlock = new AtomicInteger(-1);
private Set<Integer> brkpnts = new ConcurrentSkipListSet<>();
private Visitor<Void> entryListener = new EntryListener();
private Visitor<Void> exitListener = new ExitListener();
......@@ -58,6 +55,8 @@ public class PuppetMaster {
}
public Void checkForHalt(ASTNode node) {
System.out.println("node = [" + node + "]");
//<0 run
if (stepUntilBlock.get() > 0)
stepUntilBlock.decrementAndGet();
......@@ -76,11 +75,25 @@ public class PuppetMaster {
public void publishState() {
System.out.println("PuppetMaster.publishState");
final State<KeyData> state = puppet.getCurrentState().copy();
Platform.runLater(() -> {
currentGoals.set(state.getGoals());
currentSelectedGoal.set(state.getSelectedGoalNode());
});
//puppet is null if sucessful interprter state and publish state
if (puppet != null) {
final State<KeyData> state = puppet.getCurrentState().copy();
System.out.println(state);
Platform.runLater(() -> {
currentGoals.set(state.getGoals());
currentSelectedGoal.set(state.getSelectedGoalNode());
});
} else {
//if puppet is null an empty state may be reached therefore state get goals etc returns null
Platform.runLater(() -> {
currentGoals.set(Collections.emptyList());
currentSelectedGoal.set(null);
});
}
}
/**
......@@ -115,26 +128,26 @@ public class PuppetMaster {
return currentSelectedGoal.get();
}
public SimpleObjectProperty<GoalNode<KeyData>> currentSelectedGoalProperty() {
return currentSelectedGoal;
}
public void setCurrentSelectedGoal(GoalNode<KeyData> currentSelectedGoal) {
this.currentSelectedGoal.set(currentSelectedGoal);
}
public List<GoalNode<KeyData>> getCurrentGoals() {
return currentGoals.get();
public SimpleObjectProperty<GoalNode<KeyData>> currentSelectedGoalProperty() {
return currentSelectedGoal;
}
public SimpleObjectProperty<List<GoalNode<KeyData>>> currentGoalsProperty() {
return currentGoals;
public List<GoalNode<KeyData>> getCurrentGoals() {
return currentGoals.get();
}
public void setCurrentGoals(List<GoalNode<KeyData>> currentGoals) {
this.currentGoals.set(currentGoals);
}
public SimpleObjectProperty<List<GoalNode<KeyData>>> currentGoalsProperty() {
return currentGoals;
}
public Set<Integer> getBreakpoints() {
return brkpnts;
}
......
package edu.kit.formal.gui.controls;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.MapProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleMapProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableMap;
import org.antlr.v4.runtime.Token;
import org.fxmisc.richtext.CodeArea;
import java.util.Collections;
import java.util.Map;
/**
* A code area with support for line highlightning.
* Created by weigl on 10.06.2017.
*
* @author Alexander Weigl
*/
public class BaseCodeArea extends CodeArea {
protected MapProperty<Integer, String> lineToClass = new SimpleMapProperty<>(FXCollections.observableHashMap());
protected BooleanProperty enableLineHighlighting = new SimpleBooleanProperty();
protected BooleanProperty enableCurrentLineHighlighting = new SimpleBooleanProperty();
public BaseCodeArea() {
init();
}
public BaseCodeArea(String text) {
super(text);
init();
}
private void init() {
}
public void setText(String text) {
replaceText(text);
}
protected void highlightLines() {
if (enableLineHighlighting.get() || enableCurrentLineHighlighting.get()) {
LineMapping lm = new LineMapping(getText());
if (enableLineHighlighting.get()) {
for (Map.Entry<Integer, String> entry : lineToClass.entrySet()) {
hightlightLine(lm, entry.getKey(), entry.getValue());
}
}
if (enableCurrentLineHighlighting.get()) {
int caret = getCaretPosition();
hightlightLine(lm, lm.getLine(caret), "current-line");
}
}
}
public void jumpTo(Token token) {
//token.getStartIndex();
}
protected void hightlightLine(LineMapping lm, int line, String clazz) {
final int start = lm.getLineStart(line);
final int end = lm.getLineEnd(line);
setStyle(start, end, Collections.singleton(clazz));
}
public ObservableMap<Integer, String> getLineToClass() {
return lineToClass.get();
}
public MapProperty<Integer, String> lineToClassProperty() {
return lineToClass;
}
public void setLineToClass(ObservableMap<Integer, String> lineToClass) {
this.lineToClass.set(lineToClass);
}
public boolean isEnableLineHighlighting() {
return enableLineHighlighting.get();
}
public BooleanProperty enableLineHighlightingProperty() {
return enableLineHighlighting;
}
public void setEnableLineHighlighting(boolean enableLineHighlighting) {
this.enableLineHighlighting.set(enableLineHighlighting);
}
public boolean isEnableCurrentLineHighlighting() {
return enableCurrentLineHighlighting.get();
}
public BooleanProperty enableCurrentLineHighlightingProperty() {
return enableCurrentLineHighlighting;
}
public void setEnableCurrentLineHighlighting(boolean enableCurrentLineHighlighting) {
this.enableCurrentLineHighlighting.set(enableCurrentLineHighlighting);
}
}
package edu.kit.formal.gui.controls;
import com.sun.javafx.scene.control.skin.TabPaneSkin;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.TabPane;
import javafx.scene.layout.Pane;
/**
* A way to display a custom tab when tab pane is empty
* from https://stackoverflow.com/questions/35239420/display-label-if-tabpane-has-no-tabs
*/
public class CustomTabPaneSkin extends TabPaneSkin {
//private final VBox placeHolder;
//private final Label placeHolderText;
private final PlaceHolderTab placeHolder;
public CustomTabPaneSkin(TabPane tabPane) {
super(tabPane);
placeHolder = new PlaceHolderTab();
placeHolder.getVbox().minWidthProperty().bind(getSkinnable().widthProperty());
placeHolder.getVbox().minHeightProperty().bind(getSkinnable().heightProperty());
placeHolder.getVbox().setAlignment(Pos.CENTER);
for (Node node : getChildren()) {
if (node.getStyleClass().contains("tab-header-area")) {
Pane headerArea = (Pane) node;
// Header area is hidden if there is no tabs, thus when the tabpane is "empty"
headerArea.visibleProperty().addListener((observable, oldValue, newValue)
->
{
if (newValue) {
getChildren().remove(placeHolder);
} else {
getChildren().add(placeHolder);
}
}
);
break;
}
}
}
public PlaceHolderTab getPlaceHolder() {
return placeHolder;
}
}
package edu.kit.formal.gui.controls;
import de.jensd.fx.glyphs.materialdesignicons.MaterialDesignIcon;
import de.jensd.fx.glyphs.materialdesignicons.MaterialDesignIconView;
import edu.kit.formal.gui.controller.DebuggerMainWindowController;
import javafx.beans.binding.StringBinding;
import javafx.beans.property.ListProperty;
import javafx.beans.property.SimpleListProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableStringValue;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.stage.Modality;
import javafx.util.Callback;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.core.Layout;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.appender.AbstractAppender;
import org.apache.logging.log4j.core.appender.ConsoleAppender;
import org.apache.logging.log4j.core.layout.PatternLayout;
import org.controlsfx.control.StatusBar;
import java.io.PrintWriter;
import java.io.Serializable;
import java.io.StringWriter;
import java.util.Date;
import java.util.LinkedList;
import java.util.logging.LogRecord;
/**
* Created by weigl on 09.06.2017.
*/
public class DebuggerStatusBar extends StatusBar {
private static final Logger LOGGER = LogManager.getLogger(DebuggerStatusBar.class);
private Label lblCurrentNodes = new Label("#nodes: %s");
private ProgressIndicator progressIndicator = new ProgressIndicator();
private LogCatchHandlerFX logCatchHandler = new LogCatchHandlerFX();
private EventHandler<MouseEvent> toolTipHandler = event -> {
publishMessage(((Control) event.getTarget()).getTooltip().getText());
};
private final ContextMenu contextMenu = createContextMenu();
private final Dialog<Void> loggerDialog = createDialog();
public DebuggerStatusBar() {
listenOnField("psdbg");
getRightItems().addAll(
lblCurrentNodes,
progressIndicator
);
setOnMouseClicked(event -> {
if (event.getButton() == MouseButton.SECONDARY) {
contextMenu.show(this, event.getScreenX(), event.getScreenY());
}
});
}
private final Appender loggerHandler = createAppender();
private Appender createAppender() {
PatternLayout layout = PatternLayout.createDefaultLayout();
return new AbstractAppender("", null, layout) {
@Override
public void append(LogEvent event) {
publishMessage(event.getMessage().getFormattedMessage());
}
};
}
public void publishMessage(String format, Object... args) {
String msg = String.format(format, args);
setText(msg);
}
public EventHandler<MouseEvent> getTooltipHandler() {
return toolTipHandler;
}
public void listenOnField(ObservableStringValue value) {
value.addListener((observable, oldValue, newValue) -> {
publishMessage(newValue);
});
}
public void listenOnField(Logger logger) {
org.apache.logging.log4j.core.Logger plogger = ((org.apache.logging.log4j.core.Logger) logger); // Bypassing the public API
plogger.addAppender(loggerHandler);
plogger.addAppender(logCatchHandler);
logger.info("Listener added");
}
public void listenOnField(String loggerCategory) {
listenOnField(LogManager.getLogger(loggerCategory));
}
public void indicateProgress() {
progressIndicator.setProgress(-1);
}
public void stopProgress() {
progressIndicator.setProgress(100);
}
public ContextMenu createContextMenu() {
ContextMenu cm = new ContextMenu();
Menu viewOptions = new Menu("View Options");
MenuItem showLog = new MenuItem("Show Log", new MaterialDesignIconView(MaterialDesignIcon.FORMAT_LIST_BULLETED));
showLog.setOnAction(this::showLog);
cm.getItems().addAll(viewOptions, showLog);
return cm;
}
private void showLog(ActionEvent actionEvent) {
loggerDialog.show();
}
public Dialog<Void> createDialog() {
final TableView<LogEvent> recordView = new TableView<>(logCatchHandler.recordsProperty());
recordView.setEditable(false);
recordView.setSortPolicy(param -> false);
TableColumn<LogEvent, Date> dateColumn = new TableColumn<>("Date");
TableColumn<LogEvent, Level> levelColumn = new TableColumn<>("Level");
//TableColumn<LogRecord, String> classColumn = new TableColumn<>("Class");
TableColumn<LogEvent, String> messageColumn = new TableColumn<>("Message");
recordView.getColumns().setAll(dateColumn, levelColumn, messageColumn);
dateColumn.setCellValueFactory(
param -> new SimpleObjectProperty<>(new Date(param.getValue().getTimeMillis())
));
levelColumn.setCellValueFactory(
param -> new SimpleObjectProperty<>(param.getValue().getLevel())
);
messageColumn.setCellValueFactory(
param -> {
return new SimpleStringProperty(param.getValue().getMessage().getFormattedMessage());
/*String s = formatter.formatMessage(param.getValue());
if (param.getValue().getThrown() != null) {