diff --git a/cli-lanterna/src/main/groovy/com/muwire/clilanterna/CliLanterna.groovy b/cli-lanterna/src/main/groovy/com/muwire/clilanterna/CliLanterna.groovy index 2b51a50c..6c18d035 100644 --- a/cli-lanterna/src/main/groovy/com/muwire/clilanterna/CliLanterna.groovy +++ b/cli-lanterna/src/main/groovy/com/muwire/clilanterna/CliLanterna.groovy @@ -104,7 +104,18 @@ class CliLanterna { i2pProps["i2cp.tcp.port"] = String.valueOf(i2pPort) i2pPropsFile.withOutputStream { i2pProps.store(it, "") } } - + + def cliProps + def cliPropsFile = new File(home, "cli.properties") + if (cliPropsFile.exists()) { + Properties p = new Properties() + cliPropsFile.withInputStream { + p.load(it) + } + cliProps = new CliSettings(p) + } else + cliProps = new CliSettings(new Properties()) + Window window = new BasicWindow("MuWire "+ MW_VERSION) window.setHints([Window.Hint.CENTERED]) @@ -155,7 +166,7 @@ class CliLanterna { System.exit(1) } - window = new MainWindowView("MuWire "+MW_VERSION, core, textGUI, screen) + window = new MainWindowView("MuWire "+MW_VERSION, core, textGUI, screen, cliProps) core.startServices() core.eventBus.publish(new UILoadedEvent()) diff --git a/cli-lanterna/src/main/groovy/com/muwire/clilanterna/CliSettings.groovy b/cli-lanterna/src/main/groovy/com/muwire/clilanterna/CliSettings.groovy new file mode 100644 index 00000000..20994b77 --- /dev/null +++ b/cli-lanterna/src/main/groovy/com/muwire/clilanterna/CliSettings.groovy @@ -0,0 +1,25 @@ +package com.muwire.clilanterna + +class CliSettings { + + boolean clearCancelledDownloads + boolean clearFinishedDownloads + boolean clearUploads + + CliSettings(Properties props) { + clearCancelledDownloads = Boolean.parseBoolean(props.getProperty("clearCancelledDownloads","true")) + clearFinishedDownloads = Boolean.parseBoolean(props.getProperty("clearFinishedDownloads", "false")) + clearUploads = Boolean.parseBoolean(props.getProperty("clearUploads", "false")) + } + + void write(OutputStream os) { + Properties props = new Properties() + props.with { + setProperty("clearCancelledDownloads", String.valueOf(clearCancelledDownloads)) + setProperty("clearFinishedDownloads", String.valueOf(clearFinishedDownloads)) + setProperty("clearUploads", String.valueOf(clearUploads)) + + store(os, "CLI Properties") + } + } +} diff --git a/cli-lanterna/src/main/groovy/com/muwire/clilanterna/DownloadsModel.groovy b/cli-lanterna/src/main/groovy/com/muwire/clilanterna/DownloadsModel.groovy index 647ea44d..5133510f 100644 --- a/cli-lanterna/src/main/groovy/com/muwire/clilanterna/DownloadsModel.groovy +++ b/cli-lanterna/src/main/groovy/com/muwire/clilanterna/DownloadsModel.groovy @@ -13,15 +13,17 @@ import net.i2p.data.DataHelper class DownloadsModel { private final TextGUIThread guiThread private final Core core + private final CliSettings props private final List downloaders = new ArrayList<>() private final TableModel model = new TableModel("Name", "Status", "Progress", "Speed", "ETA") private long lastRetryTime - DownloadsModel(TextGUIThread guiThread, Core core) { + DownloadsModel(TextGUIThread guiThread, Core core, CliSettings props) { this.guiThread = guiThread this.core = core + this.props = props core.eventBus.register(DownloadStartedEvent.class, this) Timer timer = new Timer(true) @@ -46,6 +48,14 @@ class DownloadsModel { private void refreshModel() { int rowCount = model.getRowCount() rowCount.times { model.removeRow(0) } + + if (props.clearCancelledDownloads) { + downloaders.removeAll { it.cancelled } + } + if (props.clearFinishedDownloads) { + downloaders.removeAll { it.getCurrentState() == Downloader.DownloadState.FINISHED } + } + downloaders.each { String status = it.getCurrentState().toString() int speedInt = it.speed() diff --git a/cli-lanterna/src/main/groovy/com/muwire/clilanterna/DownloadsView.groovy b/cli-lanterna/src/main/groovy/com/muwire/clilanterna/DownloadsView.groovy index 1bdbab8f..fc2031ef 100644 --- a/cli-lanterna/src/main/groovy/com/muwire/clilanterna/DownloadsView.groovy +++ b/cli-lanterna/src/main/groovy/com/muwire/clilanterna/DownloadsView.groovy @@ -28,6 +28,7 @@ class DownloadsView extends BasicWindow { this.textGUI = textGUI setHints([Window.Hint.EXPANDED]) + LayoutData layoutData = GridLayout.createLayoutData(Alignment.CENTER, Alignment.CENTER, true, false) Panel contentPanel = new Panel() contentPanel.setLayoutManager(new GridLayout(1)) @@ -36,10 +37,18 @@ class DownloadsView extends BasicWindow { table.setSelectAction({rowSelected()}) table.setTableModel(model.model) table.setVisibleRows(terminalSize.getRows()) - contentPanel.addComponent(table, GridLayout.createLayoutData(Alignment.CENTER, Alignment.CENTER,true,false)) + contentPanel.addComponent(table, layoutData) + + Panel buttonsPanel = new Panel() + buttonsPanel.setLayoutManager(new GridLayout(2)) + Button clearButton = new Button("Clear Done",{clearDone()}) + buttonsPanel.addComponent(clearButton, layoutData) + Button closeButton = new Button("Close",{close()}) - contentPanel.addComponent(closeButton, GridLayout.createLayoutData(Alignment.CENTER, Alignment.CENTER,true,false)) + buttonsPanel.addComponent(closeButton, layoutData) + + contentPanel.addComponent(buttonsPanel, layoutData) setComponent(contentPanel) closeButton.takeFocus() @@ -75,4 +84,11 @@ class DownloadsView extends BasicWindow { close.takeFocus() textGUI.addWindowAndWait(prompt) } + + private void clearDone() { + model.downloaders.removeAll { + def state = it.getCurrentState() + state == Downloader.DownloadState.CANCELLED || state == Downloader.DownloadState.FINISHED + } + } } diff --git a/cli-lanterna/src/main/groovy/com/muwire/clilanterna/MainWindowView.groovy b/cli-lanterna/src/main/groovy/com/muwire/clilanterna/MainWindowView.groovy index 9b9705a8..5ec8a7bf 100644 --- a/cli-lanterna/src/main/groovy/com/muwire/clilanterna/MainWindowView.groovy +++ b/cli-lanterna/src/main/groovy/com/muwire/clilanterna/MainWindowView.groovy @@ -49,15 +49,15 @@ class MainWindowView extends BasicWindow { private final Label sharedFiles private final Label updateStatus - public MainWindowView(String title, Core core, TextGUI textGUI, Screen screen) { + public MainWindowView(String title, Core core, TextGUI textGUI, Screen screen, CliSettings props) { super(title); this.core = core this.textGUI = textGUI this.screen = screen - downloadsModel = new DownloadsModel(textGUI.getGUIThread(),core) - uploadsModel = new UploadsModel(textGUI.getGUIThread(), core) + downloadsModel = new DownloadsModel(textGUI.getGUIThread(),core, props) + uploadsModel = new UploadsModel(textGUI.getGUIThread(), core, props) filesModel = new FilesModel(textGUI.getGUIThread(),core) trustModel = new TrustModel(textGUI.getGUIThread(), core) diff --git a/cli-lanterna/src/main/groovy/com/muwire/clilanterna/UploadsModel.groovy b/cli-lanterna/src/main/groovy/com/muwire/clilanterna/UploadsModel.groovy index 31a42dd6..340211d2 100644 --- a/cli-lanterna/src/main/groovy/com/muwire/clilanterna/UploadsModel.groovy +++ b/cli-lanterna/src/main/groovy/com/muwire/clilanterna/UploadsModel.groovy @@ -13,12 +13,14 @@ import net.i2p.data.DataHelper class UploadsModel { private final TextGUIThread guiThread private final Core core - private final List uploaders = new ArrayList<>() + private CliSettings props + private final List uploaders = new ArrayList<>() private final TableModel model = new TableModel("Name","Progress","Downloader","Remote Pieces") - UploadsModel(TextGUIThread guiThread, Core core) { + UploadsModel(TextGUIThread guiThread, Core core, CliSettings props) { this.guiThread = guiThread this.core = core + this.props = props core.eventBus.register(UploadEvent.class, this) core.eventBus.register(UploadFinishedEvent.class, this) @@ -32,29 +34,53 @@ class UploadsModel { } void onUploadEvent(UploadEvent e) { - guiThread.invokeLater({uploaders.add(e.uploader)}) + guiThread.invokeLater { + UploaderWrapper found = null + uploaders.each { + if (it.uploader == e.uploader) { + found = it + return + } + } + if (found != null) { + found.uploader = e.uploader + found.finished = false + } else + uploaders << new UploaderWrapper(uploader : e.uploader) + } } void onUploadFinishedEvent(UploadFinishedEvent e) { - guiThread.invokeLater({uploaders.remove(e.uploader)}) + guiThread.invokeLater { + uploaders.each { + if (it.uploader == e.uploader) { + it.finished = true + return + } + } + } } private void refreshModel() { int uploadersSize = model.getRowCount() uploadersSize.times { model.removeRow(0) } - + + if (props.clearUploads) { + uploaders.removeAll { it.finished } + } + uploaders.each { - String name = it.getName() - int percent = it.getProgress() + String name = it.uploader.getName() + int percent = it.uploader.getProgress() String percentString = "$percent% of piece".toString() - String downloader = it.getDownloader() + String downloader = it.uploader.getDownloader() - int pieces = it.getTotalPieces() - int done = it.getDonePieces() + int pieces = it.uploader.getTotalPieces() + int done = it.uploader.getDonePieces() int percentTotal = -1 if (pieces != 0) percentTotal = (done * 100) / pieces - long size = it.getTotalSize() + long size = it.uploader.getTotalSize() String totalSize = "" if (size > 0) totalSize = " of " + DataHelper.formatSize2Decimal(size, false) + "B" @@ -63,4 +89,14 @@ class UploadsModel { model.addRow([name, percentString, downloader, remotePieces]) } } + + private static class UploaderWrapper { + Uploader uploader + boolean finished + + @Override + public String toString() { + uploader.getName() + } + } } diff --git a/cli-lanterna/src/main/groovy/com/muwire/clilanterna/UploadsView.groovy b/cli-lanterna/src/main/groovy/com/muwire/clilanterna/UploadsView.groovy index 2be0a744..3da4c0f5 100644 --- a/cli-lanterna/src/main/groovy/com/muwire/clilanterna/UploadsView.groovy +++ b/cli-lanterna/src/main/groovy/com/muwire/clilanterna/UploadsView.groovy @@ -29,9 +29,19 @@ class UploadsView extends BasicWindow { table.setTableModel(model.model) table.setVisibleRows(terminalSize.getRows()) contentPanel.addComponent(table, layoutData) + + Panel buttonsPanel = new Panel() + buttonsPanel.setLayoutManager(new GridLayout(2)) + Button clearDoneButton = new Button("Clear Finished",{ + model.uploaders.removeAll { it.finished } + }) Button closeButton = new Button("Close",{close()}) - contentPanel.addComponent(closeButton, layoutData) + + buttonsPanel.addComponent(clearDoneButton, layoutData) + buttonsPanel.addComponent(closeButton, layoutData) + + contentPanel.addComponent(buttonsPanel, layoutData) setComponent(contentPanel) closeButton.takeFocus()