Skip to content
Merged
22 changes: 11 additions & 11 deletions src/main/java/de/doubleslash/keeptime/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ private void readSettings() {
final Settings settings;
if (settingsList.isEmpty()) {
settings = new Settings();
settings.setTaskBarColor(Model.TASK_BAR_COLOR.get());
settings.setTaskBarColor(model.taskBarColor.get());

settings.setDefaultBackgroundColor(Model.ORIGINAL_DEFAULT_BACKGROUND_COLOR);
settings.setDefaultFontColor(Model.ORIGINAL_DEFAULT_FONT_COLOR);
Expand All @@ -188,23 +188,23 @@ private void readSettings() {
settings = settingsList.get(0);
}

Model.DEFAULT_BACKGROUND_COLOR.set(settings.getDefaultBackgroundColor());
Model.DEFAULT_FONT_COLOR.set(settings.getDefaultFontColor());
Model.HOVER_BACKGROUND_COLOR.set(settings.getHoverBackgroundColor());
Model.HOVER_FONT_COLOR.set(settings.getHoverFontColor());
Model.TASK_BAR_COLOR.set(settings.getTaskBarColor());
Model.USE_HOTKEY.set(settings.isUseHotkey());
Model.DISPLAY_PROJECTS_RIGHT.set(settings.isDisplayProjectsRight());
Model.HIDE_PROJECTS_ON_MOUSE_EXIT.set(settings.isHideProjectsOnMouseExit());
model.defaultBackgroundColor.set(settings.getDefaultBackgroundColor());
model.defaultFontColor.set(settings.getDefaultFontColor());
model.hoverBackgroundColor.set(settings.getHoverBackgroundColor());
model.hoverFontColor.set(settings.getHoverFontColor());
model.taskBarColor.set(settings.getTaskBarColor());
model.useHotkey.set(settings.isUseHotkey());
model.displayProjectsRight.set(settings.isDisplayProjectsRight());
model.hideProjectsOnMouseExit.set(settings.isHideProjectsOnMouseExit());
}

private void initialisePopupUI(final Stage primaryStage) throws IOException {
LOG.debug("Initialising popup UI.");

globalScreenListener = new GlobalScreenListener();

Model.USE_HOTKEY.addListener((a, b, newValue) -> globalScreenListener.register(newValue));
globalScreenListener.register(Model.USE_HOTKEY.get());
model.useHotkey.addListener((a, b, newValue) -> globalScreenListener.register(newValue));
globalScreenListener.register(model.useHotkey.get());

popupViewStage = new Stage();
popupViewStage.initOwner(primaryStage);
Expand Down
57 changes: 34 additions & 23 deletions src/main/java/de/doubleslash/keeptime/controller/Controller.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import javax.annotation.PreDestroy;

Expand Down Expand Up @@ -59,7 +58,7 @@ public void changeProject(final Project newProject) {
}

public void changeProject(final Project newProject, final long minusSeconds) {
final Work currentWork = Model.activeWorkItem.get();
final Work currentWork = model.activeWorkItem.get();

final LocalDateTime now = dateProvider.dateTimeNow().minusSeconds(minusSeconds);
final LocalDate dateNow = now.toLocalDate();
Expand Down Expand Up @@ -89,7 +88,7 @@ public void changeProject(final Project newProject, final long minusSeconds) {
model.getPastWorkItems().removeIf(w -> !dateNow.isEqual(w.getCreationDate()));
LOG.debug("Removed '{}' work items from past work items.", sizeBefore - model.getPastWorkItems().size());
}
Model.activeWorkItem.set(work);
model.activeWorkItem.set(work);
}

public void addNewProject(final String projectName, final boolean isWork, final Color projectColor,
Expand Down Expand Up @@ -122,14 +121,14 @@ public void updateSettings(final Color hoverBackgroundColor, final Color hoverFo

model.getSettingsRepository().save(settings);

Model.DEFAULT_BACKGROUND_COLOR.set(settings.getDefaultBackgroundColor());
Model.DEFAULT_FONT_COLOR.set(settings.getDefaultFontColor());
Model.HOVER_BACKGROUND_COLOR.set(settings.getHoverBackgroundColor());
Model.HOVER_FONT_COLOR.set(settings.getHoverFontColor());
Model.TASK_BAR_COLOR.set(settings.getTaskBarColor());
Model.USE_HOTKEY.set(settings.isUseHotkey());
Model.DISPLAY_PROJECTS_RIGHT.set(settings.isDisplayProjectsRight());
Model.HIDE_PROJECTS_ON_MOUSE_EXIT.set(settings.isHideProjectsOnMouseExit());
model.defaultBackgroundColor.set(settings.getDefaultBackgroundColor());
model.defaultFontColor.set(settings.getDefaultFontColor());
model.hoverBackgroundColor.set(settings.getHoverBackgroundColor());
model.hoverFontColor.set(settings.getHoverFontColor());
model.taskBarColor.set(settings.getTaskBarColor());
model.useHotkey.set(settings.isUseHotkey());
model.displayProjectsRight.set(settings.isDisplayProjectsRight());
model.hideProjectsOnMouseExit.set(settings.isHideProjectsOnMouseExit());
}

@PreDestroy
Expand Down Expand Up @@ -245,37 +244,49 @@ List<Project> adaptProjectIndexesAfterRemoving(final List<Project> originalList,
}

public void setComment(final String notes) {
final Work work = Model.activeWorkItem.get();
final Work work = model.activeWorkItem.get();
work.setNotes(notes);
}

/**
* Calculate todays seconds counted as work
*/
public long calcTodaysWorkSeconds() {
final List<Work> workItems = new ArrayList<>();

return model.getPastWorkItems().stream().filter(work -> {
for (final Work work : model.getPastWorkItems()) {
final Project project = work.getProject();
// find up to date reference to project
final Optional<Project> optionalProject = model.getAllProjects().stream()
.filter(p -> p.getId() == project.getId()).findAny();
if (optionalProject.isPresent()) {
return optionalProject.get().isWork();
for (final Project p : model.getAllProjects()) {
if (p.getId() == project.getId()) {
if (p.isWork()) {
workItems.add(work);
}
break;
}
}
// TODO should not happen
return false;
}).mapToLong(work -> Duration.between(work.getStartTime(), work.getEndTime()).getSeconds()).sum();
}

return calcSeconds(workItems);
}

/**
* Calculate todays present seconds (work+nonWork)
*/
public long calcTodaysSeconds() {
return model.getPastWorkItems().stream()
.mapToLong(work -> Duration.between(work.getStartTime(), work.getEndTime()).getSeconds()).sum();
return calcSeconds(model.getPastWorkItems());
}

public ObservableList<Project> getAvailableProjects() {
return model.getAvailableProjects();
}

public long calcSeconds(final List<Work> workItems) {
long seconds = 0;

for (final Work w : workItems) {
seconds += Duration.between(w.getStartTime(), w.getEndTime()).getSeconds();
}

return seconds;
}
}
21 changes: 10 additions & 11 deletions src/main/java/de/doubleslash/keeptime/model/Model.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,21 +62,20 @@ public Model(final ProjectRepository projectRepository, final WorkRepository wor
Comparator.comparing(Project::getIndex));
private ObservableList<Project> allProjects = FXCollections.observableArrayList();

protected static final ObservableList<Work> pastWorkItems = FXCollections.observableArrayList();
public static final ObjectProperty<Work> activeWorkItem = new SimpleObjectProperty<>();
protected final ObservableList<Work> pastWorkItems = FXCollections.observableArrayList();
public final ObjectProperty<Work> activeWorkItem = new SimpleObjectProperty<>();

public static final ObjectProperty<Color> TASK_BAR_COLOR = new SimpleObjectProperty<>(ORIGINAL_TASK_BAR_FONT_COLOR);
public final ObjectProperty<Color> taskBarColor = new SimpleObjectProperty<>(ORIGINAL_TASK_BAR_FONT_COLOR);

public static final ObjectProperty<Color> HOVER_BACKGROUND_COLOR = new SimpleObjectProperty<>(
public final ObjectProperty<Color> hoverBackgroundColor = new SimpleObjectProperty<>(
ORIGINAL_HOVER_BACKGROUND_COLOR);
public static final ObjectProperty<Color> HOVER_FONT_COLOR = new SimpleObjectProperty<>(ORIGINAL_HOVER_Font_COLOR);
public static final ObjectProperty<Color> DEFAULT_BACKGROUND_COLOR = new SimpleObjectProperty<>(
public final ObjectProperty<Color> hoverFontColor = new SimpleObjectProperty<>(ORIGINAL_HOVER_Font_COLOR);
public final ObjectProperty<Color> defaultBackgroundColor = new SimpleObjectProperty<>(
ORIGINAL_DEFAULT_BACKGROUND_COLOR);
public static final ObjectProperty<Color> DEFAULT_FONT_COLOR = new SimpleObjectProperty<>(
ORIGINAL_DEFAULT_FONT_COLOR);
public static final ObjectProperty<Boolean> USE_HOTKEY = new SimpleObjectProperty<>(false);
public static final ObjectProperty<Boolean> DISPLAY_PROJECTS_RIGHT = new SimpleObjectProperty<>(false);
public static final ObjectProperty<Boolean> HIDE_PROJECTS_ON_MOUSE_EXIT = new SimpleObjectProperty<>(true);
public final ObjectProperty<Color> defaultFontColor = new SimpleObjectProperty<>(ORIGINAL_DEFAULT_FONT_COLOR);
public final ObjectProperty<Boolean> useHotkey = new SimpleObjectProperty<>(false);
public final ObjectProperty<Boolean> displayProjectsRight = new SimpleObjectProperty<>(false);
public final ObjectProperty<Boolean> hideProjectsOnMouseExit = new SimpleObjectProperty<>(true);

public void setWorkRepository(final WorkRepository workRepository) {
this.workRepository = workRepository;
Expand Down
55 changes: 55 additions & 0 deletions src/main/java/de/doubleslash/keeptime/view/ColorTimeLine.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright 2019 doubleSlash Net Business GmbH
//
// This file is part of KeepTime.
// KeepTime is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

package de.doubleslash.keeptime.view;

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

import de.doubleslash.keeptime.model.Work;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.paint.Color;

public class ColorTimeLine {

private final Canvas canvas;

public ColorTimeLine(final Canvas canvas) {
this.canvas = canvas;
}

public void update(final List<Work> workItems, final long seconds) {
final GraphicsContext gc = canvas.getGraphicsContext2D();

gc.setFill(new Color(.3, .3, .3, .3));
gc.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
gc.fillRect(0, 0, canvas.getWidth(), canvas.getHeight());
double currentX = 0;
for (final Work w : workItems) {
final long workedSeconds = Duration.between(w.getStartTime(), w.getEndTime()).getSeconds();
final double width = (double) workedSeconds / seconds * canvas.getWidth();
final Color fill = w.getProject().getColor();

gc.setFill(fill);
gc.fillRect(currentX, 0, width, canvas.getHeight());

currentX += width;
}

}

}
42 changes: 37 additions & 5 deletions src/main/java/de/doubleslash/keeptime/view/ReportController.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,17 @@

import de.doubleslash.keeptime.common.DateFormatter;
import de.doubleslash.keeptime.common.FontProvider;
import de.doubleslash.keeptime.controller.Controller;
import de.doubleslash.keeptime.model.Model;
import de.doubleslash.keeptime.model.Project;
import de.doubleslash.keeptime.model.Work;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.canvas.Canvas;
import javafx.scene.control.Button;
import javafx.scene.control.DateCell;
import javafx.scene.control.DatePicker;
Expand All @@ -46,6 +50,8 @@
import javafx.scene.input.ClipboardContent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.shape.Circle;
import javafx.util.Callback;

public class ReportController {
Expand All @@ -71,12 +77,19 @@ public class ReportController {
@FXML
private ScrollPane scrollPane;

@FXML
private Canvas colorTimeLineCanvas;

private static final Logger LOG = LoggerFactory.getLogger(ReportController.class);

private DatePicker datePicker; // for calender element
private DatePicker datePicker; // for calendar element

private Model model;

private Controller controller;

private ColorTimeLine colorTimeLine;

@FXML
private void initialize() {
LOG.info("Init reportController");
Expand All @@ -86,17 +99,22 @@ private void initialize() {
LOG.info("Datepicker selected value changed to {}", newvalue);
updateReport(newvalue);
});

colorTimeLine = new ColorTimeLine(colorTimeLineCanvas);
}

private void updateReport(final LocalDate newvalue) {
this.currentDayLabel.setText(DateFormatter.toDayDateString(newvalue));
final List<Work> currentWorkItems = model.getWorkRepository().findByCreationDate(newvalue);

colorTimeLine.update(currentWorkItems, controller.calcSeconds(currentWorkItems));

final SortedSet<Project> workedProjectsSet = currentWorkItems.stream().map(Work::getProject)
.collect(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Project::getName))));

this.gridPane.getChildren().clear();
this.gridPane.getRowConstraints().clear();
this.gridPane.getColumnConstraints().get(0).setPrefWidth(300);

int rowIndex = 0;
long currentWorkSeconds = 0;
Expand All @@ -105,13 +123,23 @@ private void updateReport(final LocalDate newvalue) {
for (final Project project : workedProjectsSet) {
final Label projectName = new Label(project.getName());
projectName.setFont(FontProvider.getBoldFont());
this.gridPane.add(projectName, 0, rowIndex);
projectName.setUnderline(project.isWork());
final Circle circle = new Circle(5, project.getColor());

final HBox projectNameHBox = new HBox();
projectNameHBox.setAlignment(Pos.CENTER_LEFT);
projectNameHBox.setPadding(new Insets(0, 0, 0, 5));
projectNameHBox.setSpacing(5);

projectNameHBox.getChildren().add(circle);
projectNameHBox.getChildren().add(projectName);

this.gridPane.add(projectNameHBox, 0, rowIndex);

final List<Work> onlyCurrentProjectWork = currentWorkItems.stream().filter(w -> w.getProject() == project)
.collect(Collectors.toList());

final long todaysWorkSeconds = onlyCurrentProjectWork.stream()
.mapToLong(work -> DateFormatter.getSecondsBewtween(work.getStartTime(), work.getEndTime())).sum();
final long todaysWorkSeconds = controller.calcSeconds(onlyCurrentProjectWork);

currentSeconds += todaysWorkSeconds;
if (project.isWork()) {
Expand Down Expand Up @@ -153,13 +181,13 @@ private void updateReport(final LocalDate newvalue) {

rowIndex++;
}
// textArea.setText(pr.getNotes(true));
bProjectReport.setUserData(pr.getNotes(true));
}
this.scrollPane.setVvalue(0); // scroll to the top

this.currentDayTimeLabel.setText(DateFormatter.secondsToHHMMSS(currentSeconds));
this.currentDayWorkTimeLabel.setText(DateFormatter.secondsToHHMMSS(currentWorkSeconds));

}

private Button createProjectReport() {
Expand Down Expand Up @@ -209,4 +237,8 @@ public void updateItem(final LocalDate item, final boolean empty) {
public void update() {
updateReport(this.datePicker.getValue());
}

public void setController(final Controller controller) {
this.controller = controller;
}
}
Loading