Skip to content

Commit

Permalink
Code cleanup (#278)
Browse files Browse the repository at this point in the history
* Fix sonar warnings

---------

Co-authored-by: kaklakariada <[email protected]>
  • Loading branch information
kaklakariada and kaklakariada authored May 4, 2024
1 parent abbea6f commit ce69d09
Show file tree
Hide file tree
Showing 29 changed files with 338 additions and 292 deletions.
2 changes: 1 addition & 1 deletion jfxui/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ tasks.jpackage {

appName = "WhiteRabbit"
vendor = '"It\'s all code"'
copyright = '"Copyright (C) 2021 Christoph Pirkl <christoph at users.sourceforge.net>"'
copyright = '"Copyright (C) 2024 Christoph Pirkl <christoph at users.sourceforge.net>"'
licenseFile = "${rootProject.rootDir}/LICENSE"
appDescription = '"A time recording tool"'
icon = "${projectDir}/src/main/resources/icon.png"
Expand Down
89 changes: 49 additions & 40 deletions jfxui/src/main/java/org/itsallcode/whiterabbit/jfxui/JavaFxApp.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@

import java.lang.ProcessHandle.Info;
import java.nio.file.Paths;
import java.time.*;
import java.time.Clock;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalTime;
import java.time.YearMonth;
import java.util.Arrays;
import java.util.Optional;
import java.util.concurrent.ScheduledExecutorService;
Expand All @@ -17,8 +21,13 @@
import org.itsallcode.whiterabbit.jfxui.ui.AppUi;
import org.itsallcode.whiterabbit.jfxui.ui.InterruptionDialog;
import org.itsallcode.whiterabbit.jfxui.uistate.UiStateService;
import org.itsallcode.whiterabbit.logic.*;
import org.itsallcode.whiterabbit.logic.model.*;
import org.itsallcode.whiterabbit.logic.Config;
import org.itsallcode.whiterabbit.logic.ConfigLoader;
import org.itsallcode.whiterabbit.logic.DefaultWorkingDirProvider;
import org.itsallcode.whiterabbit.logic.WorkingDirProvider;
import org.itsallcode.whiterabbit.logic.model.Activity;
import org.itsallcode.whiterabbit.logic.model.DayRecord;
import org.itsallcode.whiterabbit.logic.model.MonthIndex;
import org.itsallcode.whiterabbit.logic.service.AppService;
import org.itsallcode.whiterabbit.logic.service.AppServiceCallback;
import org.itsallcode.whiterabbit.logic.service.singleinstance.OtherInstance;
Expand Down Expand Up @@ -56,7 +65,8 @@ public JavaFxApp()
this(new DefaultWorkingDirProvider(), Clock.systemDefaultZone(), new ScheduledThreadPoolExecutor(1));
}

JavaFxApp(WorkingDirProvider workingDirProvider, Clock clock, ScheduledExecutorService executorService)
JavaFxApp(final WorkingDirProvider workingDirProvider, final Clock clock,
final ScheduledExecutorService executorService)
{
this.workingDirProvider = workingDirProvider;
this.clock = clock;
Expand All @@ -70,14 +80,14 @@ public void init()
{
doInitialize();
}
catch (final Exception e)
catch (final RuntimeException e)
{
stop();
throw e;
}
}

private void notifyPreloaderProgress(Type notificationType)
private void notifyPreloaderProgress(final Type notificationType)
{
notifyPreloader(new ProgressPreloaderNotification(this, notificationType));
}
Expand Down Expand Up @@ -113,16 +123,16 @@ private Config loadConfig()
}

@Override
public void start(Stage primaryStage)
public void start(final Stage primaryStage)
{
this.primaryStage = primaryStage;
state.setPrimaryStage(primaryStage);
LOG.info("Starting UI");
LOG.trace("Starting UI");
doStart(primaryStage);
notifyPreloaderProgress(Type.STARTUP_FINISHED);
}

private void doStart(Stage primaryStage)
private void doStart(final Stage primaryStage)
{
this.ui = new AppUi.Builder(this, actions, appService, primaryStage, state).build();

Expand Down Expand Up @@ -193,7 +203,8 @@ private void startAppService()
appService.start();
}

