]> Pileus Git - ~andy/gtk/blob - gtk/gtkbox.c
Added notice to look in AUTHORS and ChangeLog files for a list of changes.
[~andy/gtk] / gtk / gtkbox.c
1 /* GTK - The GIMP Toolkit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 /*
21  * Modified by the GTK+ Team and others 1997-1999.  See the AUTHORS
22  * file for a list of people on the GTK+ Team.  See the ChangeLog
23  * files for a list of changes.  These files are distributed with
24  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
25  */
26
27 #include "gtkbox.h"
28
29 enum {
30   ARG_0,
31   ARG_SPACING,
32   ARG_HOMOGENEOUS
33 };
34
35 enum {
36   CHILD_ARG_0,
37   CHILD_ARG_EXPAND,
38   CHILD_ARG_FILL,
39   CHILD_ARG_PADDING,
40   CHILD_ARG_PACK_TYPE,
41   CHILD_ARG_POSITION
42 };
43
44 static void gtk_box_class_init (GtkBoxClass    *klass);
45 static void gtk_box_init       (GtkBox         *box);
46 static void gtk_box_get_arg    (GtkObject      *object,
47                                 GtkArg         *arg,
48                                 guint           arg_id);
49 static void gtk_box_set_arg    (GtkObject      *object,
50                                 GtkArg         *arg,
51                                 guint           arg_id);
52 static void gtk_box_map        (GtkWidget      *widget);
53 static void gtk_box_unmap      (GtkWidget      *widget);
54 static void gtk_box_draw       (GtkWidget      *widget,
55                                 GdkRectangle   *area);
56 static gint gtk_box_expose     (GtkWidget      *widget,
57                                 GdkEventExpose *event);
58 static void gtk_box_add        (GtkContainer   *container,
59                                 GtkWidget      *widget);
60 static void gtk_box_remove     (GtkContainer   *container,
61                                 GtkWidget      *widget);
62 static void gtk_box_forall     (GtkContainer   *container,
63                                 gboolean        include_internals,
64                                 GtkCallback     callback,
65                                 gpointer        callback_data);
66 static void gtk_box_set_child_arg (GtkContainer   *container,
67                                    GtkWidget      *child,
68                                    GtkArg         *arg,
69                                    guint           arg_id);
70 static void gtk_box_get_child_arg (GtkContainer   *container,
71                                    GtkWidget      *child,
72                                    GtkArg         *arg,
73                                    guint           arg_id);
74 static GtkType gtk_box_child_type (GtkContainer   *container);
75      
76
77 static GtkContainerClass *parent_class = NULL;
78
79
80 GtkType
81 gtk_box_get_type (void)
82 {
83   static GtkType box_type = 0;
84
85   if (!box_type)
86     {
87       static const GtkTypeInfo box_info =
88       {
89         "GtkBox",
90         sizeof (GtkBox),
91         sizeof (GtkBoxClass),
92         (GtkClassInitFunc) gtk_box_class_init,
93         (GtkObjectInitFunc) gtk_box_init,
94         /* reserved_1 */ NULL,
95         /* reserved_2 */ NULL,
96         (GtkClassInitFunc) NULL,
97       };
98
99       box_type = gtk_type_unique (GTK_TYPE_CONTAINER, &box_info);
100     }
101
102   return box_type;
103 }
104
105 static void
106 gtk_box_class_init (GtkBoxClass *class)
107 {
108   GtkObjectClass *object_class;
109   GtkWidgetClass *widget_class;
110   GtkContainerClass *container_class;
111
112   object_class = (GtkObjectClass*) class;
113   widget_class = (GtkWidgetClass*) class;
114   container_class = (GtkContainerClass*) class;
115
116   parent_class = gtk_type_class (GTK_TYPE_CONTAINER);
117
118   gtk_object_add_arg_type ("GtkBox::spacing", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_SPACING);
119   gtk_object_add_arg_type ("GtkBox::homogeneous", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_HOMOGENEOUS);
120   gtk_container_add_child_arg_type ("GtkBox::expand", GTK_TYPE_BOOL, GTK_ARG_READWRITE, CHILD_ARG_EXPAND);
121   gtk_container_add_child_arg_type ("GtkBox::fill", GTK_TYPE_BOOL, GTK_ARG_READWRITE, CHILD_ARG_FILL);
122   gtk_container_add_child_arg_type ("GtkBox::padding", GTK_TYPE_ULONG, GTK_ARG_READWRITE, CHILD_ARG_PADDING);
123   gtk_container_add_child_arg_type ("GtkBox::pack_type", GTK_TYPE_PACK_TYPE, GTK_ARG_READWRITE, CHILD_ARG_PACK_TYPE);
124   gtk_container_add_child_arg_type ("GtkBox::position", GTK_TYPE_LONG, GTK_ARG_READWRITE, CHILD_ARG_POSITION);
125
126   object_class->set_arg = gtk_box_set_arg;
127   object_class->get_arg = gtk_box_get_arg;
128
129   widget_class->map = gtk_box_map;
130   widget_class->unmap = gtk_box_unmap;
131   widget_class->draw = gtk_box_draw;
132   widget_class->expose_event = gtk_box_expose;
133
134   container_class->add = gtk_box_add;
135   container_class->remove = gtk_box_remove;
136   container_class->forall = gtk_box_forall;
137   container_class->child_type = gtk_box_child_type;
138   container_class->set_child_arg = gtk_box_set_child_arg;
139   container_class->get_child_arg = gtk_box_get_child_arg;
140 }
141
142 static void
143 gtk_box_init (GtkBox *box)
144 {
145   GTK_WIDGET_SET_FLAGS (box, GTK_NO_WINDOW);
146
147   box->children = NULL;
148   box->spacing = 0;
149   box->homogeneous = FALSE;
150 }
151
152 static void
153 gtk_box_set_arg (GtkObject    *object,
154                  GtkArg       *arg,
155                  guint         arg_id)
156 {
157   GtkBox *box;
158
159   box = GTK_BOX (object);
160
161   switch (arg_id)
162     {
163     case ARG_SPACING:
164       gtk_box_set_spacing (box, GTK_VALUE_INT (*arg));
165       break;
166     case ARG_HOMOGENEOUS:
167       gtk_box_set_homogeneous (box, GTK_VALUE_BOOL (*arg));
168       break;
169     default:
170       break;
171     }
172 }
173
174 static void
175 gtk_box_get_arg (GtkObject    *object,
176                  GtkArg       *arg,
177                  guint         arg_id)
178 {
179   GtkBox *box;
180
181   box = GTK_BOX (object);
182
183   switch (arg_id)
184     {
185     case ARG_SPACING:
186       GTK_VALUE_INT (*arg) = box->spacing;
187       break;
188     case ARG_HOMOGENEOUS:
189       GTK_VALUE_BOOL (*arg) = box->homogeneous;
190       break;
191     default:
192       arg->type = GTK_TYPE_INVALID;
193       break;
194     }
195 }
196
197 static GtkType
198 gtk_box_child_type      (GtkContainer   *container)
199 {
200   return GTK_TYPE_WIDGET;
201 }
202
203 static void
204 gtk_box_set_child_arg (GtkContainer   *container,
205                        GtkWidget      *child,
206                        GtkArg         *arg,
207                        guint           arg_id)
208 {
209   gboolean expand = 0;
210   gboolean fill = 0;
211   guint padding = 0;
212   GtkPackType pack_type = 0;
213
214   if (arg_id != CHILD_ARG_POSITION)
215     gtk_box_query_child_packing (GTK_BOX (container),
216                                  child,
217                                  &expand,
218                                  &fill,
219                                  &padding,
220                                  &pack_type);
221   
222   switch (arg_id)
223     {
224     case CHILD_ARG_EXPAND:
225       gtk_box_set_child_packing (GTK_BOX (container),
226                                  child,
227                                  GTK_VALUE_BOOL (*arg),
228                                  fill,
229                                  padding,
230                                  pack_type);
231       break;
232     case CHILD_ARG_FILL:
233       gtk_box_set_child_packing (GTK_BOX (container),
234                                  child,
235                                  expand,
236                                  GTK_VALUE_BOOL (*arg),
237                                  padding,
238                                  pack_type);
239       break;
240     case CHILD_ARG_PADDING:
241       gtk_box_set_child_packing (GTK_BOX (container),
242                                  child,
243                                  expand,
244                                  fill,
245                                  GTK_VALUE_ULONG (*arg),
246                                  pack_type);
247       break;
248     case CHILD_ARG_PACK_TYPE:
249       gtk_box_set_child_packing (GTK_BOX (container),
250                                  child,
251                                  expand,
252                                  fill,
253                                  padding,
254                                  GTK_VALUE_ENUM (*arg));
255       break;
256     case CHILD_ARG_POSITION:
257       gtk_box_reorder_child (GTK_BOX (container),
258                              child,
259                              GTK_VALUE_LONG (*arg));
260       break;
261     default:
262       break;
263     }
264 }
265
266 static void
267 gtk_box_get_child_arg (GtkContainer   *container,
268                        GtkWidget      *child,
269                        GtkArg         *arg,
270                        guint           arg_id)
271 {
272   gboolean expand = 0;
273   gboolean fill = 0;
274   guint padding = 0;
275   GtkPackType pack_type = 0;
276   GList *list;
277
278   if (arg_id != CHILD_ARG_POSITION)
279     gtk_box_query_child_packing (GTK_BOX (container),
280                                  child,
281                                  &expand,
282                                  &fill,
283                                  &padding,
284                                  &pack_type);
285   
286   switch (arg_id)
287     {
288     case CHILD_ARG_EXPAND:
289       GTK_VALUE_BOOL (*arg) = expand;
290       break;
291     case CHILD_ARG_FILL:
292       GTK_VALUE_BOOL (*arg) = fill;
293       break;
294     case CHILD_ARG_PADDING:
295       GTK_VALUE_ULONG (*arg) = padding;
296       break;
297     case CHILD_ARG_PACK_TYPE:
298       GTK_VALUE_ENUM (*arg) = pack_type;
299       break;
300     case CHILD_ARG_POSITION:
301       GTK_VALUE_LONG (*arg) = 0;
302       for (list = GTK_BOX (container)->children; list; list = list->next)
303         {
304           GtkBoxChild *child_entry;
305
306           child_entry = list->data;
307           if (child_entry->widget == child)
308             break;
309           GTK_VALUE_LONG (*arg)++;
310         }
311       if (!list)
312         GTK_VALUE_LONG (*arg) = -1;
313       break;
314     default:
315       arg->type = GTK_TYPE_INVALID;
316       break;
317     }
318 }
319
320 void
321 gtk_box_pack_start (GtkBox    *box,
322                     GtkWidget *child,
323                     gboolean   expand,
324                     gboolean   fill,
325                     guint      padding)
326 {
327   GtkBoxChild *child_info;
328
329   g_return_if_fail (box != NULL);
330   g_return_if_fail (GTK_IS_BOX (box));
331   g_return_if_fail (child != NULL);
332   g_return_if_fail (child->parent == NULL);
333
334   child_info = g_new (GtkBoxChild, 1);
335   child_info->widget = child;
336   child_info->padding = padding;
337   child_info->expand = expand ? TRUE : FALSE;
338   child_info->fill = fill ? TRUE : FALSE;
339   child_info->pack = GTK_PACK_START;
340
341   box->children = g_list_append (box->children, child_info);
342
343   gtk_widget_set_parent (child, GTK_WIDGET (box));
344
345   if (GTK_WIDGET_VISIBLE (GTK_WIDGET (box)))
346     {
347       if (GTK_WIDGET_REALIZED (GTK_WIDGET (box)) &&
348           !GTK_WIDGET_REALIZED (child))
349         gtk_widget_realize (child);
350       
351       if (GTK_WIDGET_MAPPED (GTK_WIDGET (box)) &&
352           !GTK_WIDGET_MAPPED (child))
353         gtk_widget_map (child);
354     }
355
356   if (GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (box))
357     gtk_widget_queue_resize (child);
358 }
359
360 void
361 gtk_box_pack_end (GtkBox    *box,
362                   GtkWidget *child,
363                   gboolean   expand,
364                   gboolean   fill,
365                   guint      padding)
366 {
367   GtkBoxChild *child_info;
368
369   g_return_if_fail (box != NULL);
370   g_return_if_fail (GTK_IS_BOX (box));
371   g_return_if_fail (child != NULL);
372   g_return_if_fail (child->parent == NULL);
373
374   child_info = g_new (GtkBoxChild, 1);
375   child_info->widget = child;
376   child_info->padding = padding;
377   child_info->expand = expand ? TRUE : FALSE;
378   child_info->fill = fill ? TRUE : FALSE;
379   child_info->pack = GTK_PACK_END;
380
381   box->children = g_list_append (box->children, child_info);
382
383   gtk_widget_set_parent (child, GTK_WIDGET (box));
384
385   if (GTK_WIDGET_VISIBLE (GTK_WIDGET (box)))
386     {
387       if (GTK_WIDGET_REALIZED (GTK_WIDGET (box)) &&
388           !GTK_WIDGET_REALIZED (child))
389         gtk_widget_realize (child);
390       
391       if (GTK_WIDGET_MAPPED (GTK_WIDGET (box)) &&
392           !GTK_WIDGET_MAPPED (child))
393         gtk_widget_map (child);
394     }
395   
396   if (GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (box))
397     gtk_widget_queue_resize (child);
398 }
399
400 void
401 gtk_box_pack_start_defaults (GtkBox    *box,
402                              GtkWidget *child)
403 {
404   g_return_if_fail (box != NULL);
405   g_return_if_fail (GTK_IS_BOX (box));
406   g_return_if_fail (child != NULL);
407
408   gtk_box_pack_start (box, child, TRUE, TRUE, 0);
409 }
410
411 void
412 gtk_box_pack_end_defaults (GtkBox    *box,
413                            GtkWidget *child)
414 {
415   g_return_if_fail (box != NULL);
416   g_return_if_fail (GTK_IS_BOX (box));
417   g_return_if_fail (child != NULL);
418
419   gtk_box_pack_end (box, child, TRUE, TRUE, 0);
420 }
421
422 void
423 gtk_box_set_homogeneous (GtkBox  *box,
424                          gboolean homogeneous)
425 {
426   g_return_if_fail (box != NULL);
427   g_return_if_fail (GTK_IS_BOX (box));
428
429   if ((homogeneous ? TRUE : FALSE) != box->homogeneous)
430     {
431       box->homogeneous = homogeneous ? TRUE : FALSE;
432       gtk_widget_queue_resize (GTK_WIDGET (box));
433     }
434 }
435
436 void
437 gtk_box_set_spacing (GtkBox *box,
438                      gint    spacing)
439 {
440   g_return_if_fail (box != NULL);
441   g_return_if_fail (GTK_IS_BOX (box));
442
443   if (spacing != box->spacing)
444     {
445       box->spacing = spacing;
446       gtk_widget_queue_resize (GTK_WIDGET (box));
447     }
448 }
449
450 void
451 gtk_box_reorder_child (GtkBox                   *box,
452                        GtkWidget                *child,
453                        gint                      position)
454 {
455   GList *list;
456
457   g_return_if_fail (box != NULL);
458   g_return_if_fail (GTK_IS_BOX (box));
459   g_return_if_fail (child != NULL);
460
461   list = box->children;
462   while (list)
463     {
464       GtkBoxChild *child_info;
465
466       child_info = list->data;
467       if (child_info->widget == child)
468         break;
469
470       list = list->next;
471     }
472
473   if (list && box->children->next)
474     {
475       GList *tmp_list;
476
477       if (list->next)
478         list->next->prev = list->prev;
479       if (list->prev)
480         list->prev->next = list->next;
481       else
482         box->children = list->next;
483
484       tmp_list = box->children;
485       while (position && tmp_list->next)
486         {
487           position--;
488           tmp_list = tmp_list->next;
489         }
490
491       if (position)
492         {
493           tmp_list->next = list;
494           list->prev = tmp_list;
495           list->next = NULL;
496         }
497       else
498         {
499           if (tmp_list->prev)
500             tmp_list->prev->next = list;
501           else
502             box->children = list;
503           list->prev = tmp_list->prev;
504           tmp_list->prev = list;
505           list->next = tmp_list;
506         }
507
508       if (GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (box))
509         gtk_widget_queue_resize (child);
510     }
511 }
512
513 void
514 gtk_box_query_child_packing (GtkBox             *box,
515                              GtkWidget          *child,
516                              gboolean           *expand,
517                              gboolean           *fill,
518                              guint              *padding,
519                              GtkPackType        *pack_type)
520 {
521   GList *list;
522   GtkBoxChild *child_info = NULL;
523
524   g_return_if_fail (box != NULL);
525   g_return_if_fail (GTK_IS_BOX (box));
526   g_return_if_fail (child != NULL);
527
528   list = box->children;
529   while (list)
530     {
531       child_info = list->data;
532       if (child_info->widget == child)
533         break;
534
535       list = list->next;
536     }
537
538   if (list)
539     {
540       if (expand)
541         *expand = child_info->expand;
542       if (fill)
543         *fill = child_info->fill;
544       if (padding)
545         *padding = child_info->padding;
546       if (pack_type)
547         *pack_type = child_info->pack;
548     }
549 }
550
551 void
552 gtk_box_set_child_packing (GtkBox               *box,
553                            GtkWidget            *child,
554                            gboolean              expand,
555                            gboolean              fill,
556                            guint                 padding,
557                            GtkPackType           pack_type)
558 {
559   GList *list;
560   GtkBoxChild *child_info = NULL;
561
562   g_return_if_fail (box != NULL);
563   g_return_if_fail (GTK_IS_BOX (box));
564   g_return_if_fail (child != NULL);
565
566   list = box->children;
567   while (list)
568     {
569       child_info = list->data;
570       if (child_info->widget == child)
571         break;
572
573       list = list->next;
574     }
575
576   if (list)
577     {
578       child_info->expand = expand != FALSE;
579       child_info->fill = fill != FALSE;
580       child_info->padding = padding;
581       if (pack_type == GTK_PACK_END)
582         child_info->pack = GTK_PACK_END;
583       else
584         child_info->pack = GTK_PACK_START;
585
586       if (GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (box))
587         gtk_widget_queue_resize (child);
588     }
589 }
590
591 static void
592 gtk_box_map (GtkWidget *widget)
593 {
594   GtkBox *box;
595   GtkBoxChild *child;
596   GList *children;
597
598   g_return_if_fail (widget != NULL);
599   g_return_if_fail (GTK_IS_BOX (widget));
600
601   box = GTK_BOX (widget);
602   GTK_WIDGET_SET_FLAGS (box, GTK_MAPPED);
603
604   children = box->children;
605   while (children)
606     {
607       child = children->data;
608       children = children->next;
609
610       if (GTK_WIDGET_VISIBLE (child->widget) &&
611           !GTK_WIDGET_MAPPED (child->widget))
612         gtk_widget_map (child->widget);
613     }
614 }
615
616 static void
617 gtk_box_unmap (GtkWidget *widget)
618 {
619   GtkBox *box;
620   GtkBoxChild *child;
621   GList *children;
622
623   g_return_if_fail (widget != NULL);
624   g_return_if_fail (GTK_IS_BOX (widget));
625
626   box = GTK_BOX (widget);
627   GTK_WIDGET_UNSET_FLAGS (box, GTK_MAPPED);
628
629   children = box->children;
630   while (children)
631     {
632       child = children->data;
633       children = children->next;
634
635       if (GTK_WIDGET_VISIBLE (child->widget) &&
636           GTK_WIDGET_MAPPED (child->widget))
637         gtk_widget_unmap (child->widget);
638     }
639 }
640
641 static void
642 gtk_box_draw (GtkWidget    *widget,
643               GdkRectangle *area)
644 {
645   GtkBox *box;
646   GtkBoxChild *child;
647   GdkRectangle child_area;
648   GList *children;
649   
650   g_return_if_fail (widget != NULL);
651   g_return_if_fail (GTK_IS_BOX (widget));
652    
653   if (GTK_WIDGET_DRAWABLE (widget))
654     {
655       box = GTK_BOX (widget);
656         
657       children = box->children;
658       while (children)
659         {
660           child = children->data;
661           children = children->next;
662              
663           if (gtk_widget_intersect (child->widget, area, &child_area))
664             gtk_widget_draw (child->widget, &child_area);
665         }
666     }
667 }
668
669 static gint
670 gtk_box_expose (GtkWidget      *widget,
671                 GdkEventExpose *event)
672 {
673   GtkBox *box;
674   GtkBoxChild *child;
675   GdkEventExpose child_event;
676   GList *children;
677
678   g_return_val_if_fail (widget != NULL, FALSE);
679   g_return_val_if_fail (GTK_IS_BOX (widget), FALSE);
680   g_return_val_if_fail (event != NULL, FALSE);
681
682   if (GTK_WIDGET_DRAWABLE (widget))
683     {
684       box = GTK_BOX (widget);
685
686       child_event = *event;
687
688       children = box->children;
689       while (children)
690         {
691           child = children->data;
692           children = children->next;
693
694           if (GTK_WIDGET_NO_WINDOW (child->widget) &&
695               gtk_widget_intersect (child->widget, &event->area, &child_event.area))
696             gtk_widget_event (child->widget, (GdkEvent*) &child_event);
697         }
698     }
699
700   return FALSE;
701 }
702
703 static void
704 gtk_box_add (GtkContainer *container,
705              GtkWidget    *widget)
706 {
707   g_return_if_fail (container != NULL);
708   g_return_if_fail (GTK_IS_BOX (container));
709   g_return_if_fail (widget != NULL);
710
711   gtk_box_pack_start_defaults (GTK_BOX (container), widget);
712 }
713
714 static void
715 gtk_box_remove (GtkContainer *container,
716                 GtkWidget    *widget)
717 {
718   GtkBox *box;
719   GtkBoxChild *child;
720   GList *children;
721
722   g_return_if_fail (container != NULL);
723   g_return_if_fail (GTK_IS_BOX (container));
724   g_return_if_fail (widget != NULL);
725
726   box = GTK_BOX (container);
727
728   children = box->children;
729   while (children)
730     {
731       child = children->data;
732
733       if (child->widget == widget)
734         {
735           gboolean was_visible;
736
737           was_visible = GTK_WIDGET_VISIBLE (widget);
738           gtk_widget_unparent (widget);
739
740           box->children = g_list_remove_link (box->children, children);
741           g_list_free (children);
742           g_free (child);
743
744           /* queue resize regardless of GTK_WIDGET_VISIBLE (container),
745            * since that's what is needed by toplevels.
746            */
747           if (was_visible)
748             gtk_widget_queue_resize (GTK_WIDGET (container));
749
750           break;
751         }
752
753       children = children->next;
754     }
755 }
756
757 static void
758 gtk_box_forall (GtkContainer *container,
759                 gboolean      include_internals,
760                 GtkCallback   callback,
761                 gpointer      callback_data)
762 {
763   GtkBox *box;
764   GtkBoxChild *child;
765   GList *children;
766
767   g_return_if_fail (container != NULL);
768   g_return_if_fail (GTK_IS_BOX (container));
769   g_return_if_fail (callback != NULL);
770
771   box = GTK_BOX (container);
772
773   children = box->children;
774   while (children)
775     {
776       child = children->data;
777       children = children->next;
778
779       if (child->pack == GTK_PACK_START)
780         (* callback) (child->widget, callback_data);
781     }
782
783   children = g_list_last (box->children);
784   while (children)
785     {
786       child = children->data;
787       children = children->prev;
788
789       if (child->pack == GTK_PACK_END)
790         (* callback) (child->widget, callback_data);
791     }
792 }