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