Added several improvements, changes and bug fixes

This commit is contained in:
Robert Vokac 2024-03-16 14:51:11 +00:00
parent 8787ba9551
commit 30d4ff30a4
No known key found for this signature in database
GPG Key ID: 693D30BEE3329055
15 changed files with 457 additions and 228 deletions

View File

@ -8,6 +8,7 @@ import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.nanoboot.utils.timecalc.utils.common.NumberFormats;
/**
* @author Robert Vokac
@ -31,7 +32,7 @@ public class Activity implements Comparable<Activity> {
private int spentHours;
private int spentMinutes;
private String flags;
private String nextActivityId;
private int sortkey;
public String createSubject() {
return ticket + SUBJECT_FIELD_SEPARATOR + name;
@ -39,13 +40,18 @@ public class Activity implements Comparable<Activity> {
public String createTotalComment() {
return ticket + SUBJECT_FIELD_SEPARATOR + year + "-" + month + "-" + day
+ SUBJECT_FIELD_SEPARATOR + ((spentHours + spentMinutes / 60d)
+ "h") + SUBJECT_FIELD_SEPARATOR
+ SUBJECT_FIELD_SEPARATOR + (
NumberFormats.FORMATTER_TWO_DECIMAL_PLACES.format(spentHours + spentMinutes / 60d)
+ "h") + SUBJECT_FIELD_SEPARATOR
+ comment;
}
public Set<String> flagsAsSet() {
Set<String> set = new HashSet<>();
for(String flag:flags.split(":")) {
if(flag.isEmpty()) {
//nothing to do
continue;
}
set.add(flag);
}
return set;
@ -64,24 +70,10 @@ public class Activity implements Comparable<Activity> {
@Override
public int compareTo(Activity o) {
int result = Integer.valueOf(year).compareTo(Integer.valueOf(o.year));
if(result != 0) {
return result;
}
result = Integer.valueOf(month).compareTo(Integer.valueOf(o.month));
if(result != 0) {
return result;
}
result = Integer.valueOf(day).compareTo(Integer.valueOf(o.day));
if(result != 0) {
return result;
}
if(this.nextActivityId != null && this.nextActivityId.equals(o.getId())) {
return -1;
}
if(o.nextActivityId != null && o.nextActivityId.equals(o.getId())) {
return 1;
}
return 0;
return Integer.valueOf(sortkey).compareTo(Integer.valueOf(o.sortkey));
}
public String getSpentTimeAsString() {
return (getSpentHours() < 10 ? "0" : "") + getSpentHours() + ":" + (getSpentMinutes() < 10 ? "0" : "") + getSpentMinutes();
}
}

View File

@ -17,14 +17,14 @@ public class ActivityForStats extends Activity {
public ActivityForStats(String id, int year, int month, int day,
String name,
String comment, String ticket, int spentHours, int spentMinutes,
String flags, String nextActivityId,
String flags, int sortkey,
int todaySpentHours,
int todaySpentMinutes,
int todayRemainsHours,
int todayRemainsMinutes) {
super(id, year, month, day, name, comment, ticket, spentHours,
spentMinutes,
flags, nextActivityId);
flags, sortkey);
this.todaySpentHours = todaySpentHours;
this.todaySpentMinutes = todaySpentMinutes;
this.todayRemainsHours = todayRemainsHours;

View File

@ -12,10 +12,6 @@ public interface ActivityRepositoryApi {
void create(Activity activity);
Activity getLastActivityForDay(int year, int month, int day);
Activity getPreviousActivity(String id);
List<Activity> list(int year, int month, int day);
List<Activity> list(String ticket);
@ -28,4 +24,10 @@ public interface ActivityRepositoryApi {
public List<String> getYears();
public void putToClipboard(Activity activity);
public Activity getFromClipboard();
public int getLargestSortkey(int year, int month, int day);
}

View File

@ -1,17 +1,18 @@
package org.nanoboot.utils.timecalc.persistence.impl.sqlite;
import org.nanoboot.utils.timecalc.app.TimeCalcException;
import org.nanoboot.utils.timecalc.entity.Activity;
import org.nanoboot.utils.timecalc.persistence.api.ActivityRepositoryApi;
import org.nanoboot.utils.timecalc.utils.common.Utils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import org.nanoboot.utils.timecalc.persistence.api.ActivityRepositoryApi;
import java.util.List;
import org.nanoboot.utils.timecalc.app.TimeCalcException;
import org.nanoboot.utils.timecalc.entity.Activity;
import org.nanoboot.utils.timecalc.utils.common.Utils;
import java.util.OptionalInt;
/**
* @author Robert Vokac
@ -25,9 +26,10 @@ public class ActivityRepositorySQLiteImpl implements ActivityRepositoryApi {
this.sqliteConnectionFactory = sqliteConnectionFactory;
}
private Activity activityInClipboard = null;
@Override
public void create(Activity activity) {
Activity lastActivityForDay = getLastActivityForDay(activity.getYear(), activity.getMonth(), activity.getDay());
StringBuilder sb = new StringBuilder();
sb
.append("INSERT INTO ")
@ -51,7 +53,7 @@ public class ActivityRepositorySQLiteImpl implements ActivityRepositoryApi {
stmt.setInt(++i, activity.getSpentHours());
stmt.setInt(++i, activity.getSpentMinutes());
stmt.setString(++i, activity.getFlags());
stmt.setNull(++i, Types.VARCHAR);
stmt.setInt(++i, activity.getSortkey());
//
stmt.execute();
@ -64,11 +66,6 @@ public class ActivityRepositorySQLiteImpl implements ActivityRepositoryApi {
throw new TimeCalcException(ex);
}
if(lastActivityForDay != null) {
lastActivityForDay.setNextActivityId(activity.getId());
update(lastActivityForDay);
}
}
@Override
@ -103,12 +100,7 @@ public class ActivityRepositorySQLiteImpl implements ActivityRepositoryApi {
ex.printStackTrace();
throw new TimeCalcException(ex);
}
Activity previousActivity = getPreviousActivity(id);
Activity nextActivity = read(activityToBeDeleted.getNextActivityId());
if(previousActivity != null) {
previousActivity.setNextActivityId(nextActivity == null ? null : nextActivity.getId());
update(previousActivity);
}
}
@ -210,7 +202,7 @@ public class ActivityRepositorySQLiteImpl implements ActivityRepositoryApi {
.append(ActivityTable.SPENT_HOURS).append("=?, ")
.append(ActivityTable.SPENT_MINUTES).append("=?, ")
.append(ActivityTable.FLAGS).append("=?, ")
.append(ActivityTable.NEXT_ACTIVITY_ID).append("=? ")
.append(ActivityTable.SORTKEY).append("=? ")
.append(" WHERE ").append(
ActivityTable.ID).append("=?");
@ -225,7 +217,7 @@ public class ActivityRepositorySQLiteImpl implements ActivityRepositoryApi {
stmt.setInt(++i, activity.getSpentHours());
stmt.setInt(++i, activity.getSpentMinutes());
stmt.setString(++i, activity.getFlags());
stmt.setString(++i, activity.getNextActivityId());
stmt.setInt(++i, activity.getSortkey());
stmt.setString(++i, activity.getId());
@ -293,7 +285,7 @@ public class ActivityRepositorySQLiteImpl implements ActivityRepositoryApi {
rs.getInt(ActivityTable.SPENT_HOURS),
rs.getInt(ActivityTable.SPENT_MINUTES),
rs.getString(ActivityTable.FLAGS),
rs.getString(ActivityTable.NEXT_ACTIVITY_ID)
rs.getInt(ActivityTable.SORTKEY)
);
}
@ -336,101 +328,37 @@ public class ActivityRepositorySQLiteImpl implements ActivityRepositoryApi {
return result;
}
@Override
public Activity getLastActivityForDay(int year, int month, int day) {
List<Activity> result = new ArrayList<>();
StringBuilder sb = new StringBuilder();
sb
.append("SELECT * FROM ")
.append(ActivityTable.TABLE_NAME)
.append(" WHERE ")
.append(ActivityTable.YEAR).append("=? AND ")
.append(ActivityTable.MONTH).append("=? AND ")
.append(ActivityTable.DAY).append("=? AND ")
.append(ActivityTable.NEXT_ACTIVITY_ID)
.append(" IS NULL ");
String sql = sb.toString();
int i = 0;
ResultSet rs = null;
try (
Connection connection = sqliteConnectionFactory.createConnection(); PreparedStatement stmt = connection.prepareStatement(sql);) {
stmt.setInt(++i, year);
stmt.setInt(++i, month);
stmt.setInt(++i, day);
rs = stmt.executeQuery();
while (rs.next()) {
result.add(extractActivityFromResultSet(rs));
}
} catch (SQLException | ClassNotFoundException e) {
System.out.println(e.getMessage());
throw new RuntimeException(e);
} finally {
try {
if (rs != null) {
rs.close();
}
} catch (SQLException ex) {
System.out.println(ex.getMessage());
throw new RuntimeException(ex);
}
}
if(result.isEmpty()) {
return null;
}
if(result.size() == 1) {
return result.get(0);
}
throw new TimeCalcException("Fatal error: More (" + result.size() + ") than one activity per one day with next activity id set to null: " + year + ", " + month + ", " + day);
public void putToClipboard(Activity activity) {
this.activityInClipboard = activity;
}
@Override
public Activity getPreviousActivity(String id) {
List<Activity> result = new ArrayList<>();
StringBuilder sb = new StringBuilder();
sb
.append("SELECT * FROM ")
.append(ActivityTable.TABLE_NAME)
.append(" WHERE ")
.append(ActivityTable.NEXT_ACTIVITY_ID).append("=? ");
String sql = sb.toString();
int i = 0;
ResultSet rs = null;
try (
Connection connection = sqliteConnectionFactory.createConnection(); PreparedStatement stmt = connection.prepareStatement(sql);) {
stmt.setString(++i, id);
rs = stmt.executeQuery();
while (rs.next()) {
result.add(extractActivityFromResultSet(rs));
}
} catch (SQLException | ClassNotFoundException e) {
System.out.println(e.getMessage());
throw new RuntimeException(e);
} finally {
try {
if (rs != null) {
rs.close();
}
} catch (SQLException ex) {
System.out.println(ex.getMessage());
throw new RuntimeException(ex);
}
}
if(result.isEmpty()) {
public Activity getFromClipboard() {
if(this.activityInClipboard == null) {
return null;
}
if(result.size() == 1) {
result.get(0);
Activity a = new Activity(
null,
2000, 1,1,
activityInClipboard.getName(),
activityInClipboard.getComment(),
activityInClipboard.getTicket(),
0,0, "", 1);
return activityInClipboard;
}
@Override
public int getLargestSortkey(int year, int month, int day) {
OptionalInt optional =
list(year, month, day).stream().map(Activity::getSortkey)
.mapToInt(e -> e).max();
if (optional.isPresent()) {
System.out.println("getLargestSortkey=" +optional.getAsInt());
return optional.getAsInt();
} else {
return 1;
}
throw new TimeCalcException("Fatal error: More than one activity, which is previous for this activity id:" + id);
}
}

View File

@ -37,7 +37,7 @@ class ActivityTable {
public static final String SPENT_HOURS = "SPENT_HOURS";
public static final String SPENT_MINUTES = "SPENT_MINUTES";
public static final String FLAGS = "FLAGS";
public static final String NEXT_ACTIVITY_ID = "NEXT_ACTIVITY_ID";
public static final String SORTKEY = "SORTKEY";
private ActivityTable() {
//Not meant to be instantiated.

View File

@ -5,6 +5,7 @@ import java.util.List;
import java.util.Map;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
@ -41,7 +42,6 @@ public class ActivitiesWindow extends TWindow {
List<String> yearsList = activityRepository.getYears();
TTabbedPane tp = new TTabbedPane();
JButton addYearButton = new JButton("Add year");
addYearButton.setBounds(SwingUtils.MARGIN, SwingUtils.MARGIN, 150, 30);
add(addYearButton);

View File

@ -1,17 +1,11 @@
package org.nanoboot.utils.timecalc.swing.common;
import org.nanoboot.utils.timecalc.entity.Activity;
import org.nanoboot.utils.timecalc.persistence.api.ActivityRepositoryApi;
import javax.swing.BorderFactory;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
/**
* @author Robert
@ -19,6 +13,14 @@ import java.awt.event.MouseListener;
*/
public class ActivityHeader extends JPanel {
private static final Font FONT = new Font("sans", Font.BOLD, 12);
public static final Dimension PREFERRED_SIZE = new Dimension(200, 40);
public static final Dimension PREFERRED_SIZE1 = new Dimension(80, 40);
public static final Dimension PREFERRED_SIZE3 = new Dimension(60, 40);
public static final Dimension PREFERRED_SIZE4 = new Dimension(40, 40);
public static final Dimension PREFERRED_SIZE2 = new Dimension(100, 40);
private TTextField sortkey = new TTextField("Sortkey");
private TTextField name = new TTextField("Name");
private TTextField comment = new TTextField("Comment");
private TTextField ticket = new TTextField("Ticket");
@ -27,12 +29,13 @@ public class ActivityHeader extends JPanel {
private TTextField flags = new TTextField("Flags");
private TTextField subject = new TTextField("Subject");
private TTextField totalComment = new TTextField("Total comment");
private TTextField today = new TTextField("Today");
private TTextField remains = new TTextField("Remains");
private TTextField done = new TTextField("Done");
private TTextField todo = new TTextField("Todo");
public ActivityHeader() {
this.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
add(sortkey);
add(name);
add(comment);
add(ticket);
@ -41,20 +44,22 @@ public class ActivityHeader extends JPanel {
add(flags);
add(subject);
add(totalComment);
add(today);
add(remains);
add(done);
add(todo);
name.setPreferredSize(new Dimension(200, 40));
comment.setPreferredSize(new Dimension(200, 40));
ticket.setPreferredSize(new Dimension(80, 40));
spentTime.setPreferredSize(new Dimension(80, 40));
sortkey.setPreferredSize(PREFERRED_SIZE1);
name.setPreferredSize(PREFERRED_SIZE);
comment.setPreferredSize(PREFERRED_SIZE);
ticket.setPreferredSize(PREFERRED_SIZE1);
spentTime.setPreferredSize(PREFERRED_SIZE1);
flags.setPreferredSize(new Dimension(100, 40));
subject.setPreferredSize(new Dimension(100, 40));
totalComment.setPreferredSize(new Dimension(100, 40));
today.setPreferredSize(new Dimension(80, 40));
remains.setPreferredSize(new Dimension(80, 40));
flags.setPreferredSize(PREFERRED_SIZE2);
subject.setPreferredSize(PREFERRED_SIZE2);
totalComment.setPreferredSize(PREFERRED_SIZE2);
done.setPreferredSize(PREFERRED_SIZE3);
todo.setPreferredSize(PREFERRED_SIZE3);
sortkey.setEditable(false);
name.setEditable(false);
comment.setEditable(false);
ticket.setEditable(false);
@ -63,9 +68,10 @@ public class ActivityHeader extends JPanel {
flags.setEditable(false);
subject.setEditable(false);
totalComment.setEditable(false);
today.setEditable(false);
remains.setEditable(false);
done.setEditable(false);
todo.setEditable(false);
sortkey.setFont(FONT);
name.setFont(FONT);
comment.setFont(FONT);
ticket.setFont(FONT);
@ -74,9 +80,10 @@ public class ActivityHeader extends JPanel {
flags.setFont(FONT);
subject.setFont(FONT);
totalComment.setFont(FONT);
today.setFont(FONT);
remains.setFont(FONT);
done.setFont(FONT);
todo.setFont(FONT);
sortkey.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
name.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
comment.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
ticket.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
@ -85,8 +92,8 @@ public class ActivityHeader extends JPanel {
flags.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
subject.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
totalComment.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
today.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
remains.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
done.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
todo.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
//this.setBorder(BorderFactory.createLineBorder(Color.ORANGE, 1));
setAlignmentX(LEFT_ALIGNMENT);

View File

@ -1,25 +1,37 @@
package org.nanoboot.utils.timecalc.swing.common;
import lombok.Getter;
import org.nanoboot.utils.timecalc.entity.Activity;
import org.nanoboot.utils.timecalc.persistence.api.ActivityRepositoryApi;
import org.nanoboot.utils.timecalc.utils.common.TTime;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
/**
* @author Robert
* @since 13.03.2024
*/
public class ActivityPanel extends JPanel {
public class ActivityPanel extends JPanel implements Comparable<ActivityPanel> {
public static final Dimension PREFERRED_SIZE = new Dimension(200, 40);
public static final Dimension PREFERRED_SIZE1 = new Dimension(80, 40);
public static final Dimension PREFERRED_SIZE3 = new Dimension(60, 40);
public static final Dimension PREFERRED_SIZE4 = new Dimension(40, 40);
public static final Dimension PREFERRED_SIZE2 = new Dimension(100, 40);
private final ActivityRepositoryApi activityRepository;
@Getter
private final Activity activity;
private TTextField sortkey = new TTextField("1");
private TTextField name = new TTextField("");
private TTextField comment = new TTextField("");
private TTextField ticket = new TTextField("");
@ -28,14 +40,17 @@ public class ActivityPanel extends JPanel {
private TTextField flags = new TTextField("Flags");
private TTextField subject = new TTextField("");
private TTextField totalComment = new TTextField("");
private TTextField today = new TTextField("00:00");
private TTextField remains = new TTextField("00:00");
public TTextField today = new TTextField("00:00");
public TTextField remains = new TTextField("00:00");
@Getter
private boolean deleted;
public ActivityPanel(ActivityRepositoryApi activityRepository,
Activity activity) {
Activity activity, DayPanel dayPanel) {
this.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
this.activity = activity;
add(sortkey);
add(name);
add(comment);
add(ticket);
@ -47,19 +62,46 @@ public class ActivityPanel extends JPanel {
add(today);
add(remains);
name.setPreferredSize(new Dimension(200, 40));
comment.setPreferredSize(new Dimension(200, 40));
ticket.setPreferredSize(new Dimension(80, 40));
spentTime.setPreferredSize(new Dimension(80, 40));
// JButton moveThisButton = new SmallTButton("Move ");
// JButton moveBeforeButton = new SmallTButton("Here");
JButton copyButton = new SmallTButton("Copy");
JButton deleteButton = new SmallTButton("Delete");
JButton subjectButton = new SmallTButton("Sub");
JButton totalCommentButton = new SmallTButton("TotCom");
// add(moveThisButton);
// add(moveBeforeButton);
add(copyButton);
add(deleteButton);
add(subjectButton);
add(totalCommentButton);
// moveThisButton.setFont(SwingUtils.SMALL_FONT);
// moveBeforeButton.setFont(SwingUtils.SMALL_FONT);
copyButton.setFont(SwingUtils.SMALL_FONT);
deleteButton.setFont(SwingUtils.SMALL_FONT);
subjectButton.setFont(SwingUtils.SMALL_FONT);
totalCommentButton.setFont(SwingUtils.SMALL_FONT);
flags.setPreferredSize(new Dimension(100, 40));
subject.setPreferredSize(new Dimension(100, 40));
totalComment.setPreferredSize(new Dimension(100, 40));
today.setPreferredSize(new Dimension(80, 40));
remains.setPreferredSize(new Dimension(80, 40));
sortkey.setPreferredSize(PREFERRED_SIZE1);
name.setPreferredSize(PREFERRED_SIZE);
comment.setPreferredSize(PREFERRED_SIZE);
ticket.setPreferredSize(PREFERRED_SIZE1);
spentTime.setPreferredSize(PREFERRED_SIZE1);
flags.setPreferredSize(PREFERRED_SIZE2);
subject.setPreferredSize(PREFERRED_SIZE2);
totalComment.setPreferredSize(PREFERRED_SIZE2);
today.setPreferredSize(PREFERRED_SIZE3);
remains.setPreferredSize(PREFERRED_SIZE3);
// moveThisButton.setPreferredSize(PREFERRED_SIZE4);
// moveBeforeButton.setPreferredSize(PREFERRED_SIZE4);
copyButton.setPreferredSize(PREFERRED_SIZE4);
deleteButton.setPreferredSize(PREFERRED_SIZE4);
subjectButton.setPreferredSize(PREFERRED_SIZE4);
totalCommentButton.setPreferredSize(PREFERRED_SIZE3);
this.setPreferredSize(new Dimension(getWidth(), 40));
sortkey.setEditable(false);
name.setEditable(false);
comment.setEditable(false);
ticket.setEditable(false);
@ -71,6 +113,7 @@ public class ActivityPanel extends JPanel {
today.setEditable(false);
remains.setEditable(false);
sortkey.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
name.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
comment.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
ticket.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
@ -82,55 +125,153 @@ public class ActivityPanel extends JPanel {
today.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
remains.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
name.addMouseListener(new MouseListener() {
@Override
public void mouseClicked(MouseEvent e) {
String result = (String) JOptionPane.showInputDialog(
null,
"Select new name",
"New name",
JOptionPane.PLAIN_MESSAGE,
null,
null,
name.getText()
);
if (result != null) {
activity.setName(result);
activityRepository.update(activity);
name.setText(result);
}
sortkey.addMouseListener((MouseClickedListener) e -> {
String result = (String) JOptionPane.showInputDialog(
null,
"Select new sortkey",
"New sortkey",
JOptionPane.PLAIN_MESSAGE,
null,
null,
sortkey.getText()
);
if (result != null) {
activity.setSortkey(Integer.valueOf(result));
activityRepository.update(activity);
sortkey.setText(result);
dayPanel.sortActivityPanels();
}
});
@Override
public void mousePressed(MouseEvent e) {
name.addMouseListener((MouseClickedListener) e -> {
String result = (String) JOptionPane.showInputDialog(
null,
"Select new name",
"New name",
JOptionPane.PLAIN_MESSAGE,
null,
null,
name.getText()
);
if (result != null) {
activity.setName(result);
activityRepository.update(activity);
name.setText(result);
subject.setText(activity.createSubject());
}
@Override
public void mouseReleased(MouseEvent e) {
});
comment.addMouseListener((MouseClickedListener) e -> {
String result = (String) JOptionPane.showInputDialog(
null,
"Select new comment",
"New comment",
JOptionPane.PLAIN_MESSAGE,
null,
null,
comment.getText()
);
if (result != null) {
activity.setComment(result);
activityRepository.update(activity);
comment.setText(result);
totalComment.setText(activity.createTotalComment());
}
@Override
public void mouseEntered(MouseEvent e) {
});
ticket.addMouseListener((MouseClickedListener) e -> {
String result = (String) JOptionPane.showInputDialog(
null,
"Select new ticket",
"New ticket",
JOptionPane.PLAIN_MESSAGE,
null,
null,
ticket.getText()
);
if (result != null) {
activity.setTicket(result);
activityRepository.update(activity);
ticket.setText(result);
subject.setText(activity.createSubject());
totalComment.setText(activity.createTotalComment());
}
});
spentTime.addMouseListener((MouseClickedListener) e -> {
String result = (String) JOptionPane.showInputDialog(
null,
"Select new spent time",
"New spent time",
JOptionPane.PLAIN_MESSAGE,
null,
null,
spentTime.getText()
);
if (result != null) {
TTime spentTimeTTime = new TTime(result);
activity.setSpentHours(spentTimeTTime.getHour());
activity.setSpentMinutes(spentTimeTTime.getMinute());
activityRepository.update(activity);
spentTime.setText(result);
totalComment.setText(activity.createTotalComment());
dayPanel.sortActivityPanels();
}
});
@Override
public void mouseExited(MouseEvent e) {
flags.addMouseListener((MouseClickedListener) e -> {
String result = (String) JOptionPane.showInputDialog(
null,
"Select new flags",
"New flags",
JOptionPane.PLAIN_MESSAGE,
null,
null,
flags.getText()
);
if (result != null) {
activity.setFlags(result);
activityRepository.update(activity);
flags.setText(result);
}
});
name.setText(activity.getName());
comment.setText(activity.getComment());
ticket.setText(activity.getTicket());
spentTime.setText((activity.getSpentHours() < 10 ? "0" : "") + activity
.getSpentHours() + ":" + (activity.getSpentMinutes() < 10 ? "0" :
"") + activity.getSpentMinutes());
spentTime.setText(activity.getSpentTimeAsString());
flags.setText(activity.getFlags());
subject.setText(activity.createSubject());
totalComment.setText(activity.createTotalComment());
sortkey.setText(String.valueOf(activity.getSortkey()));
this.activityRepository = activityRepository;
//this.setBorder(BorderFactory.createLineBorder(Color.ORANGE, 1));
setAlignmentX(LEFT_ALIGNMENT);
// moveThisButton.addActionListener(e-> {
// //dayPanel.switchPositionsForThisActivityAndThePreviousActivity(getActivity());
// //dayPanel.markActivityAsToBeMoved(getActivity());
// });
//
// moveBeforeButton.addActionListener(e-> {
// //dayPanel.moveMarkedActivityBeforeThisActivity(getActivity());
// });
deleteButton.addActionListener(e -> {
activityRepository.delete(this.activity.getId());
deleted = true;
});
copyButton.addActionListener(e -> {
activityRepository.putToClipboard(this.activity);
});
subjectButton.addActionListener(e-> {
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(new StringSelection(subject.getText()), null);
});
totalCommentButton.addActionListener(e-> {
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(new StringSelection(totalComment.getText()), null);
});
dayPanel.sortActivityPanels();
}
@Override
public int compareTo(ActivityPanel o) {
return this.getActivity().compareTo(o.getActivity());
}
}

View File

@ -2,15 +2,30 @@ package org.nanoboot.utils.timecalc.swing.common;
import org.nanoboot.utils.timecalc.entity.Activity;
import org.nanoboot.utils.timecalc.persistence.api.ActivityRepositoryApi;
import org.nanoboot.utils.timecalc.utils.common.NumberFormats;
import org.nanoboot.utils.timecalc.utils.common.TTime;
import org.nanoboot.utils.timecalc.utils.common.Utils;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.Timer;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.stream.Collectors;
/**
* @author robertvokac
@ -24,6 +39,8 @@ public class DayPanel extends JPanel {
private final Map<String, DayPanel> map = new HashMap<>();
private final ActivityRepositoryApi activityRepository;
private JButton loadButton;
private JScrollPane scrollPane;
private JPanel panelInsideScrollPane;
public DayPanel(String yearIn, String monthIn, String dayIn,
ActivityRepositoryApi activityRepository) {
@ -33,7 +50,7 @@ public class DayPanel extends JPanel {
this.month = monthIn;
this.day = dayIn;
this.activityRepository = activityRepository;
setSize(1350, 600);
setSize(1450, 600);
this.setLayout(null);
this.loadButton = new JButton("Load");
@ -67,12 +84,25 @@ public class DayPanel extends JPanel {
buttons.setAlignmentX(LEFT_ALIGNMENT);
JButton newButton = new JButton("New");
JButton pasteButton = new JButton("Paste");
JButton reviewButton = new JButton("Review");;
buttons.add(newButton);
buttons.add(pasteButton);
buttons.add(reviewButton);
add(buttons);
this.scrollPane
= new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
add(scrollPane);
this.panelInsideScrollPane = new JPanel();
panelInsideScrollPane.setLayout(new BoxLayout(panelInsideScrollPane, BoxLayout.Y_AXIS));
scrollPane.setViewportView(panelInsideScrollPane);
ActivityHeader activityHeader = new ActivityHeader();
add(activityHeader);
panelInsideScrollPane.add(activityHeader);
activityHeader.setMaximumSize(new Dimension(1200, 40));
buttons.setMaximumSize(new Dimension(1000, 40));
for (Activity a : activityRepository.list(
Integer.valueOf(year),
@ -80,26 +110,118 @@ public class DayPanel extends JPanel {
Integer.valueOf(day))) {
ActivityPanel comp =
new ActivityPanel(activityRepository, a);
comp.setMaximumSize(new Dimension(1200, 40));
add(comp);
new ActivityPanel(activityRepository, a, this);
comp.setMaximumSize(new Dimension(1300, 40));
panelInsideScrollPane.add(comp);
}
new Timer(100, e -> {
List<Component>
list = Arrays.stream(panelInsideScrollPane.getComponents()).filter(c-> c instanceof ActivityPanel).filter(c-> ((ActivityPanel)c).isDeleted()).collect(
Collectors.toList());
if(!list.isEmpty()) {
list.forEach(c->panelInsideScrollPane.remove(c));
}
revalidate();
}).start();
revalidate();
newButton.addActionListener(e-> {
Activity newActivity = new Activity(UUID.randomUUID().toString(), Integer.valueOf(year), Integer.valueOf(month), Integer.valueOf(day), "", "", "", 0, 0, "", null);
Activity newActivity = new Activity(UUID.randomUUID().toString(), Integer.valueOf(year), Integer.valueOf(month), Integer.valueOf(day), "", "", "", 0, 0, "", 1 + activityRepository.getLargestSortkey(Integer.valueOf(year), Integer.valueOf(month), Integer.valueOf(day)));
ActivityPanel comp =
new ActivityPanel(activityRepository, newActivity);
new ActivityPanel(activityRepository, newActivity, this);
comp.setMaximumSize(new Dimension(1200, 40));
add(comp);
activityRepository.create(newActivity);
panelInsideScrollPane.add(comp);
revalidate();
});
// for (int i = 0; i < 10; i++) {
// add(new ActivityPanel(activityRepository,
// new Activity("id", 2000, 7, 7, "name", "comment", "ticket", 2, 30,
// "a b c", null)));
// }
pasteButton.addActionListener(e-> {
Activity afc = activityRepository.getFromClipboard();
if(afc == null) {
Utils.showNotification("There is no activity in clipboard. Nothing to do.");
return;
}
Activity newActivity = new Activity(UUID.randomUUID().toString(), Integer.valueOf(year), Integer.valueOf(month), Integer.valueOf(day),
afc.getName(), afc.getComment(), afc.getTicket(), 0, 0, "", 1 + activityRepository.getLargestSortkey(Integer.valueOf(year), Integer.valueOf(month), Integer.valueOf(day)));
ActivityPanel comp =
new ActivityPanel(activityRepository, newActivity, this);
comp.setMaximumSize(new Dimension(1200, 40));
add(comp);
activityRepository.create(newActivity);
panelInsideScrollPane.add(comp);
revalidate();
});
reviewButton.addActionListener(e->{
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(new StringSelection(Arrays
.stream(panelInsideScrollPane.getComponents())
.filter(c-> c instanceof ActivityPanel)
.map(ap->((ActivityPanel) ap).getActivity())
.map(a->a.createTotalComment())
.collect(
Collectors.joining("\n"))), null);
});
// for (int i = 0; i < 10; i++) {
// add(new ActivityPanel(activityRepository,
// new Activity("id", 2000, 7, 7, "name", "comment", "ticket", 2, 30,
// "a b c", null)));
// }
}
public List<Activity> getActivities() {
return Arrays
.stream(panelInsideScrollPane.getComponents())
.filter(c-> c instanceof ActivityPanel)
.map(ap->((ActivityPanel) ap).getActivity()).collect(Collectors.toList());
}
public int getIndexForActivityPanel(Activity a) {
for(int i = 0;i<panelInsideScrollPane.getComponentCount();i++) {
Component c = panelInsideScrollPane.getComponent(i);
if(c instanceof ActivityPanel) {
if(((ActivityPanel)c).getActivity().equals(a)) {
return i;
}
}
}
return -1;
}
public ActivityPanel getActivityPanelForActivity(Activity a) {
Optional<Component> optional = Arrays
.stream(panelInsideScrollPane.getComponents())
.filter(c-> c instanceof ActivityPanel)
.filter(c-> ((ActivityPanel) c).getActivity().equals(a))
.findFirst();
if(optional.isPresent()) {
return (ActivityPanel) optional.get();
} else {
return null;
}
}
public void sortActivityPanels() {
List<ActivityPanel> list = new ArrayList<>();
Arrays
.stream(panelInsideScrollPane.getComponents())
.filter(c-> c instanceof ActivityPanel).forEach(e-> list.add((ActivityPanel) e));
Collections.sort(list);
for(ActivityPanel ap:list) {
panelInsideScrollPane.remove(ap);
}
double done = 0d;
double todo = 8d;
for(ActivityPanel ap:list) {
panelInsideScrollPane.add(ap);
double now = ap.getActivity().getSpentHours() + ap.getActivity().getSpentMinutes() / 60d;
done = done + now;
todo = todo - now;
ap.today.setText(TTime.ofMilliseconds((int)(done * 60d * 60d * 1000d)).toString().substring(0,5));
ap.remains.setText(TTime.ofMilliseconds((int)(todo * 60d * 60d * 1000d)).toString().substring(0,5));
}
revalidate();
}
}

View File

@ -32,7 +32,7 @@ public class MonthPanel extends JPanel {
setLayout(null);
this.tp = new TTabbedPane();
add(tp);
tp.setBounds(0, 0, 1350, 650);
tp.setBounds(0, 0, 1450, 650);
ChangeListener changeListener = new ChangeListener() {
private boolean secondOrLaterChange = false;

View File

@ -0,0 +1,31 @@
package org.nanoboot.utils.timecalc.swing.common;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
/**
* @author Robert
* @since 14.03.2024
*/
public interface MouseClickedListener extends MouseListener {
@Override
default void mousePressed(MouseEvent e) {
}
@Override
default void mouseReleased(MouseEvent e) {
}
@Override
default void mouseEntered(MouseEvent e) {
}
@Override
default void mouseExited(MouseEvent e) {
}
}

View File

@ -10,9 +10,13 @@ public class SmallTButton extends TButton {
private static final Insets INSETS = new Insets(1, 1, 1, 1);
public SmallTButton(char character) {
super(String.valueOf(character), 15, 15);
public SmallTButton(String s) {
super(s, 15, 15);
//setFont(SwingUtils.SMALL_FONT);
setMargin(INSETS);
}
public SmallTButton(char character) {
this(String.valueOf(character));
}
}

View File

@ -26,7 +26,7 @@ public class YearPanel extends JPanel {
setLayout(null);
this.tp = new TTabbedPane();
add(tp);
tp.setBounds(0, 0, 1350, 700);
tp.setBounds(0, 0, 1450, 700);
ChangeListener changeListener = new ChangeListener() {
private boolean secondOrLaterChange = false;

View File

@ -0,0 +1 @@
ALTER TABLE "ACTIVITY" DROP COLUMN "NEXT_ACTIVITY_ID";

View File

@ -0,0 +1 @@
ALTER TABLE "ACTIVITY" ADD COLUMN "SORTKEY" NUMBER DEFAULT 1;