## The ETable Widget

Chris
Lahey

    	    clahey@helixcode.com

Miguel
de Icaza

    	    miguel@helixcode.com

2000
Helix Code, Inc.

## Introduction

&ETable; is a table widget on steroids. It is intended to provide all the table functionality needed throughout &Evolution;, and hopefully be general purpose enough to be used in other projects.

&ETable; provides a lot of interactive control over the data in the table. Without any work from the programmer, &ETable; provides rearrangeable columns and editable data. When finished, &ETable; will also provide, again with no programmer intervention, easy interactive sorting and grouping.

&ETable; gives you a great deal of functionality, flexibility, and power. Most of this power is internal to the widget, but some of the flexibility requires a bit of work by the programmer. However, once you learn it, &ETable; is not very hard at all to use.

&ETable;'s power comes from the fact that it is fully model/view/controller based. Various models are involved into the process of rendering the information, and various views are provided. The programmer has a wide range of options: from the most finely hand-tuned table to a generic all-encompasing widget that takes over most of tasks. It is up to the programmer: he can use the simple to use &ETable; widget that takes care of everything in a generic way, or he can use the various components to roll his own tabular display.

&ETable; ships with a standard set of information renderers: strings, bitmaps, toggle-buttons, check-boxes, and multi-line strings. But the programmer can write and implement his own renderer for his information. This means that by default &ETable; provides the basic display facilities that programmers required, but they offer the programmer a complete freedom to incorporate new cell renderers.

## ETableModel

The data back end for the &ETable; is an &ETableModel;. The &ETableModel is an abstract interface that acts as the information repository for the various &ETable components.

To use &ETable; you have to create a subclass of the abstract &ETableModel; class. However, to save you the work of defining a new `GtkClass` every time you use &ETable, there is a predefined subclass of &ETableModel; called &ETableSimple; which simply takes a list of function callbacks to perform the various operations.

## Columns

There are two different meanings to the word "column". The first is the model column (defined by the &ETableCol: object). A model column describes how it maps to the column in the &ETableModel; as well as containing information about its properties (name, resizability, resize dimensions, and a renderer for this specific columns).

&ETable; distinguishes between a model column index, and a view column index. The former reflects the column in which the data is stored in the &ETableModel; The later represents the actual location at which the column is being displayed in the screen.

Each view column index corresponds to a specific model column, though a model column may have any number of view columns associated with it (including zero). For example the same column might be rendered twice, or the data from one column could be used to display different bits of information

The view column does not necessarily depend on only one model column. In some cases, the view column renderer can be given a reference to another model column to get extra information about its display. For example, a mail program could display deleted messages with a line through them by creating a model column with no corresponding view column that told whether or not the message is deleted, and then having the text column strikethrough the display if the invisible column had a value corresponding to "deleted".

The view column also specifies a few other pieces of information. One piece of information is the renderer. &ETable; provides a number of renderers to choose from, or you can write your own. Currently, there are renderers for text, image sets, and checkboxes.

The view column also includes information about the header. There are two types of headers: text, and pixbuf. The first allows you to specify a string which is rendered in the header. The second allows you to specify an image to copy into the header.

## Header

The &ETableHeader; represents the header information for the table. The &ETableHeader; is used in two different ways. The first is the in the full_header element of an &ETable;. This is the list of possible columns in the view. You add each of your columns to this &ETableHeader; and then pass it into the &ETable;.

The second use is completely internal. &ETable; uses another &ETableHeader; to store the actual displayed columns. Many of the &ETableHeader; functions are for this purpose. The only functions that users of the library should need to use are `e_table_header_new` and `e_table_header_add_col`.

## Layout Specification

&ETable; uses an &ETableSpecification; to layout the columns of the widget. The &ETableSpecification; is specified as XML data passed into the &ETable; as a string.

The most powerful part of the &ETableSpecification; is that when finished, &ETable; will allow you to get a copy of an &ETableSpecification; that describes the current view of the tree. This allows the developer to save the current view so that next time the user opens this table, they find it in exactly the state that they left it.

The XML specification allows for a number of things. First, it allows you to pick a set of default columns to be shown. Thus, even if you had hundreds of pieces of data, you could choose to only display a few that fit on the screen by default.

The second major thing that the &ETableSpecification; allows you to specify is the column grouping and sorting. &ETable; has a powerful mechanism for allowing the user to choose columns to group by, thus allowing multiple columns of sorting, as well as visual grouping of similar elements and interactive selection of what data to display.

The grouping in &ETableSpecification; is specified as a hierarchy of columns to group by. Each level of the hierarchy lets you sort by a particular column, either ascending or descending. All levels except the last cause the canvas to group by the given column.

An example &ETableSpecification; follows.

          <ETableSpecification>
            <columns-shown frozen_columns="2">
    	  <column> 0 </column>
    	  <column> 1 </column>
    	  <column> 2 </column>
    	  <column> 3 </column>
    	  <column> 4 </column>
    	</columns-shown>
    	<grouping>
    	  <group column="3" ascending="1">
    	    <group column="4" ascending="0">
    	      <leaf column="2" ascending="1"/>
    	    </group>
    	  </group>
    	</grouping>
          </ETableSpecification>

This example has 5 columns which are initially in order. It has 2 levels of grouping. The first is grouped by the 4th column (all indexes are 0 based) and sorts those groups in ascending order. Inside those groups, the data is grouped by the fifth column and sorted in descending order of the fifth column. Finally, the data in those groups is sorted by the third column in ascending order. Due to the "frozen_columns" attribute on the columns-shown element, the user will not be able to rearrange the first two columns. They will always be the first two.

## Conclusion

All in all, &ETable; is a very powerful widget. Once you learn to use it, you have access to a vast amount of power requiring a comparatively small amount of work.