Sophie

Sophie

distrib > Mandriva > 2010.0 > i586 > media > contrib-release > by-pkgid > 91213ddcfbe7f54821d42c2d9e091326 > files > 19

gap-system-packages-4.4.12-5mdv2010.0.i586.rpm

  
  4 Browsing Tables in GAP using ncurses –The User Interface
  
  As  stated in Section 1.1, one aim of the Browse package is to provide tools
  for the quite usual task to show a two-dimensional array or certain rows and
  columns  of it on a character screen in a formatted way, to navigate in this
  array via key strokes (and mouse events), and to search for strings, to sort
  the array by row or column values etc.
  
  The  idea  is  that  one  starts  with  an  array  of  data, the main table.
  Optionally,  labels for each row of the main table are given, which are also
  arranged  in  an array (with perhaps several columns), the row labels table;
  analogously,  a  column  labels  table of labels for the columns of the main
  table  may be given. The row labels are shown to the left of the main table,
  the  column  labels  are shown above the main table. The space above the row
  labels  and to the left of the column labels can be used for a fourth table,
  the corner table, with information about the labels or about the main table.
  Optionally,  a  header  and a footer may be shown above and below these four
  tables,  respectively.  Header and footer are not separated into columns. So
  the shown window has the following structure.
  
        ----------------------------------
        |             header             |
        ----------------------------------
        |        |                       |
        | corner |     column labels     |
        |        |                       |
        ----------------------------------
        |        |                       |
        |        |                       |
        |  row   |         main          |
        | labels |         table         |
        |        |                       |
        |        |                       |
        |        |                       |
        ----------------------------------
        |             footer             |
        ----------------------------------
  
  If  not the whole tables fit into the window then only subranges of rows and
  columns of the main table are shown, together with the corresponding row and
  column  labels.  Also  in  this  case, the row heights and column widths are
  computed  w.r.t. the whole table not w.r.t. the shown rows and columns. This
  means  that the shown row labels are unchanged if the range of shown columns
  is changed, the shown column labels are unchanged if the range of shown rows
  is changed, and the whole corner table is always shown.
  
  The  current  chapter describes the user interface for standard applications
  of  this  kind,  i. e., those applications for which one just has to collect
  the data to be shown in a record –which we call a browse table– without need
  for additional GAP programming.
  
  Section 4.1  gives  an overview of the features available in standard browse
  table  applications,  and  Section 4.2 describes the data structures used in
  browse    tables.    Finally,    Section 4.3    introduces    the   function
  NCurses.BrowseGeneric  (4.3-1),  which  is  the generic function for showing
  browse table in visual mode.
  
  For technical details needed to extend these applications and to build other
  applications, see Chapter 5.
  
  Examples of browse table applications are shown in Chapter 6.
  
  
  4.1 Features Supported by the Function NCurses.BrowseGeneric
  
  Standard applications of the function NCurses.BrowseGeneric (4.3-1) have the
  following  functionality.  Other  applications may provide only a subset, or
  add further functionality, see Chapters 5 and 6.
  
  Scrolling:
        The  subranges  of  shown  rows  and  columns of the main table can be
        modified, such that the focus area is moved to the left, to the right,
        up,  or  down;  depending  on  the  context, the focus is moved by one
        character,  by  one  table  cell  or  a  part  of  it,  by  the window
        height/width  (minus  one character or minus one table cell). If mouse
        events are enabled then cells can be selected also via mouse clicks.
  
  Selecting:
        A  cell,  row, or column of the main table can be selected; then it is
        shown  highlighted  on  the  screen  (by  default  using the attribute
        NCurses.attrs.STANDOUT, see Section 2.1-7). The selection can be moved
        inside  the  main  table  to  a neighboring cell, row, or column; this
        causes  also  scrolling  of the main table when the window borders are
        reached.
  
  Searching:
        A  search  string  is entered by the user, and the first matching cell
        becomes  selected;  one can search further for the next matching cell.
        Global search parameters define what matching means (case sensitive or
        not,  search  for substrings or complete words) and what the first and
        the  next matching cells are (search in the whole table or just in the
        selected  row  or  column,  search  for  whole  words  or  prefixes or
        suffixes, search forwards or backwards).
  
  Sorting:
        If  a  row  or  column  is  selected then the main table can be sorted
        w.r.t.  the  entries  in  this  row  or column. Global sort parameters
        describe   for   example  whether  one  wants  to  sort  ascending  or
        descending, or case sensitive or not.
  
        If  a  categorized  table is sorted by a column then the category rows
        are  removed  and  the  current sorting and filtering by rows is reset
        before  the  table is sorted by the given column. If a table is sorted
        by  a  column/row  that  is  already  sorted by a column/row then this
        ordering is reset first.
  
        Sorting  can be undone globally, i. e., one can return to the unsorted
        table.
  
  Sorting and Categorizing:
  
        If  a  column is selected then the main table can be sorted w.r.t. the
        entries in this column, and additionally these entries are turned into
        category  rows,  i. e.,  additional  rows are added to the main table,
        appearing  immediately  above the table rows with a fixed value in the
        selected  column,  and  showing this column value. (There should be no
        danger  to  mix  up  this notion of categories with the one introduced
        in 'Reference:  Categories'.) The category rows can be collapsed (that
        is,  the table rows that belong to this category row are not shown) or
        expanded  (that  is,  the corresponding table rows are shown). Some of
        the  global  search  parameters affect the category rows, for example,
        whether  the  category rows shall involve a counter showing the number
        of  corresponding  data  rows,  or  whether  a row of the browse table
        appears under different category rows.
  
        Sorting and categorizing can be undone globally, i. e., one can return
        to the unsorted table without category rows.
  
  Filtering:
  
        The browse table can be restricted to those rows or columns in which a
        given search string occurs. (Also entries in collapsed rows can match;
        they  remain  collapsed then.) As a consequence, the category rows are
        restricted  to  those  under  which  a  matching  row  occurs.  (It is
        irrelevant whether the search string occurs in category rows.)
  
        If  the search string does not occur at all then a message is printed,
        and  the  table  remains  as  it  was  before.  If  a  browse table is
        restricted  then  this  fact  is  indicated by the message "restricted
        table" in the lower right corner of the window.
  
        When  a column or row is selected then the search is restricted to the
        entries  in  this column or row, respectively. Besides using a search,
        one  can also explicitly hide the selected row or column. Filtering in
        an  already  restricted  table  restricts  the  shown  rows or columns
        further.
  
        Filtering  can  be  undone  globally,  i. e.,  one  can  return to the
        unrestricted table.
  
  Help:
        Depending  on  the application and on the situation, different sets of
        user  inputs  may  be available and different meanings of these inputs
        are  possible. An overview of the currently available inputs and their
        meanings can be opened in each situation, by hitting the ? key.
  
  Re-entering:
        When one has called NCurses.BrowseGeneric (4.3-1) with a browse table,
        and  returns  from visual mode to the GAP prompt after some navigation
        steps,  calling NCurses.BrowseGeneric again with this table will enter
        visual  mode in the same situation where it was left. For example, the
        cell  in  the  top-left  position will be the same as before, and if a
        cell was selected before then this cell will be selected now. (One can
        avoid   this   behavior   using   the   optional  second  argument  of
        NCurses.BrowseGeneric.)
  
  Logging:
        The  integers  corresponding  to  the  user  inputs in visual mode are
        collected in a list that is stored in the component dynamic.log of the
        browse  table. It can be used for repeating the inputs with the replay
        feature.  (For  browse table applications that give the user no access
        to  the  browse  table itself, one can force the log to be assigned to
        the   component   log   of   the   global   variable  BrowseData,  see
        Section 5.4-1.)
  
  Replay:
        Instead  of  interactively  hitting  keys  in  visual  mode,  one  can
        prescribe the user inputs to a browse table via a "replay record"; the
        inputs  are  then processed with given time intervals. The easiest way
        to   create   a   meaningful   replay   record  is  via  the  function
        BrowseData.SetReplay  (5.4-2), with argument the dynamic.log component
        of  the  browse  table  in  question that was stored in an interactive
        session.
  
  The  following  features  are  not  available in standard applications. They
  require additional programming.
  
  Clicking:
        One  possible action is to "click" a selected cell, row, or column, by
        hitting  the  Enter key. It depends on the application what the effect
        is. A typical situation is that a corresponding GAP object is added to
        the  list  of return values of NCurses.BrowseGeneric (4.3-1). Again it
        depends  on  the  application what this GAP object is. In order to use
        this  feature,  one  has  to provide a record whose components are GAP
        functions,  see Section 5.4-1 for details. If mouse events are enabled
        then  also  mouse  clicks can be used as an alternative to hitting the
        Enter key.
  
  Return Value:
  
        The  function  NCurses.BrowseGeneric  (4.3-1)  may have an application
        dependent  return value. A typical situation is that a list of objects
        corresponding to those cells is returned that were "clicked" in visual
        mode.  In  order  to  use  this feature, one has to assign the desired
        value to the component dynamic.Return of the browse table.
  
  
  4.2 Data Structures used by NCurses.BrowseGeneric
  
  4.2-1 BrowseData.IsBrowseTableCellData
  
  > BrowseData.IsBrowseTableCellData( obj ) __________________________function
  Returns:  true if the argument is a list or a record in a supported format.
  
  A table cell data object describes the input data for the contents of a cell
  in   a  browse  table.  It  is  represented  by  either  an  attribute  line
  (see NCurses.IsAttributeLine (2.2-3)), for cells of height one, or a list of
  attribute  lines  or  a record with the components rows, a list of attribute
  lines,  and  optionally  align,  a  substring of "bclt", which describes the
  alignment  of  the attribute lines in the table cell -- bottom, horizontally
  centered,  left,  and  top  alignment;  the  default is right and vertically
  centered  alignment. (Note that the height of a table row and the width of a
  table column can be larger than the height and width of an individual cell.)
  
  ---------------------------  Example  ----------------------------
    gap> BrowseData.IsBrowseTableCellData( "abc" );
    true
    gap> BrowseData.IsBrowseTableCellData( [ "abc", "def" ] );
    true
    gap> BrowseData.IsBrowseTableCellData( rec( rows:= [ "ab", "cd" ],
    >                                           align:= "tl" ) );
    true
    gap> BrowseData.IsBrowseTableCellData( "" );
    true
    gap> BrowseData.IsBrowseTableCellData( [] );
    true
  ------------------------------------------------------------------
  
  The  empty  string  is a table cell data object of height one and width zero
  whereas   the   empty   list   (which  is  not  in  IsStringRep  (Reference:
  IsStringRep)) is a table cell data object of height zero and width zero.
  
  4.2-2 BrowseData.BlockEntry
  
  > BrowseData.BlockEntry( tablecelldata, height, width ) ____________function
  Returns:  a list of attribute lines.
  
  For       a       table       cell       data      object      tablecelldata
  (see BrowseData.IsBrowseTableCellData  (4.2-1))  and  two  positive integers
  height  and  width, BrowseData.BlockEntry returns a list of height attribute
  lines   of   displayed  length  width  each  (see NCurses.WidthAttributeLine
  (2.2-7)), that represents the formatted version of tablecelldata.
  
  If  the rows of tablecelldata have different numbers of displayed characters
  then  they  are  filled  up  to  the  desired  numbers  of rows and columns,
  according   to  the  alignment  prescribed  by  tablecelldata;  the  default
  alignment is right and vertically centered.
  
  ---------------------------  Example  ----------------------------
    gap> BrowseData.BlockEntry( "abc", 3, 5 );
    [ "     ", "  abc", "     " ]
    gap> BrowseData.BlockEntry( rec( rows:= [ "ab", "cd" ],
    >                                align:= "tl" ), 3, 5 );
    [ "ab   ", "cd   ", "     " ]
  ------------------------------------------------------------------
  
  4.2-3 BrowseData.IsBrowseTable
  
  > BrowseData.IsBrowseTable( obj ) __________________________________function
  Returns:  true  if  the  argument  record has the required components and is
            consistent.
  
  A browse table is a GAP record that can be used as the first argument of the
  function NCurses.BrowseGeneric (4.3-1).
  
  The  supported  components  of  a  browse  table are work and dynamic, their
  values  must  be  records:  The components in work describe that part of the
  data  that  are not likely to depend on user interactions, such as the table
  entries  and  their  heights  and widths. The components in dynamic describe
  that  part  of  the  data that is intended to change with user interactions,
  such  as  the  currently  shown  top-left entry of the table, or the current
  status  w.r.t.  sorting. For example, suppose you call NCurses.BrowseGeneric
  (4.3-1)  twice  with the same browse table; the second call enters the table
  in  the  same status where it was left after the first call if the component
  dynamic  is  kept,  whereas  one has to reset (which usually simply means to
  unbind)  the  component  dynamic if one wants to start in the same status as
  before the first call.
  
  The  following  components  are  the most important ones for standard browse
  applications.  All  these  components  belong  to the work record. For other
  supported  components (of work as well as of dynamic) and for the meaning of
  the term "mode", see Section 5.2.
  
  main
        is  the  list of lists of table cell data objects that form the matrix
        to  be  shown. There is no default for this component. (It is possible
        to  compute  the  entries  of  the  main  table  on  demand,  see  the
        description of the component Main in Section 5.4-1. In this situation,
        the value of the component main can be an empty list.)
  
  header
        describes  a  header  that shall be shown above the column labels. The
        value  is  either  a  list  of  attribute lines ("static header") or a
        function  or  a  record  whose  component names are names of available
        modes  of  the  browse table ("dynamic header"). In the function case,
        the  function  must  take  the  browse table as its only argument, and
        return  a  list  of attribute lines. In the record case, the values of
        the  components  must be such functions. It is assumed that the number
        of  these  lines  depends at most on the mode. The default is an empty
        list, i. e., there is no header.
  
  footer
        describes  a  footer that shall be shown below the table. The value is
        analogous  to  that  of  footer.  The default is an empty list, i. e.,
        there is no footer.
  
  labelsRow
        is  a  list  of  row  label rows, each being a list of table cell data
        objects.  These  rows  are  shown  to  the left of the main table. The
        default is an empty list, i. e., there are no row labels.
  
  labelsCol
        is  a list of column information rows, each being a list of table cell
        data  objects.  These  rows  are shown between the header and the main
        table.  The  default  is  an  empty  list,  i. e., there are no column
        labels.
  
  corner
        is  a list of lists of table cell data objects that are printed in the
        upper  left  corner,  i. e.,  to the left of the column label rows and
        above the row label columns. The default is an empty list.
  
  sepRow
        describes the separators above and below rows of the main table and of
        the  row labels table. The value is either an attribute line or a (not
        necessarily  dense)  list  of  attribute  lines.  In  the former case,
        repetitions  of  the  attribute line are used as separators below each
        row  and  above  the  first  row  of  the  table;  in the latter case,
        repetitions  of  the  entry  at the first position (if bound) are used
        above  the  first  row, and repetitions of the last bound entry before
        the  (i+2)-th  position  (if  there  is such an entry at all) are used
        below  the i-th table row. The default is an empty string, which means
        that there are no row separators.
  
  sepCol
        describes  the  separators  in front of and behind columns of the main
        table  and  of  the  column  labels  table. The format of the value is
        analogous to that of the component sepRow; the default is the string "
        " (whitespace of width one).
  
  sepLabelsCol
        describes  the  separators  above  and below rows of the column labels
        table  and  of the corner table, analogously to sepRow. The default is
        an   empty  string,  which  means  that  there  are  no  column  label
        separators.
  
  sepLabelsRow
        describes  the  separators  in  front of and behind columns of the row
        labels  table  and  of  the  corner  table, analogously to sepCol. The
        default is an empty string.
  
  We give a few examples of standard applications.
  
  The  first  example  defines  a  small  browse table by prescribing only the
  component  work.main,  so  the  defaults  for row and column labels (no such
  labels),  and  for  separators  are used. The table cells are given by plain
  strings, so they have height one. Usually this table will fit on the screen.
  
  ---------------------------  Example  ----------------------------
    gap> m:= 10;;  n:= 5;;
    gap> xpl1:= rec( work:= rec(
    >      main:= List( [ 1 .. m ], i -> List( [ 1 .. n ],
    >        j -> String( [ i, j ] ) ) ) ) );;
    gap> BrowseData.IsBrowseTable( xpl1 );
    true
  ------------------------------------------------------------------
  
  In  the  second  example,  also  row and column labels appear, and different
  separators are used. The table cells have height three. Also this table will
  usually fit on the screen.
  
  ---------------------------  Example  ----------------------------
    gap> m:= 6;;  n:= 5;;
    gap> xpl2:= rec( work:= rec(
    >      main:= List( [ 1 .. m ], i -> List( [ 1 .. n ],
    >        j -> rec( rows:= List( [ -i*j, i*j*1000+j, i-j ], String ),
    >                  align:= "c" ) ) ),
    >      labelsRow:= List( [ 1 .. m ], i -> [ String( i ) ] ),
    >      labelsCol:= [ List( [ 1 .. n ], String ) ],
    >      sepRow:= "-",
    >      sepCol:= "|",
    >  ) );;
    gap> BrowseData.IsBrowseTable( xpl2 );
    true
  ------------------------------------------------------------------
  
  The third example additionally has a static header and a dynamic footer, and
  the  table  cells involve attributes. This table will usually not fit on the
  screen.
  
  ---------------------------  Example  ----------------------------
    gap> m:= 30;;  n:= 25;;
    gap> xpl3:= rec( work:= rec(
    >      header:= [ "                    Example 3" ],
    >      main:= List( [ 1 .. m ], i -> List( [ 1 .. n ],
    >        j -> rec( rows:= [ String( -i*j ),
    >                           [ NCurses.attrs.BOLD, true,
    >                             NCurses.attrs.ColorPairs[56+1], true,
    >                             String( i*j*1000+j ),
    >                             NCurses.attrs.NORMAL, true ],
    >                             String( i-j ) ],
    >                  align:= "c" ) ) ),
    >      labelsRow:= List( [ 1 .. 30 ], i -> [ String( i ) ] ),
    >      sepLabelsRow:= " % ",
    >      labelsCol:= [ List( [ 1 .. 30 ], i -> [
    >        NCurses.attrs.ColorPairs[ 56+4 ], true,
    >        String( i ),
    >        NCurses.attrs.NORMAL, true ] ) ],
    >      sepLabelsCol:= "=",
    >      sepRow:= "*",
    >      sepCol:= " |",
    >      footer:= t -> [ Concatenation( "top-left entry is: ",
    >                          String( t.dynamic.topleft{ [ 1, 2] } ) ) ],
    >  ) );;
    gap> BrowseData.IsBrowseTable( xpl3 );
    true
  ------------------------------------------------------------------
  
  The  fourth  example illustrates that highlighting may not work properly for
  browse  tables containing entries whose attributes are not set with explicit
  Boolean     values,     see     NCurses.IsAttributeLine     (2.2-3).    Call
  NCurses.BrowseGeneric  (4.3-1)  with  the  browse  table xpl4, and select an
  entry (or a column or a row): Only the middle row of each selected cell will
  be highlighted, because only in this row, the color attribute is switched on
  with an explicit true.
  
  ---------------------------  Example  ----------------------------
    gap> xpl4:= rec(
    >     defc:= NCurses.defaultColors,
    >     wd:= Maximum( List( ~.defc, Length ) ),
    >     ca:= NCurses.ColorAttr,
    >     work:= rec(
    >       header:= [ "Examples of NCurses.ColorAttr" ],
    >       main:= List( ~.defc, i -> List( ~.defc,
    >         j -> [ [ ~.ca( i, j ), String( i, ~.wd ) ],        # no true!
    >                [ ~.ca( i, j ), true, String( "on", ~.wd ) ],
    >                [ ~.ca( i, j ), String( j, ~.wd ) ] ] ) ),  # no true!
    >       labelsRow:= List( ~.defc, i -> [ String( i ) ] ),
    >       labelsCol:= [ List( ~.defc, String ) ],
    >       sepRow:= "-",
    >       sepCol:= [ " |", "|" ],
    >  ) );;
    gap> BrowseData.IsBrowseTable( xpl4 );
    true
  ------------------------------------------------------------------
  
  
  4.3 The Function NCurses.BrowseGeneric
  
  4.3-1 NCurses.BrowseGeneric
  
  > NCurses.BrowseGeneric( t[, arec] ) _______________________________function
  Returns:  an application dependent value, or nothing.
  
  NCurses.BrowseGeneric    is    used    to    show   the   browse   table   t
  (see BrowseData.IsBrowseTable  (4.2-3)) in a formatted way on a text screen,
  and allows the user to navigate in this table.
  
  The optional argument arec, if given, must be a record whose components work
  and  dynamic,  if  bound, are used to provide defaults for missing values in
  the  corresponding  components  of  t.  The  default  for  arec  and for the
  components  not  provided  in  arec  is  BrowseData.defaults, see BrowseData
  (5.4-1), the function BrowseData.SetDefaults sets these default values.
  
  At  least  the  component work.main must be bound in t, with value a list of
  list   of  table  cell  data  objects,  see BrowseData.IsBrowseTableCellData
  (4.2-1).
  
  When  the  window or the screen is too small for the browse table, according
  to its component work.minyx, the table will not be shown in visual mode, and
  fail  is returned. (This holds also if there would be no return value of the
  call  in  a  large enough screen.) Thus one should check for fail results of
  programmatic calls of NCurses.BrowseGeneric, and one should better not admit
  fail as a regular return value.
  
  Most  likely,  NCurses.BrowseGeneric will not be called on the command line,
  but  the  browse  table t will be composed by a suitable function which then
  calls NCurses.BrowseGeneric, see the examples in Chapter 6.