XML Viewer - Overview

- the GUI for the RecvData Module-
 


 
Models used for numerical simulations of the Earth's clima are producing a lot of data usually saved in a big pool of variables. The best way to maintain an overview over the computed data is to create a hierarchical structure based on following observations:
  • the models consist in a set of interacting modules (e.g. atmosphere, biosphere, etc.)
  • inside each module, different processes are beeing simulated (e.g. inside the module atmosphere one can define the processes thermodynamics, dynamics, etc.)
  • inside a process, the computed data can be splitted in categories (e.g. diagnostic, prognostic, etc.)
  • each category can contain variables (here called rows) also grouped in small structures
  • every row can contain none, one or many columns (e.g. description of the variable, units and the code of the variable) and none, one or many rows (in this way the small structures will be created)
The pupose of the project is to create a Graphical User Interface (GUI), which will provide a user-friendly mechanism for the selection of the variables.
The structure of the model wiil be saved as an XML file based on a well-defined XML grammar named Data Type Definition (DTD). 
The <structure> tag is the root tag of the XML document. He will contain one <labeling> tag, none, one or many <module> tags and an <help> tag.
The <labeling> tag contains the data needed to initialize the GUI (the caption string, box labels and column labels, also the column numbers for the description, units and code of a variable - needed for the return sequence called by gui_name).
The <help> tag can contain an entire HTML file which will be shown when the Help button is pressed.
The <module>, <process> and <category> tags represents a module, a process respectivelly a category as described above.
An <module> tag contains one <modulelabel> tag (which includes the name of the module) and none, one or many <process> tags. An <process> tag contains one <processlabel> tag (which includes the name of the process) and none, one or many <category> tags. An <category> tag contains one <categorylabel> tag (which includes the name of the category) and none, one or many <row> tags.
Each <row> tag represents one row in the GUI and contains none, one or many <cell> tags, and none, one or many <row> tags. A <row> tag also has an optional attribute named "default"of type boolean ("0" = false, "1" = true) which describes whether or not the row will be selected by default inside the GUI. 
Each <cell> tag can contain none, one or many <word> tags. A <cell> tag is the representation of a column in the GUI which can be created by concatenating the <word> tags inside it, separated by a comma.
A the text tags such as <modulelabel>, <processlabel>, <category>, <columnlabel>, <word> and <help> can contain any type of text data, including a HTML file.

Regarding the DTD of the XML file, the best design found was to create an object for each XML tag.

So we have one object of type VObject for the tags <module>, <process> and <category>. For each <row> tag it exists an VRow object and for each <cell> tag an VCell object. The help dialog (HelpGUI) is created with QtDesigner and it containts a QTextBrowser which will receive the data inside of the <help> tag. Another dialog created with the QtDesigner is SelectionGUI. This QDialog contains only the graphical design of the GUI. Thea implementation of the user interaction is in the VSelectionGUI class which extends SelectionGUI. DialogThread is a QThread class, created to keep the event loop of the GUI.

At the startup, the main function invokes "gui_init(xmlText)". This creates a DialogThread which creates a VSelectionGUI. The VSelectionGUI object reads in the xmlText passed trough it in the constructor. After processing the <labeling> tag and the <help> tag, the <module> tags are added, an VObject of type "module", to an object VObject named "rootObject" which is used as a list of modules. Each module can have none, one or more VObjects of type "process". The <row> tag an the <cell> tag are represented by an VRow object, respectively an VCell object.

Each process can have none, one or more VObjects of type "category". Each category can have none, one or more VRows. Each row can have none, one or more VCells and can also include none, one or more VRows. An VObject has an QList<VObject> named "childrensList" and an VRow* named "rowList". The "childrenList" is used only if the VObject is an module or a process; otherwise "rowList" is used to save the children.

When Apply is pressed, the VSelectionGUI invokes rootObject's "getSelection(this)". This method is invoked recursively (top-down). By passing this (of type VSelectionGUI) to each object in the data tree, each object would add itself (if it is selected) to the selection list by invoking VSelectionGUI's "addListSelected(this)", where "this" is of type VRow (the VObject objects are only passing the invokation down to their children). The "addListSelected" method inserts into the QList<QString> "currentChoiceList" the codes from the selected variables - which will be returned with the "vect_code_names* gui_choice(void)" method defined in the "Interface.h".

The method "char* gui_name(char* single_code_name)" also defined in "Interface.h", returns the entire row from the list. This return value contains the description, the units and the code of the variable in the column defined by the "descriptioncolumn", the "unitscolumn" respectively by the "codecolumn" attributes in the XML file (or their default values when none specified).

The method "gui_clean()" will stop and then delete the GUI's execution thread (of type DialogThread) created and started when "gui_init()" was invoked.

All the methods defined in the "Interface.h" are actually passed through the DialogThread to the VSelectionGUI. The two methods will return 0 or NULL if an error occured. The other two methods "gui_init" and "gui_clean" will return true or false depending if the method was successfull or not.

By pressing the Apply button, the method "categoryChanged()" is invoked, inside of which the old selection is saved to the old list of objects, the lists are deleted (comming up next), and then generated from the new-selected rows. There are two lists: "listOfRows" which contains the VRows from the current category, and the seccond one "listOfListViewRows" which contains the QListViewItems generated from the VRow which has the same index but is in the first list. Those two lists are generated in parallel by calling VRow's "getQListViewItem" for each root row in the current category. VRow's "getQListViewItem" is invoked recursivelly top-down to it's children, and each VRow invokes VSelectionGUI's "addListViewItem" to add the QListView and "this" (of type VRow to the two lists). In the same time the children of the QListView are also generated . Those two lists are only for intarnal use regarding the selection mechanism (it was the easiest an the safest way at the moment).

The defaults in the XML file are:
        - descriptioncolumn = 0 (first)
        - unitscolumn = 1 (seccond)
        - codecolumn = 2 (third)
        - all the label-tags are set by default to "+AFw-0"
        - if a column is not labeled "Column x unlabeled" will appear as label
        - the tags <structure>, <labeling> and <help> must exist in the XML file
        - the "default" attributes within a <row> tag are optional and default set to "0" = FALSE ( they are of type boolean = 0 or 1 are the allowed values )

THE ORDER OF THE ELEMENTS IN THE XML FILE MUST BE THE SAME AS DEFINED IN THE DTD DIAGRAM, SO PLEASE USE A TOOL TO CHECK XML THE FILE AGAINS "structure.dtd" BEFORE USING IT.
 



© Bogdan Stanca 2001