diff --git a/messages/src/main/proto/data_transfer_objects.proto b/messages/src/main/proto/data_transfer_objects.proto index b2d8bcc0d1..6d47b9572a 100644 --- a/messages/src/main/proto/data_transfer_objects.proto +++ b/messages/src/main/proto/data_transfer_objects.proto @@ -57,6 +57,9 @@ message LookupTableDto { bool visible = 5; bool allow_lookup = 6; bool pick_once = 7; + google.protobuf.StringValue group = 8; + google.protobuf.StringValue metadata = 9; + google.protobuf.StringValue metadata_type = 10; } message LookupEntryDto { diff --git a/src/main/java/net/rptools/maptool/client/functions/LookupTableFunction.java b/src/main/java/net/rptools/maptool/client/functions/LookupTableFunction.java index 3d67edd2b3..1b05480e7e 100644 --- a/src/main/java/net/rptools/maptool/client/functions/LookupTableFunction.java +++ b/src/main/java/net/rptools/maptool/client/functions/LookupTableFunction.java @@ -21,6 +21,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; +import java.util.stream.Collectors; import java.util.stream.Stream; import net.rptools.lib.MD5Key; import net.rptools.maptool.client.MapTool; @@ -45,6 +46,7 @@ public LookupTableFunction() { "tblImage", "tableImage", "getTableNames", + "getTableGroups", "getTableRoll", "setTableRoll", "clearTable", @@ -67,7 +69,11 @@ public LookupTableFunction() { "resetTablePicks", "getTablePickOnce", "setTablePickOnce", - "getTablePicksLeft"); + "getTablePicksLeft", + "getTableGroup", + "setTableGroup", + "getTableMetadata", + "setTableMetadata"); } /** The singleton instance. */ @@ -88,18 +94,39 @@ public Object childEvaluate( throws ParserException { if ("getTableNames".equalsIgnoreCase(function)) { + /* + getTableNames(delim) - get all/visible table names + getTableNames(delim, group) - get all/visible table names in a named group + */ + FunctionUtil.checkNumberParam("getTableNames", params, 0, 2); + String delim = ","; + String group = null; + if (params.size() > 0) { + delim = params.get(0).toString(); + } + if (params.size() > 1) { + group = params.get(1).toString(); + } + if ("json".equalsIgnoreCase(delim)) { + JsonArray jsonArray = new JsonArray(); + getTableList(MapTool.getPlayer().isGM(), group).forEach(jsonArray::add); + return jsonArray; + } + return StringUtils.join(getTableList(MapTool.getPlayer().isGM(), group), delim); + + } else if ("getTableGroups".equalsIgnoreCase(function)) { - FunctionUtil.checkNumberParam("getTableNames", params, 0, 1); + FunctionUtil.checkNumberParam("getTableGroups", params, 0, 1); String delim = ","; if (params.size() > 0) { delim = params.get(0).toString(); } if ("json".equalsIgnoreCase(delim)) { JsonArray jsonArray = new JsonArray(); - getTableList(MapTool.getPlayer().isGM()).forEach(jsonArray::add); + getTableGroupList(MapTool.getPlayer().isGM()).forEach(jsonArray::add); return jsonArray; } - return StringUtils.join(getTableList(MapTool.getPlayer().isGM()), delim); + return StringUtils.join(getTableGroupList(MapTool.getPlayer().isGM()), delim); } else if ("getTableVisible".equalsIgnoreCase(function)) { @@ -468,6 +495,52 @@ public Object childEvaluate( LookupTable lookupTable = getMaptoolTable(name, function); return lookupTable.getPicksLeft(); + } else if ("getTableGroup".equalsIgnoreCase(function)) { + /* + * getTableGroup(tblName) - get the named table's group + */ + checkTrusted(function); + FunctionUtil.checkNumberParam("getTableGroup", params, 1, 1); + String name = params.get(0).toString(); + LookupTable lookupTable = getMaptoolTable(name, function); + return lookupTable.getGroup(); + + } else if ("setTableGroup".equalsIgnoreCase(function)) { + /* + * setTableGroup(tblName, group) - set the named table's group + */ + checkTrusted(function); + FunctionUtil.checkNumberParam("setTableGroup", params, 2, 2); + String name = params.get(0).toString(); + String group = params.get(1).toString(); + LookupTable lookupTable = getMaptoolTable(name, function); + lookupTable.setGroup(group); + processMutatedLookupTable(lookupTable, true); + return ""; + + } else if ("getTableMetadata".equalsIgnoreCase(function)) { + /* + * getTableMetadata(tblName) - get the named table's metadata + */ + checkTrusted(function); + FunctionUtil.checkNumberParam("getTableMetadata", params, 1, 1); + String name = params.get(0).toString(); + LookupTable lookupTable = getMaptoolTable(name, function); + return lookupTable.getMetadata(); + + } else if ("setTableMetadata".equalsIgnoreCase(function)) { + /* + * setTableMetadata(tblName, metadata) - set the named table's metadata + */ + checkTrusted(function); + FunctionUtil.checkNumberParam("setTableMetadata", params, 2, 2); + String name = params.get(0).toString(); + String metadata = params.get(1).toString(); + LookupTable lookupTable = getMaptoolTable(name, function); + lookupTable.setMetadata(metadata); + processMutatedLookupTable(lookupTable, true); + return ""; + } else { // if tbl, table, tblImage or tableImage FunctionUtil.checkNumberParam(function, params, 1, 3); String name = params.get(0).toString(); @@ -570,21 +643,47 @@ private void processMutatedLookupTable(LookupTable lookupTable, boolean dataOnly } /** - * * If GM return all tables Otherwise only return visible tables + * * If GM return all tables otherwise only return visible tables, optionally filtered by table + * group * - * @param isGm boolean Does the calling function has GM privileges + * @param isGm boolean Does the calling function has GM privilege + * @param group String Only return tables in the group * @return a list of table names */ - private List getTableList(boolean isGm) { + private List getTableList(boolean isGm, String group) { List tables = new ArrayList<>(); - if (isGm) tables.addAll(MapTool.getCampaign().getLookupTableMap().keySet()); - else - MapTool.getCampaign().getLookupTableMap().values().stream() - .filter(LookupTable::getVisible) - .forEachOrdered((lt) -> tables.add(lt.getName())); + var stream = MapTool.getCampaign().getLookupTableMap().values().stream(); + if (!isGm) { + stream = stream.filter(LookupTable::getVisible); + } + if (group != null) { + stream = stream.filter(lt -> lt.getGroup().equals(group)); + } + stream.forEachOrdered((lt) -> tables.add(lt.getName())); return tables; } + /** + * If GM return all table groups otherwise only return groups for visible tables + * + * @param isGm does the calling function has GM privileges + * @return a list of table groups + */ + private List getTableGroupList(boolean isGm) { + return MapTool.getCampaign().getLookupTableMap().values().stream() + // If not GM, only keep visible tables + .filter(lt -> isGm || lt.getVisible()) + // Get the group name from the table + .map(LookupTable::getGroup) + // Remove any null groups + .filter(Objects::nonNull) + // Remove duplicate groups + .distinct() + // Sort groups + .sorted() + .collect(Collectors.toList()); + } + /** * Function to return a MapTool table. * diff --git a/src/main/java/net/rptools/maptool/client/ui/lookuptable/EditLookupTablePanel.java b/src/main/java/net/rptools/maptool/client/ui/lookuptable/EditLookupTablePanel.java index ff9fe32e45..bfe27deecf 100644 --- a/src/main/java/net/rptools/maptool/client/ui/lookuptable/EditLookupTablePanel.java +++ b/src/main/java/net/rptools/maptool/client/ui/lookuptable/EditLookupTablePanel.java @@ -22,18 +22,20 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.ArrayList; import java.util.List; import java.util.Objects; import javax.annotation.Nullable; -import javax.swing.BorderFactory; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JTable; -import javax.swing.WindowConstants; +import javax.swing.*; import javax.swing.table.AbstractTableModel; import javax.swing.table.TableCellRenderer; import net.rptools.lib.MD5Key; +import net.rptools.maptool.client.AppConstants; +import net.rptools.maptool.client.AppPreferences; import net.rptools.maptool.client.MapTool; import net.rptools.maptool.client.MapToolUtil; import net.rptools.maptool.client.swing.AbeillePanel; @@ -48,6 +50,10 @@ import net.rptools.maptool.model.AssetManager; import net.rptools.maptool.model.LookupTable; import net.rptools.maptool.model.LookupTable.LookupEntry; +import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; +import org.fife.ui.rsyntaxtextarea.SyntaxConstants; +import org.fife.ui.rsyntaxtextarea.Theme; +import org.fife.ui.rtextarea.RTextScrollPane; public class EditLookupTablePanel extends AbeillePanel { private static final int PICKED_COLUMN_INDEX = 0; @@ -99,6 +105,7 @@ public void showDialog(@Nullable LookupTable lookupTable, boolean isNew) { .setIcon(RessourceManager.getSmallIcon(Icons.TABLEPANEL_TABLE_PLAYER_LOOKUP)); view.getPickOnceIcon().setIcon(RessourceManager.getSmallIcon(Icons.TABLEPANEL_TABLE_PICK_ONCE)); + loadTableGroups(); bind(lookupTable); dialogFactory.display(); @@ -188,11 +195,73 @@ public void initTableImage() { replaceComponent(view.getTableImagePlaceholder(), tableImageAssetPanel); } + public void initMetadataSyntaxArea() { + + // configure the syntax text area + RSyntaxTextArea rsta = view.getTableMetadata(); + rsta.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_NONE); + rsta.setCodeFoldingEnabled(true); + rsta.setEditable(true); + rsta.setInsertPairedCharacters(false); + rsta.setLineWrap(true); + rsta.setTabSize(4); + rsta.setWrapStyleWord(true); + rsta.setUseFocusableTips(false); + + RTextScrollPane rtsp = view.getTableMetadataScrollPane(); + rtsp.setLineNumbersEnabled(true); + + // theme the syntax text area + Path themePath = + AppConstants.THEMES_DIR + .toPath() + .resolve(AppPreferences.defaultMacroEditorTheme.get() + ".xml"); + try (InputStream in = Files.newInputStream(themePath)) { + Theme.load(in).apply(rsta); + } catch (IOException e) { + System.err.println("Unable to load theme: " + themePath + " " + e); + } + + JComboBox syntaxStyle = view.getTableMetadataType(); + syntaxStyle.addItem(SyntaxConstants.SYNTAX_STYLE_NONE); + syntaxStyle.addItem(SyntaxConstants.SYNTAX_STYLE_CSV); + syntaxStyle.addItem(SyntaxConstants.SYNTAX_STYLE_HTML); + syntaxStyle.addItem(SyntaxConstants.SYNTAX_STYLE_JSON); + syntaxStyle.addItem(SyntaxConstants.SYNTAX_STYLE_MARKDOWN); + syntaxStyle.addItem(SyntaxConstants.SYNTAX_STYLE_XML); + + syntaxStyle.addActionListener( + e -> { + rsta.setSyntaxEditingStyle((String) syntaxStyle.getSelectedItem()); + }); + } + + /** + * Populate the Table Groups ComboBox with groups already used. Should be outside an {@code init*} + * method as needs to respond to group changes. + */ + public void loadTableGroups() { + view.getTableGroup().removeAllItems(); + + MapTool.getCampaign().getLookupTableMap().values().stream() + // Get the group name from the table + .map(LookupTable::getGroup) + // Remove any null groups + .filter(Objects::nonNull) + // Remove duplicate groups + .distinct() + // Sort groups + .sorted() + // Add to the ComboBox + .forEach(group -> view.getTableGroup().addItem(group)); + } + @Override public void bind(LookupTable lookupTable) { super.bind(lookupTable); view.getTableName().setText(lookupTable.getName()); + view.getTableGroup().setSelectedItem(lookupTable.getGroup()); view.getDefaultTableRoll() .setText(lookupTable.getPickOnce() ? "" : lookupTable.calculateRoll()); tableImageAssetPanel.setImageId(lookupTable.getTableImage()); @@ -203,6 +272,12 @@ public void bind(LookupTable lookupTable) { view.getDefaultTableRoll().setEnabled(!lookupTable.getPickOnce()); view.getResetPicks().setEnabled(lookupTable.getPickOnce()); + view.getTableMetadata().setText(lookupTable.getMetadata()); + view.getTableMetadataType().setSelectedItem(lookupTable.getMetadataType()); + if (view.getTableMetadataType().getSelectedItem() == null) { + view.getTableMetadataType().setSelectedItem(SyntaxConstants.SYNTAX_STYLE_NONE); + } + view.getTableName().requestFocusInWindow(); var model = new LookupTableTableModel(); @@ -241,6 +316,14 @@ public boolean commit() { } var isPickOnce = view.getPickOnce().isSelected(); + // Get the selected or entered table group from the combo box + Object selectedTableGroup = view.getTableGroup().getSelectedItem(); + String group = selectedTableGroup == null ? "" : selectedTableGroup.toString(); + + String metadata = view.getTableMetadata().getText().trim(); + String metadataType = + Objects.requireNonNull(view.getTableMetadataType().getSelectedItem()).toString(); + // Before modifying the table, parse and validate all the entries to avoid partial modification // in case of error. var entries = new ArrayList(); @@ -284,11 +367,14 @@ public boolean commit() { // save existing name for later removal from LookupTableMap String origname = lookupTable.getName(); lookupTable.setName(name); + lookupTable.setGroup(group); lookupTable.setPickOnce(isPickOnce); lookupTable.setRoll(isPickOnce ? null : view.getDefaultTableRoll().getText()); lookupTable.setTableImage(tableImageAssetPanel.getImageId()); lookupTable.setVisible(view.getIsVisible().isSelected()); lookupTable.setAllowLookup(view.getAllowLookup().isSelected()); + lookupTable.setMetadata(metadata); + lookupTable.setMetadataType(metadataType); lookupTable.clearEntries(); for (var entry : entries) { diff --git a/src/main/java/net/rptools/maptool/client/ui/lookuptable/EditLookupTablePanelView.form b/src/main/java/net/rptools/maptool/client/ui/lookuptable/EditLookupTablePanelView.form index 2512356cdf..8e9a8cd65a 100644 --- a/src/main/java/net/rptools/maptool/client/ui/lookuptable/EditLookupTablePanelView.form +++ b/src/main/java/net/rptools/maptool/client/ui/lookuptable/EditLookupTablePanelView.form @@ -1,32 +1,16 @@
- + - + - - - - - - - - - - - - - - - - - + @@ -44,7 +28,7 @@ - + @@ -52,7 +36,7 @@ - + @@ -61,7 +45,7 @@ - + @@ -71,7 +55,7 @@ - + @@ -81,17 +65,17 @@ - + - + - + @@ -102,7 +86,7 @@ - + @@ -119,7 +103,7 @@ - + @@ -137,7 +121,7 @@ - + @@ -145,7 +129,7 @@ - + @@ -154,7 +138,7 @@ - + @@ -163,7 +147,7 @@ - + @@ -171,13 +155,119 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + diff --git a/src/main/java/net/rptools/maptool/client/ui/lookuptable/EditLookupTablePanelView.java b/src/main/java/net/rptools/maptool/client/ui/lookuptable/EditLookupTablePanelView.java index 7802961c5c..674de5da74 100644 --- a/src/main/java/net/rptools/maptool/client/ui/lookuptable/EditLookupTablePanelView.java +++ b/src/main/java/net/rptools/maptool/client/ui/lookuptable/EditLookupTablePanelView.java @@ -15,11 +15,14 @@ package net.rptools.maptool.client.ui.lookuptable; import javax.swing.*; +import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; +import org.fife.ui.rtextarea.RTextScrollPane; public class EditLookupTablePanelView { private JPanel mainPanel; private JTextField tableName; + private JComboBox tableGroup; private JTextField defaultTableRoll; private JCheckBox isVisible; private JCheckBox allowLookup; @@ -30,6 +33,9 @@ public class EditLookupTablePanelView { private JLabel isVisibleIcon; private JLabel allowLookupIcon; private JLabel pickOnceIcon; + private RSyntaxTextArea tableMetadata; + private RTextScrollPane tableMetadataScrollPane; + private JComboBox tableMetadataType; public JComponent getRootComponent() { return mainPanel; @@ -39,6 +45,10 @@ public JTextField getTableName() { return tableName; } + public JComboBox getTableGroup() { + return tableGroup; + } + public JTextField getDefaultTableRoll() { return defaultTableRoll; } @@ -78,4 +88,16 @@ public JLabel getAllowLookupIcon() { public JLabel getPickOnceIcon() { return pickOnceIcon; } + + public RSyntaxTextArea getTableMetadata() { + return tableMetadata; + } + + public RTextScrollPane getTableMetadataScrollPane() { + return tableMetadataScrollPane; + } + + public JComboBox getTableMetadataType() { + return tableMetadataType; + } } diff --git a/src/main/java/net/rptools/maptool/client/ui/lookuptable/LookupTableDetailsTablePanelModel.java b/src/main/java/net/rptools/maptool/client/ui/lookuptable/LookupTableDetailsTablePanelModel.java index f5fe608cf1..537eb0475f 100644 --- a/src/main/java/net/rptools/maptool/client/ui/lookuptable/LookupTableDetailsTablePanelModel.java +++ b/src/main/java/net/rptools/maptool/client/ui/lookuptable/LookupTableDetailsTablePanelModel.java @@ -35,17 +35,19 @@ public class LookupTableDetailsTablePanelModel extends AbstractTableModel { List.of( DetailsTableColumn.IMAGE, DetailsTableColumn.NAME, + DetailsTableColumn.GROUP, DetailsTableColumn.PLAYER_VISIBLE, DetailsTableColumn.ALLOW_LOOKUP, DetailsTableColumn.PICK_ONCE, DetailsTableColumn.ROLL, DetailsTableColumn.COUNT_ENTRIES, DetailsTableColumn.COUNT_VALUES, - DetailsTableColumn.COUNT_IMAGES); + DetailsTableColumn.COUNT_IMAGES, + DetailsTableColumn.METADATA); /** Defines the details view columns visible for non-GMs and their sequence */ private static final List PLAYER_COLUMNS = - List.of(DetailsTableColumn.IMAGE, DetailsTableColumn.NAME); + List.of(DetailsTableColumn.IMAGE, DetailsTableColumn.NAME, DetailsTableColumn.GROUP); /** * Retries the set list of details view columns based on GM role or not @@ -88,7 +90,7 @@ Object getValue(LookupTable table) { String.class, SwingConstants.LEFT, 200, - Icons.WINDOW_TABLES, + null, null, null) { @Override @@ -96,6 +98,20 @@ Object getValue(LookupTable table) { return table.getName(); } }, + GROUP( + I18N.getText("Label.group"), + I18N.getText("LookupTablePanel.group.tooltip"), + String.class, + SwingConstants.LEFT, + 100, + null, + null, + null) { + @Override + Object getValue(LookupTable table) { + return table.getGroup(); + } + }, PLAYER_VISIBLE( null, I18N.getText("EditLookupTablePanel.showplayer"), @@ -193,6 +209,20 @@ Object getValue(LookupTable table) { Object getValue(LookupTable table) { return table.getEntryImageCount(); } + }, + METADATA( + I18N.getText("EditLookupTablePanel.tab.metadata"), + I18N.getText("LookupTablePanel.metadata.tooltip"), + String.class, + SwingConstants.LEFT, + 100, + null, + null, + null) { + @Override + Object getValue(LookupTable table) { + return table.hasMetadata() ? table.getMetadataType() : ""; + } }; private final String title; diff --git a/src/main/java/net/rptools/maptool/client/ui/lookuptable/LookupTablePanel.java b/src/main/java/net/rptools/maptool/client/ui/lookuptable/LookupTablePanel.java index c8491e5527..7c4e56c1b6 100644 --- a/src/main/java/net/rptools/maptool/client/ui/lookuptable/LookupTablePanel.java +++ b/src/main/java/net/rptools/maptool/client/ui/lookuptable/LookupTablePanel.java @@ -47,6 +47,9 @@ public class LookupTablePanel extends AbeillePanel { /** a tabular view of {@link LookupTable}s' details */ private LookupTableDetailsTablePanel detailsTablePanel; + /** cache edit panel instance so position and dimensions are retained within the session */ + private EditLookupTablePanel editLookupTablePanel; + /** manages the different views and so only one is visible as a time */ private CardLayout viewLayout; @@ -55,6 +58,13 @@ public LookupTablePanel() { panelInit(); } + private EditLookupTablePanel getEditLookupTablePanel() { + if (editLookupTablePanel == null) { + editLookupTablePanel = new EditLookupTablePanel(); + } + return editLookupTablePanel; + } + /** the view options */ private enum ViewMode { /** a view of {@code LookupTable} images and their names as labels. */ @@ -134,7 +144,7 @@ public void mouseClicked(MouseEvent e) { if (detailsTable.columnAtPoint(e.getPoint()) == 0) { lookupTableRoll(lookupTable); } else { - new EditLookupTablePanel().showDialog(lookupTable, false); + getEditLookupTablePanel().showDialog(lookupTable, false); } } else { lookupTableRoll(lookupTable); @@ -219,7 +229,7 @@ public void initDuplicateButton() { } LookupTable lookupTable = new LookupTable(selected); lookupTable.setName("Copy of " + lookupTable.getName()); - new EditLookupTablePanel().showDialog(lookupTable, true); + getEditLookupTablePanel().showDialog(lookupTable, true); imagePanel.clearSelection(); refreshStructure(); @@ -236,7 +246,7 @@ public void initEditTableButton() { if (lookupTable == null) { return; } - new EditLookupTablePanel().showDialog(lookupTable, false); + getEditLookupTablePanel().showDialog(lookupTable, false); refreshData(); }); } @@ -247,7 +257,7 @@ public void initNewTableButton() { getNewButton() .addActionListener( e -> { - new EditLookupTablePanel().showDialog(new LookupTable(), true); + getEditLookupTablePanel().showDialog(new LookupTable(), true); imagePanel.clearSelection(); refreshStructure(); }); diff --git a/src/main/java/net/rptools/maptool/model/LookupTable.java b/src/main/java/net/rptools/maptool/model/LookupTable.java index 5bb5ebe271..942835c908 100644 --- a/src/main/java/net/rptools/maptool/model/LookupTable.java +++ b/src/main/java/net/rptools/maptool/model/LookupTable.java @@ -27,6 +27,7 @@ import net.rptools.maptool.server.proto.LookupTableDto; import net.rptools.maptool.util.ExpressionParserFactory; import net.rptools.parser.ParserException; +import org.fife.ui.rsyntaxtextarea.SyntaxConstants; public class LookupTable { @@ -34,6 +35,7 @@ public class LookupTable { private @Nonnull List entryList = new ArrayList<>(); private @Nullable String name; + private @Nullable String group; private @Nullable String defaultRoll; private @Nullable MD5Key tableImage; private @Nonnull Boolean visible = true; @@ -41,6 +43,8 @@ public class LookupTable { // Flags a table as Pick Once, i.e. each entry can only be chosen once before the // table must be reset(). private @Nonnull Boolean pickOnce = false; + private @Nullable String metadata; + private @Nullable String metadataType; public static final String NO_PICKS_LEFT = "NO_PICKS_LEFT"; @@ -48,12 +52,15 @@ public LookupTable() {} public LookupTable(LookupTable table) { name = table.name; + group = table.group; defaultRoll = table.defaultRoll; tableImage = table.tableImage; pickOnce = table.pickOnce; visible = table.visible; allowLookup = table.allowLookup; entryList.addAll(table.entryList); + metadata = table.metadata; + metadataType = table.metadataType; } public String getRoll() { @@ -94,6 +101,30 @@ public String getName() { return name; } + public void setGroup(@Nullable String group) { + this.group = group; + } + + public String getGroup() { + return group == null ? "" : group; + } + + public void setMetadata(@Nullable String metadata) { + this.metadata = metadata; + } + + public String getMetadata() { + return metadata == null ? "" : metadata; + } + + public void setMetadataType(@Nullable String metadataType) { + this.metadataType = metadataType; + } + + public @Nullable String getMetadataType() { + return metadataType == null ? SyntaxConstants.SYNTAX_STYLE_NONE : metadataType; + } + /** * Finds the first entry that matches a given roll result. * @@ -532,9 +563,19 @@ public long getEntryValueCount() { .count(); } + /** + * Returns if the table has any metadata or not. + * + * @return true/false + */ + public boolean hasMetadata() { + return metadata != null && !metadata.isBlank(); + } + public static LookupTable fromDto(LookupTableDto dto) { var table = new LookupTable(); table.name = dto.hasName() ? dto.getName().getValue() : null; + table.group = dto.hasGroup() ? dto.getGroup().getValue() : null; table.entryList = dto.getEntriesList().stream().map(e -> LookupEntry.fromDto(e)).collect(Collectors.toList()); table.defaultRoll = dto.hasDefaultRoll() ? dto.getDefaultRoll().getValue() : null; @@ -542,6 +583,8 @@ public static LookupTable fromDto(LookupTableDto dto) { table.setVisible(dto.getVisible()); table.setAllowLookup(dto.getAllowLookup()); table.setPickOnce(dto.getPickOnce()); + table.metadata = dto.hasMetadata() ? dto.getMetadata().getValue() : null; + table.metadataType = dto.hasMetadataType() ? dto.getMetadataType().getValue() : null; return table; } @@ -551,6 +594,9 @@ public LookupTableDto toDto() { if (name != null) { dto.setName(StringValue.of(name)); } + if (group != null) { + dto.setGroup(StringValue.of(group)); + } if (defaultRoll != null) { dto.setDefaultRoll(StringValue.of(defaultRoll)); } @@ -560,6 +606,12 @@ public LookupTableDto toDto() { dto.setVisible(visible); dto.setAllowLookup(allowLookup); dto.setPickOnce(pickOnce); + if (metadata != null) { + dto.setName(StringValue.of(metadata)); + } + if (metadataType != null) { + dto.setName(StringValue.of(metadataType)); + } return dto.build(); } } diff --git a/src/main/resources/net/rptools/maptool/language/i18n.properties b/src/main/resources/net/rptools/maptool/language/i18n.properties index 7ca803a223..dd40e8753d 100644 --- a/src/main/resources/net/rptools/maptool/language/i18n.properties +++ b/src/main/resources/net/rptools/maptool/language/i18n.properties @@ -260,6 +260,7 @@ Label.lights = Vision Label.type = Type Label.name = Name Label.gmname = GM Name +Label.group = Group Label.speechName = Speech Bubble Name Label.optional = Optional Label.options = Options @@ -438,6 +439,8 @@ EditLookupTablePanel.showplayer = Show Table to Players EditLookupTablePanel.lookup = Allow Lookup by Players EditLookupTablePanel.pickOnce = Pick Once Table EditLookupTablePanel.resetPicks = Reset Picks +EditLookupTablePanel.tab.entries = Entries +EditLookupTablePanel.tab.metadata = Metadata EditTokenDialog.label.label = Label EditTokenDialog.menu.notes.sendChat = Send to Chat @@ -678,12 +681,14 @@ LookupTablePanel.error.saveFailed = Could not save table "{0}". LookupTablePanel.info.saved = Table saved as "{0}". LookupTablePanel.msg.titleEdit = Edit Table LookupTablePanel.msg.titleNew = New Table +LookupTablePanel.group.tooltip = Table group (optional). LookupTablePanel.countEntries = Entries LookupTablePanel.countEntries.tooltip = A count of the number of table entries. LookupTablePanel.countValues = Values LookupTablePanel.countValues.tooltip = A count of the number of table entries with values. LookupTablePanel.countImages = Images LookupTablePanel.countImages.tooltip = A count of the number of table entries with images. +LookupTablePanel.metadata.tooltip = The metadata type if the table has metadata. LookupTablePanel.viewIcons = Icons LookupTablePanel.viewDetails = Details LookupTablePanel.viewIcons.tooltip = Show an icon view of table images and name labels.