1#############################################################################
2##
3#W  gapdata.g             GAP 4 package `browse'                Thomas Breuer
4##
5#Y  Copyright (C)  2007,  Lehrstuhl D für Mathematik,   RWTH Aachen,  Germany
6##
7
8
9#############################################################################
10##
11#F  BrowseGapData()
12##
13##  <#GAPDoc Label="GAPData_section">
14##  <Section Label="sec:datadisp">
15##  <Heading>Overview of &GAP; Data</Heading>
16##
17##  The &GAP; system contains several data collections such as libraries of
18##  groups and character tables.
19##  Clearly the function <Ref Func="NCurses.BrowseGeneric"/> can be used to
20##  visualize interesting information about such data collections,
21##  in the form of an <Q>overview table</Q> whose rows correspond to the
22##  objects in the collection;
23##  each column of the table shows a piece of information about the objects.
24##  (One possibility to create such overviews is given by
25##  <Ref Func="BrowseTableFromDatabaseIdEnumerator"/>.)
26##
27##  <ManSection>
28##  <Func Name="BrowseGapData" Arg=""/>
29##
30##  <Returns>
31##  the return value of the chosen application if there is one.
32##  </Returns>
33##  <Description>
34##  The function <Ref Func="BrowseGapData"/> shows the choices in the list
35##  <C>BrowseData.GapDataOverviews</C>, in a browse table with one column.
36##  When an entry is <Q>clicked</Q> then the associated function is called,
37##  and the table of choices is closed.
38##  <P/>
39##  The idea is that each entry of <C>BrowseData.GapDataOverviews</C>
40##  describes an overview of a data collection.
41##  <P/>
42##  The &Browse; package provides overviews of
43##  <List>
44##  <Item>
45##      the current AMS Mathematics Subject Classification codes
46##      (see <Ref Func="BrowseMSC"/>),
47##  </Item>
48##  <Item>
49##      the contents of the <Package>AtlasRep</Package> package
50##      <Cite Key="AtlasRep"/> (only if this package is loaded,
51##      see Section&nbsp;<Ref Sect="sec:atlasdisp"/>),
52##  </Item>
53##  <Item>
54##      <Index Key="BrowseConwayPolynomials" Subkey="see BrowseGapData">
55##      <C>BrowseConwayPolynomials</C></Index>
56##      the Conway polynomials in &GAP;
57##      (calls <C>BrowseConwayPolynomials()</C>),
58##  </Item>
59##  <Item>
60##      profile information for &GAP; functions
61##      (see Section&nbsp;<Ref Sect="sec:profiledisp"/>),
62##  </Item>
63##  <Item>
64##      the list of &GAP; related bibliography entries in the file
65##      <F>bibl/gap-publishednicer.bib</F> of the <Package>Browse</Package>
66##      package
67##      (see Section&nbsp;<Ref Sect="sec:gapbibl"/>),
68##  </Item>
69##  <Item>
70##      the &GAP; manuals (see Section&nbsp;<Ref Sect="sec:manualdisp"/>),
71##  </Item>
72##  <Item>
73##      <Index Key="BrowseGapMethods" Subkey="see BrowseGapData">
74##      <C>BrowseGapMethods</C></Index>
75##      &GAP; operations and methods
76##      (calls <C>BrowseGapMethods()</C>),
77##  </Item>
78##  <Item>
79##      <Index Key="BrowseGapPackages" Subkey="see BrowseGapData">
80##      <C>BrowseGapPackages</C></Index>
81##      the installed &GAP; packages
82##      (calls <C>BrowseGapPackages()</C>),
83##  </Item>
84##  <Item>
85##      &GAP;'s user preferences
86##      (see Section&nbsp;<Ref Sect="sec:userpref"/>),
87##  </Item>
88##  <Item>
89##      the contents of the <Package>TomLib</Package> package
90##      <Cite Key="TomLib"/> (only if this package is loaded,
91##      see Section&nbsp;<Ref Sect="sect:tomlibinfo"/>),
92##  </Item>
93##  </List>
94##  <P/>
95##  Other &GAP; packages may add more overviews,
96##  using the function <Ref Func="BrowseGapDataAdd"/>.
97##  For example, there are overviews of
98##  <List>
99##  <Item>
100##      the bibliographies in the <Package>ATLAS</Package> of Finite Groups
101##      <Cite Key="CCN85"/> and in the
102##      <Package>ATLAS</Package> of Brauer Characters <Cite Key="JLPW95"/>
103##      (see
104##      <Ref Func="BrowseBibliographySporadicSimple" BookName="atlasrep"/>),
105##  </Item>
106##  <Item>
107##      atomic irrationalities that occur in character tables in the
108##      <Package>ATLAS</Package> of Finite Groups <Cite Key="CCN85"/>
109##      or the <Package>ATLAS</Package> of Brauer Characters
110##      <Cite Key="JLPW95"/> (see
111##      Section <Ref Func="BrowseCommonIrrationalities" BookName="ctbllib"/>),
112##  </Item>
113##  <Item>
114##      the differences between the versions of the character table data
115##      in the <Package>CTblLib</Package> package (see Section
116##      <Ref Func="BrowseCTblLibDifferences" BookName="ctbllib"/>),
117##  </Item>
118##  <Item>
119##      the information in the &GAP; Character Table Library
120##      (see Section <Ref Func="BrowseCTblLibInfo" BookName="ctbllib"/>),
121##  </Item>
122##  <Item>
123##      an overview of minimal degrees of representations of groups from the
124##      <Package>ATLAS</Package> of Group Representations
125##      (see Section <Ref Func="BrowseMinimalDegrees" BookName="atlasrep"/>).
126##  </Item>
127##  </List>
128##  <!-- add reference to the MFER package? -->
129##  <!-- as soon as BrowseMOSS becomes public, add it -->
130##  <P/>
131##  Except that always one table cell is selected,
132##  the full functionality of the function
133##  <Ref Func="NCurses.BrowseGeneric"/> is available.
134##  <P/>
135##  <Example><![CDATA[
136##  gap> n:= [ 14, 14, 14 ];;  # ``do nothing''
137##  gap> # open the overview of Conway polynomials
138##  gap> BrowseData.SetReplay( Concatenation( "/Conway Polynomials",
139##  >      [ NCurses.keys.ENTER, NCurses.keys.ENTER ], "srdddd", n, "Q" ) );
140##  gap> BrowseGapData();;
141##  gap> # open the overview of GAP packages
142##  gap> BrowseData.SetReplay( Concatenation( "/GAP Packages",
143##  >      [ NCurses.keys.ENTER, NCurses.keys.ENTER ], "/Browse",
144##  >      [ NCurses.keys.ENTER ], "n", n, "Q" ) );
145##  gap> BrowseGapData();;
146##  gap> BrowseData.SetReplay( false );
147##  ]]></Example>
148##  <P/>
149##  <E>Implementation remarks</E>:
150##  The browse table has a static header, a dynamic footer showing the
151##  description of the currently selected entry, no row or column labels,
152##  and exactly one column of fixed width equal to the screen width.
153##  If the chosen application has a return value then this is returned by
154##  <Ref Func="BrowseGapData"/>, otherwise nothing is returned.
155##  The component <C>work.SpecialGrid</C> of the browse table is used to
156##  draw a border around the list of choices and another border around the
157##  footer.
158##  Only one mode is needed in which an entry is selected.
159##  <P/>
160##  The code can be found in the file <F>app/gapdata.g</F> of the package.
161##  </Description>
162##  </ManSection>
163##
164##  <#Include Label="BrowseGapDataAdd_man">
165##  </Section>
166##  <#/GAPDoc>
167##
168BindGlobal( "BrowseGapData", function()
169    local width, height, footers, footerlength, emptyline, table;
170
171    if not IsBound( BrowseData.GapDataOverviews ) then
172      return;
173    fi;
174
175    width:= NCurses.getmaxyx( 0 )[2] - 4;
176    height:= NCurses.getmaxyx( 0 )[1];
177    footers:= List( BrowseData.GapDataOverviews,
178                    x -> SplitString( FormatParagraph( x[4], width, "left",
179                                        [ "  ", "  " ] ), "\n" ) );
180    footerlength:= MaximumList( List( footers, Length ) ) + 3;
181    emptyline:= ListWithIdenticalEntries( width, ' ' );
182    footers:= List( footers, l -> Concatenation( [ emptyline, emptyline ],
183                l,  ListWithIdenticalEntries( footerlength - Length( l ) - 3,
184                 emptyline ) ) );
185
186    # Construct and show the browse table.
187    table:= rec(
188      work:= rec(
189        align:= "tl",
190        header:= [ "",
191                   [ NCurses.attrs.UNDERLINE, true, "GAP Data Overviews" ],
192                   "",
193                   "" ],
194        footer:= t -> footers[ t.dynamic.indexRow[
195                                   t.dynamic.selectedEntry[1] ] / 2 ],
196        availableModes:= Filtered( BrowseData.defaults.work.availableModes,
197                             x -> x.name in [ "select_entry", "help" ] ),
198        main:= List( BrowseData.GapDataOverviews,
199                     pair -> [ rec( rows:= [ pair[1] ], align:= "tl" ) ] ),
200        sepCol:= [ "| ", " |" ],
201        widthCol:= [ , width ],
202        SpecialGrid:= function( t, data )
203          local len;
204
205          len:= data.footerLength + 1;
206          data:= data.gridsInfo[1];
207          NCurses.Grid( t.dynamic.window,
208                        data.trow - 1, data.brow + 1, data.lcol, data.rcol,
209                        [ data.trow - 1, data.brow + 1 ],
210                        [ data.lcol, data.rcol ] );
211          NCurses.Grid( t.dynamic.window,
212                        data.brow + 2, data.brow + len, data.lcol, data.rcol,
213                        [ data.brow + 2, data.brow + len ],
214                        [ data.lcol, data.rcol ] );
215        end,
216        Click:= rec(
217          select_entry:= rec(
218            helplines:= [ "start the chosen Browse application" ],
219            action:= function( t )
220              local oldreplay, replay, currlog, steps, pos;
221
222              # Cut off the done replay part.
223              if IsBound( BrowseData.defaults.dynamic.replay ) then
224                oldreplay:= BrowseData.defaults.dynamic.replay;
225                replay:= t.dynamic.replay;
226                currlog:= replay.logs[ replay.pointer ];
227                steps:= currlog.steps{ [ currlog.position
228                                         .. Length( currlog.steps ) ] };
229                BrowseData.SetReplay( steps );
230              fi;
231
232              # Quit the current table, and start the application.
233              BrowseData.actions.QuitTable.action( t );
234              pos:= t.dynamic.indexRow[ t.dynamic.selectedEntry[1] ] / 2;
235              if BrowseData.GapDataOverviews[ pos ][3] then
236                t.dynamic.Return:= BrowseData.GapDataOverviews[ pos ][2]();
237              else
238                BrowseData.GapDataOverviews[ pos ][2]();
239              fi;
240
241              # Reinstall the original replay value.
242              if IsBound( oldreplay ) then
243                BrowseData.defaults.dynamic.replay:= oldreplay;
244              fi;
245            end ),
246        ),
247      ),
248      dynamic:= rec(
249        selectedEntry:= [ 2, 2 ],
250        activeModes:= [ First( BrowseData.defaults.work.availableModes,
251                               x -> x.name = "select_entry" ) ],
252      ),
253    );
254
255    NCurses.BrowseGeneric( table );
256    if IsBound( table.dynamic.Return ) then
257      return table.dynamic.Return;
258    fi;
259end );
260
261
262#############################################################################
263##
264#E
265
266