source: branches/port5/PHYLO/PH_display.cxx

Last change on this file was 5893, checked in by westram, 16 years ago
  • prefix rename only ('ap'→'ph')
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 21.8 KB
Line 
1#include "phylo.hxx"
2#include "phwin.hxx"
3#include "PH_display.hxx"
4#include <cstring>
5
6extern void display_status(AW_window *,AW_CL,AW_CL);
7GB_ERROR    ph_check_initialized();
8
9void vertical_change_cb(AW_window *aww,void *cb1,void *cb2)
10{
11    AWUSE(cb1); AWUSE(cb2);
12    PH_display::ph_display->monitor_vertical_scroll_cb(aww);
13}
14
15void horizontal_change_cb(AW_window *aww,void *cb1,void *cb2)
16{
17    AWUSE(cb1); AWUSE(cb2);
18    PH_display::ph_display->monitor_horizontal_scroll_cb(aww);
19}
20
21void ph_view_matrix_cb(AW_window *aww)
22{
23    AW_window *main_win = PH_used_windows::windowList->phylo_main_window;
24    AWUSE(aww);
25
26    PH_display::ph_display->initialize(matrix_dpy);
27    PH_display::ph_display->display();
28    main_win->set_vertical_change_callback((AW_CB2)vertical_change_cb,0,0);
29    main_win->set_horizontal_change_callback((AW_CB2)horizontal_change_cb,0,0);
30}
31
32void ph_view_species_cb(AW_window *aww,AW_CL cb1,AW_CL cb2)
33{
34    AWUSE(aww); AWUSE(cb1); AWUSE(cb2);
35    AW_window *main_win = PH_used_windows::windowList->phylo_main_window;
36
37    PH_display::ph_display->initialize(species_dpy);
38    PH_display::ph_display->display();
39    main_win->set_vertical_change_callback((AW_CB2)vertical_change_cb,0,0);
40    main_win->set_horizontal_change_callback((AW_CB2)horizontal_change_cb,0,0);
41}
42
43void ph_view_filter_cb(AW_window *aww,AW_CL ,AW_CL )
44{
45    GB_ERROR err = ph_check_initialized();
46    if (err) {
47        aw_message(err);
48    }
49    else {
50        AW_window *main_win  = PH_used_windows::windowList->phylo_main_window;
51        AWUSE(aww);
52        PH_filter *ph_filter = new PH_filter;
53
54        ph_filter->init(PHDATA::ROOT->get_seq_len());
55        PHDATA::ROOT->markerline=ph_filter->calculate_column_homology();
56        PH_display::ph_display->initialize(filter_dpy);
57        PH_display::ph_display->display();
58        main_win->set_vertical_change_callback((AW_CB2)vertical_change_cb,0,0);
59        main_win->set_horizontal_change_callback((AW_CB2)horizontal_change_cb,0,0);
60    }
61}
62
63
64PH_display::PH_display()
65{
66    memset((char *) this,0,sizeof(PH_display));
67    this->display_what = NONE;
68}
69
70
71void PH_display::initialize (display_type dpyt)
72{
73    display_what = dpyt;
74    device=PH_used_windows::windowList->phylo_main_window->get_device(AW_MIDDLE_AREA);
75    if(!device)
76    {
77        aw_message("could not get device !!");
78        return;
79    }
80    const AW_font_information *aw_fi=device->get_font_information(0,0);
81    switch(display_what)
82    {
83        case NONE:
84            return;
85           
86        case species_dpy:
87        case filter_dpy:
88            cell_width  = aw_fi->max_letter.width;
89            cell_height = aw_fi->max_letter.height+5;
90            cell_offset = 3;
91
92            off_dx = SPECIES_NAME_LEN*aw_fi->max_letter.width+20;
93            off_dy = cell_height*3;
94           
95            total_cells_horiz = PHDATA::ROOT->get_seq_len();
96            total_cells_vert  = PHDATA::ROOT->nentries;
97            set_scrollbar_steps(PH_used_windows::windowList->phylo_main_window, cell_width,cell_height,50,50);
98            break;
99
100        case matrix_dpy:
101            cell_width  = aw_fi->max_letter.width*SPECIES_NAME_LEN;
102            cell_height = aw_fi->max_letter.height*2;
103            cell_offset = 10;   // draw cell_offset pixels above cell base_line
104
105            off_dx = SPECIES_NAME_LEN*aw_fi->max_letter.width+20;
106            off_dy = 3*cell_height;
107           
108            total_cells_horiz = PHDATA::ROOT->nentries;
109            total_cells_vert  = PHDATA::ROOT->nentries;
110            set_scrollbar_steps(PH_used_windows::windowList->phylo_main_window, cell_width,cell_height,50,50);
111            break;
112
113        default:
114            aw_message("init: unknown display type (maybe not implemented yet)");
115            break;
116    }  // switch
117    resized();  // initalize window_size dependend parameters
118}
119
120
121void PH_display::resized(void)
122{
123    AW_rectangle squ;
124    AW_rectangle rect =  { 0, 0, 0, 0 };
125    long         horiz_paint_size,vert_paint_size;
126
127    PH_used_windows::windowList->phylo_main_window->get_device(AW_MIDDLE_AREA)-> get_area_size(&squ);
128    screen_width  = squ.r-squ.l;
129    screen_height = squ.b-squ.t;
130
131    switch(display_what) {
132        case NONE:
133            return;
134
135        case species_dpy:
136            horiz_paint_size = (squ.r-off_dx)/cell_width;
137            vert_paint_size  = (squ.b-off_dy)/cell_height;
138            horiz_page_size  = (PHDATA::ROOT->get_seq_len() > horiz_paint_size) ? horiz_paint_size : PHDATA::ROOT->get_seq_len();
139            vert_page_size   = (long(PHDATA::ROOT->nentries) > vert_paint_size) ? vert_paint_size : PHDATA::ROOT->nentries;
140            rect.l           = 0;
141            rect.t           = 0;
142            rect.r           = (int) ((PHDATA::ROOT->get_seq_len()-horiz_page_size)*cell_width+squ.r);
143            rect.b           = (int) ((PHDATA::ROOT->nentries-vert_page_size)*cell_height+squ.b);
144            break;
145
146        case matrix_dpy: {
147            const AW_font_information *aw_fi = device->get_font_information(0,0);
148
149            horiz_paint_size = (squ.r-aw_fi->max_letter.width-off_dx)/cell_width;
150            vert_paint_size  = (squ.b-off_dy)/cell_height;
151            horiz_page_size  = (long(PHDATA::ROOT->nentries) > horiz_paint_size) ? horiz_paint_size : PHDATA::ROOT->nentries;
152            vert_page_size   = (long(PHDATA::ROOT->nentries) > vert_paint_size) ? vert_paint_size : PHDATA::ROOT->nentries;
153            rect.l           = 0;
154            rect.t           = 0;
155            rect.r           = (int) ((PHDATA::ROOT->nentries-horiz_page_size)*cell_width+squ.r);
156            rect.b           = (int) ((PHDATA::ROOT->nentries-vert_page_size)*cell_height+squ.b);
157            break;
158        }
159        case filter_dpy:
160            horiz_paint_size  = (squ.r-off_dx)/cell_width;
161            vert_paint_size   = (squ.b-off_dy)/cell_height;
162            vert_paint_size  -= (3/8)/cell_height +2;
163            horiz_page_size   = (PHDATA::ROOT->get_seq_len() > horiz_paint_size) ? horiz_paint_size : PHDATA::ROOT->get_seq_len();
164            vert_page_size    = (long(PHDATA::ROOT->nentries) > vert_paint_size) ? vert_paint_size : PHDATA::ROOT->nentries;
165            rect.l            = 0;
166            rect.t            = 0;
167            rect.r            = (int) ((PHDATA::ROOT->get_seq_len()-horiz_page_size)*cell_width+squ.r);
168            rect.b            = (int) ((PHDATA::ROOT->nentries-vert_page_size)*cell_height+squ.b);
169            break;
170
171        default:
172            aw_message("resized: unknown display type (maybe not implemented yet)");
173            break;
174    }
175
176    horiz_page_start = 0; horiz_last_view_start=0;
177    vert_page_start  = 0; vert_last_view_start=0;
178
179    device->reset();            // clip_size == device_size
180    device->clear(-1);
181    device->set_right_clip_border((int)(off_dx+cell_width*horiz_page_size));
182    device->reset();            // reset shift_x and shift_y
183
184    PH_used_windows::windowList->phylo_main_window->set_vertical_scrollbar_position(0);
185    PH_used_windows::windowList->phylo_main_window->set_horizontal_scrollbar_position(0);
186    PH_used_windows::windowList->phylo_main_window->tell_scrolled_picture_size(rect);
187    PH_used_windows::windowList->phylo_main_window->calculate_scrollbars();
188}
189
190
191
192void PH_display::display(void)   // draw area
193{
194    char buf[50],cbuf[2];
195    long x,y,xpos,ypos;
196    AW_window *main_win = PH_used_windows::windowList->phylo_main_window;
197    // AW_font_information *aw_fi=0;
198    long minhom;
199    long maxhom;
200    long startcol,stopcol;
201
202    if (!PHDATA::ROOT) return; // not correctly initialized yet
203
204    float *markerline = PHDATA::ROOT->markerline;
205
206    if(!device) return;
207    GB_transaction dummy(PHDATA::ROOT->gb_main);
208    switch(display_what)  // be careful: text origin is lower left
209    {
210        case NONE: return;
211        case species_dpy:
212            device->shift(AW::Vector(off_dx, off_dy));
213            ypos=0;
214            for(y=vert_page_start;y<(vert_page_start+vert_page_size) &&
215                    (y<total_cells_vert);y++)
216            {
217                device->text(0,PHDATA::ROOT->hash_elements[y]->name,-off_dx,
218                             ypos*cell_height-cell_offset,
219                             0.0,-1,0,0);                          // species names
220
221                GBDATA     *gb_seq_data = PHDATA::ROOT->hash_elements[y]->gb_species_data_ptr;
222                const char *seq_data    = GB_read_char_pntr(gb_seq_data);
223                long        seq_len     = GB_read_count(gb_seq_data);
224               
225                device->text(0,
226                             (horiz_page_start >=seq_len) ? "" : (seq_data+horiz_page_start),
227                             0,ypos*cell_height-cell_offset,
228                             0.0,-1,0,0);                          // alignment
229                ypos++;
230            }
231            device->shift(-AW::Vector(off_dx, off_dy));
232            break;
233
234        case matrix_dpy:
235            device->shift(AW::Vector(off_dx, off_dy));
236            xpos=0;
237            for(x=horiz_page_start;x<(horiz_page_start+horiz_page_size) &&
238                    (x<total_cells_horiz);x++)
239            {
240                ypos=0;
241                for(y=vert_page_start;y<(vert_page_start+vert_page_size) &&
242                        (y<total_cells_vert);y++)
243                {
244                    sprintf(buf,"%3.4f",PHDATA::ROOT->matrix->get(x,y));
245                    device->text(0,buf,xpos*cell_width,ypos*cell_height-cell_offset,
246                                 0.0,-1,0,0);
247                    ypos++;
248                }
249                // display horizontal speciesnames :
250                device->text(0,PHDATA::ROOT->hash_elements[x]->name,
251                             xpos*cell_width,cell_height-off_dy-cell_offset,0.0,-1,0,0);
252                xpos++;
253            }
254            device->shift(AW::Vector(-off_dx, 0));
255            // display vertical speciesnames
256            ypos=0;
257            for(y=vert_page_start;y<vert_page_start+vert_page_size;y++)
258            {
259                device->text(0,PHDATA::ROOT->hash_elements[y]->name,
260                             0,ypos*cell_height-cell_offset,0.0,-1,0,0);
261                ypos++;
262            }
263            device->shift(AW::Vector(0, -off_dy));
264            break;
265
266
267
268
269        case filter_dpy: {
270            device->shift(AW::Vector(off_dx, off_dy));
271            ypos=0;
272            for(y=vert_page_start;y<(vert_page_start+vert_page_size) &&
273                    (y<total_cells_vert);y++)
274            {
275                device->text(0,PHDATA::ROOT->hash_elements[y]->name,-off_dx,
276                             ypos*cell_height-cell_offset,
277                             0.0,-1,0,0);                          // species names
278
279                GBDATA     *gb_seq_data = PHDATA::ROOT->hash_elements[y]->gb_species_data_ptr;
280                const char *seq_data    = GB_read_char_pntr(gb_seq_data);
281                long        seq_len     = GB_read_count(gb_seq_data);
282
283                device->text(0,
284                             (horiz_page_start >=seq_len) ? "" : (seq_data+horiz_page_start),
285                             0,ypos*cell_height-cell_offset,
286                             0.0,-1,0,0); // alignment
287                ypos++;
288            }
289            xpos=0;
290            cbuf[0]='\0'; cbuf[1]='\0';
291            const AW_font_information *aw_fi=device->get_font_information(0,0);
292            minhom = main_win->get_root()->awar("phyl/filter/minhom")->read_int();
293            maxhom = main_win->get_root()->awar("phyl/filter/maxhom")->read_int();
294            startcol = main_win->get_root()->awar("phyl/filter/startcol")->read_int();
295            stopcol = main_win->get_root()->awar("phyl/filter/stopcol")->read_int();
296            for (x = horiz_page_start; x < horiz_page_start + horiz_page_size; x++) {
297                int             gc = 1;
298                float       ml = markerline[x];
299                if (x < startcol || x>stopcol){
300                    gc = 2;
301                }
302                if (markerline[x] >= 0.0) {
303                    if (    ml < minhom ||
304                            ml > maxhom){
305                        gc = 2;
306                    }
307                    sprintf(buf, "%3.0f", ml);
308                }
309                else {
310                    gc = 2;
311                    sprintf(buf, "XXX");
312                }
313
314                for (y = 0; y < 3; y++) {
315                    strncpy(cbuf, buf + y, 1);
316                    device->text(gc, cbuf, xpos * cell_width + 1,
317                                 vert_page_size * cell_height +
318                                 y * aw_fi->max_letter.height,
319                                 0.0, -1, 0, 0);
320                }
321                xpos++;
322            }
323            device->shift(-AW::Vector(off_dx, off_dy));
324            break;
325        }
326
327        default:
328            printf("\ndisplay: unknown display type (maybe not implemented yet)\n");
329    }
330}
331
332
333void PH_display::print(void)
334{
335    printf("\nContents of class PH_display:\n");
336    printf("display_what: %d\n",display_what);
337    printf("screen_width:          %f  screen_height:        %f\n",screen_width,screen_height);
338    printf("cell_width:            %ld  cell_height:          %ld\n",cell_width,cell_height);
339    printf("cell_offset:           %ld\n",cell_offset);
340    printf("horiz_page_size:       %ld  vert_page_size:       %ld\n",horiz_page_size,vert_page_size);
341    printf("horiz_page_start:      %ld  vert_page_start:      %ld\n",horiz_page_start,vert_page_start);
342    printf("off_dx:                %ld  off_dy:               %ld\n",off_dx,off_dy);
343    printf("horiz_last_view_start: %ld  vert_last_view_start: %ld\n" ,horiz_last_view_start,vert_last_view_start);
344}
345
346
347void PH_display::set_scrollbar_steps(AW_window *aww,long width_h,long width_v,long page_h,long page_v)
348{
349    char buffer[200];
350
351    sprintf(buffer,"window/%s/scroll_width_horizontal",aww->window_defaults_name);
352    aww->get_root()->awar(buffer)->write_int(width_h);
353    sprintf(buffer,"window/%s/scroll_width_vertical",aww->window_defaults_name);
354    aww->get_root()->awar(buffer)->write_int(width_v);
355    sprintf( buffer,"window/%s/horizontal_page_increment",aww->window_defaults_name);
356    aww->get_root()->awar(buffer)->write_int(page_h);
357    sprintf(buffer,"window/%s/vertical_page_increment",aww->window_defaults_name);
358    aww->get_root()->awar(buffer)->write_int(page_v);
359}
360
361
362void PH_display::monitor_vertical_scroll_cb(AW_window *aww)    // draw area
363{
364    long diff;
365
366    if(!device) return;
367    if(vert_last_view_start==aww->slider_pos_vertical) return;
368    diff=(aww->slider_pos_vertical-vert_last_view_start)/cell_height;
369    // fast scroll: be careful: no transformation in move_region
370    if(diff==1) // scroll one position up (== \/ arrow pressed)
371    {
372        device->move_region(0,off_dy,screen_width,vert_page_size*cell_height,0,off_dy-cell_height);
373
374        // device->line(0,0,off_dy+1,100,off_dy+1,-1,0,0);  // source top
375        // device->line(0,0,(vert_page_size-1)*cell_height+off_dy+1,100,
376        //  (vert_page_size-1)*cell_height+off_dy+1,-1,0,0);  // source bottom
377        // device->line(0,0,off_dy-cell_height,50,off_dy-cell_height,-1,0,0); // target top
378
379        device->clear_part(0,off_dy-cell_height+(vert_page_size-1)*cell_height+1,
380                           screen_width,cell_height, -1);
381
382        // device->line(0,6,off_dy-cell_height+(vert_page_size-1)*cell_height+1,
383        // 6,off_dy-cell_height+(vert_page_size)*cell_height,-1,0,0);
384
385        device->push_clip_scale();
386        device->set_top_clip_border((int)(off_dy+(vert_page_size-2)*cell_height));
387    }
388    else if(diff==-1) // scroll one position down (== /\ arrow pressed)
389    {
390        device->move_region(0,off_dy-cell_height,screen_width,(vert_page_size-1)*cell_height+1,0,
391                            off_dy);
392        // device->line(0,0,off_dy-cell_height,50,off_dy-cell_height,-1,0,0);
393        // device->line(0,0,(vert_page_size-1)*cell_height+1+(off_dy-cell_height),
394        //                50,(vert_page_size-1)*cell_height+1+(off_dy-cell_height),-1,0,0);
395        device->clear_part(0,off_dy-cell_height,screen_width,cell_height, -1);
396        // device->line(0,0,off_dy-cell_height,50,off_dy-cell_height,-1,0,0);
397        // device->line(0,0,off_dy,50,off_dy,-1,0,0);
398        device->push_clip_scale();
399        device->set_bottom_clip_border((int)off_dy);
400    }
401    else  device->clear(-1);
402
403    vert_last_view_start=aww->slider_pos_vertical;
404    vert_page_start=aww->slider_pos_vertical/cell_height;
405    display();
406    if((diff==1) || (diff==-1))  device->pop_clip_scale();
407}
408
409void PH_display::monitor_horizontal_scroll_cb(AW_window *aww)  // draw area
410{
411    long diff;
412
413    if(!device) return;
414    if( horiz_last_view_start==aww->slider_pos_horizontal) return;
415    diff=(aww->slider_pos_horizontal- horiz_last_view_start)/cell_width;
416    // fast scroll
417    if(diff==1)   // scroll one position left ( > arrow pressed)
418    {
419        device->move_region(off_dx+cell_width,0,
420                            horiz_page_size*cell_width,screen_height,
421                            off_dx,0);
422
423        // device->line(0,off_dx+cell_width,0,off_dx+cell_width,screen_height,-1,0,0);   // left border
424        // device->line(0,horiz_page_size*cell_width+off_dx+cell_width,0,
425        //            horiz_page_size*cell_width+off_dx+cell_width,screen_height,-1,0,0); // right border
426        // device->line(0,off_dx,0,off_dx,screen_height,-1,0,0);  // target
427
428        device->clear_part(off_dx+(horiz_page_size-1)*cell_width,0,cell_width,screen_height, -1);
429
430        // device->line(0,off_dx+(horiz_page_size-1)*cell_width,0,
431        //             off_dx+(horiz_page_size-1)*cell_width,screen_height,-1,0,0);
432        // device->line(0,off_dx+(horiz_page_size-1)*cell_width+cell_width,0,
433        //              off_dx+(horiz_page_size-1)*cell_width+cell_width,screen_height,-1,0,0);
434
435        device->push_clip_scale();
436        device->set_left_clip_border((int)((horiz_page_size-1)*cell_width));
437    }
438    else if(diff==-1) // scroll one position right ( < arrow pressed)
439    {
440        device->move_region(off_dx,0,(horiz_page_size-1)*cell_width,screen_height,off_dx+cell_width,
441                            0);
442        device->clear_part(off_dx,0,cell_width,screen_height, -1);
443        device->push_clip_scale();
444        device->set_right_clip_border((int)(off_dx+cell_width));
445    }
446    else device->clear(-1);
447
448    horiz_last_view_start=aww->slider_pos_horizontal;
449    horiz_page_start=aww->slider_pos_horizontal/cell_width;
450    display();
451    if((diff==1) || (diff==-1))  device->pop_clip_scale();
452}
453
454PH_display_status::PH_display_status(AW_device *awd)
455{
456    AW_rectangle rect;
457    device=awd;
458
459    if(!device) return;
460    const AW_font_information *aw_fi=device->get_font_information(0,0);
461    font_width=aw_fi->max_letter.width;
462    font_height=aw_fi->max_letter.height;
463    device->reset();
464    device->get_area_size(&rect);
465    device->set_foreground_color(0,AW_WINDOW_FG);
466    max_x=(rect.r-rect.l)/font_width;
467    max_y=(rect.b-rect.t)/font_height;
468    x_pos=0.0;
469    y_pos=0.0;
470    tab_pos=x_pos;
471}
472
473void PH_display_status::write(const char *text)
474{
475    device->text(0,text,x_pos*font_width,y_pos*font_height,0.0,-1,0,0);
476    x_pos+=strlen(text);
477}
478
479void PH_display_status::writePadded(const char *text, size_t len)
480{
481    device->text(0,text,x_pos*font_width,y_pos*font_height,0.0,-1,0,0);
482    x_pos += len;
483}
484
485void PH_display_status::write(long numl)
486{
487    char buf[20];
488
489    sprintf(buf,"%ld",numl);
490    write(buf);
491}
492
493void PH_display_status::write(AW_pos numA)
494{
495    char buf[20];
496
497    sprintf(buf,"%3.3G",numA);
498    write(buf);
499}
500
501void PH_display_status::clear(void){
502    device->clear(-1);
503}
504
505void display_status(AW_window *dummy,AW_CL cl_awroot,AW_CL cd2)    // bottom area
506{
507    AWUSE(dummy); AWUSE(cd2);
508    AW_root *aw_root = (AW_root *) cl_awroot;
509
510    if(!PH_display::ph_display) return;
511    if(!PH_used_windows::windowList) return;
512
513    {
514        static PH_display_status phds(PH_used_windows::windowList->phylo_main_window->get_device (AW_BOTTOM_AREA));
515        phds.clear();
516       
517        const int LABEL_LEN = 21;
518
519        switch(PH_display::ph_display->displayed())
520        {
521            case NONE: return;
522            case filter_dpy:
523            case species_dpy: phds.set_origin();
524                phds.set_cursor((phds.get_size('x')/2)-10,0);
525                phds.write("STATUS REPORT FILTER");
526                phds.newline();
527               
528                phds.writePadded("Start at column:", LABEL_LEN);
529                phds.write((long)aw_root->awar("phyl/filter/startcol")->read_int());
530                phds.move_x(15);
531                phds.set_tab();
532                phds.writePadded("Stop at column:", LABEL_LEN);
533                phds.write((long)aw_root->awar("phyl/filter/stopcol")->read_int());
534                phds.newline();
535
536                phds.writePadded("Minimal similarity:", LABEL_LEN);
537                phds.write((long)aw_root->awar("phyl/filter/minhom")->read_int());
538                phds.set_cursor_x(phds.get_tab());
539                phds.writePadded("Maximal similarity:", LABEL_LEN);
540                phds.write((long)aw_root->awar("phyl/filter/maxhom")->read_int());
541                phds.newline();
542                phds.newline();
543
544                phds.writePadded("'.':", LABEL_LEN);
545                phds.write(filter_text[aw_root->awar("phyl/filter/point")->read_int()]);
546                phds.newline();
547
548                phds.writePadded("'-':", LABEL_LEN);
549                phds.write(filter_text[aw_root->awar("phyl/filter/minus")->read_int()]);
550                phds.newline();
551
552                phds.writePadded("ambiguity codes:", LABEL_LEN);
553                phds.write(filter_text[aw_root->awar("phyl/filter/rest")->read_int()]);
554                phds.newline();
555
556                phds.writePadded("lowercase chars:", LABEL_LEN);
557                phds.write(filter_text[aw_root->awar("phyl/filter/lower")->read_int()]);
558                break;
559
560            case matrix_dpy: phds.set_origin();
561                phds.set_cursor((phds.get_size('x')/2)-10,0);
562                phds.write("STATUS REPORT MATRIX");
563                break;
564               
565            default: printf("\nstatus: unknown display type (maybe not implemented yet)\n");
566        }
567    }
568}
569
Note: See TracBrowser for help on using the repository browser.