Skip to content

Commit b6c4858

Browse files
committed
changed gridPane of workItem display in the Report to a TreeTableView
1 parent c64c2d1 commit b6c4858

File tree

5 files changed

+184
-141
lines changed

5 files changed

+184
-141
lines changed

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

Lines changed: 86 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -31,31 +31,32 @@
3131
import com.sun.javafx.scene.control.skin.DatePickerSkin;
3232

3333
import de.doubleslash.keeptime.common.DateFormatter;
34-
import de.doubleslash.keeptime.common.FontProvider;
3534
import de.doubleslash.keeptime.common.Resources;
3635
import de.doubleslash.keeptime.common.Resources.RESOURCE;
3736
import de.doubleslash.keeptime.controller.Controller;
3837
import de.doubleslash.keeptime.exceptions.FXMLLoaderException;
3938
import de.doubleslash.keeptime.model.Model;
4039
import de.doubleslash.keeptime.model.Project;
4140
import de.doubleslash.keeptime.model.Work;
41+
import de.doubleslash.keeptime.view.worktable.ProjectTableRow;
42+
import de.doubleslash.keeptime.view.worktable.TableRow;
43+
import de.doubleslash.keeptime.view.worktable.WorkTableRow;
4244
import javafx.event.ActionEvent;
4345
import javafx.event.EventHandler;
4446
import javafx.fxml.FXML;
4547
import javafx.fxml.FXMLLoader;
46-
import javafx.geometry.Insets;
47-
import javafx.geometry.Pos;
4848
import javafx.scene.Node;
4949
import javafx.scene.canvas.Canvas;
5050
import javafx.scene.control.Button;
5151
import javafx.scene.control.ButtonType;
52-
import javafx.scene.control.ContextMenu;
5352
import javafx.scene.control.DateCell;
5453
import javafx.scene.control.DatePicker;
5554
import javafx.scene.control.Dialog;
5655
import javafx.scene.control.Label;
57-
import javafx.scene.control.MenuItem;
58-
import javafx.scene.control.ScrollPane;
56+
import javafx.scene.control.TreeItem;
57+
import javafx.scene.control.TreeTableColumn;
58+
import javafx.scene.control.TreeTableView;
59+
import javafx.scene.control.cell.TreeItemPropertyValueFactory;
5960
import javafx.scene.input.Clipboard;
6061
import javafx.scene.input.ClipboardContent;
6162
import javafx.scene.layout.AnchorPane;
@@ -85,10 +86,7 @@ public class ReportController {
8586
private Label currentDayTimeLabel;
8687

8788
@FXML
88-
private GridPane gridPane;
89-
90-
@FXML
91-
private ScrollPane scrollPane;
89+
private TreeTableView<TableRow> workTableTreeView;
9290

9391
@FXML
9492
private AnchorPane reportRoot;
@@ -98,8 +96,6 @@ public class ReportController {
9896

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

101-
private DatePicker datePicker; // for calendar element
102-
10399
private Model model;
104100

105101
private Controller controller;
@@ -114,121 +110,89 @@ public class ReportController {
114110
private void initialize() {
115111
LOG.info("Init reportController");
116112
currentReportDate = LocalDate.now();
117-
113+
initTableView();
118114
colorTimeLine = new ColorTimeLine(colorTimeLineCanvas);
119115
}
120116

117+
private void initTableView() {
118+
final TreeTableColumn<TableRow, String> noteColumn = new TreeTableColumn<>("Notes");
119+
noteColumn.setCellValueFactory(new TreeItemPropertyValueFactory<TableRow, String>("notes"));
120+
noteColumn.setMinWidth(200);
121+
this.workTableTreeView.getColumns().add(noteColumn);
122+
123+
final TreeTableColumn<TableRow, String> timeRangeColumn = new TreeTableColumn<>("Timeslot");
124+
timeRangeColumn.setCellValueFactory(new TreeItemPropertyValueFactory<TableRow, String>("timeRange"));
125+
timeRangeColumn.setMinWidth(100);
126+
this.workTableTreeView.getColumns().add(timeRangeColumn);
127+
128+
final TreeTableColumn<TableRow, String> timeSumColumn = new TreeTableColumn<>("Duration");
129+
timeSumColumn.setCellValueFactory(new TreeItemPropertyValueFactory<TableRow, String>("timeSum"));
130+
timeSumColumn.setMinWidth(100);
131+
this.workTableTreeView.getColumns().add(timeSumColumn);
132+
133+
final TreeTableColumn<TableRow, Button> buttonColumn = new TreeTableColumn<>();
134+
buttonColumn.setCellValueFactory(new TreeItemPropertyValueFactory<TableRow, Button>("buttonBox"));
135+
buttonColumn.setMinWidth(100);
136+
buttonColumn.setSortable(false);
137+
this.workTableTreeView.getColumns().add(buttonColumn);
138+
139+
workTableTreeView.setShowRoot(false);
140+
141+
}
142+
121143
private void updateReport(final LocalDate dateToShow) {
122144
this.currentReportDate = dateToShow;
123145
this.loadCalenderWidget();
124146
reportRoot.requestFocus();
125147

126-
this.currentDayLabel.setText(DateFormatter.toDayDateString(dateToShow));
127-
final List<Work> currentWorkItems = model.getWorkRepository().findByCreationDateOrderByStartTimeAsc(dateToShow);
128-
;
148+
this.currentDayLabel.setText(DateFormatter.toDayDateString(this.currentReportDate));
149+
final List<Work> currentWorkItems = model.getWorkRepository()
150+
.findByCreationDateOrderByStartTimeAsc(this.currentReportDate);
129151

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

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

135-
this.gridPane.getChildren().clear();
136-
this.gridPane.getRowConstraints().clear();
137-
this.gridPane.getColumnConstraints().get(0).setPrefWidth(300);
138-
139-
int rowIndex = 0;
140157
long currentWorkSeconds = 0;
141158
long currentSeconds = 0;
142159

143-
for (final Project project : workedProjectsSet) {
144-
final Label projectName = new Label(project.getName());
145-
projectName.setFont(FontProvider.getBoldFont());
146-
projectName.setUnderline(project.isWork());
147-
final Circle circle = new Circle(5, project.getColor());
148-
149-
final HBox projectNameHBox = new HBox();
150-
projectNameHBox.setAlignment(Pos.CENTER_LEFT);
151-
projectNameHBox.setPadding(new Insets(0, 0, 0, 5));
152-
projectNameHBox.setSpacing(5);
153-
154-
projectNameHBox.getChildren().add(circle);
155-
projectNameHBox.getChildren().add(projectName);
156-
157-
this.gridPane.add(projectNameHBox, 0, rowIndex);
160+
final TreeItem<TableRow> root = new TreeItem<>();
158161

162+
for (final Project project : workedProjectsSet) {
159163
final List<Work> onlyCurrentProjectWork = currentWorkItems.stream().filter(w -> w.getProject() == project)
160164
.collect(Collectors.toList());
161165

162-
final long todaysWorkSeconds = controller.calcSeconds(onlyCurrentProjectWork);
166+
final long projectWorkSeconds = controller.calcSeconds(onlyCurrentProjectWork);
163167

164-
currentSeconds += todaysWorkSeconds;
168+
currentSeconds += projectWorkSeconds;
165169
if (project.isWork()) {
166-
currentWorkSeconds += todaysWorkSeconds;
170+
currentWorkSeconds += projectWorkSeconds;
167171
}
168172

169-
final Label workedTimeLabel = new Label(DateFormatter.secondsToHHMMSS(todaysWorkSeconds));
170-
workedTimeLabel.setFont(FontProvider.getBoldFont());
171-
this.gridPane.add(workedTimeLabel, 2, rowIndex);
172-
173-
// text will be set later
174-
final Button bProjectReport = createProjectReport();
175-
this.gridPane.add(bProjectReport, 1, rowIndex);
176-
177-
rowIndex++;
178-
179-
final ProjectReport pr = new ProjectReport(onlyCurrentProjectWork.size());
180-
for (int j = 0; j < onlyCurrentProjectWork.size(); j++) {
181-
final Work work = onlyCurrentProjectWork.get(j);
182-
final String workedHours = DateFormatter
183-
.secondsToHHMMSS(DateFormatter.getSecondsBewtween(work.getStartTime(), work.getEndTime()));
173+
final HBox projectButtonBox = new HBox();
174+
projectButtonBox.getChildren().add(createProjectReportButton(onlyCurrentProjectWork));
175+
// TODO center Dot
184176

185-
final String currentWorkNote = work.getNotes();
186-
pr.appendToWorkNotes(currentWorkNote);
187-
final Label commentLabel = new Label(currentWorkNote);
188-
commentLabel.setFont(FontProvider.getDefaultFont());
189-
commentLabel.setWrapText(true);
190-
this.gridPane.add(commentLabel, 0, rowIndex);
177+
final Circle circle = new Circle(9, project.getColor());
191178

192-
final Label fromTillLabel = new Label(DateFormatter.toTimeString(work.getStartTime()) + " - "
193-
+ DateFormatter.toTimeString(work.getEndTime()));
194-
fromTillLabel.setFont(FontProvider.getDefaultFont());
195-
fromTillLabel.setWrapText(true);
196-
this.gridPane.add(fromTillLabel, 1, rowIndex);
179+
final TreeItem<TableRow> projectRow = new TreeItem<>(
180+
new ProjectTableRow(project, projectWorkSeconds, projectButtonBox), circle);
197181

198-
final Label workedHoursLabel = new Label(workedHours);
199-
workedHoursLabel.setFont(FontProvider.getDefaultFont());
200-
this.gridPane.add(workedHoursLabel, 2, rowIndex);
201-
202-
final HBox clickDummy = new HBox();
203-
final ContextMenu contextMenu = new ContextMenu();
204-
final MenuItem editMenuItem = new MenuItem("edit");
205-
206-
editMenuItem.setOnAction(e -> {
207-
LOG.info("Edit work");
208-
final Dialog<Work> dialog = setupEditWorkDialog("Edit work", "Edit work ", work);
209-
210-
final Optional<Work> result = dialog.showAndWait();
211-
212-
result.ifPresent(editedWork -> {
213-
controller.editWork(work, editedWork);
214-
215-
this.update();
216-
});
217-
});
218-
219-
contextMenu.getItems().add(editMenuItem);
220-
221-
clickDummy.setOnContextMenuRequested(
222-
event -> contextMenu.show(clickDummy, event.getScreenX(), event.getScreenY()));
182+
for (final Work w : onlyCurrentProjectWork) {
183+
final HBox workButtonBox = new HBox();
184+
workButtonBox.getChildren().add(createEditWorkButton(w));
185+
final TreeItem<TableRow> workRow = new TreeItem<>(new WorkTableRow(w, workButtonBox));
186+
projectRow.getChildren().add(workRow);
187+
}
223188

224-
this.gridPane.add(clickDummy, 0, rowIndex, 3, 1);
189+
projectRow.setExpanded(true);
190+
root.getChildren().add(projectRow);
225191

226-
rowIndex++;
227-
}
228-
bProjectReport.setUserData(pr.getNotes(true));
229192
}
230-
this.scrollPane.setVvalue(0); // scroll to the top
231193

194+
root.setExpanded(true);
195+
workTableTreeView.setRoot(root);
232196
this.currentDayTimeLabel.setText(DateFormatter.secondsToHHMMSS(currentSeconds));
233197
this.currentDayWorkTimeLabel.setText(DateFormatter.secondsToHHMMSS(currentWorkSeconds));
234198

@@ -262,6 +226,24 @@ public void updateItem(final LocalDate item, final boolean empty) {
262226

263227
}
264228

229+
private Button createEditWorkButton(final Work work) {
230+
final Button bProjectReport = new Button("edit");
231+
232+
bProjectReport.setOnAction(e -> {
233+
LOG.info("Edit work");
234+
final Dialog<Work> dialog = setupEditWorkDialog("Edit work", "Edit work ", work);
235+
236+
final Optional<Work> result = dialog.showAndWait();
237+
238+
result.ifPresent(editedWork -> {
239+
controller.editWork(work, editedWork);
240+
241+
this.update();
242+
});
243+
});
244+
return bProjectReport;
245+
}
246+
265247
private Dialog<Work> setupEditWorkDialog(final String title, final String headerText, final Work work) {
266248
final Dialog<Work> dialog = new Dialog<>();
267249

@@ -299,20 +281,23 @@ private GridPane setUpEditWorkGridPane(final Work work, final Dialog<Work> dialo
299281
return grid;
300282
}
301283

302-
private Button createProjectReport() {
284+
private Button createProjectReportButton(final List<Work> projectWork) {
303285
final Button bProjectReport = new Button("Copy to clipboard");
304286
final EventHandler<ActionEvent> eventListener = new EventHandler<ActionEvent>() {
305287

306288
@Override
307289
public void handle(final ActionEvent event) {
308-
final Object source = event.getSource();
309-
final Button btn = (Button) source;
310-
final Object userData = btn.getUserData();
311-
final String notes = (String) userData;
290+
LOG.debug("copied to Clipboard");
291+
final ProjectReport pr = new ProjectReport(projectWork.size());
292+
for (int j = 0; j < projectWork.size(); j++) {
293+
final Work work = projectWork.get(j);
294+
final String currentWorkNote = work.getNotes();
295+
pr.appendToWorkNotes(currentWorkNote);
312296

297+
}
313298
final Clipboard clipboard = Clipboard.getSystemClipboard();
314299
final ClipboardContent content = new ClipboardContent();
315-
content.putString(notes);
300+
content.putString(pr.getNotes(true));
316301
clipboard.setContent(content);
317302
}
318303

@@ -323,8 +308,6 @@ public void handle(final ActionEvent event) {
323308

324309
public void setModel(final Model model) {
325310
this.model = model;
326-
327-
this.loadCalenderWidget();
328311
}
329312

330313
public void update() {
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package de.doubleslash.keeptime.view.worktable;
2+
3+
import de.doubleslash.keeptime.common.DateFormatter;
4+
import de.doubleslash.keeptime.model.Project;
5+
import javafx.scene.layout.HBox;
6+
7+
public class ProjectTableRow implements TableRow {
8+
9+
private final Project project;
10+
private final long projectWorkSeconds;
11+
private final HBox buttonBox;
12+
13+
public ProjectTableRow(final Project project, final long projectWorkSeconds, final HBox buttonBox) {
14+
this.projectWorkSeconds = projectWorkSeconds;
15+
this.project = project;
16+
this.buttonBox = buttonBox;
17+
}
18+
19+
@Override
20+
public String getNotes() {
21+
return project.getName();
22+
}
23+
24+
@Override
25+
public String getTimeRange() {
26+
return null;
27+
28+
}
29+
30+
@Override
31+
public String getTimeSum() {
32+
return DateFormatter.secondsToHHMMSS(projectWorkSeconds);
33+
34+
}
35+
36+
@Override
37+
public HBox getButtonBox() {
38+
return buttonBox;
39+
}
40+
41+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package de.doubleslash.keeptime.view.worktable;
2+
3+
import javafx.scene.layout.HBox;
4+
5+
public interface TableRow {
6+
7+
public String getNotes();
8+
9+
public String getTimeRange();
10+
11+
public String getTimeSum();
12+
13+
public HBox getButtonBox();
14+
15+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
2+
package de.doubleslash.keeptime.view.worktable;
3+
4+
import de.doubleslash.keeptime.common.DateFormatter;
5+
import de.doubleslash.keeptime.model.Work;
6+
import javafx.scene.layout.HBox;
7+
8+
public class WorkTableRow implements TableRow {
9+
private final Work work;
10+
private final HBox buttonBox;
11+
12+
public WorkTableRow(final Work work, final HBox buttonBox) {
13+
this.work = work;
14+
this.buttonBox = buttonBox;
15+
}
16+
17+
@Override
18+
public String getNotes() {
19+
return work.getNotes();
20+
}
21+
22+
@Override
23+
public String getTimeRange() {
24+
return DateFormatter.toTimeString(work.getStartTime()) + " - " + DateFormatter.toTimeString(work.getEndTime());
25+
26+
}
27+
28+
@Override
29+
public String getTimeSum() {
30+
return DateFormatter.secondsToHHMMSS(DateFormatter.getSecondsBewtween(work.getStartTime(), work.getEndTime()));
31+
32+
}
33+
34+
@Override
35+
public HBox getButtonBox() {
36+
return buttonBox;
37+
}
38+
39+
}

0 commit comments

Comments
 (0)