Skip to content

Commit 982f1ca

Browse files
committed
Merge branch 'develop' into feature/advanced_controlls
# Conflicts: # src/main/java/de/doubleslash/keeptime/view/ReportController.java # src/main/java/de/doubleslash/keeptime/view/SettingsController.java # src/main/resources/layouts/report.fxml
2 parents 44bbe7b + d7276d0 commit 982f1ca

File tree

10 files changed

+238
-106
lines changed

10 files changed

+238
-106
lines changed

src/main/java/de/doubleslash/keeptime/Main.java

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ private void readSettings() {
173173
final Settings settings;
174174
if (settingsList.isEmpty()) {
175175
settings = new Settings();
176-
settings.setTaskBarColor(Model.TASK_BAR_COLOR.get());
176+
settings.setTaskBarColor(model.taskBarColor.get());
177177

178178
settings.setDefaultBackgroundColor(Model.ORIGINAL_DEFAULT_BACKGROUND_COLOR);
179179
settings.setDefaultFontColor(Model.ORIGINAL_DEFAULT_FONT_COLOR);
@@ -188,23 +188,23 @@ private void readSettings() {
188188
settings = settingsList.get(0);
189189
}
190190

191-
Model.DEFAULT_BACKGROUND_COLOR.set(settings.getDefaultBackgroundColor());
192-
Model.DEFAULT_FONT_COLOR.set(settings.getDefaultFontColor());
193-
Model.HOVER_BACKGROUND_COLOR.set(settings.getHoverBackgroundColor());
194-
Model.HOVER_FONT_COLOR.set(settings.getHoverFontColor());
195-
Model.TASK_BAR_COLOR.set(settings.getTaskBarColor());
196-
Model.USE_HOTKEY.set(settings.isUseHotkey());
197-
Model.DISPLAY_PROJECTS_RIGHT.set(settings.isDisplayProjectsRight());
198-
Model.HIDE_PROJECTS_ON_MOUSE_EXIT.set(settings.isHideProjectsOnMouseExit());
191+
model.defaultBackgroundColor.set(settings.getDefaultBackgroundColor());
192+
model.defaultFontColor.set(settings.getDefaultFontColor());
193+
model.hoverBackgroundColor.set(settings.getHoverBackgroundColor());
194+
model.hoverFontColor.set(settings.getHoverFontColor());
195+
model.taskBarColor.set(settings.getTaskBarColor());
196+
model.useHotkey.set(settings.isUseHotkey());
197+
model.displayProjectsRight.set(settings.isDisplayProjectsRight());
198+
model.hideProjectsOnMouseExit.set(settings.isHideProjectsOnMouseExit());
199199
}
200200

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

204204
globalScreenListener = new GlobalScreenListener();
205205

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

209209
popupViewStage = new Stage();
210210
popupViewStage.initOwner(primaryStage);

src/main/java/de/doubleslash/keeptime/controller/Controller.java

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import java.time.LocalDateTime;
2222
import java.util.ArrayList;
2323
import java.util.List;
24-
import java.util.Optional;
2524

2625
import javax.annotation.PreDestroy;
2726

@@ -59,7 +58,7 @@ public void changeProject(final Project newProject) {
5958
}
6059

6160
public void changeProject(final Project newProject, final long minusSeconds) {
62-
final Work currentWork = Model.activeWorkItem.get();
61+
final Work currentWork = model.activeWorkItem.get();
6362

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

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

123122
model.getSettingsRepository().save(settings);
124123

125-
Model.DEFAULT_BACKGROUND_COLOR.set(settings.getDefaultBackgroundColor());
126-
Model.DEFAULT_FONT_COLOR.set(settings.getDefaultFontColor());
127-
Model.HOVER_BACKGROUND_COLOR.set(settings.getHoverBackgroundColor());
128-
Model.HOVER_FONT_COLOR.set(settings.getHoverFontColor());
129-
Model.TASK_BAR_COLOR.set(settings.getTaskBarColor());
130-
Model.USE_HOTKEY.set(settings.isUseHotkey());
131-
Model.DISPLAY_PROJECTS_RIGHT.set(settings.isDisplayProjectsRight());
132-
Model.HIDE_PROJECTS_ON_MOUSE_EXIT.set(settings.isHideProjectsOnMouseExit());
124+
model.defaultBackgroundColor.set(settings.getDefaultBackgroundColor());
125+
model.defaultFontColor.set(settings.getDefaultFontColor());
126+
model.hoverBackgroundColor.set(settings.getHoverBackgroundColor());
127+
model.hoverFontColor.set(settings.getHoverFontColor());
128+
model.taskBarColor.set(settings.getTaskBarColor());
129+
model.useHotkey.set(settings.isUseHotkey());
130+
model.displayProjectsRight.set(settings.isDisplayProjectsRight());
131+
model.hideProjectsOnMouseExit.set(settings.isHideProjectsOnMouseExit());
133132
}
134133

135134
@PreDestroy
@@ -245,37 +244,49 @@ List<Project> adaptProjectIndexesAfterRemoving(final List<Project> originalList,
245244
}
246245

247246
public void setComment(final String notes) {
248-
final Work work = Model.activeWorkItem.get();
247+
final Work work = model.activeWorkItem.get();
249248
work.setNotes(notes);
250249
}
251250

252251
/**
253252
* Calculate todays seconds counted as work
254253
*/
255254
public long calcTodaysWorkSeconds() {
255+
final List<Work> workItems = new ArrayList<>();
256256

257-
return model.getPastWorkItems().stream().filter(work -> {
257+
for (final Work work : model.getPastWorkItems()) {
258258
final Project project = work.getProject();
259-
// find up to date reference to project
260-
final Optional<Project> optionalProject = model.getAllProjects().stream()
261-
.filter(p -> p.getId() == project.getId()).findAny();
262-
if (optionalProject.isPresent()) {
263-
return optionalProject.get().isWork();
259+
for (final Project p : model.getAllProjects()) {
260+
if (p.getId() == project.getId()) {
261+
if (p.isWork()) {
262+
workItems.add(work);
263+
}
264+
break;
265+
}
264266
}
265-
// TODO should not happen
266-
return false;
267-
}).mapToLong(work -> Duration.between(work.getStartTime(), work.getEndTime()).getSeconds()).sum();
267+
}
268+
269+
return calcSeconds(workItems);
268270
}
269271

270272
/**
271273
* Calculate todays present seconds (work+nonWork)
272274
*/
273275
public long calcTodaysSeconds() {
274-
return model.getPastWorkItems().stream()
275-
.mapToLong(work -> Duration.between(work.getStartTime(), work.getEndTime()).getSeconds()).sum();
276+
return calcSeconds(model.getPastWorkItems());
276277
}
277278

278279
public ObservableList<Project> getAvailableProjects() {
279280
return model.getAvailableProjects();
280281
}
282+
283+
public long calcSeconds(final List<Work> workItems) {
284+
long seconds = 0;
285+
286+
for (final Work w : workItems) {
287+
seconds += Duration.between(w.getStartTime(), w.getEndTime()).getSeconds();
288+
}
289+
290+
return seconds;
291+
}
281292
}

src/main/java/de/doubleslash/keeptime/model/Model.java

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -62,21 +62,20 @@ public Model(final ProjectRepository projectRepository, final WorkRepository wor
6262
Comparator.comparing(Project::getIndex));
6363
private ObservableList<Project> allProjects = FXCollections.observableArrayList();
6464

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

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

70-
public static final ObjectProperty<Color> HOVER_BACKGROUND_COLOR = new SimpleObjectProperty<>(
70+
public final ObjectProperty<Color> hoverBackgroundColor = new SimpleObjectProperty<>(
7171
ORIGINAL_HOVER_BACKGROUND_COLOR);
72-
public static final ObjectProperty<Color> HOVER_FONT_COLOR = new SimpleObjectProperty<>(ORIGINAL_HOVER_Font_COLOR);
73-
public static final ObjectProperty<Color> DEFAULT_BACKGROUND_COLOR = new SimpleObjectProperty<>(
72+
public final ObjectProperty<Color> hoverFontColor = new SimpleObjectProperty<>(ORIGINAL_HOVER_Font_COLOR);
73+
public final ObjectProperty<Color> defaultBackgroundColor = new SimpleObjectProperty<>(
7474
ORIGINAL_DEFAULT_BACKGROUND_COLOR);
75-
public static final ObjectProperty<Color> DEFAULT_FONT_COLOR = new SimpleObjectProperty<>(
76-
ORIGINAL_DEFAULT_FONT_COLOR);
77-
public static final ObjectProperty<Boolean> USE_HOTKEY = new SimpleObjectProperty<>(false);
78-
public static final ObjectProperty<Boolean> DISPLAY_PROJECTS_RIGHT = new SimpleObjectProperty<>(false);
79-
public static final ObjectProperty<Boolean> HIDE_PROJECTS_ON_MOUSE_EXIT = new SimpleObjectProperty<>(true);
75+
public final ObjectProperty<Color> defaultFontColor = new SimpleObjectProperty<>(ORIGINAL_DEFAULT_FONT_COLOR);
76+
public final ObjectProperty<Boolean> useHotkey = new SimpleObjectProperty<>(false);
77+
public final ObjectProperty<Boolean> displayProjectsRight = new SimpleObjectProperty<>(false);
78+
public final ObjectProperty<Boolean> hideProjectsOnMouseExit = new SimpleObjectProperty<>(true);
8079

8180
public void setWorkRepository(final WorkRepository workRepository) {
8281
this.workRepository = workRepository;
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Copyright 2019 doubleSlash Net Business GmbH
2+
//
3+
// This file is part of KeepTime.
4+
// KeepTime is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU General Public License
15+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
17+
package de.doubleslash.keeptime.view;
18+
19+
import java.time.Duration;
20+
import java.util.List;
21+
22+
import de.doubleslash.keeptime.model.Work;
23+
import javafx.scene.canvas.Canvas;
24+
import javafx.scene.canvas.GraphicsContext;
25+
import javafx.scene.paint.Color;
26+
27+
public class ColorTimeLine {
28+
29+
private final Canvas canvas;
30+
31+
public ColorTimeLine(final Canvas canvas) {
32+
this.canvas = canvas;
33+
}
34+
35+
public void update(final List<Work> workItems, final long seconds) {
36+
final GraphicsContext gc = canvas.getGraphicsContext2D();
37+
38+
gc.setFill(new Color(.3, .3, .3, .3));
39+
gc.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
40+
gc.fillRect(0, 0, canvas.getWidth(), canvas.getHeight());
41+
double currentX = 0;
42+
for (final Work w : workItems) {
43+
final long workedSeconds = Duration.between(w.getStartTime(), w.getEndTime()).getSeconds();
44+
final double width = (double) workedSeconds / seconds * canvas.getWidth();
45+
final Color fill = w.getProject().getColor();
46+
47+
gc.setFill(fill);
48+
gc.fillRect(currentX, 0, width, canvas.getHeight());
49+
50+
currentX += width;
51+
}
52+
53+
}
54+
55+
}

src/main/java/de/doubleslash/keeptime/view/ReportController.java

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,17 @@
3030

3131
import de.doubleslash.keeptime.common.DateFormatter;
3232
import de.doubleslash.keeptime.common.FontProvider;
33+
import de.doubleslash.keeptime.controller.Controller;
3334
import de.doubleslash.keeptime.model.Model;
3435
import de.doubleslash.keeptime.model.Project;
3536
import de.doubleslash.keeptime.model.Work;
3637
import javafx.event.ActionEvent;
3738
import javafx.event.EventHandler;
3839
import javafx.fxml.FXML;
40+
import javafx.geometry.Insets;
41+
import javafx.geometry.Pos;
3942
import javafx.scene.Node;
43+
import javafx.scene.canvas.Canvas;
4044
import javafx.scene.control.Button;
4145
import javafx.scene.control.DateCell;
4246
import javafx.scene.control.DatePicker;
@@ -47,6 +51,8 @@
4751
import javafx.scene.layout.AnchorPane;
4852
import javafx.scene.layout.BorderPane;
4953
import javafx.scene.layout.GridPane;
54+
import javafx.scene.layout.HBox;
55+
import javafx.scene.shape.Circle;
5056
import javafx.util.Callback;
5157

5258
public class ReportController {
@@ -69,18 +75,26 @@ public class ReportController {
6975

7076
@FXML
7177
private GridPane gridPane;
78+
7279
@FXML
7380
private ScrollPane scrollPane;
7481

7582
@FXML
7683
private AnchorPane reportRoot;
7784

85+
@FXML
86+
private Canvas colorTimeLineCanvas;
87+
7888
private static final Logger LOG = LoggerFactory.getLogger(ReportController.class);
7989

80-
private DatePicker datePicker; // for calender element
90+
private DatePicker datePicker; // for calendar element
8191

8292
private Model model;
8393

94+
private Controller controller;
95+
96+
private ColorTimeLine colorTimeLine;
97+
8498
@FXML
8599
private void initialize() {
86100
LOG.info("Init reportController");
@@ -90,18 +104,23 @@ private void initialize() {
90104
LOG.info("Datepicker selected value changed to {}", newvalue);
91105
updateReport(newvalue);
92106
});
107+
108+
colorTimeLine = new ColorTimeLine(colorTimeLineCanvas);
93109
}
94110

95111
private void updateReport(final LocalDate newvalue) {
96112
reportRoot.requestFocus();
97113
this.currentDayLabel.setText(DateFormatter.toDayDateString(newvalue));
98114
final List<Work> currentWorkItems = model.getWorkRepository().findByCreationDate(newvalue);
99115

116+
colorTimeLine.update(currentWorkItems, controller.calcSeconds(currentWorkItems));
117+
100118
final SortedSet<Project> workedProjectsSet = currentWorkItems.stream().map(Work::getProject)
101119
.collect(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Project::getName))));
102120

103121
this.gridPane.getChildren().clear();
104122
this.gridPane.getRowConstraints().clear();
123+
this.gridPane.getColumnConstraints().get(0).setPrefWidth(300);
105124

106125
int rowIndex = 0;
107126
long currentWorkSeconds = 0;
@@ -110,13 +129,23 @@ private void updateReport(final LocalDate newvalue) {
110129
for (final Project project : workedProjectsSet) {
111130
final Label projectName = new Label(project.getName());
112131
projectName.setFont(FontProvider.getBoldFont());
113-
this.gridPane.add(projectName, 0, rowIndex);
132+
projectName.setUnderline(project.isWork());
133+
final Circle circle = new Circle(5, project.getColor());
134+
135+
final HBox projectNameHBox = new HBox();
136+
projectNameHBox.setAlignment(Pos.CENTER_LEFT);
137+
projectNameHBox.setPadding(new Insets(0, 0, 0, 5));
138+
projectNameHBox.setSpacing(5);
139+
140+
projectNameHBox.getChildren().add(circle);
141+
projectNameHBox.getChildren().add(projectName);
142+
143+
this.gridPane.add(projectNameHBox, 0, rowIndex);
114144

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

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

121150
currentSeconds += todaysWorkSeconds;
122151
if (project.isWork()) {
@@ -158,13 +187,13 @@ private void updateReport(final LocalDate newvalue) {
158187

159188
rowIndex++;
160189
}
161-
// textArea.setText(pr.getNotes(true));
162190
bProjectReport.setUserData(pr.getNotes(true));
163191
}
164192
this.scrollPane.setVvalue(0); // scroll to the top
165193

166194
this.currentDayTimeLabel.setText(DateFormatter.secondsToHHMMSS(currentSeconds));
167195
this.currentDayWorkTimeLabel.setText(DateFormatter.secondsToHHMMSS(currentWorkSeconds));
196+
168197
}
169198

170199
private Button createProjectReport() {
@@ -214,4 +243,8 @@ public void updateItem(final LocalDate item, final boolean empty) {
214243
public void update() {
215244
updateReport(this.datePicker.getValue());
216245
}
246+
247+
public void setController(final Controller controller) {
248+
this.controller = controller;
249+
}
217250
}

0 commit comments

Comments
 (0)