File name : GRIDUTIL.TXT
Author    : Mario Pinkster
address   : 0pinkster01@almere.flnet.nl
Subject   : GRIDUTIL.PAS
Updated   : 23-08-1996

THIS IS FREEWARE FOR DELPHI-1

Purpose
The form and procedures encapsulated by the GRIDUTIL.PAS
and *.DFM source files serve two distinct purposes:
  - store and retrieve the visibility, order and column
    widths of grid columns displayed in any TDBGrid.
  - allow end-user to edit visibility of columns at
    run-time by means of a special dialog that has
    checkmarks for every column that the programmer deems
    necessary to be made visible and unvisible at run-time.

Overview
As the two purposes mentioned above are related but not
intertwined, I will deal with them separately.

Overview of storing and retrieving grid column layout.

  Storing is done by reading the data from the dataset
  associated with the datasource of the grid and then
  writing this data as one or more strings to a windows
  INI file. The strings consist of integer numbers
  separated by commas.

  Retrieving pretty much follows the reverse procedure:
  the strings are read from the windows INI file, the data
  in the strings is decoded and the decoded data is assigned
  to the appropriate properties of the dataset of the
  datasource of the grid.

  In this process, the individual fields of the dataset are
  assigned an ordering sequence that determines which integers
  in the strings in the INI file are associated with the data
  for the field. For instance, a '0' as the second number
  in the visibility string means that the second field is
  not visible. The fields in the dataset are ordered according
  to the alfabetical ordering of the fieldnames.


Overview of editing the visibility of grid columns at run-time

  This is done by preparing and then running a specialized
  form, contained in GRIDUTIL.DFM. For each grid column for
  which the visibility must be edited the programmer calls
  the AddCheck method of the form. This will dynamically
  add a checkbox for the column in question.
  After all AddCheck calls have been made, the Run method is
  called. This method automatically sets the checkmarks
  for all added checkboxes on or off according to the
  current visibility state of the columns in the grid
  and then performs a ShowModal.


How to use the sources provided in the zipped archive

  This is not a component so you cannot install it on
  your palette. Instead, when you want to make use of
  the storing and retrieveing of layout, make sure the
  files GRIDUTIL.PAS and STRTOOLS.PAS are somehwere on
  your library path.
  When you also want to use the visibility editing
  facility, add the source GRIDUTIL.PAS (together with
  GRIDUTIL.DFM) to your project. You can either leave
  this form autocreated (Delphi default) so that all
  your grids share the same instance of TDlgColumnVisible,
  or you can create and destroy instances of
  TDlgColumnVisible on the fly. I have no recommendation
  on which is better.
  The example included in the package uses one of the
  Paradox tables of the Delphi MAST example, so make
  sure you have a BDE Alias called DBDEMOS pointing to
  the Delphi example data.