private void messageFromOtherInstanceReceived(String message, RunningInstanceCallback.ClientConnection client)
private void messageFromOtherInstanceReceived(final String message,
final RunningInstanceCallback.ClientConnection client)
{
if (MESSAGE_BRING_TO_FRONT.equals(message))
{
Expand All @@ -218,12 +229,10 @@ public void bringWindowToFront()
Platform.runLater(() -> {
if (primaryStage.isShowing())
{
LOG.debug("Request focus");
primaryStage.requestFocus();
}
else
{
LOG.debug("Show primary stage");
primaryStage.show();
}
});
Expand Down Expand Up @@ -268,26 +277,26 @@ public void startManualInterruption()
private final class AppServiceCallbackImplementation implements AppServiceCallback
{
@Override
public InterruptionDetectedDecision automaticInterruptionDetected(LocalTime startOfInterruption,
Duration interruption)
public InterruptionDetectedDecision automaticInterruptionDetected(final LocalTime startOfInterruption,
final Duration interruption)
{
return JavaFxUtil
.runOnFxApplicationThread(() -> showAutomaticInterruptionDialog(startOfInterruption, interruption));
}

private InterruptionDetectedDecision showAutomaticInterruptionDialog(LocalTime startOfInterruption,
Duration interruption)
private InterruptionDetectedDecision showAutomaticInterruptionDialog(final LocalTime startOfInterruption,
final Duration interruption)
{
final Alert alert = createAlertDialog(startOfInterruption, interruption);
LOG.info("Showing automatic interruption alert starting at {} for {}...", startOfInterruption,
interruption);
final Optional<ButtonType> selectedButton = alert.showAndWait();
final InterruptionDetectedDecision decision = evaluateButton(selectedButton);
final InterruptionDetectedDecision decision = evaluateButton(selectedButton.orElse(null));
LOG.info("User clicked button {} -> {}", selectedButton, decision);
return decision;
}

private Alert createAlertDialog(LocalTime startOfInterruption, Duration interruption)
private Alert createAlertDialog(final LocalTime startOfInterruption, final Duration interruption)
{
final Alert alert = new Alert(AlertType.CONFIRMATION);
alert.setTitle("Interruption detected");
Expand All @@ -302,59 +311,59 @@ private Alert createAlertDialog(LocalTime startOfInterruption, Duration interrup
return alert;
}

private InterruptionDetectedDecision evaluateButton(final Optional<ButtonType> selectedButton)
private InterruptionDetectedDecision evaluateButton(final ButtonType selectedButton)
{
if (isButton(selectedButton, ButtonData.FINISH) && !state.stoppedWorkingForToday.get())
if (selectedButton == null)
{
return InterruptionDetectedDecision.SKIP_INTERRUPTION;
}
if (selectedButton.getButtonData() == ButtonData.FINISH && !state.stoppedWorkingForToday.get())
{
return InterruptionDetectedDecision.STOP_WORKING_FOR_TODAY;
}
if (isButton(selectedButton, ButtonData.YES))
if (selectedButton.getButtonData() == ButtonData.YES)
{
return InterruptionDetectedDecision.ADD_INTERRUPTION;
}
return InterruptionDetectedDecision.SKIP_INTERRUPTION;
}

private boolean isButton(Optional<ButtonType> button, ButtonData data)
@Override
public void recordUpdated(final DayRecord day)
{
return button.map(ButtonType::getButtonData)
.filter(d -> d == data)
.isPresent();
final YearMonth month = YearMonth.from(day.getDate());
JavaFxUtil.runOnFxApplicationThread(() -> recordUpdated(day, month));
}

@Override
public void recordUpdated(DayRecord day)
private void recordUpdated(final DayRecord day, final YearMonth month)
{
final YearMonth month = YearMonth.from(day.getDate());
JavaFxUtil.runOnFxApplicationThread(() -> {
ensureMonthAvailable(month);
if (state.currentMonth.get().getYearMonth().equals(month))
ensureMonthAvailable(month);
if (state.currentMonth.get().getYearMonth().equals(month))
{
state.currentMonth.setValue(day.getMonth());
if (daySelected(day))
{
state.currentMonth.setValue(day.getMonth());
if (daySelected(day))
{
ui.updateActivities(day);
}
ui.updateActivities(day);
}
});
}
}

private boolean daySelected(DayRecord dayRecord)
private boolean daySelected(final DayRecord dayRecord)
{
final Optional<DayRecord> selectedDay = state.getSelectedDay();
return selectedDay.isPresent() && selectedDay.get().getDate().equals(dayRecord.getDate());
}

@Override
public void exceptionOccurred(Exception e)
public void exceptionOccurred(final Exception e)
{
final String message = "An error occured: " + e.getClass() + ": " + e.getMessage();
LOG.error(message, e);
actions.showErrorDialog(message);
}

@Override
public void workStoppedForToday(boolean stopWorking)
public void workStoppedForToday(final boolean stopWorking)
{
JavaFxUtil.runOnFxApplicationThread(() -> state.stoppedWorkingForToday.setValue(stopWorking));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,29 @@
package org.itsallcode.whiterabbit.jfxui.feature;

import static java.util.stream.Collectors.toList;

import java.text.NumberFormat;
import java.text.ParsePosition;
import java.time.Duration;
import java.util.List;
import java.util.function.UnaryOperator;
import java.util.Locale;

import org.itsallcode.whiterabbit.logic.service.AppService;

import javafx.application.Platform;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.control.ButtonBar.ButtonData;
import javafx.scene.layout.*;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Dialog;
import javafx.scene.control.DialogPane;
import javafx.scene.control.Label;
import javafx.scene.control.MenuItem;
import javafx.scene.control.Spinner;
import javafx.scene.control.SplitMenuButton;
import javafx.scene.control.TextFormatter;
import javafx.scene.control.TextFormatter.Change;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.util.converter.IntegerStringConverter;

public class InterruptionPresetFeature
Expand Down Expand Up @@ -50,15 +58,15 @@ private List<MenuItem> createPresetMenuItems()
.mapToLong(Integer::longValue)
.mapToObj(Duration::ofMinutes)
.map(this::createMenuitem)
.collect(toList());
.toList();
}

private MenuItem createMenuitem(final Duration interruption)
{
final String verb = interruption.isNegative() ? "Subtract" : "Add";
final MenuItem menuItem = new MenuItem(
verb + " interruption of " + appService.formatter().format(interruption.abs()));
menuItem.setId(verb.toLowerCase() + "-interruption-preset-" + interruption.toString());
menuItem.setId(verb.toLowerCase(Locale.ENGLISH) + "-interruption-preset-" + interruption.toString());
menuItem.setOnAction(event -> addInterruptionForToday(interruption));
return menuItem;
}
Expand All @@ -68,15 +76,14 @@ private void addInterruptionForToday(final Duration interruption)
appService.addInterruption(appService.getClock().getCurrentDate(), interruption);
}

private static class DurationInputDialog extends Dialog<Duration>
private static final class DurationInputDialog extends Dialog<Duration>
{
private final GridPane grid;
private final Label label;
private final Spinner<Integer> spinner;

private DurationInputDialog()
{
final DialogPane dialogPane = getDialogPane();
final int maxValue = (int) Duration.ofHours(8).toMinutes();

spinner = new Spinner<>(0, maxValue, 0, 5);
Expand All @@ -85,31 +92,14 @@ private DurationInputDialog()
spinner.setEditable(true);

final NumberFormat numberFormat = NumberFormat.getIntegerInstance();
final UnaryOperator<TextFormatter.Change> filter = change -> {
if (change.isContentChange())
{
final String newText = change.getControlNewText();
if (newText.isEmpty())
{
return change;
}
final ParsePosition parsePosition = new ParsePosition(0);
numberFormat.parse(newText, parsePosition);
if (parsePosition.getIndex() == 0 ||
parsePosition.getIndex() < newText.length())
{
return null;
}
}
return change;
};
final TextFormatter<Integer> intFormatter = new TextFormatter<>(
new IntegerStringConverter(), 0, filter);
new IntegerStringConverter(), 0, change -> removeInvalidNumber(numberFormat, change));
spinner.getEditor().setTextFormatter(intFormatter);

GridPane.setHgrow(spinner, Priority.ALWAYS);
GridPane.setFillWidth(spinner, true);

final DialogPane dialogPane = getDialogPane();
label = createContentLabel(dialogPane.getContentText());
label.setPrefWidth(Region.USE_COMPUTED_SIZE);
label.textProperty().bind(dialogPane.contentTextProperty());
Expand Down Expand Up @@ -141,6 +131,31 @@ private DurationInputDialog()
});
}

private static Change removeInvalidNumber(final NumberFormat numberFormat, final Change change)
{
if (change.isContentChange())
{
final String newText = change.getControlNewText();
if (newText.isEmpty())
{
return change;
}
if (parsingFails(numberFormat, newText))
{
return null;
}
}
return change;
}

private static boolean parsingFails(final NumberFormat numberFormat, final String text)
{
final ParsePosition parsePosition = new ParsePosition(0);
numberFormat.parse(text, parsePosition);
return parsePosition.getIndex() == 0 ||
parsePosition.getIndex() < text.length();
}

private static Label createContentLabel(final String text)
{
final Label label = new Label(text);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package org.itsallcode.whiterabbit.jfxui.table.activities;

import static java.util.stream.Collectors.toList;

import java.time.Duration;
import java.util.List;

Expand Down Expand Up @@ -59,6 +57,6 @@ static List<ActivityPropertyAdapter> wrap(final EditListener<DayRecord> editList
{
return activities.stream()
.map(a -> wrap(editListener, a))
.collect(toList());
.toList();
}
}
Loading

0 comments on commit ce69d09

Please sign in to comment.