diff --git a/core/src/main/java/com/muwire/core/SharedFile.java b/core/src/main/java/com/muwire/core/SharedFile.java index 2bbba7c3..f9583e24 100644 --- a/core/src/main/java/com/muwire/core/SharedFile.java +++ b/core/src/main/java/com/muwire/core/SharedFile.java @@ -38,6 +38,7 @@ public class SharedFile { /** Path to the top-most parent File that is shared. Null if no such exists */ private volatile Path pathToSharedParent; + private volatile String cachedVisiblePath; public SharedFile(File file, byte[] root, int pieceSize) throws IOException { this.file = file; @@ -139,14 +140,32 @@ public class SharedFile { return publishedTimestamp; } + /** + * Sets the path to the shared parent and computes + * the cached visible path. + */ public void setPathToSharedParent(Path path) { this.pathToSharedParent = path; + + String shortPath; + if (pathToSharedParent.getNameCount() > 1) { + Path tmp = pathToSharedParent.subpath(1, pathToSharedParent.getNameCount()); + shortPath = "..." + File.separator + tmp; + } else { + shortPath = "..."; + } + shortPath += File.separator + getFile().getName(); + this.cachedVisiblePath = shortPath; } public Path getPathToSharedParent() { return pathToSharedParent; } + public String getCachedVisiblePath() { + return cachedVisiblePath; + } + @Override public int hashCode() { return hashCode; diff --git a/gui/griffon-app/controllers/com/muwire/gui/OptionsController.groovy b/gui/griffon-app/controllers/com/muwire/gui/OptionsController.groovy index d841dd62..bb169fc1 100644 --- a/gui/griffon-app/controllers/com/muwire/gui/OptionsController.groovy +++ b/gui/griffon-app/controllers/com/muwire/gui/OptionsController.groovy @@ -313,6 +313,10 @@ class OptionsController { model.clearUploads = clearUploads uiSettings.clearUploads = clearUploads + boolean showUnsharedPaths = view.showUnsharedPathsCheckbox.model.isSelected() + model.showUnsharedPaths = showUnsharedPaths + uiSettings.showUnsharedPaths = showUnsharedPaths + boolean storeSearchHistory = view.storeSearchHistoryCheckbox.model.isSelected() model.storeSearchHistory = storeSearchHistory uiSettings.storeSearchHistory = storeSearchHistory diff --git a/gui/griffon-app/i18n/messages.properties b/gui/griffon-app/i18n/messages.properties index bcb58473..bb0e97a9 100644 --- a/gui/griffon-app/i18n/messages.properties +++ b/gui/griffon-app/i18n/messages.properties @@ -349,6 +349,7 @@ OPTIONS_CLEAR_HISTORY=Clear history OPTIONS_OTHER_SETTINGS=Other Settings OPTIONS_CLEAR_CANCELLED_DOWNLOADS=Automatically clear cancelled downloads OPTIONS_CLEAR_FINISHED_DOWNLOADS=Automatically clear finished downloads +OPTIONS_SHOW_UNSHARED_PATHS=Show parts of paths which are not shared in Library OPTIONS_SMOOTH_DOWNLOAD_SPEED=Smooth download speed over (seconds) OPTIONS_EXCLUDE_LOCAL_FILES=Exclude local files from results OPTIONS_CLEAR_FINISHED_UPLOADS=Automatically clear finished uploads diff --git a/gui/griffon-app/models/com/muwire/gui/OptionsModel.groovy b/gui/griffon-app/models/com/muwire/gui/OptionsModel.groovy index ab9185b0..7205061c 100644 --- a/gui/griffon-app/models/com/muwire/gui/OptionsModel.groovy +++ b/gui/griffon-app/models/com/muwire/gui/OptionsModel.groovy @@ -57,7 +57,8 @@ class OptionsModel { @Observable boolean clearUploads @Observable boolean groupByFile @Observable boolean exitOnClose - @Observable boolean closeDecisionMade + @Observable boolean closeDecisionMade + @Observable boolean showUnsharedPaths @Observable boolean messageNotifications // bw options @@ -145,6 +146,7 @@ class OptionsModel { storeSearchHistory = uiSettings.storeSearchHistory groupByFile = uiSettings.groupByFile messageNotifications = uiSettings.messageNotifications + showUnsharedPaths = uiSettings.showUnsharedPaths if (core.router != null) { inBw = String.valueOf(settings.inBw) diff --git a/gui/griffon-app/views/com/muwire/gui/MainFrameView.groovy b/gui/griffon-app/views/com/muwire/gui/MainFrameView.groovy index 1d8f2859..0846720c 100644 --- a/gui/griffon-app/views/com/muwire/gui/MainFrameView.groovy +++ b/gui/griffon-app/views/com/muwire/gui/MainFrameView.groovy @@ -912,7 +912,7 @@ class MainFrameView { // shared files table and tree JTable sharedFilesTable = builder.getVariable("shared-files-table") - sharedFilesTable.columnModel.getColumn(0).setCellRenderer(new SharedFileNameRenderer()) + sharedFilesTable.columnModel.getColumn(0).setCellRenderer(new SharedFileNameRenderer(settings)) sharedFilesTable.columnModel.getColumn(1).setCellRenderer(new SizeRenderer()) sharedFilesTable.rowSorter.addRowSorterListener({ evt -> lastSharedSortEvent = evt }) diff --git a/gui/griffon-app/views/com/muwire/gui/OptionsView.groovy b/gui/griffon-app/views/com/muwire/gui/OptionsView.groovy index 457716f3..f073d8b9 100644 --- a/gui/griffon-app/views/com/muwire/gui/OptionsView.groovy +++ b/gui/griffon-app/views/com/muwire/gui/OptionsView.groovy @@ -86,6 +86,7 @@ class OptionsView { def excludeLocalResultCheckbox def showSearchHashesCheckbox def clearUploadsCheckbox + def showUnsharedPathsCheckbox def storeSearchHistoryCheckbox def messageNotificationsCheckbox @@ -364,10 +365,13 @@ class OptionsView { label(text : trans("OPTIONS_CLEAR_FINISHED_UPLOADS"), constraints:gbc(gridx:0, gridy:4, anchor: GridBagConstraints.LINE_START, weightx : 100)) clearUploadsCheckbox = checkBox(selected : bind {model.clearUploads}, constraints : gbc(gridx:1, gridy: 4, anchor:GridBagConstraints.LINE_END)) + label(text : trans("OPTIONS_SHOW_UNSHARED_PATHS"), constraints: gbc(gridx: 0, gridy: 5, anchor: GridBagConstraints.LINE_START, weightx: 100)) + showUnsharedPathsCheckbox = checkBox(selected: bind{model.showUnsharedPaths}, + constraints: gbc(gridx: 1, gridy: 5, anchor: GridBagConstraints.LINE_END)) if (SystemTray.isSupported()) { - label(text : trans("OPTIONS_WHEN_CLOSING_MUWIRE"), constraints : gbc(gridx: 0, gridy : 5, anchor : GridBagConstraints.LINE_START, weightx: 100)) - panel (constraints : gbc(gridx:1, gridy: 5, anchor : GridBagConstraints.LINE_END)) { + label(text : trans("OPTIONS_WHEN_CLOSING_MUWIRE"), constraints : gbc(gridx: 0, gridy : 6, anchor : GridBagConstraints.LINE_START, weightx: 100)) + panel (constraints : gbc(gridx:1, gridy: 6, anchor : GridBagConstraints.LINE_END)) { buttonGroup(id : "closeBehaviorGroup") radioButton(text : trans("OPTIONS_MINIMIZE_TO_TRAY"), selected : bind {!model.exitOnClose}, buttonGroup: closeBehaviorGroup, minimizeOnCloseAction) radioButton(text : trans("EXIT"), selected : bind {model.exitOnClose}, buttonGroup : closeBehaviorGroup, exitOnCloseAction) diff --git a/gui/src/main/groovy/com/muwire/gui/SharedFileNameRenderer.groovy b/gui/src/main/groovy/com/muwire/gui/SharedFileNameRenderer.groovy index e892cd76..1d9039c5 100644 --- a/gui/src/main/groovy/com/muwire/gui/SharedFileNameRenderer.groovy +++ b/gui/src/main/groovy/com/muwire/gui/SharedFileNameRenderer.groovy @@ -5,16 +5,28 @@ import com.muwire.core.SharedFile import javax.swing.JTable import javax.swing.table.DefaultTableCellRenderer import java.awt.Component +import java.nio.file.Path class SharedFileNameRenderer extends DefaultTableCellRenderer { + + private final UISettings settings + + SharedFileNameRenderer(UISettings settings) { + this.settings = settings + } + @Override Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column) SharedFile sf = (SharedFile) value String fullPath = HTMLSanitizer.sanitize(sf.getCachedPath()) - setText(fullPath) setToolTipText(fullPath) + if (settings.showUnsharedPaths || sf.getPathToSharedParent() == null) { + setText(fullPath) + } else { + setText(HTMLSanitizer.sanitize(sf.getCachedVisiblePath())) + } if (isSelected) { setForeground(table.getSelectionForeground()) setBackground(table.getSelectionBackground()) diff --git a/gui/src/main/groovy/com/muwire/gui/UISettings.groovy b/gui/src/main/groovy/com/muwire/gui/UISettings.groovy index 7a07ca49..eb5081b6 100644 --- a/gui/src/main/groovy/com/muwire/gui/UISettings.groovy +++ b/gui/src/main/groovy/com/muwire/gui/UISettings.groovy @@ -13,6 +13,7 @@ class UISettings { boolean autoFontSize int fontSize, fontStyle int mainFrameX, mainFrameY + boolean showUnsharedPaths boolean clearCancelledDownloads boolean clearFinishedDownloads boolean excludeLocalResult @@ -57,6 +58,8 @@ class UISettings { openTabs = DataUtil.readEncodedSet(props, "openTabs") messageNotifications = Boolean.parseBoolean(props.getProperty("messageNotifications","true")) + + showUnsharedPaths = Boolean.parseBoolean(props.getProperty("showUnsharedPaths","false")) } void write(OutputStream out) throws IOException { @@ -89,6 +92,8 @@ class UISettings { DataUtil.writeEncodedSet(openTabs, "openTabs", props) props.setProperty("messageNotifications", String.valueOf(messageNotifications)) + + props.setProperty("showUnsharedPaths", String.valueOf(showUnsharedPaths)) props.store(out, "UI Properties") }