~brian-sidebotham/wxwidgets-cmake/wxpython-2.9.4

« back to all changes in this revision

Viewing changes to src/propgrid/manager.cpp

  • Committer: Brian Sidebotham
  • Date: 2013-08-03 14:30:08 UTC
  • Revision ID: brian.sidebotham@gmail.com-20130803143008-c7806tkych1tp6fc
Initial import into Bazaar

Show diffs side-by-side

added added

removed removed

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