mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-05-17 10:11:27 +00:00
* Hide button when not hovering or vault is locked
* localize
This commit is contained in:
@@ -15,7 +15,9 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
@@ -26,6 +28,7 @@ import javafx.geometry.Side;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ContextMenu;
|
||||
import javafx.scene.control.MenuItem;
|
||||
import javafx.scene.layout.HBox;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Optional;
|
||||
import java.util.ResourceBundle;
|
||||
@@ -46,9 +49,12 @@ public class EventListCellController implements FxController {
|
||||
private final ObservableValue<String> message;
|
||||
private final ObservableValue<String> description;
|
||||
private final ObservableValue<FontAwesome5Icon> icon;
|
||||
private final BooleanProperty actionsButtonVisible;
|
||||
|
||||
@FXML
|
||||
ContextMenu eventActions;
|
||||
HBox root;
|
||||
@FXML
|
||||
ContextMenu eventActionsMenu;
|
||||
@FXML
|
||||
Button eventActionsButton;
|
||||
|
||||
@@ -65,13 +71,23 @@ public class EventListCellController implements FxController {
|
||||
this.message = Bindings.createStringBinding(this::selectMessage, vaultUnlocked, eventMessage);
|
||||
this.description = Bindings.createStringBinding(this::selectDescription, vaultUnlocked, eventDescription);
|
||||
this.icon = Bindings.createObjectBinding(this::selectIcon, vaultUnlocked, eventIcon);
|
||||
this.actionsButtonVisible = new SimpleBooleanProperty();
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void initialize() {
|
||||
actionsButtonVisible.bind(Bindings.createBooleanBinding(this::determineActionsButtonVisibility, root.hoverProperty(), eventActionsMenu.showingProperty(), vaultUnlocked));
|
||||
vaultUnlocked.addListener((_,_,newValue) -> eventActionsMenu.hide());
|
||||
}
|
||||
|
||||
private boolean determineActionsButtonVisibility() {
|
||||
return vaultUnlocked.getValue() && (eventActionsMenu.isShowing() || root.isHover());
|
||||
}
|
||||
|
||||
public void setEvent(@NotNull VaultEvent item) {
|
||||
event.set(item);
|
||||
eventDescription.setValue("Vault " + item.v().getDisplayName());
|
||||
eventActions.hide();
|
||||
eventActions.getItems().clear();
|
||||
eventActionsMenu.hide();
|
||||
eventActionsMenu.getItems().clear();
|
||||
addAction("generic.action.dismiss", () -> events.remove(item));
|
||||
switch (item.actualEvent()) {
|
||||
case ConflictResolvedEvent fse -> this.adjustToConflictResolvedEvent(fse);
|
||||
@@ -82,7 +98,8 @@ public class EventListCellController implements FxController {
|
||||
|
||||
private void adjustToConflictResolvedEvent(ConflictResolvedEvent cre) {
|
||||
eventIcon.setValue(FontAwesome5Icon.FILE);
|
||||
eventMessage.setValue("Resolved conflict, new file is " + cre.resolvedCleartextPath()); //TODO:localize
|
||||
eventMessage.setValue(cre.resolvedCleartextPath().toString());
|
||||
eventDescription.setValue(resourceBundle.getString("event.conflictResolved.description"));
|
||||
if (revealService.isPresent()) {
|
||||
addAction("event.conflictResolved.showDecrypted", () -> this.showResolvedConflict(cre));
|
||||
}
|
||||
@@ -90,15 +107,18 @@ public class EventListCellController implements FxController {
|
||||
|
||||
private void adjustToConflictEvent(ConflictResolutionFailedEvent cfe) {
|
||||
eventIcon.setValue(FontAwesome5Icon.TIMES);
|
||||
eventMessage.setValue("Failed to resolve conflict for " + cfe.conflictingCiphertextPath()); //TODO:localize
|
||||
eventMessage.setValue(cfe.canonicalCleartextPath().toString());
|
||||
eventDescription.setValue(resourceBundle.getString("event.conflict.description"));
|
||||
if (revealService.isPresent()) {
|
||||
addAction("event.conflictFailed.showEncrypted", () -> reveal(cfe.conflictingCiphertextPath()));
|
||||
addAction("event.conflict.showDecrypted", () -> reveal(cfe.canonicalCleartextPath()));
|
||||
addAction("event.conflict.showEncrypted", () -> reveal(cfe.conflictingCiphertextPath()));
|
||||
}
|
||||
}
|
||||
|
||||
private void adjustToDecryptionFailedEvent(DecryptionFailedEvent dfe) {
|
||||
eventIcon.setValue(FontAwesome5Icon.BAN);
|
||||
eventMessage.setValue("Cannot decrypt " + dfe.ciphertextPath()); //TODO:localize
|
||||
eventMessage.setValue(dfe.ciphertextPath().toString());
|
||||
eventDescription.setValue(resourceBundle.getString("event.decryptionFailed.description"));
|
||||
if (revealService.isPresent()) {
|
||||
addAction("event.decryptionFailed.showEncrypted", () -> reveal(dfe.ciphertextPath()));
|
||||
}
|
||||
@@ -108,7 +128,7 @@ public class EventListCellController implements FxController {
|
||||
var entry = new MenuItem(resourceBundle.getString(localizationKey));
|
||||
entry.getStyleClass().addLast("add-vault-menu-item");
|
||||
entry.setOnAction(_ -> action.run());
|
||||
eventActions.getItems().addLast(entry);
|
||||
eventActionsMenu.getItems().addLast(entry);
|
||||
}
|
||||
|
||||
|
||||
@@ -125,7 +145,7 @@ public class EventListCellController implements FxController {
|
||||
return eventMessage.getValue();
|
||||
} else {
|
||||
var e = event.getValue();
|
||||
return "Event for " + (e != null ? e.v().getDisplayName() : ""); //TODO: localize
|
||||
return resourceBundle.getString("event.vaultLocked.message");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,7 +153,7 @@ public class EventListCellController implements FxController {
|
||||
if (vaultUnlocked.getValue()) {
|
||||
return eventDescription.getValue();
|
||||
} else {
|
||||
return "Unlock the vault to display details."; //TODO: localize
|
||||
return resourceBundle.getString("event.vaultLocked.description");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,10 +162,10 @@ public class EventListCellController implements FxController {
|
||||
public void toggleEventActionsMenu() {
|
||||
var e = event.get();
|
||||
if (e != null) {
|
||||
if (eventActions.isShowing()) {
|
||||
eventActions.hide();
|
||||
if (eventActionsMenu.isShowing()) {
|
||||
eventActionsMenu.hide();
|
||||
} else {
|
||||
eventActions.show(eventActionsButton, Side.BOTTOM, 0.0, 0.0);
|
||||
eventActionsMenu.show(eventActionsButton, Side.BOTTOM, 0.0, 0.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -165,11 +185,10 @@ public class EventListCellController implements FxController {
|
||||
revealService.orElseThrow(() -> new IllegalStateException("Function requiring revealService called, but service not available")) //
|
||||
.reveal(p);
|
||||
} catch (RevealFailedException e) {
|
||||
LOG.warn("Failed to show path {}",p, e);
|
||||
LOG.warn("Failed to show path {}", p, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-- property accessors --
|
||||
public ObservableValue<String> messageProperty() {
|
||||
return message;
|
||||
@@ -195,4 +214,13 @@ public class EventListCellController implements FxController {
|
||||
return icon.getValue();
|
||||
}
|
||||
|
||||
public ObservableValue<Boolean> actionsButtonVisibleProperty() {
|
||||
return actionsButtonVisible;
|
||||
}
|
||||
|
||||
public boolean isActionsButtonVisible() {
|
||||
return actionsButtonVisible.getValue();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
prefHeight="60"
|
||||
prefWidth="200"
|
||||
spacing="12"
|
||||
alignment="CENTER_LEFT">
|
||||
alignment="CENTER_LEFT"
|
||||
fx:id="root">
|
||||
<padding>
|
||||
<Insets topRightBottomLeft="12"/>
|
||||
</padding>
|
||||
@@ -26,15 +27,13 @@
|
||||
<Label styleClass="header-label" text="${controller.message}"/>
|
||||
<Label styleClass="detail-label" text="${controller.description}" textOverrun="CENTER_ELLIPSIS" />
|
||||
</VBox>
|
||||
<Button fx:id="eventActionsButton" contentDisplay="GRAPHIC_ONLY" onAction="#toggleEventActionsMenu">
|
||||
<Button fx:id="eventActionsButton" contentDisplay="GRAPHIC_ONLY" onAction="#toggleEventActionsMenu" managed="${controller.actionsButtonVisible}" visible="${controller.actionsButtonVisible}">
|
||||
<graphic>
|
||||
<FontAwesome5IconView glyph="ELLIPSIS_V" glyphSize="16"/>
|
||||
</graphic>
|
||||
</Button>
|
||||
|
||||
<fx:define>
|
||||
<ContextMenu fx:id="eventActions">
|
||||
<!-- entries are added in the controller -->
|
||||
</ContextMenu>
|
||||
<ContextMenu fx:id="eventActionsMenu"/>
|
||||
</fx:define>
|
||||
</HBox>
|
||||
|
||||
@@ -2,8 +2,14 @@
|
||||
additionalStyleSheets=
|
||||
|
||||
#Test
|
||||
event.vaultLocked.message=***********
|
||||
event.vaultLocked.description=Unlock the vault to display details
|
||||
event.conflictResolved.description=Resolved conflict
|
||||
event.conflictResolved.showDecrypted=Show decrypted file
|
||||
event.conflictFailed.showEncrypted=Show encrypted file
|
||||
event.conflict.description=Cannot resolve conflict.
|
||||
event.conflict.showDecrypted=Show decrypted, original file
|
||||
event.conflict.showEncrypted=Show conflicting, encrypted file
|
||||
event.decryptionFailed.description=Decryption failed.
|
||||
event.decryptionFailed.showEncrypted=Show encrypted file
|
||||
|
||||
# Generics
|
||||
|
||||
Reference in New Issue
Block a user