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