Allow reparenting wxPropertyGrid(Manager) to work; Show error and suggest calling...
[wxWidgets.git] / include / wx / propgrid / manager.h
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: wx/propgrid/manager.h
3 // Purpose: wxPropertyGridManager
4 // Author: Jaakko Salli
5 // Modified by:
6 // Created: 2005-01-14
7 // RCS-ID: $Id$
8 // Copyright: (c) Jaakko Salli
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifndef _WX_PROPGRID_MANAGER_H_
13 #define _WX_PROPGRID_MANAGER_H_
14
15 #if wxUSE_PROPGRID
16
17 #include "wx/propgrid/propgrid.h"
18
19 #include "wx/dcclient.h"
20 #include "wx/scrolwin.h"
21 #include "wx/toolbar.h"
22 #include "wx/stattext.h"
23 #include "wx/button.h"
24 #include "wx/textctrl.h"
25 #include "wx/dialog.h"
26
27 // -----------------------------------------------------------------------
28
29 #ifndef SWIG
30 extern WXDLLIMPEXP_DATA_PROPGRID(const char) wxPropertyGridManagerNameStr[];
31 #endif
32
33 /** @class wxPropertyGridPage
34
35 Holder of property grid page information. You can subclass this and
36 give instance in wxPropertyGridManager::AddPage. It inherits from
37 wxEvtHandler and can be used to process events specific to this
38 page (id of events will still be same as manager's). If you don't
39 want to use it to process all events of the page, you need to
40 return false in the derived wxPropertyGridPage::IsHandlingAllEvents.
41
42 Please note that wxPropertyGridPage lacks many non-const property
43 manipulation functions found in wxPropertyGridManager. Please use
44 parent manager (m_manager member variable) when needed.
45
46 Please note that most member functions are inherited and as such not
47 documented on this page. This means you will probably also want to read
48 wxPropertyGridInterface class reference.
49
50 @section propgridpage_event_handling Event Handling
51
52 wxPropertyGridPage receives events emitted by its wxPropertyGridManager, but
53 only those events that are specific to that page. If
54 wxPropertyGridPage::IsHandlingAllEvents returns false, then unhandled
55 events are sent to the manager's parent, as usual.
56
57 See @ref propgrid_event_handling "wxPropertyGrid Event Handling"
58 for more information.
59
60 @library{wxpropgrid}
61 @category{propgrid}
62 */
63 class WXDLLIMPEXP_PROPGRID wxPropertyGridPage : public wxEvtHandler,
64 public wxPropertyGridInterface,
65 public wxPropertyGridPageState
66 {
67 friend class wxPropertyGridManager;
68 DECLARE_CLASS(wxPropertyGridPage)
69 public:
70
71 wxPropertyGridPage();
72 virtual ~wxPropertyGridPage();
73
74 /** Deletes all properties on page.
75 */
76 virtual void Clear();
77
78 /**
79 Reduces column sizes to minimum possible that contents are still
80 visibly (naturally some margin space will be applied as well).
81
82 @return
83 Minimum size for the page to still display everything.
84
85 @remarks
86 This function only works properly if size of containing grid was
87 already fairly large.
88
89 Note that you can also get calculated column widths by calling
90 GetColumnWidth() immediately after this function returns.
91 */
92 wxSize FitColumns();
93
94 /** Returns page index in manager;
95 */
96 inline int GetIndex() const;
97
98 /** Returns x-coordinate position of splitter on a page.
99 */
100 int GetSplitterPosition( int col = 0 ) const
101 { return GetStatePtr()->DoGetSplitterPosition(col); }
102
103 /** Returns "root property". It does not have name, etc. and it is not
104 visible. It is only useful for accessing its children.
105 */
106 wxPGProperty* GetRoot() const { return GetStatePtr()->DoGetRoot(); }
107
108 /** Return pointer to contained property grid state.
109 */
110 wxPropertyGridPageState* GetStatePtr()
111 {
112 return this;
113 }
114
115 /** Return pointer to contained property grid state.
116 */
117 const wxPropertyGridPageState* GetStatePtr() const
118 {
119 return this;
120 }
121
122 /**
123 Returns id of the tool bar item that represents this page on
124 wxPropertyGridManager's wxToolBar.
125 */
126 int GetToolId() const
127 {
128 return m_id;
129 }
130
131 /** Do any member initialization in this method.
132 @remarks
133 - Called every time the page is added into a manager.
134 - You can add properties to the page here.
135 */
136 virtual void Init() {}
137
138 /** Return false here to indicate unhandled events should be
139 propagated to manager's parent, as normal.
140 */
141 virtual bool IsHandlingAllEvents() const { return true; }
142
143 /** Called every time page is about to be shown.
144 Useful, for instance, creating properties just-in-time.
145 */
146 virtual void OnShow();
147
148 virtual void RefreshProperty( wxPGProperty* p );
149
150 /** Sets splitter position on page.
151 @remarks
152 Splitter position cannot exceed grid size, and therefore setting it
153 during form creation may fail as initial grid size is often smaller
154 than desired splitter position, especially when sizers are being used.
155 */
156 void SetSplitterPosition( int splitterPos, int col = 0 );
157
158 protected:
159
160 /** Propagate to other pages.
161 */
162 virtual void DoSetSplitterPosition( int pos,
163 int splitterColumn = 0,
164 bool allPages = false,
165 bool fromAutoCenter = false );
166
167 /** Page label (may be referred as name in some parts of documentation).
168 Can be set in constructor, or passed in
169 wxPropertyGridManager::AddPage(), but *not* in both.
170 */
171 wxString m_label;
172
173 #ifndef SWIG
174
175 //virtual bool ProcessEvent( wxEvent& event );
176
177 wxPropertyGridManager* m_manager;
178
179 int m_id; // toolbar index
180
181 private:
182 bool m_isDefault; // is this base page object?
183
184 private:
185 DECLARE_EVENT_TABLE()
186 #endif
187 };
188
189 // -----------------------------------------------------------------------
190
191 /** @class wxPropertyGridManager
192
193 wxPropertyGridManager is an efficient multi-page version of wxPropertyGrid,
194 which can optionally have toolbar for mode and page selection, and help
195 text box.
196 Use window flags to select components to include.
197
198 @section propgridmanager_window_styles_ Window Styles
199
200 See @ref propgrid_window_styles.
201
202 @section propgridmanager_event_handling Event Handling
203
204 See @ref propgrid_event_handling "wxPropertyGrid Event Handling"
205 for more information.
206
207 @library{wxpropgrid}
208 @category{propgrid}
209 */
210 class WXDLLIMPEXP_PROPGRID
211 wxPropertyGridManager : public wxPanel, public wxPropertyGridInterface
212 {
213 DECLARE_CLASS(wxPropertyGridManager)
214 friend class wxPropertyGridPage;
215 public:
216
217 #ifndef SWIG
218 /**
219 Two step constructor.
220 Call Create when this constructor is called to build up the
221 wxPropertyGridManager.
222 */
223 wxPropertyGridManager();
224 #endif
225
226 /** The default constructor. The styles to be used are styles valid for
227 the wxWindow.
228 @see @link wndflags Additional Window Styles@endlink
229 */
230 wxPropertyGridManager( wxWindow *parent, wxWindowID id = wxID_ANY,
231 const wxPoint& pos = wxDefaultPosition,
232 const wxSize& size = wxDefaultSize,
233 long style = wxPGMAN_DEFAULT_STYLE,
234 const wxString& name = wxPropertyGridManagerNameStr );
235
236 /** Destructor */
237 virtual ~wxPropertyGridManager();
238
239 /** Creates new property page. Note that the first page is not created
240 automatically.
241 @param label
242 A label for the page. This may be shown as a toolbar tooltip etc.
243 @param bmp
244 Bitmap image for toolbar. If wxNullBitmap is used, then a built-in
245 default image is used.
246 @param pageObj
247 wxPropertyGridPage instance. Manager will take ownership of this object.
248 NULL indicates that a default page instance should be created.
249
250 @return
251 Returns pointer to created page.
252
253 @remarks
254 If toolbar is used, it is highly recommended that the pages are
255 added when the toolbar is not turned off using window style flag
256 switching.
257 */
258 wxPropertyGridPage* AddPage( const wxString& label = wxEmptyString,
259 const wxBitmap& bmp = wxPG_NULL_BITMAP,
260 wxPropertyGridPage* pageObj = NULL )
261 {
262 return InsertPage(-1, label, bmp, pageObj);
263 }
264
265 /** Deletes all all properties and all pages.
266 */
267 virtual void Clear();
268
269 /** Deletes all properties on given page.
270 */
271 void ClearPage( int page );
272
273 /** Forces updating the value of property from the editor control.
274 Returns true if DoPropertyChanged was actually called.
275 */
276 bool CommitChangesFromEditor( wxUint32 flags = 0 )
277 {
278 return m_pPropGrid->CommitChangesFromEditor(flags);
279 }
280
281 /**
282 Two step creation.
283 Whenever the control is created without any parameters, use Create to
284 actually create it. Don't access the control's public methods before
285 this is called.
286 @see @link wndflags Additional Window Styles@endlink
287 */
288 bool Create( wxWindow *parent, wxWindowID id = wxID_ANY,
289 const wxPoint& pos = wxDefaultPosition,
290 const wxSize& size = wxDefaultSize,
291 long style = wxPGMAN_DEFAULT_STYLE,
292 const wxString& name = wxPropertyGridManagerNameStr );
293
294 /**
295 Enables or disables (shows/hides) categories according to parameter
296 enable.
297
298 WARNING: Not tested properly, use at your own risk.
299 */
300 bool EnableCategories( bool enable )
301 {
302 long fl = m_windowStyle | wxPG_HIDE_CATEGORIES;
303 if ( enable ) fl = m_windowStyle & ~(wxPG_HIDE_CATEGORIES);
304 SetWindowStyleFlag(fl);
305 return true;
306 }
307
308 /** Selects page, scrolls and/or expands items to ensure that the
309 given item is visible. Returns true if something was actually done.
310 */
311 bool EnsureVisible( wxPGPropArg id );
312
313 /** Returns number of columns on given page. By the default,
314 returns number of columns on current page. */
315 int GetColumnCount( int page = -1 ) const;
316
317 /** Returns height of the description text box. */
318 int GetDescBoxHeight() const;
319
320 /** Returns pointer to the contained wxPropertyGrid. This does not change
321 after wxPropertyGridManager has been created, so you can safely obtain
322 pointer once and use it for the entire lifetime of the instance.
323 */
324 wxPropertyGrid* GetGrid()
325 {
326 wxASSERT(m_pPropGrid);
327 return m_pPropGrid;
328 };
329
330 const wxPropertyGrid* GetGrid() const
331 {
332 wxASSERT(m_pPropGrid);
333 return (const wxPropertyGrid*)m_pPropGrid;
334 };
335
336 /** Returns iterator class instance.
337 @remarks
338 Calling this method in wxPropertyGridManager causes run-time assertion
339 failure. Please only iterate through individual pages or use
340 CreateVIterator().
341 */
342 wxPropertyGridIterator GetIterator( int flags = wxPG_ITERATE_DEFAULT,
343 wxPGProperty* firstProp = NULL )
344 {
345 wxFAIL_MSG( "Please only iterate through individual pages "
346 "or use CreateVIterator()" );
347 return wxPropertyGridInterface::GetIterator( flags, firstProp );
348 }
349
350 wxPropertyGridConstIterator
351 GetIterator(int flags = wxPG_ITERATE_DEFAULT,
352 wxPGProperty* firstProp = NULL) const
353 {
354 wxFAIL_MSG( "Please only iterate through individual pages "
355 " or use CreateVIterator()" );
356 return wxPropertyGridInterface::GetIterator( flags, firstProp );
357 }
358
359 /** Returns iterator class instance.
360 @remarks
361 Calling this method in wxPropertyGridManager causes run-time assertion
362 failure. Please only iterate through individual pages or use
363 CreateVIterator().
364 */
365 wxPropertyGridIterator GetIterator( int flags, int startPos )
366 {
367 wxFAIL_MSG( "Please only iterate through individual pages "
368 "or use CreateVIterator()" );
369
370 return wxPropertyGridInterface::GetIterator( flags, startPos );
371 }
372
373 wxPropertyGridConstIterator GetIterator( int flags, int startPos ) const
374 {
375 wxFAIL_MSG( "Please only iterate through individual pages "
376 "or use CreateVIterator()" );
377 return wxPropertyGridInterface::GetIterator( flags, startPos );
378 }
379
380 /** Similar to GetIterator, but instead returns wxPGVIterator instance,
381 which can be useful for forward-iterating through arbitrary property
382 containers.
383 */
384 virtual wxPGVIterator GetVIterator( int flags ) const;
385
386 /** Returns currently selected page.
387 */
388 wxPropertyGridPage* GetCurrentPage() const
389 {
390 return GetPage(m_selPage);
391 }
392
393 /** Returns page object for given page index.
394 */
395 wxPropertyGridPage* GetPage( unsigned int ind ) const
396 {
397 return m_arrPages[ind];
398 }
399
400 /** Returns page object for given page name.
401 */
402 wxPropertyGridPage* GetPage( const wxString& name ) const
403 {
404 return GetPage(GetPageByName(name));
405 }
406
407 /**
408 Returns index for a page name.
409
410 If no match is found, wxNOT_FOUND is returned.
411 */
412 int GetPageByName( const wxString& name ) const;
413
414 /** Returns index for a relevant propertygrid state.
415
416 If no match is found, wxNOT_FOUND is returned.
417 */
418 int GetPageByState( const wxPropertyGridPageState* pstate ) const;
419
420 protected:
421 /** Returns wxPropertyGridPageState of given page, current page's for -1.
422 */
423 virtual wxPropertyGridPageState* GetPageState( int page ) const;
424
425 public:
426 /** Returns number of managed pages. */
427 size_t GetPageCount() const;
428
429 /** Returns name of given page. */
430 const wxString& GetPageName( int index ) const;
431
432 /** Returns "root property" of the given page. It does not have name, etc.
433 and it is not visible. It is only useful for accessing its children.
434 */
435 wxPGProperty* GetPageRoot( int index ) const;
436
437 /** Returns index to currently selected page. */
438 int GetSelectedPage() const { return m_selPage; }
439
440 /** Alias for GetSelection(). */
441 wxPGProperty* GetSelectedProperty() const
442 {
443 return GetSelection();
444 }
445
446 /** Shortcut for GetGrid()->GetSelection(). */
447 wxPGProperty* GetSelection() const
448 {
449 return m_pPropGrid->GetSelection();
450 }
451
452 /** Returns a pointer to the toolbar currently associated with the
453 wxPropertyGridManager (if any). */
454 wxToolBar* GetToolBar() const { return m_pToolbar; }
455
456 /** Creates new property page. Note that the first page is not created
457 automatically.
458 @param index
459 Add to this position. -1 will add as the last item.
460 @param label
461 A label for the page. This may be shown as a toolbar tooltip etc.
462 @param bmp
463 Bitmap image for toolbar. If wxNullBitmap is used, then a built-in
464 default image is used.
465 @param pageObj
466 wxPropertyGridPage instance. Manager will take ownership of this object.
467 If NULL, default page object is constructed.
468
469 @return
470 Returns pointer to created page.
471 */
472 virtual wxPropertyGridPage* InsertPage( int index,
473 const wxString& label,
474 const wxBitmap& bmp = wxNullBitmap,
475 wxPropertyGridPage* pageObj = NULL );
476
477 /**
478 Returns true if any property on any page has been modified by the user.
479 */
480 bool IsAnyModified() const;
481
482 /**
483 Returns true if updating is frozen (ie Freeze() called but not yet
484 Thaw() ).
485 */
486 bool IsFrozen() const { return m_pPropGrid->m_frozen > 0; }
487
488 /**
489 Returns true if any property on given page has been modified by the
490 user.
491 */
492 bool IsPageModified( size_t index ) const;
493
494 virtual void Refresh( bool eraseBackground = true,
495 const wxRect* rect = (const wxRect*) NULL );
496
497 /** Removes a page.
498 @return
499 Returns false if it was not possible to remove page in question.
500 */
501 virtual bool RemovePage( int page );
502
503 /** Select and displays a given page.
504
505 @param index
506 Index of page being seleced. Can be -1 to select nothing.
507 */
508 void SelectPage( int index );
509
510 /** Select and displays a given page (by label). */
511 void SelectPage( const wxString& label )
512 {
513 int index = GetPageByName(label);
514 wxCHECK_RET( index >= 0, wxT("No page with such name") );
515 SelectPage( index );
516 }
517
518 /** Select and displays a given page. */
519 void SelectPage( wxPropertyGridPage* ptr )
520 {
521 SelectPage( GetPageByState(ptr) );
522 }
523
524 /** Select a property. */
525 bool SelectProperty( wxPGPropArg id, bool focus = false )
526 {
527 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
528 return p->GetParentState()->DoSelectProperty(p, focus);
529 }
530
531 /** Sets number of columns on given page (default is current page).
532 */
533 void SetColumnCount( int colCount, int page = -1 );
534
535 /** Sets label and text in description box.
536 */
537 void SetDescription( const wxString& label, const wxString& content );
538
539 /** Sets y coordinate of the description box splitter. */
540 void SetDescBoxHeight( int ht, bool refresh = true );
541
542 /** Moves splitter as left as possible, while still allowing all
543 labels to be shown in full.
544 @param subProps
545 If false, will still allow sub-properties (ie. properties which
546 parent is not root or category) to be cropped.
547 @param allPages
548 If true, takes labels on all pages into account.
549 */
550 void SetSplitterLeft( bool subProps = false, bool allPages = true );
551
552 /** Sets splitter position on individual page. */
553 void SetPageSplitterPosition( int page, int pos, int column = 0 )
554 {
555 GetPage(page)->DoSetSplitterPosition( pos, column );
556 }
557
558 /** Sets splitter position for all pages.
559 @remarks
560 Splitter position cannot exceed grid size, and therefore setting it
561 during form creation may fail as initial grid size is often smaller
562 than desired splitter position, especially when sizers are being used.
563 */
564 void SetSplitterPosition( int pos, int column = 0 );
565
566 protected:
567
568 //
569 // Subclassing helpers
570 //
571
572 /**
573 Creates property grid for the manager. Reimplement in derived class to
574 use subclassed wxPropertyGrid. However, if you you do this then you
575 must also use the two-step construction (ie. default constructor and
576 Create() instead of constructor with arguments) when creating the
577 manager.
578 */
579 virtual wxPropertyGrid* CreatePropertyGrid() const;
580
581 public:
582 virtual void RefreshProperty( wxPGProperty* p );
583
584 //
585 // Overridden functions - no documentation required.
586 //
587
588 void SetId( wxWindowID winid );
589
590 virtual void Freeze();
591 virtual void Thaw();
592 virtual void SetExtraStyle ( long exStyle );
593 virtual bool SetFont ( const wxFont& font );
594 virtual void SetWindowStyleFlag ( long style );
595 virtual bool Reparent( wxWindowBase *newParent );
596
597 protected:
598 virtual wxSize DoGetBestSize() const;
599
600 public:
601
602 #ifndef SWIG
603
604 //
605 // Event handlers
606 //
607 void OnMouseMove( wxMouseEvent &event );
608 void OnMouseClick( wxMouseEvent &event );
609 void OnMouseUp( wxMouseEvent &event );
610 void OnMouseEntry( wxMouseEvent &event );
611
612 void OnPaint( wxPaintEvent &event );
613
614 void OnToolbarClick( wxCommandEvent &event );
615 void OnResize( wxSizeEvent& event );
616 void OnPropertyGridSelect( wxPropertyGridEvent& event );
617
618 protected:
619
620 wxPropertyGrid* m_pPropGrid;
621
622 wxVector<wxPropertyGridPage*> m_arrPages;
623
624 #if wxUSE_TOOLBAR
625 wxToolBar* m_pToolbar;
626 #endif
627 wxStaticText* m_pTxtHelpCaption;
628 wxStaticText* m_pTxtHelpContent;
629
630 wxPropertyGridPage* m_emptyPage;
631
632 long m_iFlags;
633
634 // Selected page index.
635 int m_selPage;
636
637 int m_width;
638
639 int m_height;
640
641 int m_extraHeight;
642
643 int m_splitterY;
644
645 int m_splitterHeight;
646
647 int m_nextTbInd;
648
649 int m_dragOffset;
650
651 wxCursor m_cursorSizeNS;
652
653 int m_nextDescBoxSize;
654
655 wxWindowID m_baseId;
656
657 unsigned char m_dragStatus;
658
659 unsigned char m_onSplitter;
660
661 virtual wxPGProperty* DoGetPropertyByName( const wxString& name ) const;
662
663 /** Select and displays a given page. */
664 virtual bool DoSelectPage( int index );
665
666 // Sets some members to defaults.
667 void Init1();
668
669 // Initializes some members.
670 void Init2( int style );
671
672 /*#ifdef __WXMSW__
673 virtual WXDWORD MSWGetStyle(long flags, WXDWORD *exstyle) const;
674 #endif*/
675
676 virtual bool ProcessEvent( wxEvent& event );
677
678 /** Recalculates new positions for components, according to the
679 given size.
680 */
681 void RecalculatePositions( int width, int height );
682
683 /** (Re)creates/destroys controls, according to the window style bits. */
684 void RecreateControls();
685
686 void UpdateDescriptionBox( int new_splittery, int new_width, int new_height );
687
688 void RepaintDescBoxDecorations( wxDC& dc,
689 int newSplitterY,
690 int newWidth,
691 int newHeight );
692
693 void SetDescribedProperty( wxPGProperty* p );
694
695 // Reimplement these to handle "descboxheight" state item
696 virtual bool SetEditableStateItem( const wxString& name, wxVariant value );
697 virtual wxVariant GetEditableStateItem( const wxString& name ) const;
698
699 private:
700 DECLARE_EVENT_TABLE()
701 #endif // #ifndef SWIG
702 };
703
704 // -----------------------------------------------------------------------
705
706 inline int wxPropertyGridPage::GetIndex() const
707 {
708 if ( !m_manager )
709 return wxNOT_FOUND;
710 return m_manager->GetPageByState(this);
711 }
712
713 // -----------------------------------------------------------------------
714
715 #endif // wxUSE_PROPGRID
716
717 #endif // _WX_PROPGRID_MANAGER_H_