I haven't responded to this thread up till now because I have been busily working on improving ShowEQ.
The experience window position is saved in the "Experience" section with the rest of the Experience window properties. It looks as follows (those who actually looked as oppossed to typing up random trash should recognize it):
Code:
<section name="Experience" >
<property name="WindowPos" >
<point x="320" y="307" />
</property>
<property name="WindowSize" >
<size width="640" height="409" />
</property>
</section>
It has too seperate properties WindowPos and WindowSize.
They are stored seperately because they are used seperately and differently. The WindowPos (positition) is only used if a window is undocked AND the "UseWindowPos" is true in the "Interface" section, whereas the WindowSize (size) is always used. The <point> tag in the "WindowPos" property represents a QPoint that gets past to QWidget::move(). The <size> tag in the "WindowSize" property which represents a QSize that gets past to QWidget::resize().
Using this XML Preference system I could have saved it like this:
Code:
<section name="Experience" >
<property name="Window" >
<rect x="320" y="307" width="640" height="409" />
</property>
</section>
I could have done that, but didn't do to the usage, including the fact that for some of the windows (prior to a recent change) their were situations were the size would be saved and NOT the position and vice versa.
Generally the XML format is a basic hierarchy:
Code:
<seqpreferences version="1.0">
<section name="Name1">
<!-- Assorted property -->
<property name="property1">
<datatype tag />
<comment></comment>
</property>
<property name="property2">
</property>
</section>
<section name="Name2">
<!-- Assorted properties -->
</section>
</seqpreferences>
Where the <section> breaks tags organize the file into multiple sections used by different aspects of the program, not all of which are simple windows. The <property> tags organize the data by a specific retrievable tag. The <datatype tag> shown above is a stand in for the group of tags used to represent the Qt data types representable in a QVariant. Most of the currently implemented data type tags represent simple data types, plus one non-simple data type, these are (attributes included in square brackets [] are optional):
Code:
<string value="" />
<!-- Represents a QString -->
<int value="" [base=""] />
<!-- Represents a signed integer in the optionally specified base>
<uint value="" [base=""] />
<!-- Represents an unsigned integer in the optionally specified base-->
<double value="" />
<!-- Represents a floating point number -->
<bool value="" />
<!-- Represents a boolean (true/false, 1/0) -->
<color [name=""] [red="" green="" blue="" [base=""]] />
<!-- Represents a QColor either by name or by it's RGB value -->
<point x="" y=">
<!-- Represents a QPoint -->
<rect x="" y="" width="" height="">
<!-- Represents a QRect -->
<size width="" height="">
<!-- Represents a QSize -->
<key sequence="" />
<!-- Represents a Qt 3.x QKeySequence /
string usable with Qt 2.x QAccel::stringToKey() -->
<font [family=""] [ponitsize=""] [bold=""] [italic=""] [strikeout=""] />
<!-- Represents a QFont -->
<sizepolicy [hsizetype=""] [vsizetype=""] [horstretch=""] [verstretch=""] />
<!-- Represents a QSizePolicy -->
<cursor shape="" />
<!-- Represents a QCursor -->
<stringlist>
<string value="" />
<!-- Any number of strings -->
<string value="" />
</stringlist>
<!-- Represents a QStringList -->
There are also two complex datatype tags that are not yet implemented (mostly because I hadn't needed them yet):
Code:
<list>
<datatype tag />
<!-- Any number and combination of datatype tags -->
<datatype tag />
</list>
<!-- Represents a QValueList<QVariant> -->
<map>
[string value=""] <datatype tag />
<!-- Any number and combination of datatype tags preceded by a string key -->
[string value=""] <datatype tag />
</map>
<!-- Represents a QMap<QString, QVariant> -->
The complex data types <stringlist>, <list>, and <map> are why I have a seperate <property> tag to name and delineate the properties within the sections instead of just throwing a name="propertyName" attribute in on all the datatype tags, since such an attribute would be meaningless in those contexts.
The advantages of this XML based preferences system are:- It makes parsing the configuration file much simpler and less prone to error.
- It organizes the data in a uniform way that represents different Qt datatypes, including complex data types that can contain other datatypes, without using 4-50 unrelated entries. So no more:
Code:
[Interface]
x = 5
y = 10
width = 640
height = 480
Font = Helvetica
FontSize = 8
FontBold = 0
- It allowed for a minimum number of modifications to the existing codes use of preferences. Those who've modifed ShowEQ before probably know why this particular advantage is important (hint: you touched X, and Y seemingly unrelated behavior happens).
- It resolves many of the long outstanding issues and bugs that existed in the previous configuration system (Map colors anyone? How about strings with spaces? Heh, how about corrupting comments?).
- Supports some level of configuration file data validation.
- Is not a binary configuration format (ala Windows registry)
- There are a wide variety of fine XML editors available for those who choose to manually edit the files.
- It works under both Qt 2.x and Qt 3.x (more difficult to manage then it should be) using Qt's DOM implementation (I could go on a serious rant about that).
- It doesn't force all the users to migrate to a new version of Qt (3.x) nor require adding a new compilation requirement (such as a real XML parser like Apache Xerces C++ that is a validating XML parser that supports DTD's, XML namespaces, XML Schemas and provides a reasonable implementation of DOM Level 2).
- It was something I was willing to spend the time and write, as opposed to writing yet another brain dead INI file format reader.
Enjoy (or not),
Zaphod (dohpaZ)
P.S. In the time it took to compose this post I could have put in a method of persisting changes to the message dialogs.