package jp.ymir.taskReporter.ui
import java.awt.Dimension
+import java.awt.event.ComponentAdapter
+import java.awt.event.ComponentEvent
import java.io._
import javax.swing.JOptionPane
+import javax.swing.JSplitPane
import javax.swing.KeyStroke
import javax.swing.event.MenuListener
import javax.swing.event.MenuEvent
+import javax.swing.filechooser.FileNameExtensionFilter
import jp.ymir.taskReporter._
import jp.ymir.taskReporter.core._
import scala.swing._
+import scala.swing.Swing._
import scala.swing.event._
class MainFrame(reportFile: Option[File]) extends Frame {
- private val reportSet: ReportSet = new ReportSet(reportFile)
+ frame =>
- title = "Task Reporter" + Main.getVersion
+ private val reportSet = new ReportSet(reportFile)
+
+ title = "Task Reporter " + Main.getVersion
+ preferredSize = Preferences.mainFrameSize()
+
+ case class FileOpened(file: File) extends Event
+ case class ReportSelected(report: Report) extends Event
+ case class ReportDeselected() extends Event
+ case class TaskSelected(task: Task) extends Event
+ case class TaskDeselected() extends Event
+
+ peer.addComponentListener(new ComponentAdapter() {
+ override def componentResized(e: ComponentEvent) {
+ Preferences.mainFrameSize() = size
+ }
+ })
+
+ menuBar = new MenuBar {
+ contents += new Menu("File") {
+ mnemonic = Key.F
+
+ val miOpen = new MenuItem(new Action("Open...") {
+ accelerator = Some(KeyStroke getKeyStroke "control O")
+ def apply {
+ val chooser = new FileChooser(Preferences.lastChosenDir()) {
+ fileSelectionMode = FileChooser.SelectionMode.FilesOnly
+ fileFilter = new FileNameExtensionFilter("TSV files", "tsv")
+ title = "Select a report file to open..."
+ peer.setAcceptAllFileFilterUsed(false)
+ }
+ val r = chooser.showOpenDialog(null)
+ if (r == FileChooser.Result.Approve) {
+ val file = chooser.selectedFile
+ Preferences.lastChosenDir() = file.getParentFile
+ reportSet load file
+ frame publish FileOpened(file)
+ }
+ }
+ })
+ contents += miOpen
+
+ val miSave = new MenuItem(new Action("Save") {
+ accelerator = Some(KeyStroke.getKeyStroke("control S"));
+ def apply = save
+ })
+ contents += miSave
+
+ contents += new Separator
+
+ contents += new MenuItem(new Action("Quit") {
+ accelerator = Some(KeyStroke.getKeyStroke("control Q"))
+ def apply = closeOperation
+ })
+
+ peer.addMenuListener(new MenuListener {
+ def menuSelected(e: MenuEvent) {
+ miOpen.enabled = !dirty
+ miSave.enabled = dirty
+ miSave.text =
+ if (reportSet.file.isEmpty)
+ "Save..."
+ else
+ "Save"
+ }
+ def menuDeselected(e: MenuEvent) {}
+ def menuCanceled(e: MenuEvent) {}
+ })
+ }
+ }
+
+ contents = new SplitPane {
+ peer.setOrientation(JSplitPane.HORIZONTAL_SPLIT)
+ continuousLayout = true
+ oneTouchExpandable = true
+ resizeWeight = 0 // Let the left pane be fixed
+
+ rightComponent = new BoxPanel(Orientation.Vertical) {
+ border = EmptyBorder(5, 5, 5, 5)
+
+ contents += new ScrollPane(
+ new Table() {
+ peer setFillsViewportHeight true
+ listenTo(frame)
+
+ override def model : Report = super.model.asInstanceOf[Report]
+
+ reactions += {
+ case ReportSelected(report) =>
+ model = report
+ if (rowCount > 0) {
+ selection.rows += rowCount - 1 // Select the last report
+ }
+ case ReportDeselected() =>
+ model = new Report() // Empty report
+ }
+
+ selection.reactions += {
+ case TableRowsSelected(_, _, false) =>
+ selection.rows.size match {
+ case 1 =>
+ val task = model(selection.rows.head)
+ frame publish TaskSelected(task)
+ case _ =>
+ frame publish TaskDeselected()
+ }
+ }
+ })
+ contents += VStrut(5)
+ contents += new Separator(Orientation.Horizontal)
+ contents += VStrut(5)
+ contents += new TaskEditor
+ contents += VStrut(5)
+ contents += new Separator(Orientation.Horizontal)
+ contents += VStrut(5)
+ contents += new FlowPanel(FlowPanel.Alignment.Left)() {
+ contents += new Button(new Action("New") {
+ def apply = {} // FIXME
+ })
+ contents += new Button(new Action("Delete...") {
+ def apply = {} // FIXME
+ })
+ }
+ }
+
+ leftComponent = new BorderPanel {
+ border = EmptyBorder(5, 5, 5, 5)
+
+ add(
+ new ScrollPane(
+ new Table() {
+ peer setFillsViewportHeight true
+ peer setModel reportSet
+ listenTo(frame)
+ reactions += {
+ case FileOpened(f) =>
+ if (rowCount > 0) {
+ selection.rows += rowCount - 1 // Select the last report
+ }
+ }
+ selection.reactions += {
+ case TableRowsSelected(_, _, false) =>
+ selection.rows.size match {
+ case 1 =>
+ val report = reportSet(selection.rows.head)
+ frame publish ReportSelected(report)
+ case _ =>
+ frame publish ReportDeselected()
+ }
+ }
+ }), BorderPanel.Position.Center)
+
+ add(
+ new FlowPanel(FlowPanel.Alignment.Left)() {
+ contents += new Button(new Action("New...") {
+ def apply = {} // FIXME
+ })
+ contents += new Button(new Action("Delete...") {
+ def apply = {} // FIXME
+ })
+ }, BorderPanel.Position.South)
+
+ preferredSize = minimumSize
+ }
+ }
+
+ reportSet.file match {
+ case Some(file) => frame publish FileOpened(file)
+ case None => frame publish ReportDeselected()
+ }
- // FIXME: Provide a way to configure this.
- size = new Dimension(640, 480)
centerOnScreen
+ visible = true
override def closeOperation {
if (dirty) {
JOptionPane.YES_NO_CANCEL_OPTION);
r match {
- case JOptionPane.YES_OPTION =>
- // FIXME
- dispose
- case JOptionPane.NO_OPTION =>
- dispose
+ case JOptionPane.YES_OPTION => save; dispose
+ case JOptionPane.NO_OPTION => dispose
case _ =>
}
}
return reportSet.dirty
}
- menuBar = new MenuBar {
- contents += new Menu("File") {
- mnemonic = Key.F
+ def save {
+ if (reportSet.file.isEmpty) {
+ val chooser = new FileChooser(Preferences.lastChosenDir())
+ val r = chooser.showSaveDialog(null)
+ if (r != FileChooser.Result.Approve) {
+ return
+ }
- contents += new MenuItem(new Action("Open...") {
- accelerator = Some(KeyStroke.getKeyStroke("control O"))
- def apply {
- // FIXME
- }
- })
+ if (chooser.selectedFile.exists) {
+ val r = JOptionPane.showConfirmDialog(
+ peer,
+ "The chosen file or directory \"" + chooser.selectedFile.getName + "\" already exists.\n" +
+ "Do you want to overwrite it?",
+ "Confirmation",
+ JOptionPane.YES_NO_OPTION)
- val save = new MenuItem(new Action("Save") {
- accelerator = Some(KeyStroke.getKeyStroke("control S"));
- def apply {
- // FIXME
- }
- })
- contents += save
- peer.addMenuListener(new MenuListener {
- def menuSelected(e: MenuEvent) {
- save.enabled = dirty
- save.text =
- if (reportSet.file.isEmpty)
- "Save..."
- else
- "Save"
+ r match {
+ case JOptionPane.YES_OPTION =>
+ case JOptionPane.NO_OPTION => return
}
- def menuDeselected(e: MenuEvent) {}
- def menuCanceled(e: MenuEvent) {}
- })
+ }
+
+ Preferences.lastChosenDir() = chooser.selectedFile.getParentFile
+ reportSet.save(chooser.selectedFile)
+ }
+ else {
+ reportSet.save
}
}
-
- visible = true
}