package jp.ymir.taskReporter.core
-import java.util.Calendar
import java.text.SimpleDateFormat
+import java.util.Calendar
+import java.util.GregorianCalendar
+import javax.swing.table.AbstractTableModel
import scala.collection.immutable._
-class Report(private val _date: Calendar) {
+class Report(private val _date: Calendar) extends AbstractTableModel {
private var _tasks : Seq[Task] = Vector()
+ def this() = this(new GregorianCalendar())
+
def date : Calendar = _date
def size : Int = _tasks.size
_tasks = _tasks :+ task
}
- def dateString : String = {
+ def dateString : String = dateString(_date)
+ def dateString(date: Calendar) : String = {
val fmt = new SimpleDateFormat("yyyy-MM-dd")
- fmt.format(_date.getTime)
+ fmt.format(date.getTime)
+ }
+
+ /* Method definitions for AbstractTableModel
+ */
+ def getColumnCount = 6
+ def getRowCount = _tasks.size
+
+ override def getColumnName(column: Int) : String = {
+ column match {
+ case 0 => "チケットID"
+ case 1 => "作業名"
+ case 2 => "仮期限"
+ case 3 => "期限"
+ case 4 => "状態"
+ case 5 => "補足"
+ }
+ }
+
+ def getValueAt(row: Int, column: Int) : Object = {
+ val task = _tasks(row)
+ column match {
+ case 0 => task.ticketID : Integer
+ case 1 => task.title
+ case 2 => task.tentativeDeadline.map(dateString).getOrElse("")
+ case 3 => task.deadline .map(dateString).getOrElse("")
+ case 4 => task.status
+ case 5 => task.supplement
+ }
}
}
package jp.ymir.taskReporter.core
import java.io._
+import java.text.SimpleDateFormat
import java.util.Calendar
import javax.swing.table.AbstractTableModel
import jp.ymir.taskReporter.core._
case object DoingFine extends Status
case object Lagging extends Status
case object WillDelay extends Status
- case object DeadlinePostponed extends Status
+ case object DeadlineChanged extends Status
case object Completed extends Status
}
throw new InvalidNumberOfColumnsException(tsvLine)
}
- val date : Calendar = {
+ var date : Calendar = {
val pattern = """^(?:報告日:)?(\d{4})/(\d{2})/(\d{2})$""".r
cols(0) match {
case pattern(year, month, day) =>
}
}
- val ticketID : Int = {
+ var ticketID : Int = {
val pattern = """^(?:チケットID:)?(\d+)$""".r
cols(1) match {
case pattern(id) => id.toInt
}
}
- val title : String = {
+ var title : String = {
val pattern = """^(?:作業名:)?(.*)$""".r
- cols(1) match {
+ cols(2) match {
+ case pattern(title) => title
+ }
+ }
+
+ var tentativeDeadline : Option[Calendar] = {
+ val pattern = """^(?:仮期限:)?(\d{4})/(\d{2})/(\d{2})$""".r
+ cols(3) match {
+ case pattern(year, month, day) =>
+ Some(new GregorianCalendar(year.toInt, month.toInt, day.toInt))
+ case _ =>
+ None
+ }
+ }
+
+ var deadline : Option[Calendar] = {
+ val pattern = """^(?:期限:)?(\d{4})/(\d{2})/(\d{2})$""".r
+ cols(4) match {
+ case pattern(year, month, day) =>
+ Some(new GregorianCalendar(year.toInt, month.toInt, day.toInt))
+ case _ =>
+ None
+ }
+ }
+
+ var status : Status = {
+ val pattern = """^(?:状態:)?(.+)$""".r
+ cols(5) match {
+ case pattern(s) =>
+ s match {
+ case "未作業" => Status.NoProgress
+ case "順調" => Status.DoingFine
+ case "悪化" => Status.Lagging
+ case "遅延" => Status.WillDelay
+ case "期限変更" => Status.DeadlineChanged
+ case "完了" => Status.Completed
+ }
+ }
+ }
+
+ var supplement : String = {
+ val pattern = """^(?:補足:)?(.*)$""".r
+ cols(6) match {
case pattern(title) => title
}
}
if (r == FileChooser.Result.Approve) {
Preferences.lastChosenDir() = chooser.selectedFile.getParentFile
reportSet.load(chooser.selectedFile)
+ // FIXME: select the last report
}
}
})
}
}
- val rootSplit = new SplitPane {
+ contents = new SplitPane {
peer.setOrientation(JSplitPane.HORIZONTAL_SPLIT)
continuousLayout = true
oneTouchExpandable = true
- resizeWeight = 0.3
+ resizeWeight = 0 // Let the left pane be fixed
+
+ rightComponent = new SplitPane {
+ peer.setOrientation(JSplitPane.VERTICAL_SPLIT)
+ continuousLayout = true
+ oneTouchExpandable = true
+ resizeWeight = 0.5
+
+ leftComponent = new ScrollPane(
+ new Table() {
+ peer.setModel(new Report()) // Empty report
+ })
+ }
leftComponent = new BorderPanel {
border = BorderFactory.createEmptyBorder(5, 5, 5, 5)
- val scroll = new ScrollPane(
+ val reportsScroll = new ScrollPane(
new Table() {
peer.setModel(reportSet)
+ if (rowCount > 0) {
+ selection.rows += rowCount - 1 // Select the last report
+ }
+ selection.reactions += {
+ case TableRowsSelected(_, _, false) =>
+ // FIXME
+ }
})
- layout(scroll) = BorderPanel.Position.Center
+ layout(reportsScroll) = BorderPanel.Position.Center
+
+ val buttons = new FlowPanel(FlowPanel.Alignment.Left)() {
+ contents += new Button(new Action("Add") {
+ def apply = {} // FIXME
+ })
+ contents += new Button(new Action("Delete...") {
+ def apply = {} // FIXME
+ })
+ }
+ layout(buttons) = BorderPanel.Position.South
+
+ preferredSize = minimumSize
}
}
- contents = rootSplit
-
- // This can only be done after putting the pane on the frame.
- rootSplit.dividerLocation = 0.3
centerOnScreen
visible = true