Skip to content

Commit

Permalink
Add image and caption filtering.
Browse files Browse the repository at this point in the history
  • Loading branch information
io7m committed Sep 26, 2024
1 parent 9c82d50 commit 382ce02
Show file tree
Hide file tree
Showing 4 changed files with 246 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,20 @@ void close()

AttributeReadableType<List<LImageWithID>> imageList();

/**
* Set the filter for the image list.
*
* @param filter The filter
*/

void imageListFilterSet(String filter);

/**
* @return The current complete list of images with a search filter applied
*/

AttributeReadableType<List<LImageWithID>> imageListFiltered();

/**
* @return The current complete list of required caption categories
*/
Expand All @@ -360,6 +374,20 @@ void close()

AttributeReadableType<List<LCaption>> imageCaptionsUnassigned();

/**
* @return The filtered list of captions not assigned to the current image
*/

AttributeReadableType<List<LCaption>> imageCaptionsUnassignedFiltered();

/**
* Set the filter for the caption list.
*
* @param filter The filter
*/

void captionsUnassignedListFilterSet(String filter);

/**
* @return Text describing the top of the undo stack, if any
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ public final class LFileModel implements LFileModelType
LOG.error("Uncaught attribute exception: ", throwable);
});

private final AttributeType<List<LCaption>> imageCaptionsUnassignedFiltered;
private final AttributeType<List<LCaption>> categoryCaptionsAssigned;
private final AttributeType<List<LCaption>> categoryCaptionsUnassigned;
private final AttributeType<List<LCaption>> imageCaptionsAssigned;
Expand All @@ -107,6 +108,7 @@ public final class LFileModel implements LFileModelType
private final AttributeType<List<LCommandRecord>> undoStack;
private final AttributeType<List<LGlobalCaption>> globalCaptions;
private final AttributeType<List<LImageWithID>> imagesAll;
private final AttributeType<List<LImageWithID>> imagesAllFiltered;
private final AttributeType<List<LMetadataValue>> metadata;
private final AttributeType<Optional<? extends LCommandType<?>>> redo;
private final AttributeType<Optional<? extends LCommandType<?>>> undo;
Expand All @@ -116,6 +118,8 @@ public final class LFileModel implements LFileModelType
private final AttributeType<Optional<String>> undoText;
private final AttributeType<Set<LCaptionID>> captionClipboard;
private final AttributeType<SortedMap<LCategoryID, List<LCaption>>> categoryCaptions;
private final AttributeType<String> captionsFilter;
private final AttributeType<String> imageFilter;
private final CloseableCollectionType<LException> resources;
private final ConcurrentHashMap<String, String> attributes;
private final LDatabaseType database;
Expand Down Expand Up @@ -150,8 +154,16 @@ private LFileModel(
ATTRIBUTES.withValue(List.of());
this.categoryCaptionsUnassigned =
ATTRIBUTES.withValue(List.of());
this.imageCaptionsUnassignedFiltered =
ATTRIBUTES.withValue(List.of());
this.captionsFilter =
ATTRIBUTES.withValue("");
this.imagesAll =
ATTRIBUTES.withValue(List.of());
this.imagesAllFiltered =
ATTRIBUTES.withValue(List.of());
this.imageFilter =
ATTRIBUTES.withValue("");
this.imageSelected =
ATTRIBUTES.withValue(Optional.empty());
this.categorySelected =
Expand Down Expand Up @@ -211,6 +223,53 @@ private LFileModel(
this.resources.add(
this.redo.subscribe((_0, _1) -> this.onRedoStateChanged())
);
this.resources.add(
this.imageFilter.subscribe((_0, _1) -> this.onImageRefilter())
);
this.resources.add(
this.imagesAll.subscribe((_0, _1) -> this.onImageRefilter())
);

this.resources.add(
this.captionsFilter.subscribe((_0, _1) -> this.onCaptionsRefilter())
);
this.resources.add(
this.imageCaptionsUnassigned.subscribe((_0, _1) -> this.onCaptionsRefilter())
);
}

private void onCaptionsRefilter()
{
final var filter =
this.captionsFilter.get().toUpperCase();

if (filter.isBlank()) {
this.imageCaptionsUnassignedFiltered.set(this.imageCaptionsUnassigned.get());
} else {
this.imageCaptionsUnassignedFiltered.set(
this.imageCaptionsUnassigned.get()
.stream()
.filter(c -> c.name().text().toUpperCase().contains(filter))
.toList()
);
}
}

private void onImageRefilter()
{
final var filter =
this.imageFilter.get().toUpperCase();

if (filter.isBlank()) {
this.imagesAllFiltered.set(this.imagesAll.get());
} else {
this.imagesAllFiltered.set(
this.imagesAll.get()
.stream()
.filter(i -> i.image().name().toUpperCase().contains(filter))
.toList()
);
}
}

/**
Expand Down Expand Up @@ -865,6 +924,19 @@ public AttributeReadableType<List<LImageWithID>> imageList()
return this.imagesAll;
}

@Override
public void imageListFilterSet(
final String filter)
{
this.imageFilter.set(Objects.requireNonNull(filter, "filter"));
}

@Override
public AttributeReadableType<List<LImageWithID>> imageListFiltered()
{
return this.imagesAllFiltered;
}

@Override
public AttributeReadableType<List<LCategory>> categoriesRequired()
{
Expand All @@ -889,6 +961,19 @@ public AttributeReadableType<List<LCaption>> imageCaptionsUnassigned()
return this.imageCaptionsUnassigned;
}

@Override
public AttributeReadableType<List<LCaption>> imageCaptionsUnassignedFiltered()
{
return this.imageCaptionsUnassignedFiltered;
}

@Override
public void captionsUnassignedListFilterSet(
final String filter)
{
this.captionsFilter.set(Objects.requireNonNull(filter, "filter"));
}

@Override
public AttributeReadableType<Optional<String>> undoText()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ protected void onFileBecameAvailable(
final LFileModelType fileModel)
{
subscriptions.add(
fileModel.imageList().subscribe((oldValue, newValue) -> {
fileModel.imageListFiltered().subscribe((oldValue, newValue) -> {
Platform.runLater(() -> {
this.imagesAll.setItems(
FXCollections.observableList(newValue)
Expand All @@ -186,7 +186,7 @@ protected void onFileBecameAvailable(
);

subscriptions.add(
fileModel.imageCaptionsUnassigned().subscribe((oldValue, newValue) -> {
fileModel.imageCaptionsUnassignedFiltered().subscribe((oldValue, newValue) -> {
Platform.runLater(() -> {
this.captionsUnassignedView.setItems(
FXCollections.observableList(newValue)
Expand Down Expand Up @@ -599,15 +599,21 @@ private void onCaptionModify()
@FXML
private void onCaptionSearchChanged()
{
// this.controller.captionsUnassignedSetFilter(
// this.captionAvailableSearch.getText().trim()
// );
this.fileModelNow()
.captionsUnassignedListFilterSet(
this.captionAvailableSearch.getText()
.trim()
);
}

@FXML
private void onImageSearchChanged()
{
// this.controller.imagesSetFilter(this.imageSearch.getText().trim());
this.fileModelNow()
.imageListFilterSet(
this.imageSearch.getText()
.trim()
);
}

@FXML
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,127 @@ public void testCaptionCopyPaste()
);
}

@Test
public void testCaptionFilter()
throws Exception
{
final var tta = new LCaptionName("A");
final var ttb = new LCaptionName("B");
final var ttc = new LCaptionName("C");

this.model.captionAdd(tta).get(TIMEOUT, SECONDS);
this.model.captionAdd(ttb).get(TIMEOUT, SECONDS);
this.model.captionAdd(ttc).get(TIMEOUT, SECONDS);

final var ta = this.findCaption("A");
final var tb = this.findCaption("B");
final var tc = this.findCaption("C");

this.model.imageAdd(
"image-a",
this.imageFile,
Optional.of(this.imageFile.toUri())
).get(TIMEOUT, SECONDS);

final var images =
this.model.imageList().get();

this.model.imageSelect(Optional.of(images.get(0).id()))
.get(TIMEOUT, SECONDS);

assertEquals(
List.of(ta, tb, tc),
this.model.imageCaptionsUnassignedFiltered().get()
);

this.model.captionsUnassignedListFilterSet("a");

assertEquals(
List.of(ta),
this.model.imageCaptionsUnassignedFiltered().get()
);

this.model.captionsUnassignedListFilterSet("b");

assertEquals(
List.of(tb),
this.model.imageCaptionsUnassignedFiltered().get()
);

this.model.captionsUnassignedListFilterSet("c");

assertEquals(
List.of(tc),
this.model.imageCaptionsUnassignedFiltered().get()
);

this.model.captionsUnassignedListFilterSet("");

assertEquals(
List.of(ta, tb, tc),
this.model.imageCaptionsUnassignedFiltered().get()
);
}

@Test
public void testImageFilter()
throws Exception
{
this.model.imageAdd(
"image-a",
this.imageFile,
Optional.of(this.imageFile.toUri())
).get(TIMEOUT, SECONDS);

this.model.imageAdd(
"image-b",
this.imageFile,
Optional.of(this.imageFile.toUri())
).get(TIMEOUT, SECONDS);

this.model.imageAdd(
"image-c",
this.imageFile,
Optional.of(this.imageFile.toUri())
).get(TIMEOUT, SECONDS);

final var images =
this.model.imageList().get();

assertEquals(
images,
this.model.imageListFiltered().get()
);

this.model.imageListFilterSet("-a");

assertEquals(
List.of(images.get(0)),
this.model.imageListFiltered().get()
);

this.model.imageListFilterSet("-b");

assertEquals(
List.of(images.get(1)),
this.model.imageListFiltered().get()
);

this.model.imageListFilterSet("-c");

assertEquals(
List.of(images.get(2)),
this.model.imageListFiltered().get()
);

this.model.imageListFilterSet("");

assertEquals(
images,
this.model.imageListFiltered().get()
);
}

private List<LCaptionName> captionListNow()
{
return this.model.captionList()
Expand Down

0 comments on commit 382ce02

Please sign in to comment.