diff --git a/forge-gui-desktop/src/main/java/forge/itemmanager/DeckManager.java b/forge-gui-desktop/src/main/java/forge/itemmanager/DeckManager.java index 707986841ad..1c70eb0e822 100644 --- a/forge-gui-desktop/src/main/java/forge/itemmanager/DeckManager.java +++ b/forge-gui-desktop/src/main/java/forge/itemmanager/DeckManager.java @@ -27,6 +27,7 @@ import forge.gui.UiCommand; import forge.gui.framework.FScreen; import forge.item.InventoryItem; +import forge.itemmanager.views.DeckNameCommentRenderer; import forge.itemmanager.views.ItemCellRenderer; import forge.itemmanager.views.ItemListView; import forge.itemmanager.views.ItemTableColumn; @@ -90,11 +91,21 @@ public void setup(final ItemManagerConfig config0) { Map colOverrides = null; if (config0.getCols().containsKey(ColumnDef.DECK_ACTIONS)) { + colOverrides = new HashMap<>(); final ItemTableColumn column = new ItemTableColumn(new ItemColumn(config0.getCols().get(ColumnDef.DECK_ACTIONS))); column.setCellRenderer(new DeckActionsRenderer()); - colOverrides = new HashMap<>(); colOverrides.put(ColumnDef.DECK_ACTIONS, column); } + + if (config0.getCols().containsKey(ColumnDef.NAME)) { + if (colOverrides == null) { + colOverrides = new HashMap<>(); + } + final ItemTableColumn nameColumn = new ItemTableColumn(new ItemColumn(config0.getCols().get(ColumnDef.NAME))); + nameColumn.setCellRenderer(new DeckNameCommentRenderer()); + colOverrides.put(ColumnDef.NAME, nameColumn); + } + super.setup(config0, colOverrides); if (isStringOnly != wasStringOnly) { diff --git a/forge-gui-desktop/src/main/java/forge/itemmanager/views/DeckNameCommentRenderer.java b/forge-gui-desktop/src/main/java/forge/itemmanager/views/DeckNameCommentRenderer.java new file mode 100644 index 00000000000..36b1f3bfe31 --- /dev/null +++ b/forge-gui-desktop/src/main/java/forge/itemmanager/views/DeckNameCommentRenderer.java @@ -0,0 +1,120 @@ +/* + * Forge: Play Magic: the Gathering. + * Copyright (C) 2011 Forge Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package forge.itemmanager.views; + +import java.awt.Component; +import java.util.Map.Entry; + +import javax.swing.JLabel; +import javax.swing.JTable; + + +import org.apache.commons.lang3.StringUtils; + +import forge.deck.Deck; +import forge.deck.DeckProxy; + +/** + * NAME column renderer for {@link forge.itemmanager.DeckManager}: shows deck display name and + * uses the deck file comment as the cell tooltip when present. + */ +@SuppressWarnings("serial") +public final class DeckNameCommentRenderer extends ItemCellRenderer { + + private static final int TOOLTIP_WRAP_WIDTH = 72; + + @Override + public Component getTableCellRendererComponent(final JTable table, final Object value, + final boolean isSelected, final boolean hasFocus, final int row, final int column) { + final JLabel lbl = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + final DeckProxy proxy = deckProxyFromRow(table, row); + if (proxy == null) { + lbl.setToolTipText(null); + return lbl; + } + final Deck deck = proxy.getDeck(); + final String comment = deck != null ? deck.getComment() : null; + final String trimmed = StringUtils.trimToNull(comment); + if (trimmed != null) { + lbl.setToolTipText(toHtmlWrappedTooltip(trimmed)); + } else { + lbl.setToolTipText(null); + } + return lbl; + } + + private static DeckProxy deckProxyFromRow(final JTable table, final int row) { + if (!(table.getModel() instanceof ItemListView.ItemTableModel)) { + return null; + } + final ItemListView.ItemTableModel tm = (ItemListView.ItemTableModel) table.getModel(); + final Entry entry = tm.rowToItem(row); + if (entry != null && entry.getKey() instanceof DeckProxy) { + return (DeckProxy) entry.getKey(); + } + return null; + } + + private static String toHtmlWrappedTooltip(final String comment) { + final String[] lines = comment.split("[\r\n]", -1); + final StringBuilder out = new StringBuilder(""); + for (int i = 0; i < lines.length; i++) { + if (i > 0) { + out.append("
"); + } + appendWrappedEscapedLine(out, lines[i]); + } + out.append(""); + return out.toString(); + } + + private static void appendWrappedEscapedLine(final StringBuilder out, final String line) { + final String escaped = escapeHtml(line); + if (escaped.isEmpty()) { + return; + } + String remaining = escaped; + boolean first = true; + while (remaining.length() > TOOLTIP_WRAP_WIDTH) { + int breakAt = remaining.lastIndexOf(' ', TOOLTIP_WRAP_WIDTH); + if (breakAt <= 0) { + breakAt = TOOLTIP_WRAP_WIDTH; + } + if (!first) { + out.append("
"); + } + out.append(remaining, 0, breakAt); + if (breakAt < remaining.length() && remaining.charAt(breakAt) == ' ') { + remaining = remaining.substring(breakAt + 1); + } else { + remaining = remaining.substring(breakAt); + } + first = false; + } + if (!remaining.isEmpty()) { + if (!first) { + out.append("
"); + } + out.append(remaining); + } + } + + private static String escapeHtml(final String s) { + return s.replace("&", "&").replace("<", "<").replace(">", ">").replace("\"", """); + } +}