Details of storing and retrieving grid layout.

  For a working example of how to use this part of
  GRIDUTIL.PAS, also see the example in MAIN.PAS
  (included in this package).

  In GRIDUTIL.PAS, there are five procedures that can be
  called externally. These procedures are NOT methods
  of the TDlgColumnVisible form. They are independent of
  this form. However, they _do_ depend on the inclusion
  of the STRTOOLS.PAS unit, which in itself is of no
  great interest and can be seen merely as a supportive
  library unit. STRTOOLS.PAS should be included in the
  zipped archive you obtained. There is no matching *.DFM
  as there is no form in STRTOOLS.PAS.

  Information is stored in a windows INI file. This means
  that a section header must be provided to indicate in
  which section of the INI file the information is or
  should be stored.
  For each layout to be stored, up to three INI strings
  may be written to the given section. One string holds
  information about column order, another about columnn
  visibility, and a third about column display widths.

  When reading, the strings are broken down into
  individual values using StrParse (from STRTOOLS.PAS)
  and then applied to the individual columns of the grid.

  The three strings for one particular grid can all be
  identified by one additional string in the call to read
  or write, as the procedures in GRIDUTIL.PAS add suffixes
  to the provided string to discern between visibility,
  ordering and width data.

  Which data strings are actually read and written is
  controlled with the options argument. Each data string
  has it's own option value. The set of options
  designated by the constant "glAll" contains all three
  individual option values:

    glAll = [ glWidths, glOrder, glVisible];


  The five external procedures for storing and retrieving
  grid layout are

  procedure ReadGridLayout(
    var ds: TDataSource;
    opt: TGridLayoutOptions;
    var ini: TIniFileType;
    section, id: string);

  ReadGridLayout is an interface procedure to set a certain
  set of values for column order, width and visibility.
  The set of values is read from the given INI file, using
  the given section header and value string prefixes.
  The read values are applied to the dataset associated
  with the given datasource. When you want to do this for
  a subset of the visibility, display width and display order
  of a grid, use another set of option constants instead
  of glAll.

  procedure GetsGridLayout(
    var ds: TDataSource;
    opt: TGridLayoutOptions;
    var v, o, w: string);

  GetsGridLayout is the actual work procedure for applying a
  grid layout to a grid. It receives three strings that
  hold comma-separated integer values that denote visibility,
  order and display width information for each column in the
  grid associated with the datasource.


  procedure WriteGridLayout(
    var ds: TDataSource;
    opt: TGridLayoutOptions;
    var ini: TIniFileType;
    section, id: string);

  WriteGridLayout is an interface procedure to save a certain
  set of values for column order, width and visibility.
  The set of values is read from the given ds.DataSet and
  written to the given INI file, using the given section
  header and value string prefixes.
  When you want to do this for a subset of the visibility,
  display width and display order of a grid, use another
  set of option constants instead of glAll.

  procedure PutsGridLayout(
    var ds: TDataSource;
    opt: TGridLayoutOptions;
    var v, o, w: string);

  PutsGridLayout is the actual work procedure for retrieving a
  grid layout from a grid into three string variables.
  It produces three strings that on output hold
  comma-separated integer values that denote visibility,
  order and display width informationfor each column in the
  grid associated with the datasource.


  procedure CopyGridLayout(
    var i, o: TDataSource;
    opt: TGridLayoutOptions);

  CopyGridLayout copies the layout data for one grid to
  another. It is necessary that both grids hold
  exactly the same number of fields and name them in the
  same way. This is not a very important procedure.

Some further things to note:

  The store/retrieve scheme is limited by the fact that
  Pascal strings as gotten from the Ini file have a
  maximum length of 255 positions.
  When you take into account that display widths are generally
  two-digit-numbers and that we use commas to seperate them, this
  limits the number of fields a grid can have while still being
  able to store/retrieve layout information using GRIDUTIL.PAS
  to approximately eighty fields.


Technical details on how to run the visibility editor.

  For a working example of how to use this part of
  GRIDUTIL.PAS, also see the example in MAIN.PAS
  (included in this package).

  The starting point is to make sure you have created
  an instance of the TDlgColumnVisible formclass.
  You can do this by including the GRIDUTIL.PAS
  and *.DFM in your project and then leaving the
  TDlgColumnVisible form as an Auto-created form.
  You can also create and destroy an instance on
  the fly as needed.
  Let us assume that the instance variable is called
  DlgColumnVisible (a var of this name exists already).

  Then, before using the dialog you can must call
  it's Clear method. This will cleanup all the
  checkboxes that were added in the previous run
  and also reset counters and restore sizes.

  At this point, you must decide if you want the
  checkboxes displayed in more than one column
  (advisable if you have more than a dozen).
  You can do this by setting the property
  TDlgColumnVisible.Cols to 1, 2 or 3. You must
  change this property programmatically, like this:

    DlgColumnVisible.Cols := 2;

  Also, you may influence the spacing somewhat by
  changing the properties ItemHeight and/or ItemWidth.
  The ItemHeight may be varied from 20 to 100 pixels,
  and the ItemWidth from 50 to 200 pixels:

    DlgColumnVisible.ItemHeight := 30;

  Having set a value for number of columns and item
  width and height, you must now start adding the
  checkboxes to the dialog. For this you must use
  the method

    DglColumnVisible.AddCheck( descript, fieldname: string);

  The first argument is the description that wil be
  used as a caption for the checkbox, the second
  is the actual fieldname of the field in the dataset
  that you want to be made visible or invisible by
  checking or unchecking this checkbox.
  The fieldname is stored internally in a stringlist.
  Adding checkboxes automatically adjusts the
  form size.

  After having added all desired checkboxes, you may
  call the Run method of the form:

    DlgColumnVisible.Run ( [DataSource1]);

  This will check or uncheck the checkboxes according
  to the current visibility of the associated fields
  (in the dataset of the _first_ datasource passed in
  the argument array).
  After that, Run wil perform a ShowModal of the form.

  When checkboxes are clicked, the corresponding field
  column in the edited grid(s) will become immediately
  visible or invisible.

