From 98a5e495638e1ef4c5826e2a67bbd7a93fb8d296 Mon Sep 17 00:00:00 2001 From: PHO Date: Fri, 26 Dec 2014 18:35:11 +0900 Subject: [PATCH] wip --- .../jp/ymir/taskReporter/core/Task.scala | 17 +++ .../taskReporter/ui/CalendarChooser.scala | 16 +++ .../jp/ymir/taskReporter/ui/DateChooser.scala | 37 ++++++ .../jp/ymir/taskReporter/ui/MainFrame.scala | 12 +- .../jp/ymir/taskReporter/ui/TaskEditor.scala | 115 ++++++++++-------- 5 files changed, 141 insertions(+), 56 deletions(-) create mode 100644 src/main/scala/jp/ymir/taskReporter/ui/CalendarChooser.scala create mode 100644 src/main/scala/jp/ymir/taskReporter/ui/DateChooser.scala diff --git a/src/main/scala/jp/ymir/taskReporter/core/Task.scala b/src/main/scala/jp/ymir/taskReporter/core/Task.scala index c87dc21..2f05f41 100644 --- a/src/main/scala/jp/ymir/taskReporter/core/Task.scala +++ b/src/main/scala/jp/ymir/taskReporter/core/Task.scala @@ -19,6 +19,23 @@ case class Task( object Task { import TSV._ + def endOfCurrentHalf: Calendar = { + val cal = new GregorianCalendar() + cal.set(Calendar.MONTH, ((cal.get(Calendar.MONTH) + 1 + 5) / 6) * 6 - 1) + cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH)) + return cal + } + + def apply(): Task = Task( + date = new GregorianCalendar(), + ticketID = None, + title = "", + expectedCompletionDate = endOfCurrentHalf, + deadline = None, + status = Status.DoingFine, + description = None + ) + sealed abstract class Status object Status { case object DoingFine extends Status { override def toString() = "順調"} diff --git a/src/main/scala/jp/ymir/taskReporter/ui/CalendarChooser.scala b/src/main/scala/jp/ymir/taskReporter/ui/CalendarChooser.scala new file mode 100644 index 0000000..c1cc77d --- /dev/null +++ b/src/main/scala/jp/ymir/taskReporter/ui/CalendarChooser.scala @@ -0,0 +1,16 @@ +package jp.ymir.taskReporter.ui +import com.toedter.calendar._ +import scala.swing._ + +class CalendarChooser(_peer: JCalendar) extends Component { + override lazy val peer = _peer + + def nullDateButtonVisible: Boolean = peer.isNullDateButtonVisible + def nullDateButtonVisible_=(b: Boolean) = peer.setNullDateButtonVisible(b) + + def todayButtonVisible: Boolean = peer.isTodayButtonVisible + def todayButtonVisible_=(b: Boolean) = peer.setTodayButtonVisible(b) + + def weekOfYearVisible: Boolean = peer.isWeekOfYearVisible + def weekOfYearVisible_=(b: Boolean) = peer.setWeekOfYearVisible(b) +} diff --git a/src/main/scala/jp/ymir/taskReporter/ui/DateChooser.scala b/src/main/scala/jp/ymir/taskReporter/ui/DateChooser.scala new file mode 100644 index 0000000..0bc7c75 --- /dev/null +++ b/src/main/scala/jp/ymir/taskReporter/ui/DateChooser.scala @@ -0,0 +1,37 @@ +package jp.ymir.taskReporter.ui +import com.toedter.calendar._ +import java.beans.PropertyChangeEvent +import java.beans.PropertyChangeListener +import java.util.Calendar +import java.util.Date +import scala.swing._ +import scala.swing.event._ + +class DateChooser extends Component { + override lazy val peer = new JDateChooser() + + case class DateChanged(from: Option[Date], to: Option[Date]) extends Event + + peer.addPropertyChangeListener("date", new PropertyChangeListener { + def propertyChange(e: PropertyChangeEvent) { + if (e.getPropertyName == "date") { + publish( + DateChanged( + from = Option(e.getOldValue.asInstanceOf[Date]), + to = Option(e.getNewValue.asInstanceOf[Date]))) + } + } + }) + + def calendar: Option[Calendar] = peer.getCalendar match { + case null => None + case cal => Some(cal) + } + def calendar_=(cal: Option[Calendar]) + = peer.setCalendar(cal.getOrElse(null)) + + def calendarChooser: CalendarChooser = new CalendarChooser(peer.getJCalendar) + + def dateFormatString: String = peer.getDateFormatString + def dateFormatString_=(fmt: String) = peer.setDateFormatString(fmt) +} diff --git a/src/main/scala/jp/ymir/taskReporter/ui/MainFrame.scala b/src/main/scala/jp/ymir/taskReporter/ui/MainFrame.scala index a09aa5d..3878d21 100644 --- a/src/main/scala/jp/ymir/taskReporter/ui/MainFrame.scala +++ b/src/main/scala/jp/ymir/taskReporter/ui/MainFrame.scala @@ -126,11 +126,13 @@ class MainFrame(reportFile: Option[File]) extends Frame { } }) contents += VStrut(5) - contents += new Separator(Orientation.Horizontal) - contents += VStrut(5) - contents += new TaskEditor - contents += VStrut(5) - contents += new Separator(Orientation.Horizontal) + contents += new TaskEditor { + listenTo(frame) + reactions += { + case TaskSelected(t) => task = t + case TaskDeselected() => task = Task() + } + } contents += VStrut(5) contents += new FlowPanel(FlowPanel.Alignment.Left)() { contents += new Button(new Action("New") { diff --git a/src/main/scala/jp/ymir/taskReporter/ui/TaskEditor.scala b/src/main/scala/jp/ymir/taskReporter/ui/TaskEditor.scala index c0761df..84a929e 100644 --- a/src/main/scala/jp/ymir/taskReporter/ui/TaskEditor.scala +++ b/src/main/scala/jp/ymir/taskReporter/ui/TaskEditor.scala @@ -1,115 +1,128 @@ package jp.ymir.taskReporter.ui -import com.toedter.calendar._ import java.awt.Insets +import java.util.Calendar import jp.ymir.taskReporter.core._ +import scala.collection.immutable._ import scala.swing._ +import scala.swing.event._ class TaskEditor extends GridBagPanel { - import GridBagPanel.Anchor._ - import GridBagPanel.Fill._ + import GridBagPanel._ + + case class TaskUpdated(t: Task) extends Event + + def task: (Calendar => Task) = d => Task( + date = d, + ticketID = noneIfEmpty(ticketID.text).map(_.toInt), + title = title.text, + expectedCompletionDate = expectedCompletionDate.calendar.getOrElse(Task.endOfCurrentHalf), + deadline = deadline.calendar, + status = status.selection.item, + description = noneIfEmpty(description.text) + ) + + def task_=(t: Task) = { + ticketID.text = t.ticketID.fold("")(_.toString) + title.text = t.title + expectedCompletionDate.calendar = Some(t.expectedCompletionDate) + deadline.calendar = t.deadline + status.selection.item = t.status + description.text = t.description.getOrElse("") + } private val commonInsets = new Insets(2, 3, 2, 3) - val date = Component.wrap(new JDateChooser() { - setDateFormatString("yyyy-MM-dd") - getJCalendar().setTodayButtonVisible(true) - getJCalendar().setWeekOfYearVisible(false) - }) - add( - new Label("報告日"), - new Constraints { gridx = 0; gridy = 0 }) - add( - date, - new Constraints() { - gridx = 1; gridy = 0; anchor = West - ipadx = 3; ipady = 3; insets = commonInsets - }) - date.minimumSize = date.preferredSize + private def noneIfEmpty[T <% StringLike[_]](str: T): Option[T] = str match { + case "" => None + case _ => Some(str) + } - val ticketID = new TextField(6) { - val isDigit = (c : Char) => c >= '0' && c <= '9' - inputVerifier = _ => wrapString(text).forall(isDigit) + private val ticketID = new TextField(6) { + def isDigit(c : Char) = c >= '0' && c <= '9' + inputVerifier = _ => wrapString(text).forall(isDigit) + horizontalAlignment = Alignment.Right peer.setMargin(commonInsets) } add( new Label("チケットID"), - new Constraints { gridx = 0; gridy = 1 }) + new Constraints { gridx = 0; gridy = 0 }) add( ticketID, new Constraints() { - gridx = 1; gridy = 1; anchor = West; insets = commonInsets + gridx = 1; gridy = 0; anchor = Anchor.West; insets = commonInsets }) ticketID.minimumSize = ticketID.preferredSize - val title = new TextField() { + private val title = new TextField() { peer.setMargin(commonInsets) } add( new Label("作業名"), - new Constraints { gridx = 0; gridy = 2 }) + new Constraints { gridx = 0; gridy = 1 }) add( title, new Constraints() { - gridx = 1; gridy = 2; fill = Horizontal; weightx = 1.0 + gridx = 1; gridy = 1; fill = Fill.Horizontal; weightx = 1.0 insets = commonInsets }) - val expectedCompletionDate = Component.wrap(new JDateChooser() { - setDateFormatString("yyyy-MM-dd") - getJCalendar().setTodayButtonVisible(true) - getJCalendar().setWeekOfYearVisible(false) - }) + private val expectedCompletionDate = new DateChooser { + dateFormatString = "yyyy-MM-dd" + calendarChooser.todayButtonVisible = true + calendarChooser.weekOfYearVisible = false + } add( new Label("作業完了予定年月日"), - new Constraints { gridx = 0; gridy = 3 }) + new Constraints { gridx = 0; gridy = 2 }) add( expectedCompletionDate, new Constraints() { - gridx = 1; gridy = 3; anchor = West - ipadx = 3; ipady = 3; insets = commonInsets + gridx = 1; gridy = 2; anchor = Anchor.West + ipadx = 3; ipady = 2; insets = commonInsets }) expectedCompletionDate.minimumSize = expectedCompletionDate.preferredSize - val deadline = Component.wrap(new JDateChooser() { - setDateFormatString("yyyy-MM-dd") - getJCalendar().setTodayButtonVisible(true) - getJCalendar().setNullDateButtonVisible(true) - getJCalendar().setWeekOfYearVisible(false) - }) + private val deadline = new DateChooser { + dateFormatString = "yyyy-MM-dd" + calendarChooser.nullDateButtonVisible = true + calendarChooser.todayButtonVisible = true + calendarChooser.weekOfYearVisible = false + } add( new Label("タスク期限"), - new Constraints { gridx = 0; gridy = 4 }) + new Constraints { gridx = 0; gridy = 3 }) add( deadline, new Constraints() { - gridx = 1; gridy = 4; anchor = West + gridx = 1; gridy = 3; anchor = Anchor.West ipadx = 3; ipady = 3; insets = commonInsets }) deadline.minimumSize = deadline.preferredSize - val status = new ComboBox[Task.Status](Task.Status.all) + private val status = new ComboBox[Task.Status](Task.Status.all) add( new Label("状態"), - new Constraints { gridx = 0; gridy = 5 }) + new Constraints { gridx = 0; gridy = 4 }) add( status, new Constraints { - gridx = 1; gridy = 5; anchor = West + gridx = 1; gridy = 4; anchor = Anchor.West ipadx = 3; ipady = 3; insets = commonInsets }) - val description = new ScrollPane(new TextArea() { + private val description = new TextArea() { rows = 5 peer.setMargin(commonInsets) - }) + } + private val scrollingDescription = new ScrollPane(description) add( new Label("説明"), - new Constraints { gridx = 0; gridy = 6 }) + new Constraints { gridx = 0; gridy = 5 }) add( - description, + scrollingDescription, new Constraints() { - gridx = 1; gridy = 6; fill = Horizontal; weightx = 1.0 + gridx = 1; gridy = 5; fill = Fill.Horizontal; weightx = 1.0 insets = commonInsets }) - description.minimumSize = description.preferredSize + scrollingDescription.minimumSize = scrollingDescription.preferredSize } -- 2.40.0