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 { frame => 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 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") { 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() } centerOnScreen visible = true override def closeOperation { if (dirty) { val r = JOptionPane.showConfirmDialog( peer, "The report file \"" + reportSet.file.get.getName + "\" has been modified.\n" + "Do you want to save it before closing?", "Confirmation", JOptionPane.YES_NO_CANCEL_OPTION); r match { case JOptionPane.YES_OPTION => save; dispose case JOptionPane.NO_OPTION => dispose case _ => } } else { dispose } } def dirty : Boolean = { return reportSet.dirty } def save { if (reportSet.file.isEmpty) { val chooser = new FileChooser(Preferences.lastChosenDir()) val r = chooser.showSaveDialog(null) if (r != FileChooser.Result.Approve) { return } 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) r match { case JOptionPane.YES_OPTION => case JOptionPane.NO_OPTION => return } } Preferences.lastChosenDir() = chooser.selectedFile.getParentFile reportSet.save(chooser.selectedFile) } else { reportSet.save } } }