]> git.saurik.com Git - wxWidgets.git/blame_incremental - include/wx/propgrid/propgridpagestate.h
Fix wxPropertyGrid::GetPropertyRect when the last item is collapsed.
[wxWidgets.git] / include / wx / propgrid / propgridpagestate.h
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: wx/propgrid/propgridpagestate.h
3// Purpose: wxPropertyGridPageState class
4// Author: Jaakko Salli
5// Modified by:
6// Created: 2008-08-24
7// Copyright: (c) Jaakko Salli
8// Licence: wxWindows licence
9/////////////////////////////////////////////////////////////////////////////
10
11#ifndef _WX_PROPGRID_PROPGRIDPAGESTATE_H_
12#define _WX_PROPGRID_PROPGRIDPAGESTATE_H_
13
14#include "wx/defs.h"
15
16#if wxUSE_PROPGRID
17
18#include "wx/propgrid/property.h"
19
20// -----------------------------------------------------------------------
21
22/** @section propgrid_hittestresult wxPropertyGridHitTestResult
23
24 A return value from wxPropertyGrid::HitTest(),
25 contains all you need to know about an arbitrary location on the grid.
26*/
27class WXDLLIMPEXP_PROPGRID wxPropertyGridHitTestResult
28{
29 friend class wxPropertyGridPageState;
30public:
31 wxPropertyGridHitTestResult()
32 {
33 m_property = NULL;
34 m_column = -1;
35 m_splitter = -1;
36 m_splitterHitOffset = 0;
37 }
38
39 ~wxPropertyGridHitTestResult()
40 {
41 }
42
43 /**
44 Returns column hit. -1 for margin.
45 */
46 int GetColumn() const { return m_column; }
47
48 /**
49 Returns property hit. NULL if empty space below
50 properties was hit instead.
51 */
52 wxPGProperty* GetProperty() const
53 {
54 return m_property;
55 }
56
57 /**
58 Returns index of splitter hit, -1 for none.
59 */
60 int GetSplitter() const { return m_splitter; }
61
62 /**
63 If splitter hit, then this member function
64 returns offset to the exact splitter position.
65 */
66 int GetSplitterHitOffset() const { return m_splitterHitOffset; }
67
68private:
69 /** Property. NULL if empty space below properties was hit */
70 wxPGProperty* m_property;
71
72 /** Column. -1 for margin. */
73 int m_column;
74
75 /** Index of splitter hit, -1 for none. */
76 int m_splitter;
77
78 /** If splitter hit, offset to that */
79 int m_splitterHitOffset;
80};
81
82// -----------------------------------------------------------------------
83
84#define wxPG_IT_CHILDREN(A) ((A)<<16)
85
86/** @section propgrid_iterator_flags wxPropertyGridIterator Flags
87 @{
88
89 NOTES: At lower 16-bits, there are flags to check if item will be included.
90 At higher 16-bits, there are same flags, but to instead check if children
91 will be included.
92*/
93
94enum wxPG_ITERATOR_FLAGS
95{
96
97/**
98 Iterate through 'normal' property items (does not include children of
99 aggregate or hidden items by default).
100*/
101wxPG_ITERATE_PROPERTIES = wxPG_PROP_PROPERTY |
102 wxPG_PROP_MISC_PARENT |
103 wxPG_PROP_AGGREGATE |
104 wxPG_PROP_COLLAPSED |
105 wxPG_IT_CHILDREN(wxPG_PROP_MISC_PARENT) |
106 wxPG_IT_CHILDREN(wxPG_PROP_CATEGORY),
107
108/** Iterate children of collapsed parents, and individual items that are hidden.
109*/
110wxPG_ITERATE_HIDDEN = wxPG_PROP_HIDDEN |
111 wxPG_IT_CHILDREN(wxPG_PROP_COLLAPSED),
112
113/**
114 Iterate children of parent that is an aggregate property (ie has fixed
115 children).
116*/
117wxPG_ITERATE_FIXED_CHILDREN = wxPG_IT_CHILDREN(wxPG_PROP_AGGREGATE) |
118 wxPG_ITERATE_PROPERTIES,
119
120/** Iterate categories.
121 Note that even without this flag, children of categories are still iterated
122 through.
123*/
124wxPG_ITERATE_CATEGORIES = wxPG_PROP_CATEGORY |
125 wxPG_IT_CHILDREN(wxPG_PROP_CATEGORY) |
126 wxPG_PROP_COLLAPSED,
127
128wxPG_ITERATE_ALL_PARENTS = wxPG_PROP_MISC_PARENT |
129 wxPG_PROP_AGGREGATE |
130 wxPG_PROP_CATEGORY,
131
132wxPG_ITERATE_ALL_PARENTS_RECURSIVELY = wxPG_ITERATE_ALL_PARENTS |
133 wxPG_IT_CHILDREN(
134 wxPG_ITERATE_ALL_PARENTS),
135
136wxPG_ITERATOR_FLAGS_ALL = wxPG_PROP_PROPERTY |
137 wxPG_PROP_MISC_PARENT |
138 wxPG_PROP_AGGREGATE |
139 wxPG_PROP_HIDDEN |
140 wxPG_PROP_CATEGORY |
141 wxPG_PROP_COLLAPSED,
142
143wxPG_ITERATOR_MASK_OP_ITEM = wxPG_ITERATOR_FLAGS_ALL,
144
145// (wxPG_PROP_MISC_PARENT|wxPG_PROP_AGGREGATE|wxPG_PROP_CATEGORY)
146wxPG_ITERATOR_MASK_OP_PARENT = wxPG_ITERATOR_FLAGS_ALL,
147
148/** Combines all flags needed to iterate through visible properties
149 (ie hidden properties and children of collapsed parents are skipped).
150*/
151wxPG_ITERATE_VISIBLE = wxPG_ITERATE_PROPERTIES |
152 wxPG_PROP_CATEGORY |
153 wxPG_IT_CHILDREN(wxPG_PROP_AGGREGATE),
154
155/** Iterate all items.
156*/
157wxPG_ITERATE_ALL = wxPG_ITERATE_VISIBLE |
158 wxPG_ITERATE_HIDDEN,
159
160/** Iterate through individual properties (ie categories and children of
161 aggregate properties are skipped).
162*/
163wxPG_ITERATE_NORMAL = wxPG_ITERATE_PROPERTIES |
164 wxPG_ITERATE_HIDDEN,
165
166/** Default iterator flags.
167*/
168wxPG_ITERATE_DEFAULT = wxPG_ITERATE_NORMAL
169
170};
171
172/** @}
173*/
174
175
176#define wxPG_ITERATOR_CREATE_MASKS(FLAGS, A, B) \
177 A = (FLAGS ^ wxPG_ITERATOR_MASK_OP_ITEM) & \
178 wxPG_ITERATOR_MASK_OP_ITEM & 0xFFFF; \
179 B = ((FLAGS>>16) ^ wxPG_ITERATOR_MASK_OP_PARENT) & \
180 wxPG_ITERATOR_MASK_OP_PARENT & 0xFFFF;
181
182
183// Macro to test if children of PWC should be iterated through
184#define wxPG_ITERATOR_PARENTEXMASK_TEST(PWC, PARENTMASK) \
185 ( \
186 !(PWC->GetFlags() & PARENTMASK) && \
187 PWC->GetChildCount() \
188 )
189
190
191// Base for wxPropertyGridIterator classes.
192class WXDLLIMPEXP_PROPGRID wxPropertyGridIteratorBase
193{
194public:
195 wxPropertyGridIteratorBase()
196 {
197 }
198
199 void Assign( const wxPropertyGridIteratorBase& it );
200
201 bool AtEnd() const { return m_property == NULL; }
202
203 /** Get current property.
204 */
205 wxPGProperty* GetProperty() const { return m_property; }
206
207 void Init( wxPropertyGridPageState* state,
208 int flags,
209 wxPGProperty* property,
210 int dir = 1 );
211
212 void Init( wxPropertyGridPageState* state,
213 int flags,
214 int startPos = wxTOP,
215 int dir = 0 );
216
217 /** Iterate to the next property.
218 */
219 void Next( bool iterateChildren = true );
220
221 /** Iterate to the previous property.
222 */
223 void Prev();
224
225 /**
226 Set base parent, ie a property when, in which iteration returns, it
227 ends.
228
229 Default base parent is the root of the used wxPropertyGridPageState.
230 */
231 void SetBaseParent( wxPGProperty* baseParent )
232 { m_baseParent = baseParent; }
233
234protected:
235
236 wxPGProperty* m_property;
237
238private:
239 wxPropertyGridPageState* m_state;
240 wxPGProperty* m_baseParent;
241
242 // Masks are used to quickly exclude items
243 int m_itemExMask;
244 int m_parentExMask;
245};
246
247
248#define wxPG_IMPLEMENT_ITERATOR(CLASS, PROPERTY, STATE) \
249 CLASS( STATE* state, int flags = wxPG_ITERATE_DEFAULT, \
250 PROPERTY* property = NULL, int dir = 1 ) \
251 : wxPropertyGridIteratorBase() \
252 { Init( (wxPropertyGridPageState*)state, flags, \
253 (wxPGProperty*)property, dir ); } \
254 CLASS( STATE* state, int flags, int startPos, int dir = 0 ) \
255 : wxPropertyGridIteratorBase() \
256 { Init( (wxPropertyGridPageState*)state, flags, startPos, dir ); } \
257 CLASS() \
258 : wxPropertyGridIteratorBase() \
259 { \
260 m_property = NULL; \
261 } \
262 CLASS( const CLASS& it ) \
263 : wxPropertyGridIteratorBase( ) \
264 { \
265 Assign(it); \
266 } \
267 ~CLASS() \
268 { \
269 } \
270 const CLASS& operator=( const CLASS& it ) \
271 { \
272 if (this != &it) \
273 Assign(it); \
274 return *this; \
275 } \
276 CLASS& operator++() { Next(); return *this; } \
277 CLASS operator++(int) { CLASS it=*this;Next();return it; } \
278 CLASS& operator--() { Prev(); return *this; } \
279 CLASS operator--(int) { CLASS it=*this;Prev();return it; } \
280 PROPERTY* operator *() const { return (PROPERTY*)m_property; } \
281 static PROPERTY* OneStep( STATE* state, \
282 int flags = wxPG_ITERATE_DEFAULT, \
283 PROPERTY* property = NULL, \
284 int dir = 1 ) \
285 { \
286 CLASS it( state, flags, property, dir ); \
287 if ( property ) \
288 { \
289 if ( dir == 1 ) it.Next(); \
290 else it.Prev(); \
291 } \
292 return *it; \
293 }
294
295
296/** @class wxPropertyGridIterator
297
298 Preferable way to iterate through contents of wxPropertyGrid,
299 wxPropertyGridManager, and wxPropertyGridPage.
300
301 See wxPropertyGridInterface::GetIterator() for more information about usage.
302
303 @library{wxpropgrid}
304 @category{propgrid}
305*/
306class WXDLLIMPEXP_PROPGRID
307 wxPropertyGridIterator : public wxPropertyGridIteratorBase
308{
309public:
310
311 wxPG_IMPLEMENT_ITERATOR(wxPropertyGridIterator,
312 wxPGProperty,
313 wxPropertyGridPageState)
314
315protected:
316};
317
318
319// Const version of wxPropertyGridIterator.
320class WXDLLIMPEXP_PROPGRID
321 wxPropertyGridConstIterator : public wxPropertyGridIteratorBase
322{
323public:
324 wxPG_IMPLEMENT_ITERATOR(wxPropertyGridConstIterator,
325 const wxPGProperty,
326 const wxPropertyGridPageState)
327
328 /**
329 Additional copy constructor.
330 */
331 wxPropertyGridConstIterator( const wxPropertyGridIterator& other )
332 {
333 Assign(other);
334 }
335
336 /**
337 Additional assignment operator.
338 */
339 const wxPropertyGridConstIterator& operator=( const wxPropertyGridIterator& it )
340 {
341 Assign(it);
342 return *this;
343 }
344
345protected:
346};
347
348// -----------------------------------------------------------------------
349
350/** Base class to derive new viterators.
351*/
352class WXDLLIMPEXP_PROPGRID wxPGVIteratorBase : public wxObjectRefData
353{
354 friend class wxPGVIterator;
355public:
356 wxPGVIteratorBase() { }
357 virtual void Next() = 0;
358protected:
359 virtual ~wxPGVIteratorBase() { }
360
361 wxPropertyGridIterator m_it;
362};
363
364/** @class wxPGVIterator
365
366 Abstract implementation of a simple iterator. Can only be used
367 to iterate in forward order, and only through the entire container.
368 Used to have functions dealing with all properties work with both
369 wxPropertyGrid and wxPropertyGridManager.
370*/
371class WXDLLIMPEXP_PROPGRID wxPGVIterator
372{
373public:
374 wxPGVIterator() { m_pIt = NULL; }
375 wxPGVIterator( wxPGVIteratorBase* obj ) { m_pIt = obj; }
376 ~wxPGVIterator() { UnRef(); }
377 void UnRef() { if (m_pIt) m_pIt->DecRef(); }
378 wxPGVIterator( const wxPGVIterator& it )
379 {
380 m_pIt = it.m_pIt;
381 m_pIt->IncRef();
382 }
383 const wxPGVIterator& operator=( const wxPGVIterator& it )
384 {
385 if (this != &it)
386 {
387 UnRef();
388 m_pIt = it.m_pIt;
389 m_pIt->IncRef();
390 }
391 return *this;
392 }
393 void Next() { m_pIt->Next(); }
394 bool AtEnd() const { return m_pIt->m_it.AtEnd(); }
395 wxPGProperty* GetProperty() const { return m_pIt->m_it.GetProperty(); }
396protected:
397 wxPGVIteratorBase* m_pIt;
398};
399
400// -----------------------------------------------------------------------
401
402/** @class wxPropertyGridPageState
403
404 Contains low-level property page information (properties, column widths,
405 etc) of a single wxPropertyGrid or single wxPropertyGridPage. Generally you
406 should not use this class directly, but instead member functions in
407 wxPropertyGridInterface, wxPropertyGrid, wxPropertyGridPage, and
408 wxPropertyGridManager.
409
410 @remarks
411 - In separate wxPropertyGrid component this class was known as
412 wxPropertyGridState.
413 - Currently this class is not implemented in wxPython.
414
415 @library{wxpropgrid}
416 @category{propgrid}
417*/
418class WXDLLIMPEXP_PROPGRID wxPropertyGridPageState
419{
420 friend class wxPGProperty;
421 friend class wxPropertyGrid;
422 friend class wxPGCanvas;
423 friend class wxPropertyGridInterface;
424 friend class wxPropertyGridPage;
425 friend class wxPropertyGridManager;
426public:
427
428 /** Default constructor. */
429 wxPropertyGridPageState();
430
431 /** Destructor. */
432 virtual ~wxPropertyGridPageState();
433
434 /** Makes sure all columns have minimum width.
435 */
436 void CheckColumnWidths( int widthChange = 0 );
437
438 /**
439 Override this member function to add custom behaviour on property
440 deletion.
441 */
442 virtual void DoDelete( wxPGProperty* item, bool doDelete = true );
443
444 wxSize DoFitColumns( bool allowGridResize = false );
445
446 wxPGProperty* DoGetItemAtY( int y ) const;
447
448 /**
449 Override this member function to add custom behaviour on property
450 insertion.
451 */
452 virtual wxPGProperty* DoInsert( wxPGProperty* parent,
453 int index,
454 wxPGProperty* property );
455
456 /**
457 This needs to be overridden in grid used the manager so that splitter
458 changes can be propagated to other pages.
459 */
460 virtual void DoSetSplitterPosition( int pos,
461 int splitterColumn = 0,
462 int flags = 0 );
463
464 bool EnableCategories( bool enable );
465
466 /** Make sure virtual height is up-to-date.
467 */
468 void EnsureVirtualHeight()
469 {
470 if ( m_vhCalcPending )
471 {
472 RecalculateVirtualHeight();
473 m_vhCalcPending = 0;
474 }
475 }
476
477 /** Returns (precalculated) height of contained visible properties.
478 */
479 unsigned int GetVirtualHeight() const
480 {
481 wxASSERT( !m_vhCalcPending );
482 return m_virtualHeight;
483 }
484
485 /** Returns (precalculated) height of contained visible properties.
486 */
487 unsigned int GetVirtualHeight()
488 {
489 EnsureVirtualHeight();
490 return m_virtualHeight;
491 }
492
493 /** Returns actual height of contained visible properties.
494 @remarks
495 Mostly used for internal diagnostic purposes.
496 */
497 inline unsigned int GetActualVirtualHeight() const;
498
499 unsigned int GetColumnCount() const
500 {
501 return (unsigned int) m_colWidths.size();
502 }
503
504 int GetColumnMinWidth( int column ) const;
505
506 int GetColumnWidth( unsigned int column ) const
507 {
508 return m_colWidths[column];
509 }
510
511 wxPropertyGrid* GetGrid() const { return m_pPropGrid; }
512
513 /** Returns last item which could be iterated using given flags.
514 @param flags
515 @link iteratorflags List of iterator flags@endlink
516 */
517 wxPGProperty* GetLastItem( int flags = wxPG_ITERATE_DEFAULT );
518
519 const wxPGProperty* GetLastItem( int flags = wxPG_ITERATE_DEFAULT ) const
520 {
521 return ((wxPropertyGridPageState*)this)->GetLastItem(flags);
522 }
523
524 /**
525 Returns currently selected property.
526 */
527 wxPGProperty* GetSelection() const
528 {
529 if ( m_selection.size() == 0 )
530 return NULL;
531 return m_selection[0];
532 }
533
534 void DoSetSelection( wxPGProperty* prop )
535 {
536 m_selection.clear();
537 if ( prop )
538 m_selection.push_back(prop);
539 }
540
541 bool DoClearSelection()
542 {
543 return DoSelectProperty(NULL);
544 }
545
546 void DoRemoveFromSelection( wxPGProperty* prop );
547
548 void DoSetColumnProportion( unsigned int column, int proportion );
549
550 int DoGetColumnProportion( unsigned int column ) const
551 {
552 return m_columnProportions[column];
553 }
554
555 void ResetColumnSizes( int setSplitterFlags );
556
557 wxPropertyCategory* GetPropertyCategory( const wxPGProperty* p ) const;
558
559 wxPGProperty* GetPropertyByLabel( const wxString& name,
560 wxPGProperty* parent = NULL ) const;
561
562 wxVariant DoGetPropertyValues( const wxString& listname,
563 wxPGProperty* baseparent,
564 long flags ) const;
565
566 wxPGProperty* DoGetRoot() const { return m_properties; }
567
568 void DoSetPropertyName( wxPGProperty* p, const wxString& newName );
569
570 // Returns combined width of margin and all the columns
571 int GetVirtualWidth() const
572 {
573 return m_width;
574 }
575
576 /**
577 Returns minimal width for given column so that all images and texts
578 will fit entirely.
579
580 Used by SetSplitterLeft() and DoFitColumns().
581 */
582 int GetColumnFitWidth(wxClientDC& dc,
583 wxPGProperty* pwc,
584 unsigned int col,
585 bool subProps) const;
586
587 /**
588 Returns information about arbitrary position in the grid.
589
590 @param pt
591 Logical coordinates in the virtual grid space. Use
592 wxScrolled<T>::CalcUnscrolledPosition() if you need to
593 translate a scrolled position into a logical one.
594 */
595 wxPropertyGridHitTestResult HitTest( const wxPoint& pt ) const;
596
597 /** Returns true if page is visibly displayed.
598 */
599 inline bool IsDisplayed() const;
600
601 bool IsInNonCatMode() const { return (bool)(m_properties == m_abcArray); }
602
603 void DoLimitPropertyEditing( wxPGProperty* p, bool limit = true )
604 {
605 p->SetFlagRecursively(wxPG_PROP_NOEDITOR, limit);
606 }
607
608 bool DoSelectProperty( wxPGProperty* p, unsigned int flags = 0 );
609
610 /** widthChange is non-client.
611 */
612 void OnClientWidthChange( int newWidth,
613 int widthChange,
614 bool fromOnResize = false );
615
616 /** Recalculates m_virtualHeight.
617 */
618 void RecalculateVirtualHeight()
619 {
620 m_virtualHeight = GetActualVirtualHeight();
621 }
622
623 void SetColumnCount( int colCount );
624
625 void PropagateColSizeDec( int column, int decrease, int dir );
626
627 bool DoHideProperty( wxPGProperty* p, bool hide, int flags = wxPG_RECURSE );
628
629 bool DoSetPropertyValueString( wxPGProperty* p, const wxString& value );
630
631 bool DoSetPropertyValue( wxPGProperty* p, wxVariant& value );
632
633 bool DoSetPropertyValueWxObjectPtr( wxPGProperty* p, wxObject* value );
634 void DoSetPropertyValues( const wxVariantList& list,
635 wxPGProperty* default_category );
636
637 void SetSplitterLeft( bool subProps = false );
638
639 /** Set virtual width for this particular page. */
640 void SetVirtualWidth( int width );
641
642 void DoSortChildren( wxPGProperty* p, int flags = 0 );
643 void DoSort( int flags = 0 );
644
645 bool PrepareAfterItemsAdded();
646
647 /** Called after virtual height needs to be recalculated.
648 */
649 void VirtualHeightChanged()
650 {
651 m_vhCalcPending = 1;
652 }
653
654 /** Base append. */
655 wxPGProperty* DoAppend( wxPGProperty* property );
656
657 /** Returns property by its name. */
658 wxPGProperty* BaseGetPropertyByName( const wxString& name ) const;
659
660 /** Called in, for example, wxPropertyGrid::Clear. */
661 void DoClear();
662
663 bool DoIsPropertySelected( wxPGProperty* prop ) const;
664
665 bool DoCollapse( wxPGProperty* p );
666
667 bool DoExpand( wxPGProperty* p );
668
669 void CalculateFontAndBitmapStuff( int vspacing );
670
671protected:
672
673 // Utility to check if two properties are visibly next to each other
674 bool ArePropertiesAdjacent( wxPGProperty* prop1,
675 wxPGProperty* prop2,
676 int iterFlags = wxPG_ITERATE_VISIBLE ) const;
677
678 int DoGetSplitterPosition( int splitterIndex = 0 ) const;
679
680 /** Returns column at x coordinate (in GetGrid()->GetPanel()).
681 @param pSplitterHit
682 Give pointer to int that receives index to splitter that is at x.
683 @param pSplitterHitOffset
684 Distance from said splitter.
685 */
686 int HitTestH( int x, int* pSplitterHit, int* pSplitterHitOffset ) const;
687
688 bool PrepareToAddItem( wxPGProperty* property,
689 wxPGProperty* scheduledParent );
690
691 /** If visible, then this is pointer to wxPropertyGrid.
692 This shall *never* be NULL to indicate that this state is not visible.
693 */
694 wxPropertyGrid* m_pPropGrid;
695
696 /** Pointer to currently used array. */
697 wxPGProperty* m_properties;
698
699 /** Array for categoric mode. */
700 wxPGRootProperty m_regularArray;
701
702 /** Array for root of non-categoric mode. */
703 wxPGRootProperty* m_abcArray;
704
705 /** Dictionary for name-based access. */
706 wxPGHashMapS2P m_dictName;
707
708 /** List of column widths (first column does not include margin). */
709 wxArrayInt m_colWidths;
710
711 /** List of indices of columns the user can edit by clicking it. */
712 wxArrayInt m_editableColumns;
713
714 /** Column proportions */
715 wxArrayInt m_columnProportions;
716
717 double m_fSplitterX;
718
719 /** Most recently added category. */
720 wxPropertyCategory* m_currentCategory;
721
722 /** Array of selected property. */
723 wxArrayPGProperty m_selection;
724
725 /** Virtual width. */
726 int m_width;
727
728 /** Indicates total virtual height of visible properties. */
729 unsigned int m_virtualHeight;
730
731 /** 1 if m_lastCaption is also the bottommost caption. */
732 unsigned char m_lastCaptionBottomnest;
733
734 /** 1 items appended/inserted, so stuff needs to be done before drawing;
735 If m_virtualHeight == 0, then calcylatey's must be done.
736 Otherwise just sort.
737 */
738 unsigned char m_itemsAdded;
739
740 /** 1 if any value is modified. */
741 unsigned char m_anyModified;
742
743 unsigned char m_vhCalcPending;
744
745 /** True if splitter has been pre-set by the application. */
746 bool m_isSplitterPreSet;
747
748 /** Used to (temporarily) disable splitter centering. */
749 bool m_dontCenterSplitter;
750
751private:
752 /** Only inits arrays, doesn't migrate things or such. */
753 void InitNonCatMode();
754};
755
756// -----------------------------------------------------------------------
757
758#endif // wxUSE_PROPGRID
759
760#endif // _WX_PROPGRID_PROPGRIDPAGESTATE_H_
761