]> git.saurik.com Git - wxWidgets.git/blob - src/propgrid/manager.cpp
Removed some old code that generated warnings on some compilers
[wxWidgets.git] / src / propgrid / manager.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/propgrid/manager.cpp
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 // For compilers that support precompilation, includes "wx/wx.h".
13 #include "wx/wxprec.h"
14
15 #ifdef __BORLANDC__
16 #pragma hdrstop
17 #endif
18
19 #if wxUSE_PROPGRID
20
21 #ifndef WX_PRECOMP
22 #include "wx/defs.h"
23 #include "wx/object.h"
24 #include "wx/hash.h"
25 #include "wx/string.h"
26 #include "wx/log.h"
27 #include "wx/event.h"
28 #include "wx/window.h"
29 #include "wx/panel.h"
30 #include "wx/dc.h"
31 #include "wx/pen.h"
32 #include "wx/brush.h"
33 #include "wx/cursor.h"
34 #include "wx/settings.h"
35 #include "wx/textctrl.h"
36 #include "wx/sizer.h"
37 #include "wx/statusbr.h"
38 #include "wx/intl.h"
39 #endif
40
41 // This define is necessary to prevent macro clearing
42 #define __wxPG_SOURCE_FILE__
43
44 #include "wx/propgrid/propgrid.h"
45
46 #include "wx/propgrid/manager.h"
47
48
49 #define wxPG_MAN_ALTERNATE_BASE_ID 11249 // Needed for wxID_ANY madnesss
50
51
52 // -----------------------------------------------------------------------
53
54 // For wxMSW cursor consistency, we must do mouse capturing even
55 // when using custom controls
56
57 #define BEGIN_MOUSE_CAPTURE \
58 if ( !(m_iFlags & wxPG_FL_MOUSE_CAPTURED) ) \
59 { \
60 CaptureMouse(); \
61 m_iFlags |= wxPG_FL_MOUSE_CAPTURED; \
62 }
63
64 #define END_MOUSE_CAPTURE \
65 if ( m_iFlags & wxPG_FL_MOUSE_CAPTURED ) \
66 { \
67 ReleaseMouse(); \
68 m_iFlags &= ~(wxPG_FL_MOUSE_CAPTURED); \
69 }
70
71 // -----------------------------------------------------------------------
72 // wxPropertyGridManager
73 // -----------------------------------------------------------------------
74
75 const char wxPropertyGridManagerNameStr[] = "wxPropertyGridManager";
76
77
78 // Categoric Mode Icon
79 static const char* gs_xpm_catmode[] = {
80 "16 16 5 1",
81 ". c none",
82 "B c black",
83 "D c #868686",
84 "L c #CACACA",
85 "W c #FFFFFF",
86 ".DDD............",
87 ".DLD.BBBBBB.....",
88 ".DDD............",
89 ".....DDDDD.DDD..",
90 "................",
91 ".....DDDDD.DDD..",
92 "................",
93 ".....DDDDD.DDD..",
94 "................",
95 ".....DDDDD.DDD..",
96 "................",
97 ".DDD............",
98 ".DLD.BBBBBB.....",
99 ".DDD............",
100 ".....DDDDD.DDD..",
101 "................"
102 };
103
104 // Alphabetic Mode Icon
105 static const char* gs_xpm_noncatmode[] = {
106 "16 16 5 1",
107 ". c none",
108 "B c black",
109 "D c #868686",
110 "L c #000080",
111 "W c #FFFFFF",
112 "..DBD...DDD.DDD.",
113 ".DB.BD..........",
114 ".BBBBB..DDD.DDD.",
115 ".B...B..........",
116 "...L....DDD.DDD.",
117 "...L............",
118 ".L.L.L..DDD.DDD.",
119 "..LLL...........",
120 "...L....DDD.DDD.",
121 "................",
122 ".BBBBB..DDD.DDD.",
123 "....BD..........",
124 "...BD...DDD.DDD.",
125 "..BD............",
126 ".BBBBB..DDD.DDD.",
127 "................"
128 };
129
130 // Default Page Icon.
131 static const char* gs_xpm_defpage[] = {
132 "16 16 5 1",
133 ". c none",
134 "B c black",
135 "D c #868686",
136 "L c #000080",
137 "W c #FFFFFF",
138 "................",
139 "................",
140 "..BBBBBBBBBBBB..",
141 "..B..........B..",
142 "..B.BB.LLLLL.B..",
143 "..B..........B..",
144 "..B.BB.LLLLL.B..",
145 "..B..........B..",
146 "..B.BB.LLLLL.B..",
147 "..B..........B..",
148 "..B.BB.LLLLL.B..",
149 "..B..........B..",
150 "..BBBBBBBBBBBB..",
151 "................",
152 "................",
153 "................"
154 };
155
156 // -----------------------------------------------------------------------
157 // wxPropertyGridPage
158 // -----------------------------------------------------------------------
159
160
161 IMPLEMENT_CLASS(wxPropertyGridPage, wxEvtHandler)
162
163
164 BEGIN_EVENT_TABLE(wxPropertyGridPage, wxEvtHandler)
165 END_EVENT_TABLE()
166
167
168 wxPropertyGridPage::wxPropertyGridPage()
169 : wxEvtHandler(), wxPropertyGridInterface(), wxPropertyGridPageState()
170 {
171 m_pState = this; // wxPropertyGridInterface to point to State
172 m_manager = NULL;
173 m_isDefault = false;
174 }
175
176 wxPropertyGridPage::~wxPropertyGridPage()
177 {
178 }
179
180 void wxPropertyGridPage::Clear()
181 {
182 GetStatePtr()->DoClear();
183 }
184
185 wxSize wxPropertyGridPage::FitColumns()
186 {
187 wxSize sz = DoFitColumns();
188 return sz;
189 }
190
191 void wxPropertyGridPage::RefreshProperty( wxPGProperty* p )
192 {
193 if ( m_manager )
194 m_manager->RefreshProperty(p);
195 }
196
197 void wxPropertyGridPage::OnShow()
198 {
199 }
200
201 void wxPropertyGridPage::SetSplitterPosition( int splitterPos, int col )
202 {
203 wxPropertyGrid* pg = GetGrid();
204 if ( pg->GetState() == this )
205 pg->SetSplitterPosition(splitterPos);
206 else
207 DoSetSplitterPosition(splitterPos, col, false);
208 }
209
210 void wxPropertyGridPage::DoSetSplitterPosition( int pos,
211 int splitterColumn,
212 bool allPages,
213 bool fromAutoCenter )
214 {
215 if ( allPages && m_manager->GetPageCount() )
216 m_manager->SetSplitterPosition( pos, splitterColumn );
217 else
218 wxPropertyGridPageState::DoSetSplitterPosition( pos,
219 splitterColumn,
220 allPages,
221 fromAutoCenter );
222 }
223
224 // -----------------------------------------------------------------------
225 // wxPropertyGridManager
226 // -----------------------------------------------------------------------
227
228 // Final default splitter y is client height minus this.
229 #define wxPGMAN_DEFAULT_NEGATIVE_SPLITTER_Y 100
230
231 // -----------------------------------------------------------------------
232
233 IMPLEMENT_CLASS(wxPropertyGridManager, wxPanel)
234
235 #define ID_ADVTOOLBAR_OFFSET 1
236 #define ID_ADVHELPCAPTION_OFFSET 2
237 #define ID_ADVHELPCONTENT_OFFSET 3
238 //#define ID_ADVBUTTON_OFFSET 4
239 #define ID_ADVTBITEMSBASE_OFFSET 5 // Must be last.
240
241 // -----------------------------------------------------------------------
242
243 BEGIN_EVENT_TABLE(wxPropertyGridManager, wxPanel)
244 EVT_MOTION(wxPropertyGridManager::OnMouseMove)
245 EVT_SIZE(wxPropertyGridManager::OnResize)
246 EVT_PAINT(wxPropertyGridManager::OnPaint)
247 EVT_LEFT_DOWN(wxPropertyGridManager::OnMouseClick)
248 EVT_LEFT_UP(wxPropertyGridManager::OnMouseUp)
249 EVT_LEAVE_WINDOW(wxPropertyGridManager::OnMouseEntry)
250 //EVT_ENTER_WINDOW(wxPropertyGridManager::OnMouseEntry)
251 END_EVENT_TABLE()
252
253 // -----------------------------------------------------------------------
254
255 wxPropertyGridManager::wxPropertyGridManager()
256 : wxPanel()
257 {
258 Init1();
259 }
260
261 // -----------------------------------------------------------------------
262
263 wxPropertyGridManager::wxPropertyGridManager( wxWindow *parent,
264 wxWindowID id,
265 const wxPoint& pos,
266 const wxSize& size,
267 long style,
268 const wxString& name )
269 : wxPanel()
270 {
271 Init1();
272 Create(parent,id,pos,size,style,name);
273 }
274
275 // -----------------------------------------------------------------------
276
277 bool wxPropertyGridManager::Create( wxWindow *parent,
278 wxWindowID id,
279 const wxPoint& pos,
280 const wxSize& size,
281 long style,
282 const wxString& name )
283 {
284 if ( !m_pPropGrid )
285 m_pPropGrid = CreatePropertyGrid();
286
287 bool res = wxPanel::Create( parent, id, pos, size,
288 (style&0xFFFF0000)|wxWANTS_CHARS,
289 name );
290 Init2(style);
291
292 return res;
293 }
294
295 // -----------------------------------------------------------------------
296
297 //
298 // Initialize values to defaults
299 //
300 void wxPropertyGridManager::Init1()
301 {
302
303 m_pPropGrid = NULL;
304
305 #if wxUSE_TOOLBAR
306 m_pToolbar = NULL;
307 #endif
308 m_pTxtHelpCaption = NULL;
309 m_pTxtHelpContent = NULL;
310
311 m_emptyPage = NULL;
312
313 m_selPage = -1;
314
315 m_width = m_height = 0;
316
317 m_splitterHeight = 5;
318
319 m_splitterY = -1; // -1 causes default to be set.
320
321 m_nextDescBoxSize = -1;
322
323 m_extraHeight = 0;
324 m_dragStatus = 0;
325 m_onSplitter = 0;
326 m_iFlags = 0;
327 }
328
329 // -----------------------------------------------------------------------
330
331 // These flags are always used in wxPropertyGrid integrated in wxPropertyGridManager.
332 #ifndef __WXMAC__
333 #define wxPG_MAN_PROPGRID_FORCED_FLAGS (wxSIMPLE_BORDER| \
334 wxNO_FULL_REPAINT_ON_RESIZE| \
335 wxCLIP_CHILDREN)
336 #else
337 #define wxPG_MAN_PROPGRID_FORCED_FLAGS (wxNO_BORDER| \
338 wxNO_FULL_REPAINT_ON_RESIZE| \
339 wxCLIP_CHILDREN)
340 #endif
341
342 // Which flags can be passed to underlying wxPropertyGrid.
343 #define wxPG_MAN_PASS_FLAGS_MASK (0xFFF0|wxTAB_TRAVERSAL)
344
345 //
346 // Initialize after parent etc. set
347 //
348 void wxPropertyGridManager::Init2( int style )
349 {
350
351 if ( m_iFlags & wxPG_FL_INITIALIZED )
352 return;
353
354 m_windowStyle |= (style&0x0000FFFF);
355
356 wxSize csz = GetClientSize();
357
358 m_cursorSizeNS = wxCursor(wxCURSOR_SIZENS);
359
360 // Prepare the first page
361 // NB: But just prepare - you still need to call Add/InsertPage
362 // to actually add properties on it.
363 wxPropertyGridPage* pd = new wxPropertyGridPage();
364 pd->m_isDefault = true;
365 pd->m_manager = this;
366 wxPropertyGridPageState* state = pd->GetStatePtr();
367 state->m_pPropGrid = m_pPropGrid;
368 m_arrPages.push_back( pd );
369 m_pPropGrid->m_pState = state;
370
371 wxWindowID baseId = GetId();
372 wxWindowID useId = baseId;
373 if ( baseId < 0 )
374 baseId = wxPG_MAN_ALTERNATE_BASE_ID;
375
376 m_baseId = baseId;
377
378 #ifdef __WXMAC__
379 // Smaller controls on Mac
380 SetWindowVariant(wxWINDOW_VARIANT_SMALL);
381 #endif
382
383 // Create propertygrid.
384 m_pPropGrid->Create(this,baseId,wxPoint(0,0),csz,
385 (m_windowStyle&wxPG_MAN_PASS_FLAGS_MASK)
386 |wxPG_MAN_PROPGRID_FORCED_FLAGS);
387
388 m_pPropGrid->m_eventObject = this;
389
390 m_pPropGrid->SetId(useId);
391
392 m_pPropGrid->m_iFlags |= wxPG_FL_IN_MANAGER;
393
394 m_pState = m_pPropGrid->m_pState;
395
396 m_pPropGrid->SetExtraStyle(wxPG_EX_INIT_NOCAT);
397
398 m_nextTbInd = baseId+ID_ADVTBITEMSBASE_OFFSET + 2;
399
400
401 // Connect to property grid onselect event.
402 // NB: Even if wxID_ANY is used, this doesn't connect properly in wxPython
403 // (see wxPropertyGridManager::ProcessEvent).
404 Connect(m_pPropGrid->GetId()/*wxID_ANY*/,
405 wxEVT_PG_SELECTED,
406 wxPropertyGridEventHandler(wxPropertyGridManager::OnPropertyGridSelect) );
407
408 // Connect to toolbar button events.
409 Connect(baseId+ID_ADVTBITEMSBASE_OFFSET,baseId+ID_ADVTBITEMSBASE_OFFSET+50,
410 wxEVT_COMMAND_TOOL_CLICKED,
411 wxCommandEventHandler(wxPropertyGridManager::OnToolbarClick) );
412
413 // Optional initial controls.
414 m_width = -12345;
415
416 m_iFlags |= wxPG_FL_INITIALIZED;
417
418 }
419
420 // -----------------------------------------------------------------------
421
422 wxPropertyGridManager::~wxPropertyGridManager()
423 {
424 END_MOUSE_CAPTURE
425
426 //m_pPropGrid->ClearSelection();
427 delete m_pPropGrid;
428 m_pPropGrid = NULL;
429
430 size_t i;
431 for ( i=0; i<m_arrPages.size(); i++ )
432 {
433 delete m_arrPages[i];
434 }
435
436 delete m_emptyPage;
437 }
438
439 // -----------------------------------------------------------------------
440
441 wxPropertyGrid* wxPropertyGridManager::CreatePropertyGrid() const
442 {
443 return new wxPropertyGrid();
444 }
445
446 // -----------------------------------------------------------------------
447
448 void wxPropertyGridManager::SetId( wxWindowID winid )
449 {
450 wxWindow::SetId(winid);
451
452 // TODO: Reconnect propgrid event handler(s).
453
454 m_pPropGrid->SetId(winid);
455 }
456
457 // -----------------------------------------------------------------------
458
459 wxSize wxPropertyGridManager::DoGetBestSize() const
460 {
461 return wxSize(60,150);
462 }
463
464 // -----------------------------------------------------------------------
465
466 bool wxPropertyGridManager::SetFont( const wxFont& font )
467 {
468 bool res = wxWindow::SetFont(font);
469 m_pPropGrid->SetFont(font);
470
471 // TODO: Need to do caption recacalculations for other pages as well.
472 unsigned int i;
473 for ( i=0; i<m_arrPages.size(); i++ )
474 {
475 wxPropertyGridPage* page = GetPage(i);
476
477 if ( page != m_pPropGrid->GetState() )
478 page->CalculateFontAndBitmapStuff(-1);
479 }
480
481 return res;
482 }
483
484 // -----------------------------------------------------------------------
485
486 void wxPropertyGridManager::SetExtraStyle( long exStyle )
487 {
488 wxWindow::SetExtraStyle( exStyle );
489 m_pPropGrid->SetExtraStyle( exStyle & 0xFFFFF000 );
490 #if wxUSE_TOOLBAR
491 if ( (exStyle & wxPG_EX_NO_FLAT_TOOLBAR) && m_pToolbar )
492 RecreateControls();
493 #endif
494 }
495
496 // -----------------------------------------------------------------------
497
498 void wxPropertyGridManager::Freeze()
499 {
500 m_pPropGrid->Freeze();
501 wxWindow::Freeze();
502 }
503
504 // -----------------------------------------------------------------------
505
506 void wxPropertyGridManager::Thaw()
507 {
508 wxWindow::Thaw();
509 m_pPropGrid->Thaw();
510 }
511
512 // -----------------------------------------------------------------------
513
514 void wxPropertyGridManager::SetWindowStyleFlag( long style )
515 {
516 int oldWindowStyle = GetWindowStyleFlag();
517
518 wxWindow::SetWindowStyleFlag( style );
519 m_pPropGrid->SetWindowStyleFlag( (m_pPropGrid->GetWindowStyleFlag()&~(wxPG_MAN_PASS_FLAGS_MASK)) |
520 (style&wxPG_MAN_PASS_FLAGS_MASK) );
521
522 // Need to re-position windows?
523 if ( (oldWindowStyle & (wxPG_TOOLBAR|wxPG_DESCRIPTION)) !=
524 (style & (wxPG_TOOLBAR|wxPG_DESCRIPTION)) )
525 {
526 RecreateControls();
527 }
528 }
529
530 // -----------------------------------------------------------------------
531
532 bool wxPropertyGridManager::Reparent( wxWindowBase *newParent )
533 {
534 if ( m_pPropGrid )
535 m_pPropGrid->OnTLPChanging((wxWindow*)newParent);
536
537 bool res = wxPanel::Reparent(newParent);
538
539 return res;
540 }
541
542 // -----------------------------------------------------------------------
543
544 // Actually shows given page.
545 bool wxPropertyGridManager::DoSelectPage( int index )
546 {
547 // -1 means no page was selected
548 //wxASSERT( m_selPage >= 0 );
549
550 wxCHECK_MSG( index >= -1 && index < (int)GetPageCount(),
551 false,
552 wxT("invalid page index") );
553
554 if ( m_selPage == index )
555 return true;
556
557 if ( m_pPropGrid->GetSelection() )
558 {
559 if ( !m_pPropGrid->ClearSelection() )
560 return false;
561 }
562
563 wxPropertyGridPage* prevPage;
564
565 if ( m_selPage >= 0 )
566 prevPage = GetPage(m_selPage);
567 else
568 prevPage = m_emptyPage;
569
570 wxPropertyGridPage* nextPage;
571
572 if ( index >= 0 )
573 {
574 nextPage = m_arrPages[index];
575
576 nextPage->OnShow();
577 }
578 else
579 {
580 if ( !m_emptyPage )
581 {
582 m_emptyPage = new wxPropertyGridPage();
583 m_emptyPage->m_pPropGrid = m_pPropGrid;
584 }
585
586 nextPage = m_emptyPage;
587 }
588
589 m_iFlags |= wxPG_FL_DESC_REFRESH_REQUIRED;
590
591 m_pPropGrid->SwitchState( nextPage->GetStatePtr() );
592
593 m_pState = m_pPropGrid->m_pState;
594
595 m_selPage = index;
596
597 #if wxUSE_TOOLBAR
598 if ( m_pToolbar )
599 {
600 if ( index >= 0 )
601 m_pToolbar->ToggleTool( nextPage->m_id, true );
602 else
603 m_pToolbar->ToggleTool( prevPage->m_id, false );
604 }
605 #endif
606
607 return true;
608 }
609
610 // -----------------------------------------------------------------------
611
612 // Changes page *and* set the target page for insertion operations.
613 void wxPropertyGridManager::SelectPage( int index )
614 {
615 DoSelectPage(index);
616 }
617
618 // -----------------------------------------------------------------------
619
620 int wxPropertyGridManager::GetPageByName( const wxString& name ) const
621 {
622 size_t i;
623 for ( i=0; i<GetPageCount(); i++ )
624 {
625 if ( m_arrPages[i]->m_label == name )
626 return i;
627 }
628 return wxNOT_FOUND;
629 }
630
631 // -----------------------------------------------------------------------
632
633 int wxPropertyGridManager::GetPageByState( const wxPropertyGridPageState* pState ) const
634 {
635 wxASSERT( pState );
636
637 size_t i;
638 for ( i=0; i<GetPageCount(); i++ )
639 {
640 if ( pState == m_arrPages[i]->GetStatePtr() )
641 return i;
642 }
643
644 return wxNOT_FOUND;
645 }
646
647 // -----------------------------------------------------------------------
648
649 const wxString& wxPropertyGridManager::GetPageName( int index ) const
650 {
651 wxASSERT( index >= 0 && index < (int)GetPageCount() );
652 return m_arrPages[index]->m_label;
653 }
654
655 // -----------------------------------------------------------------------
656
657 wxPropertyGridPageState* wxPropertyGridManager::GetPageState( int page ) const
658 {
659 // Do not change this into wxCHECK because returning NULL is important
660 // for wxPropertyGridInterface page enumeration mechanics.
661 if ( page >= (int)GetPageCount() )
662 return NULL;
663
664 if ( page == -1 )
665 return m_pState;
666 return m_arrPages[page];
667 }
668
669 // -----------------------------------------------------------------------
670
671 void wxPropertyGridManager::Clear()
672 {
673 m_pPropGrid->ClearSelection(false);
674
675 m_pPropGrid->Freeze();
676
677 int i;
678 for ( i=(int)GetPageCount()-1; i>=0; i-- )
679 RemovePage(i);
680
681 // Reset toolbar ids
682 m_nextTbInd = m_baseId+ID_ADVTBITEMSBASE_OFFSET + 2;
683
684 m_pPropGrid->Thaw();
685 }
686
687 // -----------------------------------------------------------------------
688
689 void wxPropertyGridManager::ClearPage( int page )
690 {
691 wxASSERT( page >= 0 );
692 wxASSERT( page < (int)GetPageCount() );
693
694 if ( page >= 0 && page < (int)GetPageCount() )
695 {
696 wxPropertyGridPageState* state = m_arrPages[page];
697
698 if ( state == m_pPropGrid->GetState() )
699 m_pPropGrid->Clear();
700 else
701 state->DoClear();
702 }
703 }
704
705 // -----------------------------------------------------------------------
706
707 int wxPropertyGridManager::GetColumnCount( int page ) const
708 {
709 wxASSERT( page >= -1 );
710 wxASSERT( page < (int)GetPageCount() );
711
712 return GetPageState(page)->GetColumnCount();
713 }
714
715 // -----------------------------------------------------------------------
716
717 void wxPropertyGridManager::SetColumnCount( int colCount, int page )
718 {
719 wxASSERT( page >= -1 );
720 wxASSERT( page < (int)GetPageCount() );
721
722 GetPageState(page)->SetColumnCount( colCount );
723 GetGrid()->Refresh();
724 }
725 // -----------------------------------------------------------------------
726
727 size_t wxPropertyGridManager::GetPageCount() const
728 {
729 if ( !(m_iFlags & wxPG_MAN_FL_PAGE_INSERTED) )
730 return 0;
731
732 return m_arrPages.size();
733 }
734
735 // -----------------------------------------------------------------------
736
737 wxPropertyGridPage* wxPropertyGridManager::InsertPage( int index,
738 const wxString& label,
739 const wxBitmap& bmp,
740 wxPropertyGridPage* pageObj )
741 {
742 if ( index < 0 )
743 index = GetPageCount();
744
745 wxCHECK_MSG( (size_t)index == GetPageCount(), NULL,
746 wxT("wxPropertyGridManager currently only supports appending pages (due to wxToolBar limitation)."));
747
748 bool needInit = true;
749 bool isPageInserted = m_iFlags & wxPG_MAN_FL_PAGE_INSERTED ? true : false;
750
751 wxASSERT( index == 0 || isPageInserted );
752
753 if ( !pageObj )
754 {
755 // No custom page object was given, so we will either re-use the default base
756 // page (if index==0), or create a new default page object.
757 if ( !isPageInserted )
758 {
759 pageObj = GetPage(0);
760 // Of course, if the base page was custom, we need to delete and
761 // re-create it.
762 if ( !pageObj->m_isDefault )
763 {
764 delete pageObj;
765 pageObj = new wxPropertyGridPage();
766 m_arrPages[0] = pageObj;
767 }
768 needInit = false;
769 }
770 else
771 {
772 pageObj = new wxPropertyGridPage();
773 }
774 pageObj->m_isDefault = true;
775 }
776 else
777 {
778 if ( !isPageInserted )
779 {
780 // Initial page needs to be deleted and replaced
781 delete GetPage(0);
782 m_arrPages[0] = pageObj;
783 m_pPropGrid->m_pState = pageObj->GetStatePtr();
784 }
785 }
786
787 wxPropertyGridPageState* state = pageObj->GetStatePtr();
788
789 pageObj->m_manager = this;
790
791 if ( needInit )
792 {
793 state->m_pPropGrid = m_pPropGrid;
794 state->InitNonCatMode();
795 }
796
797 if ( label.length() )
798 {
799 wxASSERT_MSG( !pageObj->m_label.length(),
800 wxT("If page label is given in constructor, empty label must be given in AddPage"));
801 pageObj->m_label = label;
802 }
803
804 pageObj->m_id = m_nextTbInd;
805
806 if ( isPageInserted )
807 m_arrPages.push_back( pageObj );
808
809 #if wxUSE_TOOLBAR
810 if ( m_windowStyle & wxPG_TOOLBAR )
811 {
812 if ( !m_pToolbar )
813 RecreateControls();
814
815 if ( !(GetExtraStyle()&wxPG_EX_HIDE_PAGE_BUTTONS) )
816 {
817 wxASSERT( m_pToolbar );
818
819 // Add separator before first page.
820 if ( GetPageCount() < 2 && (GetExtraStyle()&wxPG_EX_MODE_BUTTONS) &&
821 m_pToolbar->GetToolsCount() < 3 )
822 m_pToolbar->AddSeparator();
823
824 if ( &bmp != &wxNullBitmap )
825 m_pToolbar->AddTool(m_nextTbInd,label,bmp,label,wxITEM_RADIO);
826 //m_pToolbar->InsertTool(index+3,m_nextTbInd,bmp);
827 else
828 m_pToolbar->AddTool(m_nextTbInd,label,wxBitmap( (const char**)gs_xpm_defpage ),
829 label,wxITEM_RADIO);
830
831 m_nextTbInd++;
832
833 m_pToolbar->Realize();
834 }
835 }
836 #else
837 wxUnusedVar(bmp);
838 #endif
839
840 // If selected page was above the point of insertion, fix the current page index
841 if ( isPageInserted )
842 {
843 if ( m_selPage >= index )
844 {
845 m_selPage += 1;
846 }
847 }
848 else
849 {
850 // Set this value only when adding the first page
851 m_selPage = 0;
852 }
853
854 pageObj->Init();
855
856 m_iFlags |= wxPG_MAN_FL_PAGE_INSERTED;
857
858 wxASSERT( pageObj->GetGrid() );
859
860 return pageObj;
861 }
862
863 // -----------------------------------------------------------------------
864
865 bool wxPropertyGridManager::IsAnyModified() const
866 {
867 size_t i;
868 for ( i=0; i<GetPageCount(); i++ )
869 {
870 if ( m_arrPages[i]->GetStatePtr()->m_anyModified )
871 return true;
872 }
873 return false;
874 }
875
876 // -----------------------------------------------------------------------
877
878 bool wxPropertyGridManager::IsPageModified( size_t index ) const
879 {
880 if ( m_arrPages[index]->GetStatePtr()->m_anyModified )
881 return true;
882 return false;
883 }
884
885 // -----------------------------------------------------------------------
886
887 bool wxPropertyGridManager::IsPropertySelected( wxPGPropArg id ) const
888 {
889 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
890 for ( unsigned int i=0; i<GetPageCount(); i++ )
891 {
892 if ( GetPageState(i)->DoIsPropertySelected(p) )
893 return true;
894 }
895 return false;
896 }
897
898 // -----------------------------------------------------------------------
899
900 wxPGProperty* wxPropertyGridManager::GetPageRoot( int index ) const
901 {
902 wxASSERT( index >= 0 );
903 wxASSERT( index < (int)m_arrPages.size() );
904
905 return m_arrPages[index]->GetStatePtr()->m_properties;
906 }
907
908 // -----------------------------------------------------------------------
909
910 bool wxPropertyGridManager::RemovePage( int page )
911 {
912 wxCHECK_MSG( (page >= 0) && (page < (int)GetPageCount()),
913 false,
914 wxT("invalid page index") );
915
916 wxPropertyGridPage* pd = m_arrPages[page];
917
918 if ( m_arrPages.size() == 1 )
919 {
920 // Last page: do not remove page entry
921 m_pPropGrid->Clear();
922 m_selPage = -1;
923 m_iFlags &= ~wxPG_MAN_FL_PAGE_INSERTED;
924 pd->m_label.clear();
925 }
926
927 // Change selection if current is page
928 else if ( page == m_selPage )
929 {
930 if ( !m_pPropGrid->ClearSelection() )
931 return false;
932
933 // Substitute page to select
934 int substitute = page - 1;
935 if ( substitute < 0 )
936 substitute = page + 1;
937
938 SelectPage(substitute);
939 }
940
941 // Remove toolbar icon
942 #if wxUSE_TOOLBAR
943 if ( HasFlag(wxPG_TOOLBAR) )
944 {
945 wxASSERT( m_pToolbar );
946
947 int toolPos = GetExtraStyle() & wxPG_EX_MODE_BUTTONS ? 3 : 0;
948 toolPos += page;
949
950 // Delete separator as well, for consistency
951 if ( (GetExtraStyle() & wxPG_EX_MODE_BUTTONS) &&
952 GetPageCount() == 1 )
953 m_pToolbar->DeleteToolByPos(2);
954
955 m_pToolbar->DeleteToolByPos(toolPos);
956 }
957 #endif
958
959 if ( m_arrPages.size() > 1 )
960 {
961 m_arrPages.erase(m_arrPages.begin() + page);
962 delete pd;
963 }
964
965 // Adjust indexes that were above removed
966 if ( m_selPage > page )
967 m_selPage--;
968
969 return true;
970 }
971
972 // -----------------------------------------------------------------------
973
974 bool wxPropertyGridManager::ProcessEvent( wxEvent& event )
975 {
976 int evtType = event.GetEventType();
977
978 // NB: For some reason, under wxPython, Connect in Init doesn't work properly,
979 // so we'll need to call OnPropertyGridSelect manually. Multiple call's
980 // don't really matter.
981 if ( evtType == wxEVT_PG_SELECTED )
982 OnPropertyGridSelect((wxPropertyGridEvent&)event);
983
984 // Property grid events get special attention
985 if ( evtType >= wxPG_BASE_EVT_TYPE &&
986 evtType < (wxPG_MAX_EVT_TYPE) &&
987 m_selPage >= 0 )
988 {
989 wxPropertyGridPage* page = GetPage(m_selPage);
990 wxPropertyGridEvent* pgEvent = wxDynamicCast(&event, wxPropertyGridEvent);
991
992 // Add property grid events to appropriate custom pages
993 // but stop propagating to parent if page says it is
994 // handling everything.
995 if ( pgEvent && !page->m_isDefault )
996 {
997 /*if ( pgEvent->IsPending() )
998 page->AddPendingEvent(event);
999 else*/
1000 page->ProcessEvent(event);
1001
1002 if ( page->IsHandlingAllEvents() )
1003 event.StopPropagation();
1004 }
1005 }
1006
1007 return wxPanel::ProcessEvent(event);
1008 }
1009
1010 // -----------------------------------------------------------------------
1011
1012 void wxPropertyGridManager::RepaintDescBoxDecorations( wxDC& dc,
1013 int newSplitterY,
1014 int newWidth,
1015 int newHeight )
1016 {
1017 // Draw background
1018 wxColour bgcol = GetBackgroundColour();
1019 dc.SetBrush(bgcol);
1020 dc.SetPen(bgcol);
1021 int rectHeight = m_splitterHeight;
1022 dc.DrawRectangle(0, newSplitterY, newWidth, rectHeight);
1023 dc.SetPen( wxSystemSettings::GetColour(wxSYS_COLOUR_3DDKSHADOW) );
1024 int splitterBottom = newSplitterY + m_splitterHeight - 1;
1025 int boxHeight = newHeight - splitterBottom;
1026 if ( boxHeight > 1 )
1027 dc.DrawRectangle(0, splitterBottom, newWidth, boxHeight);
1028 else
1029 dc.DrawLine(0, splitterBottom, newWidth, splitterBottom);
1030 }
1031
1032 // -----------------------------------------------------------------------
1033
1034 void wxPropertyGridManager::UpdateDescriptionBox( int new_splittery, int new_width, int new_height )
1035 {
1036 int use_hei = new_height;
1037 use_hei--;
1038
1039 // Fix help control positions.
1040 int cap_hei = m_pPropGrid->m_fontHeight;
1041 int cap_y = new_splittery+m_splitterHeight+5;
1042 int cnt_y = cap_y+cap_hei+3;
1043 int sub_cap_hei = cap_y+cap_hei-use_hei;
1044 int cnt_hei = use_hei-cnt_y;
1045 if ( sub_cap_hei > 0 )
1046 {
1047 cap_hei -= sub_cap_hei;
1048 cnt_hei = 0;
1049 }
1050 if ( cap_hei <= 2 )
1051 {
1052 m_pTxtHelpCaption->Show( false );
1053 m_pTxtHelpContent->Show( false );
1054 }
1055 else
1056 {
1057 m_pTxtHelpCaption->SetSize(3,cap_y,new_width-6,cap_hei);
1058 m_pTxtHelpCaption->Wrap(-1);
1059 m_pTxtHelpCaption->Show( true );
1060 if ( cnt_hei <= 2 )
1061 {
1062 m_pTxtHelpContent->Show( false );
1063 }
1064 else
1065 {
1066 m_pTxtHelpContent->SetSize(3,cnt_y,new_width-6,cnt_hei);
1067 m_pTxtHelpContent->Show( true );
1068 }
1069 }
1070
1071 wxRect r(0, new_splittery, new_width, new_height-new_splittery);
1072 RefreshRect(r);
1073
1074 m_splitterY = new_splittery;
1075
1076 m_iFlags &= ~(wxPG_FL_DESC_REFRESH_REQUIRED);
1077 }
1078
1079 // -----------------------------------------------------------------------
1080
1081 void wxPropertyGridManager::RecalculatePositions( int width, int height )
1082 {
1083 int propgridY = 0;
1084 int propgridBottomY = height;
1085
1086 // Toolbar at the top.
1087 #if wxUSE_TOOLBAR
1088 if ( m_pToolbar )
1089 {
1090 m_pToolbar->SetSize(0, 0, width, -1);
1091 propgridY += m_pToolbar->GetSize().y;
1092 }
1093 #endif
1094
1095 // Help box.
1096 if ( m_pTxtHelpCaption )
1097 {
1098 int new_splittery = m_splitterY;
1099
1100 // Move m_splitterY
1101 if ( ( m_splitterY >= 0 || m_nextDescBoxSize ) && m_height > 32 )
1102 {
1103 if ( m_nextDescBoxSize >= 0 )
1104 {
1105 new_splittery = m_height - m_nextDescBoxSize - m_splitterHeight;
1106 m_nextDescBoxSize = -1;
1107 }
1108 new_splittery += (height-m_height);
1109 }
1110 else
1111 {
1112 new_splittery = height - wxPGMAN_DEFAULT_NEGATIVE_SPLITTER_Y;
1113 if ( new_splittery < 32 )
1114 new_splittery = 32;
1115 }
1116
1117 // Check if beyond minimum.
1118 int nspy_min = propgridY + m_pPropGrid->m_lineHeight;
1119 if ( new_splittery < nspy_min )
1120 new_splittery = nspy_min;
1121
1122 propgridBottomY = new_splittery;
1123
1124 UpdateDescriptionBox( new_splittery, width, height );
1125 }
1126
1127 if ( m_iFlags & wxPG_FL_INITIALIZED )
1128 {
1129 int pgh = propgridBottomY - propgridY;
1130 if ( pgh < 0 )
1131 pgh = 0;
1132 m_pPropGrid->SetSize( 0, propgridY, width, pgh );
1133
1134 m_extraHeight = height - pgh;
1135
1136 m_width = width;
1137 m_height = height;
1138 }
1139 }
1140
1141 // -----------------------------------------------------------------------
1142
1143 void wxPropertyGridManager::SetDescBoxHeight( int ht, bool refresh )
1144 {
1145 if ( m_windowStyle & wxPG_DESCRIPTION )
1146 {
1147 if ( ht != GetDescBoxHeight() )
1148 {
1149 m_nextDescBoxSize = ht;
1150 if ( refresh )
1151 RecalculatePositions(m_width, m_height);
1152 }
1153 }
1154 }
1155
1156 // -----------------------------------------------------------------------
1157
1158 int wxPropertyGridManager::GetDescBoxHeight() const
1159 {
1160 return GetClientSize().y - m_splitterY - m_splitterHeight;
1161 }
1162
1163 // -----------------------------------------------------------------------
1164
1165 void wxPropertyGridManager::OnPaint( wxPaintEvent& WXUNUSED(event) )
1166 {
1167 wxPaintDC dc(this);
1168
1169 // Update everything inside the box
1170 wxRect r = GetUpdateRegion().GetBox();
1171
1172 // Repaint splitter and any other description box decorations
1173 if ( (r.y + r.height) >= m_splitterY )
1174 RepaintDescBoxDecorations( dc, m_splitterY, m_width, m_height );
1175 }
1176
1177 // -----------------------------------------------------------------------
1178
1179 void wxPropertyGridManager::Refresh(bool eraseBackground, const wxRect* rect )
1180 {
1181 m_pPropGrid->Refresh(eraseBackground);
1182 wxWindow::Refresh(eraseBackground,rect);
1183 }
1184
1185 // -----------------------------------------------------------------------
1186
1187 void wxPropertyGridManager::RefreshProperty( wxPGProperty* p )
1188 {
1189 wxPropertyGrid* grid = p->GetGrid();
1190
1191 if ( GetPage(m_selPage)->GetStatePtr() == p->GetParent()->GetParentState() )
1192 grid->RefreshProperty(p);
1193 }
1194
1195 // -----------------------------------------------------------------------
1196
1197 void wxPropertyGridManager::RecreateControls()
1198 {
1199
1200 bool was_shown = IsShown();
1201 if ( was_shown )
1202 Show ( false );
1203
1204 wxWindowID baseId = m_pPropGrid->GetId();
1205 if ( baseId < 0 )
1206 baseId = wxPG_MAN_ALTERNATE_BASE_ID;
1207
1208 #if wxUSE_TOOLBAR
1209 if ( m_windowStyle & wxPG_TOOLBAR )
1210 {
1211 // Has toolbar.
1212 if ( !m_pToolbar )
1213 {
1214 m_pToolbar = new wxToolBar(this,baseId+ID_ADVTOOLBAR_OFFSET,
1215 wxDefaultPosition,wxDefaultSize,
1216 ((GetExtraStyle()&wxPG_EX_NO_FLAT_TOOLBAR)?0:wxTB_FLAT)
1217 /*| wxTB_HORIZONTAL | wxNO_BORDER*/ );
1218 m_pToolbar->SetToolBitmapSize(wxSize(16, 15));
1219
1220 #if defined(__WXMSW__)
1221 // Eliminate toolbar flicker on XP
1222 // NOTE: Not enabled since it corrupts drawing somewhat.
1223
1224 /*
1225 #ifndef WS_EX_COMPOSITED
1226 #define WS_EX_COMPOSITED 0x02000000L
1227 #endif
1228
1229 HWND hWnd = (HWND)m_pToolbar->GetHWND();
1230
1231 ::SetWindowLong( hWnd, GWL_EXSTYLE,
1232 ::GetWindowLong(hWnd, GWL_EXSTYLE) | WS_EX_COMPOSITED );
1233 */
1234
1235 #endif
1236
1237 m_pToolbar->SetCursor ( *wxSTANDARD_CURSOR );
1238
1239 if ( (GetExtraStyle()&wxPG_EX_MODE_BUTTONS) )
1240 {
1241 wxString desc1(_("Categorized Mode"));
1242 wxString desc2(_("Alphabetic Mode"));
1243 m_pToolbar->AddTool(baseId+ID_ADVTBITEMSBASE_OFFSET+0,
1244 desc1,wxBitmap ( (const char**)gs_xpm_catmode ),
1245 desc1,wxITEM_RADIO);
1246 m_pToolbar->AddTool(baseId+ID_ADVTBITEMSBASE_OFFSET+1,
1247 desc2,wxBitmap ( (const char**)gs_xpm_noncatmode ),
1248 desc2,wxITEM_RADIO);
1249 m_pToolbar->Realize();
1250 }
1251
1252 }
1253
1254 if ( (GetExtraStyle()&wxPG_EX_MODE_BUTTONS) )
1255 {
1256 // Toggle correct mode button.
1257 // TODO: This doesn't work in wxMSW (when changing,
1258 // both items will get toggled).
1259 int toggle_but_on_ind = ID_ADVTBITEMSBASE_OFFSET+0;
1260 int toggle_but_off_ind = ID_ADVTBITEMSBASE_OFFSET+1;
1261 if ( m_pPropGrid->m_pState->IsInNonCatMode() )
1262 {
1263 toggle_but_on_ind++;
1264 toggle_but_off_ind--;
1265 }
1266
1267 m_pToolbar->ToggleTool(baseId+toggle_but_on_ind,true);
1268 m_pToolbar->ToggleTool(baseId+toggle_but_off_ind,false);
1269 }
1270
1271 }
1272 else
1273 {
1274 // No toolbar.
1275 if ( m_pToolbar )
1276 m_pToolbar->Destroy();
1277 m_pToolbar = NULL;
1278 }
1279 #endif
1280
1281 if ( m_windowStyle & wxPG_DESCRIPTION )
1282 {
1283 // Has help box.
1284 m_pPropGrid->m_iFlags |= (wxPG_FL_NOSTATUSBARHELP);
1285
1286 if ( !m_pTxtHelpCaption )
1287 {
1288 m_pTxtHelpCaption = new wxStaticText(this,
1289 baseId+ID_ADVHELPCAPTION_OFFSET,
1290 wxT(""),
1291 wxDefaultPosition,
1292 wxDefaultSize,
1293 wxALIGN_LEFT|wxST_NO_AUTORESIZE);
1294 m_pTxtHelpCaption->SetFont( m_pPropGrid->m_captionFont );
1295 m_pTxtHelpCaption->SetCursor( *wxSTANDARD_CURSOR );
1296 }
1297 if ( !m_pTxtHelpContent )
1298 {
1299 m_pTxtHelpContent = new wxStaticText(this,
1300 baseId+ID_ADVHELPCONTENT_OFFSET,
1301 wxT(""),
1302 wxDefaultPosition,
1303 wxDefaultSize,
1304 wxALIGN_LEFT|wxST_NO_AUTORESIZE);
1305 m_pTxtHelpContent->SetCursor( *wxSTANDARD_CURSOR );
1306 }
1307
1308 SetDescribedProperty(GetSelection());
1309 }
1310 else
1311 {
1312 // No help box.
1313 m_pPropGrid->m_iFlags &= ~(wxPG_FL_NOSTATUSBARHELP);
1314
1315 if ( m_pTxtHelpCaption )
1316 m_pTxtHelpCaption->Destroy();
1317
1318 m_pTxtHelpCaption = NULL;
1319
1320 if ( m_pTxtHelpContent )
1321 m_pTxtHelpContent->Destroy();
1322
1323 m_pTxtHelpContent = NULL;
1324 }
1325
1326 int width, height;
1327
1328 GetClientSize(&width,&height);
1329
1330 RecalculatePositions(width,height);
1331
1332 if ( was_shown )
1333 Show ( true );
1334 }
1335
1336 // -----------------------------------------------------------------------
1337
1338 wxPGProperty* wxPropertyGridManager::DoGetPropertyByName( const wxString& name ) const
1339 {
1340 size_t i;
1341 for ( i=0; i<GetPageCount(); i++ )
1342 {
1343 wxPropertyGridPageState* pState = m_arrPages[i]->GetStatePtr();
1344 wxPGProperty* p = pState->BaseGetPropertyByName(name);
1345 if ( p )
1346 {
1347 return p;
1348 }
1349 }
1350 return NULL;
1351 }
1352
1353 // -----------------------------------------------------------------------
1354
1355 bool wxPropertyGridManager::EnsureVisible( wxPGPropArg id )
1356 {
1357 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
1358
1359 wxPropertyGridPageState* parentState = p->GetParentState();
1360
1361 // Select correct page.
1362 if ( m_pPropGrid->m_pState != parentState )
1363 DoSelectPage( GetPageByState(parentState) );
1364
1365 return m_pPropGrid->EnsureVisible(id);
1366 }
1367
1368 // -----------------------------------------------------------------------
1369
1370 void wxPropertyGridManager::OnToolbarClick( wxCommandEvent &event )
1371 {
1372 int id = event.GetId();
1373 if ( id >= 0 )
1374 {
1375 int baseId = m_pPropGrid->GetId();
1376 if ( baseId < 0 )
1377 baseId = wxPG_MAN_ALTERNATE_BASE_ID;
1378
1379 if ( id == ( baseId + ID_ADVTBITEMSBASE_OFFSET + 0 ) )
1380 {
1381 // Categorized mode.
1382 if ( m_pPropGrid->m_windowStyle & wxPG_HIDE_CATEGORIES )
1383 {
1384 if ( !m_pPropGrid->HasInternalFlag(wxPG_FL_CATMODE_AUTO_SORT) )
1385 m_pPropGrid->m_windowStyle &= ~wxPG_AUTO_SORT;
1386 m_pPropGrid->EnableCategories( true );
1387 }
1388 }
1389 else if ( id == ( baseId + ID_ADVTBITEMSBASE_OFFSET + 1 ) )
1390 {
1391 // Alphabetic mode.
1392 if ( !(m_pPropGrid->m_windowStyle & wxPG_HIDE_CATEGORIES) )
1393 {
1394 if ( m_pPropGrid->HasFlag(wxPG_AUTO_SORT) )
1395 m_pPropGrid->SetInternalFlag(wxPG_FL_CATMODE_AUTO_SORT);
1396 else
1397 m_pPropGrid->ClearInternalFlag(wxPG_FL_CATMODE_AUTO_SORT);
1398
1399 m_pPropGrid->m_windowStyle |= wxPG_AUTO_SORT;
1400 m_pPropGrid->EnableCategories( false );
1401 }
1402 }
1403 else
1404 {
1405 // Page Switching.
1406
1407 int index = -1;
1408 size_t i;
1409 wxPropertyGridPage* pdc;
1410
1411 // Find page with given id.
1412 for ( i=0; i<GetPageCount(); i++ )
1413 {
1414 pdc = m_arrPages[i];
1415 if ( pdc->m_id == id )
1416 {
1417 index = i;
1418 break;
1419 }
1420 }
1421
1422 wxASSERT( index >= 0 );
1423
1424 if ( DoSelectPage( index ) )
1425 {
1426
1427 // Event dispatching must be last.
1428 m_pPropGrid->SendEvent( wxEVT_PG_PAGE_CHANGED, NULL );
1429
1430 }
1431 else
1432 {
1433 // TODO: Depress the old button on toolbar.
1434 }
1435
1436 }
1437 }
1438 }
1439
1440 // -----------------------------------------------------------------------
1441
1442 bool wxPropertyGridManager::SetEditableStateItem( const wxString& name, wxVariant value )
1443 {
1444 if ( name == wxS("descboxheight") )
1445 {
1446 SetDescBoxHeight(value.GetLong(), true);
1447 return true;
1448 }
1449 return false;
1450 }
1451
1452 // -----------------------------------------------------------------------
1453
1454 wxVariant wxPropertyGridManager::GetEditableStateItem( const wxString& name ) const
1455 {
1456 if ( name == wxS("descboxheight") )
1457 {
1458 return (long) GetDescBoxHeight();
1459 }
1460 return wxNullVariant;
1461 }
1462
1463 // -----------------------------------------------------------------------
1464
1465 void wxPropertyGridManager::SetDescription( const wxString& label, const wxString& content )
1466 {
1467 if ( m_pTxtHelpCaption )
1468 {
1469 wxSize osz1 = m_pTxtHelpCaption->GetSize();
1470 wxSize osz2 = m_pTxtHelpContent->GetSize();
1471
1472 m_pTxtHelpCaption->SetLabel(label);
1473 m_pTxtHelpContent->SetLabel(content);
1474
1475 m_pTxtHelpCaption->SetSize(-1,osz1.y);
1476 m_pTxtHelpContent->SetSize(-1,osz2.y);
1477
1478 UpdateDescriptionBox( m_splitterY, m_width, m_height );
1479 }
1480 }
1481
1482 // -----------------------------------------------------------------------
1483
1484 void wxPropertyGridManager::SetDescribedProperty( wxPGProperty* p )
1485 {
1486 if ( m_pTxtHelpCaption )
1487 {
1488 if ( p )
1489 {
1490 SetDescription( p->GetLabel(), p->GetHelpString() );
1491 }
1492 else
1493 {
1494 SetDescription( wxEmptyString, wxEmptyString );
1495 }
1496 }
1497 }
1498
1499 // -----------------------------------------------------------------------
1500
1501 void wxPropertyGridManager::SetSplitterLeft( bool subProps, bool allPages )
1502 {
1503 if ( !allPages )
1504 {
1505 m_pPropGrid->SetSplitterLeft(subProps);
1506 }
1507 else
1508 {
1509 wxClientDC dc(this);
1510 dc.SetFont(m_pPropGrid->GetFont());
1511
1512 int highest = 0;
1513 unsigned int i;
1514
1515 for ( i=0; i<GetPageCount(); i++ )
1516 {
1517 int maxW = m_pState->GetColumnFitWidth(dc, m_arrPages[i]->m_properties, 0, subProps );
1518 maxW += m_pPropGrid->m_marginWidth;
1519 if ( maxW > highest )
1520 highest = maxW;
1521 }
1522
1523 if ( highest > 0 )
1524 m_pPropGrid->SetSplitterPosition( highest );
1525
1526 m_pPropGrid->m_iFlags |= wxPG_FL_DONT_CENTER_SPLITTER;
1527 }
1528 }
1529
1530 // -----------------------------------------------------------------------
1531
1532 void wxPropertyGridManager::OnPropertyGridSelect( wxPropertyGridEvent& event )
1533 {
1534 // Check id.
1535 wxASSERT_MSG( GetId() == m_pPropGrid->GetId(),
1536 wxT("wxPropertyGridManager id must be set with wxPropertyGridManager::SetId (not wxWindow::SetId).") );
1537
1538 SetDescribedProperty(event.GetProperty());
1539 event.Skip();
1540 }
1541
1542 // -----------------------------------------------------------------------
1543
1544 void wxPropertyGridManager::OnResize( wxSizeEvent& WXUNUSED(event) )
1545 {
1546 int width, height;
1547
1548 GetClientSize(&width,&height);
1549
1550 if ( m_width == -12345 )
1551 RecreateControls();
1552
1553 RecalculatePositions(width,height);
1554 }
1555
1556 // -----------------------------------------------------------------------
1557
1558 void wxPropertyGridManager::OnMouseEntry( wxMouseEvent& WXUNUSED(event) )
1559 {
1560 // Correct cursor. This is required atleast for wxGTK, for which
1561 // setting button's cursor to *wxSTANDARD_CURSOR does not work.
1562 SetCursor( wxNullCursor );
1563 m_onSplitter = 0;
1564 }
1565
1566 // -----------------------------------------------------------------------
1567
1568 void wxPropertyGridManager::OnMouseMove( wxMouseEvent &event )
1569 {
1570 if ( !m_pTxtHelpCaption )
1571 return;
1572
1573 int y = event.m_y;
1574
1575 if ( m_dragStatus > 0 )
1576 {
1577 int sy = y - m_dragOffset;
1578
1579 // Calculate drag limits
1580 int bottom_limit = m_height - m_splitterHeight + 1;
1581 int top_limit = m_pPropGrid->m_lineHeight;
1582 #if wxUSE_TOOLBAR
1583 if ( m_pToolbar ) top_limit += m_pToolbar->GetSize().y;
1584 #endif
1585
1586 if ( sy >= top_limit && sy < bottom_limit )
1587 {
1588
1589 int change = sy - m_splitterY;
1590 if ( change )
1591 {
1592 m_splitterY = sy;
1593
1594 m_pPropGrid->SetSize( m_width, m_splitterY - m_pPropGrid->GetPosition().y );
1595 UpdateDescriptionBox( m_splitterY, m_width, m_height );
1596
1597 m_extraHeight -= change;
1598 InvalidateBestSize();
1599 }
1600
1601 }
1602
1603 }
1604 else
1605 {
1606 if ( y >= m_splitterY && y < (m_splitterY+m_splitterHeight+2) )
1607 {
1608 SetCursor ( m_cursorSizeNS );
1609 m_onSplitter = 1;
1610 }
1611 else
1612 {
1613 if ( m_onSplitter )
1614 {
1615 SetCursor ( wxNullCursor );
1616 }
1617 m_onSplitter = 0;
1618 }
1619 }
1620 }
1621
1622 // -----------------------------------------------------------------------
1623
1624 void wxPropertyGridManager::OnMouseClick( wxMouseEvent &event )
1625 {
1626 int y = event.m_y;
1627
1628 // Click on splitter.
1629 if ( y >= m_splitterY && y < (m_splitterY+m_splitterHeight+2) )
1630 {
1631 if ( m_dragStatus == 0 )
1632 {
1633 //
1634 // Begin draggin the splitter
1635 //
1636
1637 BEGIN_MOUSE_CAPTURE
1638
1639 m_dragStatus = 1;
1640
1641 m_dragOffset = y - m_splitterY;
1642
1643 }
1644 }
1645 }
1646
1647 // -----------------------------------------------------------------------
1648
1649 void wxPropertyGridManager::OnMouseUp( wxMouseEvent &event )
1650 {
1651 // No event type check - basicly calling this method should
1652 // just stop dragging.
1653
1654 if ( m_dragStatus >= 1 )
1655 {
1656 //
1657 // End Splitter Dragging
1658 //
1659
1660 int y = event.m_y;
1661
1662 // DO NOT ENABLE FOLLOWING LINE!
1663 // (it is only here as a reminder to not to do it)
1664 //m_splitterY = y;
1665
1666 // This is necessary to return cursor
1667 END_MOUSE_CAPTURE
1668
1669 // Set back the default cursor, if necessary
1670 if ( y < m_splitterY || y >= (m_splitterY+m_splitterHeight+2) )
1671 {
1672 SetCursor ( wxNullCursor );
1673 }
1674
1675 m_dragStatus = 0;
1676 }
1677 }
1678
1679 // -----------------------------------------------------------------------
1680
1681 void wxPropertyGridManager::SetSplitterPosition( int pos, int splitterColumn )
1682 {
1683 wxASSERT_MSG( GetPageCount(),
1684 wxT("SetSplitterPosition() has no effect until pages have been added") );
1685
1686 size_t i;
1687 for ( i=0; i<GetPageCount(); i++ )
1688 {
1689 wxPropertyGridPage* page = GetPage(i);
1690 page->DoSetSplitterPosition( pos, splitterColumn, false );
1691 }
1692
1693 m_pPropGrid->SetInternalFlag(wxPG_FL_SPLITTER_PRE_SET);
1694 }
1695
1696 // -----------------------------------------------------------------------
1697 // wxPGVIterator_Manager
1698 // -----------------------------------------------------------------------
1699
1700 // Default returned by wxPropertyGridInterface::CreateVIterator().
1701 class wxPGVIteratorBase_Manager : public wxPGVIteratorBase
1702 {
1703 public:
1704 wxPGVIteratorBase_Manager( wxPropertyGridManager* manager, int flags )
1705 : m_manager(manager), m_flags(flags), m_curPage(0)
1706 {
1707 m_it.Init(manager->GetPage(0), flags);
1708 }
1709 virtual ~wxPGVIteratorBase_Manager() { }
1710 virtual void Next()
1711 {
1712 m_it.Next();
1713
1714 // Next page?
1715 if ( m_it.AtEnd() )
1716 {
1717 m_curPage++;
1718 if ( m_curPage < m_manager->GetPageCount() )
1719 m_it.Init( m_manager->GetPage(m_curPage), m_flags );
1720 }
1721 }
1722 private:
1723 wxPropertyGridManager* m_manager;
1724 int m_flags;
1725 unsigned int m_curPage;
1726 };
1727
1728 wxPGVIterator wxPropertyGridManager::GetVIterator( int flags ) const
1729 {
1730 return wxPGVIterator( new wxPGVIteratorBase_Manager( (wxPropertyGridManager*)this, flags ) );
1731 }
1732
1733 #endif // wxUSE_PROPGRID