diff --git a/app/gui/src/main/scala/org/bitcoins/gui/AppMenuBar.scala b/app/gui/src/main/scala/org/bitcoins/gui/AppMenuBar.scala index 5ccdb3c306..3cdc2d61cf 100644 --- a/app/gui/src/main/scala/org/bitcoins/gui/AppMenuBar.scala +++ b/app/gui/src/main/scala/org/bitcoins/gui/AppMenuBar.scala @@ -18,7 +18,7 @@ object AppMenuBar { def menuBar(model: WalletGUIModel, dlcPane: DLCPane): MenuBar = { val menuBar = new MenuBar { menus = List(new FileMenu().fileMenu, - new ViewMenu(dlcPane).viewMenu, + new ViewMenu(model, dlcPane).viewMenu, new HelpMenu(model).helpMenu) } // Use MacOS native menuing @@ -65,7 +65,7 @@ private class FileMenu() { } } -private class ViewMenu(dlcPane: DLCPane) { +private class ViewMenu(model: WalletGUIModel, dlcPane: DLCPane) { private val themeToggle: ToggleGroup = new ToggleGroup() @@ -113,9 +113,15 @@ private class ViewMenu(dlcPane: DLCPane) { onAction = _ => dlcPane.showWindow() } + private val debugWindow = new MenuItem("Debug Operations") { + accelerator = + new KeyCodeCombination(KeyCode.Digit2, KeyCombination.ShortcutDown) + onAction = _ => model.onDebug() + } + val viewMenu: Menu = new Menu("_View") { mnemonicParsing = true - items = List(themes, new SeparatorMenuItem(), dlcWindow) + items = List(themes, new SeparatorMenuItem(), dlcWindow, debugWindow) } } diff --git a/app/gui/src/main/scala/org/bitcoins/gui/WalletGUIModel.scala b/app/gui/src/main/scala/org/bitcoins/gui/WalletGUIModel.scala index 0a17fb17ff..9a4f8d7edc 100644 --- a/app/gui/src/main/scala/org/bitcoins/gui/WalletGUIModel.scala +++ b/app/gui/src/main/scala/org/bitcoins/gui/WalletGUIModel.scala @@ -109,6 +109,10 @@ class WalletGUIModel(dlcModel: DLCPaneModel)(implicit system: ActorSystem) AboutDialog.showAndWait(parentWindow.value) } + def onDebug(): Unit = { + DebugDialog.show(parentWindow.value) + } + /** Updates the wallet sync height * @return if the update was successful */ diff --git a/app/gui/src/main/scala/org/bitcoins/gui/dialog/DebugDialog.scala b/app/gui/src/main/scala/org/bitcoins/gui/dialog/DebugDialog.scala new file mode 100644 index 0000000000..93fb72fff3 --- /dev/null +++ b/app/gui/src/main/scala/org/bitcoins/gui/dialog/DebugDialog.scala @@ -0,0 +1,70 @@ +package org.bitcoins.gui.dialog + +import grizzled.slf4j.Logging +import org.bitcoins.gui.GlobalData +import scalafx.Includes._ +import scalafx.scene.control.{Button, ButtonType, Dialog} +import scalafx.scene.layout.VBox +import scalafx.stage.{Modality, Window} + +import java.awt.Desktop +import java.io.File +import java.nio.file.{Files, Paths} +import scala.util.Properties + +object DebugDialog extends Logging { + + private val LOGFILE_NAME = "bitcoin-s.log" + + def show(parentWindow: Window): Unit = { + val dialog = new Dialog[Unit]() { + initOwner(parentWindow) + initModality(Modality.None) + title = "Debug Operations" + } + + dialog.dialogPane().buttonTypes = Seq(ButtonType.Close) + dialog.dialogPane().stylesheets = GlobalData.currentStyleSheets + + val openLogButton = new Button("Open Bitcoin-S Log") { + onAction = _ => { + // Get root active network directory + val location = System.getProperty("bitcoins.log.location") + val path = Paths.get(location, LOGFILE_NAME) + if (Files.exists(path)) { + // Ubuntu seems to support Desktop and Desktop.open(), but hangs on opening file + // This is an issue in JavaFX and the common workaround is to call on another thread + // I was not having any luck with Platform.runLater wrapping call to Desktop.open getting around the bug + if (Properties.isLinux) { + // Work around native file-open alternative that works on Ubuntu + val _ = Runtime + .getRuntime() + .exec(s"/usr/bin/xdg-open ${path.toString}") + } else if (Desktop.isDesktopSupported) { + val d = Desktop.getDesktop + if (d.isSupported(Desktop.Action.OPEN)) { + // Open file in default log reader per OS + d.open(new File(path.toString)) + } else { + logger.error("Desktop.Action.OPEN on log file not supported") + } + } else { + logger.error( + "This platform is non-Linux or does not support Desktop") + } + } else { + logger.error( + s"Expected log file location does not exist ${path.toString}") + } + } + } + + dialog.dialogPane().content = new VBox { + minWidth = 300 + minHeight = 300 + children = Seq(openLogButton) + } + + val _ = dialog.show() + } +}