Commit eeff268d authored by Alexander Weigl's avatar Alexander Weigl

Road to Ctrl+F matching search

parent cba7c0f6
Pipeline #13094 failed with stage
in 5 minutes and 11 seconds
......@@ -11,8 +11,13 @@ import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyCodeCombination;
import javafx.scene.input.KeyCombination;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
/**
* Right part of the splitpane that displays the different parts of a state
......@@ -23,18 +28,28 @@ public class InspectionView extends BorderPane {
private final ReadOnlyObjectProperty<InspectionModel> model = new SimpleObjectProperty<>(
new InspectionModel()
);
@FXML
private TextField txtSearchPattern;
public GoalOptionsMenu goalOptionsMenu = new GoalOptionsMenu();
@FXML
private SequentView sequentView;
@FXML
private ListView<GoalNode<KeyData>> goalView;
@FXML
private HBox searchBar;
public InspectionView() {
Utils.createWithFXML(this);
model.get().selectedGoalNodeToShowProperty().addListener((o, a, b) -> {
goalView.getSelectionModel().select(b);
});
goalView.getSelectionModel().selectedItemProperty().addListener((o, a, b) -> {
model.get().setSelectedGoalNodeToShow(b);
model.get().setCurrentInterpreterGoal(b);
......@@ -53,9 +68,32 @@ public class InspectionView extends BorderPane {
model.get().goalsProperty().bindBidirectional(goalView.itemsProperty());
getGoalView().setCellFactory(GoalNodeListCell::new);
final KeyCombination kb = new KeyCodeCombination(KeyCode.F, KeyCombination.SHORTCUT_DOWN);
sequentView.setOnKeyReleased(event -> {
// System.out.println(event);
if (kb.match(event)) {
event.consume();
//nice animation here
searchBar.setVisible(true);
txtSearchPattern.requestFocus();
}
});
KeyCombination esc = new KeyCodeCombination(KeyCode.ESCAPE);
txtSearchPattern.setOnKeyReleased(event -> {
if (esc.match(event)) {
event.consume();
searchBar.setVisible(false);
sequentView.removeSearchHighlights();
}
});
txtSearchPattern.textProperty().addListener((p, o, n) ->
sequentView.showSearchHighlights(n)
);
Utils.addDebugListener(model.get().goalsProperty());
Utils.addDebugListener(model.get().selectedGoalNodeToShowProperty());
Utils.addDebugListener(model.get().currentInterpreterGoalProperty());
......
......@@ -8,6 +8,9 @@ import de.uka.ilkd.key.proof.Goal;
import de.uka.ilkd.key.proof.Node;
import de.uka.ilkd.key.settings.ProofIndependentSettings;
import edu.kit.formal.psdb.interpreter.KeYProofFacade;
import edu.kit.formal.psdb.termmatcher.MatchPath;
import edu.kit.formal.psdb.termmatcher.MatcherFacade;
import edu.kit.formal.psdb.termmatcher.Matchings;
import javafx.beans.Observable;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ObservableBooleanValue;
......@@ -17,8 +20,11 @@ import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import org.fxmisc.richtext.CharacterHit;
import org.fxmisc.richtext.CodeArea;
import org.key_project.util.collection.ImmutableList;
import java.io.StringWriter;
import java.util.Collections;
import java.util.Map;
/**
* @author Alexander Weigl
......@@ -134,11 +140,9 @@ public class SequentView extends CodeArea {
this.setBorder(new Border(new BorderStroke(Color.GREEN, BorderStrokeStyle.SOLID, CornerRadii.EMPTY, BorderWidths.DEFAULT)));
this.getStyleClass().add("closed-sequent-view");
} else {
this.setBorder(new Border(new BorderStroke(Color.BLACK, BorderStrokeStyle.SOLID, CornerRadii.EMPTY, BorderWidths.DEFAULT)));
this.getStyleClass().remove("closed-sequent-view");
this.getStyleClass().add("sequent-view");
}
}
......@@ -175,4 +179,33 @@ public class SequentView extends CodeArea {
}
public void removeSearchHighlights() {
clearHighlight();
}
public boolean showSearchHighlights(String pattern) {
clearHighlight();
if (pattern.trim().isEmpty())
return false;
pattern = "(..." + pattern + "...) : ?COMPLETE";
if (node.get().sequent() != null) {
Matchings m = MatcherFacade.matches(pattern, node.get().sequent());
if (m.size() == 0) return false;
for (Map<String, MatchPath> va : m) {
MatchPath<?> complete = va.get("?COMPLETE");
highlightTerm(complete.getPos());
}
}
return true;
}
private void highlightTerm(ImmutableList<Integer> complete) {
if (backend == null) {
return;
}
Range r = backend.getInitialPositionTable().rangeForPath(complete);
setStyle(r.start(), r.end(), Collections.singleton("search-highlight"));
}
}
package edu.kit.formal.psdb.termmatcher;
import de.uka.ilkd.key.logic.Term;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.key_project.util.collection.ImmutableList;
import org.key_project.util.collection.ImmutableSLList;
/**
* @author Alexander Weigl
* @version 1 (24.08.17)
*/
@Data
@EqualsAndHashCode(exclude = {"parent","posInParent"})
public class MatchPath<T> {
private final MatchPath<?> parent;
private final T term;
private final int posInParent;
public MatchPath(MatchPath<?> parent, T unit, int pos) {
posInParent = pos;
term = unit;
this.parent = parent;
}
public static MatchPath<Term> createTermPath(MatchPath<Term> path, int i) {
return new MatchPath<>(path, path.getTerm().sub(i), i);
}
public ImmutableList<Integer> getPos() {
if (parent == null) {
return ImmutableSLList.singleton(posInParent);
} else {
return parent.getPos().append(posInParent);
}
}
public static <T> MatchPath<T> createRoot(T keyTerm) {
return new MatchPath<>(null, keyTerm, -1);
}
public String toString() {
return term.toString();
}
}
......@@ -28,7 +28,7 @@ public class MatcherFacade {
MatcherImpl matcher = new MatcherImpl();
MatchPatternParser mpp = getParser(pattern);
TermPatternContext ctx = mpp.termPattern();
return matcher.accept(ctx, keyTerm);
return matcher.accept(ctx, MatchPath.createRoot(keyTerm));
}
/**
......@@ -53,11 +53,9 @@ public class MatcherFacade {
* @return Matchings
*/
public static Matchings matches(String pattern, Semisequent semiSeq) {
MatchPatternParser mpp = getParser(pattern);
SemiSeqPatternContext ctx = mpp.semiSeqPattern();
return matches(ctx, semiSeq);
}
......@@ -138,17 +136,16 @@ public class MatcherFacade {
public static Matchings matches(SemiSeqPatternContext pattern, Semisequent semiSeq) {
MatcherImpl matcher = new MatcherImpl();
ImmutableList<SequentFormula> allSequentFormulas = semiSeq.asList();
List<TermPatternContext> termPatternContexts = pattern.termPattern();
List<List<MatcherImpl.MatchInfo>> allMatches = new ArrayList<>();
for (TermPatternContext termPatternContext : termPatternContexts) {
List<MatchInfo> m = new ArrayList<>();
for (SequentFormula form : allSequentFormulas) {
Matchings temp = matcher.accept(termPatternContext, form.formula());
Matchings temp = matcher.accept(termPatternContext,
MatchPath.createRoot(form.formula()));
for (Map<String, Term> match : temp) {
for (Map<String, MatchPath> match : temp) {
m.add(new MatchInfo(match, Collections.singleton(form)));
}
}
......@@ -161,7 +158,7 @@ public class MatcherFacade {
if (res == null)
return NO_MATCH;
Set<Map<String, Term>> resMap = res.stream()
Set<Map<String, MatchPath>> resMap = res.stream()
.map(el -> el.matching)
.collect(Collectors.toSet());
......
package edu.kit.formal.psdb.termmatcher;
import java.util.ArrayList;
import java.util.Map;
import java.util.TreeMap;
/**
* Class Matching contains a hashmap of string to term
*/
public class Matchings extends ArrayList<Map<String, MatchPath>> {
public static Matchings singleton(String name, MatchPath term) {
Matchings matchings = new Matchings();
Map<String, MatchPath> va = new TreeMap<>();
va.put(name, term);
matchings.add(va);
return matchings;
}
}
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<?import de.jensd.fx.glyphs.materialdesignicons.MaterialDesignIconView?>
<?import edu.kit.formal.psdb.gui.controls.*?>
<?import javafx.geometry.Insets?>
<?import edu.kit.formal.psdb.gui.controls.SectionPane?>
<?import edu.kit.formal.psdb.gui.controls.SequentView?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>
<fx:root xmlns:fx="http://javafx.com/fxml"
xmlns="http://javafx.com/javafx"
type="javafx.scene.layout.BorderPane" styleClass="inspection-view-tab">
type="javafx.scene.layout.BorderPane"
styleClass="inspection-view-tab">
<center>
<SplitPane orientation="VERTICAL" dividerPositions="0.25,0.75">
<items>
......@@ -39,4 +41,10 @@
</items>
</SplitPane>
</center>
<bottom>
<HBox fx:id="searchBar" visible="false">
<Label text="Search Pattern:"/>
<TextField fx:id="txtSearchPattern" HBox.hgrow="ALWAYS"/>
</HBox>
</bottom>
</fx:root>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment