npruehs / tome-editor

Tome is a generic data editor for games supporting arbitrary input and output formats.
GNU Lesser General Public License v3.0
36 stars 7 forks source link

Feature request: Better support for list/map custom types #135

Open pgrimsehl opened 6 years ago

pgrimsehl commented 6 years ago

Hi,

right now the support of list/map custom types is somewhat incomplete:

  1. The key type for maps is unrestricted, so we can use maps and lists as a key. Since they the underlying data type is a QVariantMap, which maps QString to QVariant, the map / list key will be converted to a string with toString(), which does not make sense for me and may produce unexpected behaviour.

  2. While lists and map types may contain list/map types as values in their definition, Tome fails to handle this case properly in its current state: a) Although editing of these values is possible, they are not displayed correctly within the list/map widgets (empty strings) b) Storing theses values in the .tdata file is impossible, because the current XML format specifies the value of a field as XML attribute. This does not allow for any structured values such as lists and maps.

Possible solutions:

  1. Disallow list and map types to be the key type in a map definition. Map keys should be limited to: Real, Integer, String and Reference or any custom type derived from these types.

  2. Simple solution: Disallow lists and maps as value types in list and map definitions. I do not favor this solution ;)

OR

  1. Support list and map value types in lists and maps, be applying the following changes. a) Represent list and map values as strings in the list and map edit widgets (as in the record field table). This representation must not be perfect (imagine a list of maps of maps), just give the user a visual hint b) Alter the .tdata XML format to allow to store these value types properly. And while at it, make the format specification more constistent ( Records are defined using the keyword element <Record> and defining their actual Id with an XML attribute. Fields on the other hand are not defined with a keyword element such as <Field>, but with the field name itself used as element name.)

These changes could be done in the following way:

Example

<?xml version="1.0" encoding="UTF-8"?>
<Records>
    <Record Id="A" DisplayName="A">
        <!--SampleString is a string-->
        <Field Id="SampleString">
            <Value>Test</Value>
        </Field>
        <!--SampleVector is a vector 3D int-->
        <Field Id="SampleVector">
            <Value>
                <Item>
                    <Key>X</Key>
                    <Value>1</Value>
                </Item>
                <Item>
                    <Key>Y</Key>
                    <Value>2</Value>
                </Item>
                <Item>
                    <Key>Z</Key>
                    <Value>3</Value>
                </Item>
            </Value>
        </Field>        
        <!--StringList is a list of strings-->
        <Field Id="StringList">
            <Value>
                <Item>
                    <Value>A<Value/>
                </Item>
                <Item>
                    <Value>B<Value/>
                </Item>
                <Item>
                    <Value>C<Value/>
                </Item>
                <Item>
                    <Value>D<Value/>
                </Item>
            </Value>
        </Field>
        <!--StringToIntMap is a map (string -> int)-->
        <Field Id="StringToIntMap">
            <Value>
                <Item>
                    <Key>MapKey00</Key>
                    <Value>15</Value>
                </Item>
                <Item>
                    <Key>MapKey01</Key>
                    <Value>20</Value>
                </Item>
            </Value>
        </Field>        
        <!--StringToIntMapList is a list of maps (string -> int)-->
        <Field Id="StringToIntMapList">
            <Value>
                <!-- List item at [0] -->
                <Item>
                    <Value>
                        <!-- map items -->
                        <Item>
                            <Key>MapKey00</Key>
                            <Value>1</Value>
                        </Item>
                        <Item>
                            <Key>MapKey01</Key>
                            <Value>2</Value>
                        </Item>
                        <Item>
                            <Key>MapKey02</Key>
                            <Value>3</Value>
                        </Item>
                    </Value>                        
                </Item>
                <!-- List item at [1] -->
                <Item>
                    <Value>
                        <!-- map items -->
                        <Item>
                            <Key>MapKey01</Key>
                            <Value>1</Value>
                        </Item>
                        <Item>
                            <Key>MapKey01</Key>
                            <Value>2</Value>
                        </Item>
                        <Item>
                            <Key>MapKey02</Key>
                            <Value>3</Value>
                        </Item>
                    <Value>
                </Item>
            </Value>
        </Field>
    </Record>
</Records>

What do you think about these changes?