// TLCockpit
// Copyright 2017-2018 Norbert Preining
// Licensed according to GPLv3+
//
// Front end for tlmgr
package TLCockpit
import TLCockpit.ApplicationMain.{stage, tlmgr, tlpkgs}
import TLCockpit.Utils._
import TeXLive.{OsTools, TLPackage}
import scalafx.Includes._
import scalafx.collections.ObservableBuffer
import scalafx.geometry.{HPos, Insets, Orientation}
import scalafx.scene.Cursor
import scalafx.scene.layout.{ColumnConstraints, GridPane, Priority, VBox}
import scalafx.scene.control._
import scalafx.scene.input.MouseEvent
import scalafx.scene.paint.Color
class PkgInfoDialog(tlp: TLPackage) extends Dialog {
val dialog = new Dialog() {
initOwner(stage)
title = s"Package Information for $pkg"
headerText = s"Package Information for $pkg"
resizable = true
}
dialog.dialogPane().buttonTypes = Seq(ButtonType.OK)
val isInstalled = tlp.installed
val grid = new GridPane() {
hgap = 10
vgap = 10
padding = Insets(20)
}
def copyableTextfield(k: String): TextField = {
new TextField() {
text = k
editable = false
style = "-fx-background-color: rgba(0, 0, 0, 0);"
margin = Insets(0)
padding = Insets(0)
}
}
def do_one(k: String, v: String, row: Int): Int = {
grid.add(copyableTextfield(k), 0, row)
grid.add(copyableTextfield(v), 1, row)
// grid.add(new Label(k), 0, row)
// grid.add(new Label(v) {
// wrapText = true
// }, 1, row)
row + 1
}
var crow = 0
val pkg = tlp.name
crow = do_one("package", pkg, crow)
crow = do_one("category", tlp.category, crow)
crow = do_one("shortdesc", tlp.shortdesc.getOrElse(""), crow)
crow = do_one("longdesc", tlp.longdesc.getOrElse(""), crow)
crow = do_one("installed", if (tlp.installed) "Yes" else "No", crow)
crow = do_one("available", if (tlp.available) "Yes" else "No", crow)
if (tlp.installed)
crow = do_one("local revision", tlp.lrev.toString, crow)
if (tlp.available)
crow = do_one("remote revision", tlp.rrev.toString, crow)
val binsizesum = tlp.binsize.values.toList.sum * TeXLive.tlBlockSize
val binsizestr = if (binsizesum > 0) "bin " + humanReadableByteSize(binsizesum) + " " else ""
val runsizestr = if (tlp.runsize > 0) "run " + humanReadableByteSize(tlp.runsize) + " " else ""
val srcsizestr = if (tlp.srcsize > 0) "src " + humanReadableByteSize(tlp.srcsize) + " " else ""
val docsizestr = if (tlp.docsize > 0) "doc " + humanReadableByteSize(tlp.docsize) + " " else ""
crow = do_one("sizes", runsizestr + docsizestr + binsizestr + srcsizestr, crow)
val catdata = tlp.cataloguedata
if (catdata.version.isDefined)
crow = do_one("cat-version", catdata.version.get, crow)
if (catdata.date.isDefined)
crow = do_one("cat-date", catdata.date.get, crow)
if (catdata.license.isDefined)
crow = do_one("cat-license", catdata.license.get, crow)
if (catdata.topics.isDefined)
crow = do_one("cat-topics", catdata.topics.get, crow)
if (catdata.related.isDefined)
crow = do_one("cat-related", catdata.related.get, crow)
// add files section
//println(tlpkgs(pkg))
val docFiles = tlp.docfiles
if (docFiles.nonEmpty) {
// grid.add(new Label("doc files"), 0, crow)
grid.add(copyableTextfield("doc files"), 0, crow)
grid.add(doListView(docFiles.map(s => s.file.replaceFirst("RELOC", "texmf-dist")), isInstalled), 1, crow)
crow += 1
}
val runFiles = tlp.runfiles
if (runFiles.nonEmpty) {
// grid.add(new Label("run files"), 0, crow)
grid.add(copyableTextfield("run files"), 0, crow)
grid.add(doListView(runFiles.map(s => s.replaceFirst("RELOC", "texmf-dist")), false), 1, crow)
crow += 1
}
val srcFiles = tlp.srcfiles
if (srcFiles.nonEmpty) {
// grid.add(new Label("src files"), 0, crow)
grid.add(copyableTextfield("src files"), 0, crow)
grid.add(doListView(srcFiles.map(s => s.replaceFirst("RELOC", "texmf-dist")), false), 1, crow)
crow += 1
}
val binFiles = tlp.binfiles
if (binFiles.nonEmpty) {
// grid.add(new Label("bin files"), 0, crow)
grid.add(copyableTextfield("bin files"), 0, crow)
grid.add(doListView(binFiles.flatMap(_._2).toSeq.map(s => s.replaceFirst("RELOC", "texmf-dist")), false), 1, crow)
crow += 1
}
grid.columnConstraints = Seq(new ColumnConstraints(100, 200, 200), new ColumnConstraints(100, 400, 5000, Priority.Always, HPos.LEFT, true))
dialog.dialogPane().content = grid
dialog.width = 600
// dialog.height = 1500
// dialog
def showAndWait(): Unit = this.dialog.showAndWait()
def doListView(files: Seq[String], clickable: Boolean): scalafx.scene.Node = {
if (files.length <= 5) {
val vb = new VBox()
vb.children = files.map { f =>
val fields = f.split(" ")
val foo = copyableTextfield(fields(0))
if (clickable) {
foo.style = foo.getStyle + "-fx-text-fill: blue;"
foo.onMouseClicked = { me: MouseEvent => OsTools.openFile(tlmgr.tlroot + "/" + fields(0)) }
foo.cursor = Cursor.Hand
}
foo
// new Label(fields(0)) {
// if (clickable) {
// textFill = Color.Blue
// onMouseClicked = { me: MouseEvent => OsTools.openFile(tlmgr.tlroot + "/" + fields(0)) }
// cursor = Cursor.Hand
// }
// }
}
vb
} else {
val vb = new ListView[String] {}
vb.minHeight = 100
vb.prefHeight = 100
vb.maxHeight = 200
vb.vgrow = Priority.Always
vb.orientation = Orientation.Vertical
vb.cellFactory = { p => {
val foo = new ListCell[String]
// ensure tighter spacing similar to the other entires
foo.padding = Insets(0)
foo.item.onChange { (_, _, str) => foo.text = str }
if (clickable) {
foo.textFill = Color.Blue
foo.onMouseClicked = { me: MouseEvent => OsTools.openFile(tlmgr.tlroot + "/" + foo.text.value) }
foo.cursor = Cursor.Hand
}
foo
}
}
// vb.children = docFiles.map { f =>
vb.items = ObservableBuffer(files.map { f =>
val fields = f.split(" ")
fields(0)
})
vb
}
}
}