From: Niki Roo Date: Fri, 17 May 2019 21:07:29 +0000 (+0200) Subject: ConfigItem: fix some errors, add jDoc X-Git-Url: http://git.nikiroo.be/?p=nikiroo-utils.git;a=commitdiff_plain;h=76b51de96af0b8dfa9615db37823fffd093fcfe3 ConfigItem: fix some errors, add jDoc --- diff --git a/src/be/nikiroo/utils/resources/MetaInfo.java b/src/be/nikiroo/utils/resources/MetaInfo.java index d95e98c..15ff762 100644 --- a/src/be/nikiroo/utils/resources/MetaInfo.java +++ b/src/be/nikiroo/utils/resources/MetaInfo.java @@ -3,9 +3,6 @@ package be.nikiroo.utils.resources; import java.util.ArrayList; import java.util.Iterator; import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; import be.nikiroo.utils.resources.Meta.Format; @@ -32,6 +29,19 @@ public class MetaInfo> implements Iterable> { private String name; private String description; + /** + * Create a new {@link MetaInfo} from a value (without children). + *

+ * For instance, you can call + * new MetaInfo(Config.class, configBundle, Config.MY_VALUE). + * + * @param type + * the type of enum the value is + * @param bundle + * the bundle this value belongs to + * @param id + * the value itself + */ public MetaInfo(Class type, Bundle bundle, E id) { this.bundle = bundle; this.id = id; @@ -79,7 +89,7 @@ public class MetaInfo> implements Iterable> { } /** - * THe name of this item, deduced from its ID. + * The name of this item, deduced from its ID. *

* In other words, it is the ID but presented in a displayable form. * @@ -98,20 +108,53 @@ public class MetaInfo> implements Iterable> { return description; } + /** + * The format this item is supposed to follow + * + * @return the format + */ public Format getFormat() { return meta.format(); } - // for ComboBox, this is mostly a suggestion + /** + * The allowed list of values that a {@link Format#FIXED_LIST} item is + * allowed to be, or a list of suggestions for {@link Format#COMBO_LIST} + * items. + * + * @return the list of values + */ public String[] getAllowedValues() { return meta.list(); } - // TODO: use it! + /** + * This item is a comma-separated list of values instead of a single value. + *

+ * The list items are separated by a comma, each surrounded by + * double-quotes, with backslashes and double-quotes escaped by a backslash. + *

+ * Example: "un", "deux" + * + * @return TRUE if it is + */ public boolean isArray() { return meta.array(); } + /** + * This item is only used as a group, not as an option. + *

+ * For instance, you could have LANGUAGE_CODE as a group for which you won't + * use the value in the program, and LANGUAGE_CODE_FR, LANGUAGE_CODE_EN + * inside for which the value must be set. + * + * @return TRUE if it is a group + */ + public boolean isGroup() { + return meta.group(); + } + /** * The value stored by this item, as a {@link String}. * @@ -121,46 +164,113 @@ public class MetaInfo> implements Iterable> { return value; } + /** + * The default value of this item, as a {@link String}. + * + * @return the default value + */ public String getDefaultString() { return meta.def(); } + /** + * The value stored by this item, as a {@link Boolean}. + * + * @return the value + */ public Boolean getBoolean() { return BundleHelper.parseBoolean(getString()); } + /** + * The default value of this item, as a {@link Boolean}. + * + * @return the default value + */ public Boolean getDefaultBoolean() { return BundleHelper.parseBoolean(getDefaultString()); } + /** + * The value stored by this item, as a {@link Character}. + * + * @return the value + */ public Character getCharacter() { return BundleHelper.parseCharacter(getString()); } + /** + * The default value of this item, as a {@link Character}. + * + * @return the default value + */ public Character getDefaultCharacter() { return BundleHelper.parseCharacter(getDefaultString()); } + /** + * The value stored by this item, as an {@link Integer}. + * + * @return the value + */ public Integer getInteger() { return BundleHelper.parseInteger(getString()); } + /** + * The default value of this item, as an {@link Integer}. + * + * @return the default value + */ public Integer getDefaultInteger() { return BundleHelper.parseInteger(getDefaultString()); } + /** + * The value stored by this item, as a colour (represented here as an + * {@link Integer}) if it represents a colour, or NULL if it doesn't. + *

+ * The returned colour value is an ARGB value. + * + * @return the value + */ public Integer getColor() { return BundleHelper.parseColor(getString()); } + /** + * The default value stored by this item, as a colour (represented here as + * an {@link Integer}) if it represents a colour, or NULL if it doesn't. + *

+ * The returned colour value is an ARGB value. + * + * @return the value + */ public Integer getDefaultColor() { return BundleHelper.parseColor(getDefaultString()); } + /** + * A {@link String} representation of the list of values. + *

+ * The list of values is comma-separated and each value is surrounded by + * double-quotes; backslashes and double-quotes are escaped by a backslash. + * + * @return the value + */ public List getList() { return BundleHelper.parseList(getString()); } + /** + * A {@link String} representation of the default list of values. + *

+ * The list of values is comma-separated and each value is surrounded by + * double-quotes; backslashes and double-quotes are escaped by a backslash. + * + * @return the value + */ public List getDefaultList() { return BundleHelper.parseList(getDefaultString()); } @@ -175,28 +285,66 @@ public class MetaInfo> implements Iterable> { this.value = value; } + /** + * The value stored by this item, as a {@link Boolean}. + * + * @param value + * the new value + */ public void setBoolean(boolean value) { setString(BundleHelper.fromBoolean(value)); } + /** + * The value stored by this item, as a {@link Character}. + * + * @param value + * the new value + */ public void setCharacter(char value) { setString(BundleHelper.fromCharacter(value)); } + /** + * The value stored by this item, as an {@link Integer}. + * + * @param value + * the new value + */ public void setInteger(int value) { setString(BundleHelper.fromInteger(value)); } + /** + * The value stored by this item, as a colour (represented here as an + * {@link Integer}) if it represents a colour, or NULL if it doesn't. + *

+ * The returned colour value is an ARGB value. + * + * @param value + * the value + */ public void setColor(int value) { setString(BundleHelper.fromColor(value)); } + /** + * A {@link String} representation of the default list of values. + *

+ * The list of values is comma-separated and each value is surrounded by + * double-quotes; backslashes and double-quotes are escaped by a backslash. + * + * @param value + * the {@link String} representation + * + */ public void setList(List value) { setString(BundleHelper.fromList(value)); } /** - * Reload the value from the {@link Bundle}. + * Reload the value from the {@link Bundle}, so the last value that was + * saved will be used. */ public void reload() { value = bundle.getString(id); @@ -210,7 +358,14 @@ public class MetaInfo> implements Iterable> { } } - // listeners will be called AFTER reload + /** + * Add a listener that will be called after a reload operation. + *

+ * You could use it to refresh the UI for instance. + * + * @param listener + * the listener + */ public void addReloadedListener(Runnable listener) { reloadedListeners.add(listener); } @@ -230,20 +385,43 @@ public class MetaInfo> implements Iterable> { bundle.setString(id, value); } - // listeners will be called BEFORE save + /** + * Add a listener that will be called before a save operation. + *

+ * You could use it to make some modification to the stored value before it + * is saved. + * + * @param listener + * the listener + */ public void addSaveListener(Runnable listener) { saveListeners.add(listener); } + /** + * The sub-items if any (if no sub-items, will return an empty list). + *

+ * Sub-items are declared when a {@link Meta} has an ID that starts with the + * ID of a {@link Meta#group()} {@link MetaInfo}. + *

+ * For instance: + *

    + *
  • {@link Meta} MY_PREFIX is a {@link Meta#group()}
  • + *
  • {@link Meta} MY_PREFIX_DESCRIPTION is another {@link Meta}
  • + *
  • MY_PREFIX_DESCRIPTION will be a child of MY_PREFIX
  • + *
+ * + * @return the sub-items if any + */ + public List> getChildren() { + return children; + } + @Override public Iterator> iterator() { return children.iterator(); } - public List> getChildren() { - return children; - } - /** * Create a list of {@link MetaInfo}, one for each of the item in the given * {@link Bundle}. @@ -260,55 +438,57 @@ public class MetaInfo> implements Iterable> { static public > List> getItems(Class type, Bundle bundle) { List> list = new ArrayList>(); + List> shadow = new ArrayList>(); for (E id : type.getEnumConstants()) { - list.add(new MetaInfo(type, bundle, id)); + MetaInfo info = new MetaInfo(type, bundle, id); + list.add(info); + shadow.add(info); } - return list; - } - - // TODO: multiple levels? - static public > Map, List>> getGroupedItems( - Class type, Bundle bundle) { - Map, List>> map = new TreeMap, List>>(); - Map, List>> map1 = new TreeMap, List>>(); - - List> ungrouped = new ArrayList>(); - for (MetaInfo info : getItems(type, bundle)) { - if (info.meta.group()) { - List> list = new ArrayList>(); - map.put(info, list); - map1.put(info, list); - } else { - ungrouped.add(info); - } - } + for (int i = 0; i < list.size(); i++) { + MetaInfo info = list.get(i); - for (int i = 0; i < ungrouped.size(); i++) { - MetaInfo info = ungrouped.get(i); - MetaInfo group = findParent(info, map.keySet()); - if (group != null) { - map.get(group).add(info); - ungrouped.remove(i--); + MetaInfo parent = findParent(info, shadow); + if (parent != null) { + list.remove(i--); + parent.children.add(info); } } - if (ungrouped.size() > 0) { - map.put(null, ungrouped); - } - - return map; + return list; } + /** + * Find the longest parent of the given {@link MetaInfo}, which means: + *
    + *
  • the parent is a {@link Meta#group()}
  • + *
  • the parent Id is a substring of the Id of the given {@link MetaInfo}
  • + *
  • there is no other parent sharing a substring for this + * {@link MetaInfo} with a longer Id
  • + *
+ * + * @param + * the kind of enum + * @param info + * the info to look for a parent for + * @param candidates + * the list of potential parents + * + * @return the longest parent or NULL if no parent is found + */ static private > MetaInfo findParent(MetaInfo info, - Set> candidates) { + List> candidates) { + String id = info.id.toString(); MetaInfo group = null; for (MetaInfo pcandidate : candidates) { - if (info.id.toString().startsWith(pcandidate.id.toString())) { - if (group == null - || group.id.toString().length() < pcandidate.id - .toString().length()) { - group = pcandidate; + if (pcandidate.isGroup()) { + String candidateId = pcandidate.id.toString(); + if (!id.equals(candidateId) && id.startsWith(candidateId)) { + if (group == null + || group.id.toString().length() < candidateId + .length()) { + group = pcandidate; + } } } } diff --git a/src/be/nikiroo/utils/ui/ConfigEditor.java b/src/be/nikiroo/utils/ui/ConfigEditor.java index 367396d..b2182ad 100644 --- a/src/be/nikiroo/utils/ui/ConfigEditor.java +++ b/src/be/nikiroo/utils/ui/ConfigEditor.java @@ -57,7 +57,7 @@ public class ConfigEditor> extends JPanel { items = MetaInfo.getItems(type, bundle); for (MetaInfo item : items) { - main.add(new ConfigItem(item)); + addItem(main, item); } main.add(createButton("Reset", new ActionListener() { @@ -98,6 +98,17 @@ public class ConfigEditor> extends JPanel { })); } + private void addItem(JPanel main, MetaInfo item) { + if (item.isGroup()) { + // TODO + for (MetaInfo subitem : item) { + addItem(main, subitem); + } + } else { + main.add(new ConfigItem(item)); + } + } + /** * Add an action button for this action. * diff --git a/src/be/nikiroo/utils/ui/ConfigItem.java b/src/be/nikiroo/utils/ui/ConfigItem.java index 95de836..9769ab1 100644 --- a/src/be/nikiroo/utils/ui/ConfigItem.java +++ b/src/be/nikiroo/utils/ui/ConfigItem.java @@ -28,11 +28,16 @@ import javax.swing.plaf.basic.BasicArrowButton; import be.nikiroo.utils.StringUtils; import be.nikiroo.utils.StringUtils.Alignment; import be.nikiroo.utils.resources.Bundle; +import be.nikiroo.utils.resources.Meta.Format; import be.nikiroo.utils.resources.MetaInfo; /** * A graphical item that reflect a configuration option from the given * {@link Bundle}. + *

+ * This graphical item can be edited, and the result will be saved back into the + * linked {@link MetaInfo}; you still have to save the {@link MetaInfo} should + * you wish to, of course. * * @author niki * @@ -42,10 +47,22 @@ import be.nikiroo.utils.resources.MetaInfo; public class ConfigItem> extends JPanel { private static final long serialVersionUID = 1L; + /** + * Create a new {@link ConfigItem} for the given {@link MetaInfo}. + * + * @param info + * the {@link MetaInfo} + */ public ConfigItem(MetaInfo info) { this.setLayout(new BorderLayout()); - switch (info.getFormat()) { + // TODO: support arrays + Format fmt = info.getFormat(); + if (info.isArray()) { + fmt = Format.STRING; + } + + switch (fmt) { case BOOLEAN: addBooleanField(info); break;