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

« back to all changes in this revision

Viewing changes to src/propgrid/propgridiface.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/propgridiface.cpp
 
3
// Purpose:     wxPropertyGridInterface class
 
4
// Author:      Jaakko Salli
 
5
// Modified by:
 
6
// Created:     2008-08-24
 
7
// RCS-ID:      $Id: propgridiface.cpp 66728 2011-01-22 14:38:36Z DS $
 
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/dcmemory.h"
 
32
    #include "wx/button.h"
 
33
    #include "wx/pen.h"
 
34
    #include "wx/brush.h"
 
35
    #include "wx/settings.h"
 
36
    #include "wx/sizer.h"
 
37
    #include "wx/intl.h"
 
38
#endif
 
39
 
 
40
#include "wx/propgrid/property.h"
 
41
#include "wx/propgrid/propgrid.h"
 
42
 
 
43
 
 
44
const wxChar *wxPGTypeName_long = wxT("long");
 
45
const wxChar *wxPGTypeName_bool = wxT("bool");
 
46
const wxChar *wxPGTypeName_double = wxT("double");
 
47
const wxChar *wxPGTypeName_wxString = wxT("string");
 
48
const wxChar *wxPGTypeName_void = wxT("void*");
 
49
const wxChar *wxPGTypeName_wxArrayString = wxT("arrstring");
 
50
 
 
51
 
 
52
// ----------------------------------------------------------------------------
 
53
// VariantDatas
 
54
// ----------------------------------------------------------------------------
 
55
 
 
56
WX_PG_IMPLEMENT_VARIANT_DATA_EXPORTED(wxPoint, WXDLLIMPEXP_PROPGRID)
 
57
WX_PG_IMPLEMENT_VARIANT_DATA_EXPORTED(wxSize, WXDLLIMPEXP_PROPGRID)
 
58
WX_PG_IMPLEMENT_VARIANT_DATA_EXPORTED_DUMMY_EQ(wxArrayInt, WXDLLIMPEXP_PROPGRID)
 
59
IMPLEMENT_VARIANT_OBJECT_EXPORTED(wxFont, WXDLLIMPEXP_PROPGRID)
 
60
 
 
61
// -----------------------------------------------------------------------
 
62
// wxPGPropArgCls
 
63
// -----------------------------------------------------------------------
 
64
 
 
65
wxPGProperty* wxPGPropArgCls::GetPtr( wxPropertyGridInterface* iface ) const
 
66
{
 
67
    if ( m_flags == IsProperty )
 
68
    {
 
69
        wxASSERT_MSG( m_ptr.property, wxT("invalid property ptr") );
 
70
        return m_ptr.property;
 
71
    }
 
72
    else if ( m_flags & IsWxString )
 
73
        return iface->GetPropertyByNameA(*m_ptr.stringName);
 
74
    else if ( m_flags & IsCharPtr )
 
75
        return iface->GetPropertyByNameA(m_ptr.charName);
 
76
    else if ( m_flags & IsWCharPtr )
 
77
        return iface->GetPropertyByNameA(m_ptr.wcharName);
 
78
 
 
79
    return NULL;
 
80
}
 
81
 
 
82
// -----------------------------------------------------------------------
 
83
// wxPropertyGridInterface
 
84
// -----------------------------------------------------------------------
 
85
 
 
86
void wxPropertyGridInterface::RefreshGrid( wxPropertyGridPageState* state )
 
87
{
 
88
    if ( !state )
 
89
        state = m_pState;
 
90
 
 
91
    wxPropertyGrid* grid = state->GetGrid();
 
92
    if ( grid->GetState() == state && !grid->IsFrozen() )
 
93
    {
 
94
        grid->Refresh();
 
95
    }
 
96
}
 
97
 
 
98
// -----------------------------------------------------------------------
 
99
 
 
100
wxPGProperty* wxPropertyGridInterface::Append( wxPGProperty* property )
 
101
{
 
102
    wxPGProperty* retp = m_pState->DoAppend(property);
 
103
 
 
104
    wxPropertyGrid* grid = m_pState->GetGrid();
 
105
    if ( grid )
 
106
        grid->RefreshGrid();
 
107
 
 
108
    return retp;
 
109
}
 
110
 
 
111
// -----------------------------------------------------------------------
 
112
 
 
113
wxPGProperty* wxPropertyGridInterface::AppendIn( wxPGPropArg id, wxPGProperty* newproperty )
 
114
{
 
115
    wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxNullProperty)
 
116
    wxPGProperty* pwc = (wxPGProperty*) p;
 
117
    wxPGProperty* retp = m_pState->DoInsert(pwc, pwc->GetChildCount(), newproperty);
 
118
    return retp;
 
119
}
 
120
 
 
121
// -----------------------------------------------------------------------
 
122
 
 
123
wxPGProperty* wxPropertyGridInterface::Insert( wxPGPropArg id, wxPGProperty* property )
 
124
{
 
125
    wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxNullProperty)
 
126
    wxPGProperty* retp = m_pState->DoInsert(p->GetParent(), p->GetIndexInParent(), property);
 
127
    RefreshGrid();
 
128
    return retp;
 
129
}
 
130
 
 
131
// -----------------------------------------------------------------------
 
132
 
 
133
wxPGProperty* wxPropertyGridInterface::Insert( wxPGPropArg id, int index, wxPGProperty* newproperty )
 
134
{
 
135
    wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxNullProperty)
 
136
    wxPGProperty* retp = m_pState->DoInsert((wxPGProperty*)p,index,newproperty);
 
137
    RefreshGrid();
 
138
    return retp;
 
139
}
 
140
 
 
141
// -----------------------------------------------------------------------
 
142
 
 
143
void wxPropertyGridInterface::DeleteProperty( wxPGPropArg id )
 
144
{
 
145
    wxPG_PROP_ARG_CALL_PROLOG()
 
146
 
 
147
    wxPropertyGridPageState* state = p->GetParentState();
 
148
 
 
149
    state->DoDelete( p, true );
 
150
 
 
151
    RefreshGrid(state);
 
152
}
 
153
 
 
154
// -----------------------------------------------------------------------
 
155
 
 
156
wxPGProperty* wxPropertyGridInterface::RemoveProperty( wxPGPropArg id )
 
157
{
 
158
    wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxNullProperty)
 
159
 
 
160
    wxCHECK( !p->GetChildCount() || p->HasFlag(wxPG_PROP_AGGREGATE),
 
161
             wxNullProperty);
 
162
 
 
163
    wxPropertyGridPageState* state = p->GetParentState();
 
164
 
 
165
    state->DoDelete( p, false );
 
166
 
 
167
    RefreshGrid(state);
 
168
 
 
169
    return p;
 
170
}
 
171
 
 
172
// -----------------------------------------------------------------------
 
173
 
 
174
wxPGProperty* wxPropertyGridInterface::ReplaceProperty( wxPGPropArg id, wxPGProperty* property )
 
175
{
 
176
    wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxNullProperty)
 
177
 
 
178
    wxPGProperty* replaced = p;
 
179
    wxCHECK_MSG( replaced && property,
 
180
                 wxNullProperty,
 
181
                 wxT("NULL property") );
 
182
    wxCHECK_MSG( !replaced->IsCategory(),
 
183
                 wxNullProperty,
 
184
                 wxT("cannot replace this type of property") );
 
185
    wxCHECK_MSG( !m_pState->IsInNonCatMode(),
 
186
                 wxNullProperty,
 
187
                 wxT("cannot replace properties in alphabetic mode") );
 
188
 
 
189
    // Get address to the slot
 
190
    wxPGProperty* parent = replaced->GetParent();
 
191
    int ind = replaced->GetIndexInParent();
 
192
 
 
193
    wxPropertyGridPageState* state = replaced->GetParentState();
 
194
    DeleteProperty(replaced); // Must use generic Delete
 
195
    state->DoInsert(parent,ind,property);
 
196
 
 
197
    return property;
 
198
}
 
199
 
 
200
// -----------------------------------------------------------------------
 
201
// wxPropertyGridInterface property operations
 
202
// -----------------------------------------------------------------------
 
203
 
 
204
wxPGProperty* wxPropertyGridInterface::GetSelection() const
 
205
{
 
206
    return m_pState->GetSelection();
 
207
}
 
208
 
 
209
// -----------------------------------------------------------------------
 
210
 
 
211
bool wxPropertyGridInterface::ClearSelection( bool validation )
 
212
{
 
213
    bool res = DoClearSelection(validation, wxPG_SEL_DONT_SEND_EVENT);
 
214
    wxPropertyGrid* pg = GetPropertyGrid();
 
215
    if ( pg )
 
216
        pg->Refresh();
 
217
    return res;
 
218
}
 
219
 
 
220
// -----------------------------------------------------------------------
 
221
 
 
222
bool wxPropertyGridInterface::DoClearSelection( bool validation,
 
223
                                                int selFlags )
 
224
{
 
225
    if ( !validation )
 
226
        selFlags |= wxPG_SEL_NOVALIDATE;
 
227
 
 
228
    wxPropertyGridPageState* state = m_pState;
 
229
 
 
230
    if ( state )
 
231
    {
 
232
        wxPropertyGrid* pg = state->GetGrid();
 
233
        if ( pg->GetState() == state )
 
234
            return pg->DoSelectProperty(NULL, selFlags);
 
235
        else
 
236
            state->DoSetSelection(NULL);
 
237
    }
 
238
 
 
239
    return true;
 
240
}
 
241
 
 
242
// -----------------------------------------------------------------------
 
243
 
 
244
void wxPropertyGridInterface::LimitPropertyEditing( wxPGPropArg id, bool limit )
 
245
{
 
246
    wxPG_PROP_ARG_CALL_PROLOG()
 
247
 
 
248
    m_pState->DoLimitPropertyEditing(p, limit);
 
249
    RefreshProperty(p);
 
250
}
 
251
 
 
252
// -----------------------------------------------------------------------
 
253
 
 
254
bool wxPropertyGridInterface::EnableProperty( wxPGPropArg id, bool enable )
 
255
{
 
256
    wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
 
257
 
 
258
    wxPropertyGridPageState* state = p->GetParentState();
 
259
    wxPropertyGrid* grid = state->GetGrid();
 
260
 
 
261
    if ( enable )
 
262
    {
 
263
        if ( !(p->m_flags & wxPG_PROP_DISABLED) )
 
264
            return false;
 
265
 
 
266
        // If active, Set active Editor.
 
267
        if ( grid && grid->GetState() == state && p == grid->GetSelection() )
 
268
            grid->DoSelectProperty( p, wxPG_SEL_FORCE );
 
269
    }
 
270
    else
 
271
    {
 
272
        if ( p->m_flags & wxPG_PROP_DISABLED )
 
273
            return false;
 
274
 
 
275
        // If active, Disable as active Editor.
 
276
        if ( grid && grid->GetState() == state && p == grid->GetSelection() )
 
277
            grid->DoSelectProperty( p, wxPG_SEL_FORCE );
 
278
    }
 
279
 
 
280
    p->DoEnable(enable);
 
281
 
 
282
    RefreshProperty( p );
 
283
 
 
284
    return true;
 
285
}
 
286
 
 
287
// -----------------------------------------------------------------------
 
288
 
 
289
bool wxPropertyGridInterface::ExpandAll( bool doExpand )
 
290
{
 
291
    wxPropertyGridPageState* state = m_pState;
 
292
 
 
293
    if ( !state->DoGetRoot()->GetChildCount() )
 
294
        return true;
 
295
 
 
296
    wxPropertyGrid* pg = state->GetGrid();
 
297
 
 
298
    if ( GetSelection() && GetSelection() != state->DoGetRoot() &&
 
299
         !doExpand )
 
300
    {
 
301
        pg->DoClearSelection();
 
302
    }
 
303
 
 
304
    wxPGVIterator it;
 
305
 
 
306
    for ( it = GetVIterator( wxPG_ITERATE_ALL ); !it.AtEnd(); it.Next() )
 
307
    {
 
308
        wxPGProperty* p = (wxPGProperty*) it.GetProperty();
 
309
        if ( p->GetChildCount() )
 
310
        {
 
311
            if ( doExpand )
 
312
            {
 
313
                if ( !p->IsExpanded() )
 
314
                {
 
315
                    state->DoExpand(p);
 
316
                }
 
317
            }
 
318
            else
 
319
            {
 
320
                if ( p->IsExpanded() )
 
321
                {
 
322
                    state->DoCollapse(p);
 
323
                }
 
324
            }
 
325
        }
 
326
    }
 
327
 
 
328
    pg->RecalculateVirtualSize();
 
329
 
 
330
    RefreshGrid();
 
331
 
 
332
    return true;
 
333
}
 
334
 
 
335
// -----------------------------------------------------------------------
 
336
 
 
337
void wxPropertyGridInterface::ClearModifiedStatus()
 
338
{
 
339
    unsigned int pageIndex = 0;
 
340
 
 
341
    for (;;)
 
342
    {
 
343
        wxPropertyGridPageState* page = GetPageState(pageIndex);
 
344
        if ( !page ) break;
 
345
 
 
346
        page->DoGetRoot()->SetFlagRecursively(wxPG_PROP_MODIFIED, false);
 
347
        page->m_anyModified = false;
 
348
 
 
349
        pageIndex++;
 
350
    }
 
351
 
 
352
    // Update active editor control, if any
 
353
    GetPropertyGrid()->RefreshEditor();
 
354
}
 
355
 
 
356
bool wxPropertyGridInterface::SetColumnProportion( unsigned int column,
 
357
                                                   int proportion )
 
358
{
 
359
    wxCHECK(m_pState, false);
 
360
    wxPropertyGrid* pg = m_pState->GetGrid();
 
361
    wxCHECK(pg, false);
 
362
    wxCHECK(pg->HasFlag(wxPG_SPLITTER_AUTO_CENTER), false);
 
363
    m_pState->DoSetColumnProportion(column, proportion);
 
364
    return true;
 
365
}
 
366
 
 
367
// -----------------------------------------------------------------------
 
368
// wxPropertyGridInterface property value setting and getting
 
369
// -----------------------------------------------------------------------
 
370
 
 
371
void wxPGGetFailed( const wxPGProperty* p, const wxString& typestr )
 
372
{
 
373
    wxPGTypeOperationFailed(p, typestr, wxS("Get"));
 
374
}
 
375
 
 
376
// -----------------------------------------------------------------------
 
377
 
 
378
void wxPGTypeOperationFailed( const wxPGProperty* p,
 
379
                              const wxString& typestr,
 
380
                              const wxString& op )
 
381
{
 
382
    wxASSERT( p != NULL );
 
383
    wxLogError( _("Type operation \"%s\" failed: Property labeled \"%s\" is of type \"%s\", NOT \"%s\"."),
 
384
        op.c_str(), p->GetLabel().c_str(), p->GetValue().GetType().c_str(), typestr.c_str() );
 
385
}
 
386
 
 
387
// -----------------------------------------------------------------------
 
388
 
 
389
void wxPropertyGridInterface::SetPropVal( wxPGPropArg id, wxVariant& value )
 
390
{
 
391
    wxPG_PROP_ARG_CALL_PROLOG()
 
392
 
 
393
    if ( p )
 
394
        p->SetValue(value);
 
395
}
 
396
 
 
397
// -----------------------------------------------------------------------
 
398
 
 
399
void wxPropertyGridInterface::SetPropertyValueString( wxPGPropArg id, const wxString& value )
 
400
{
 
401
    wxPG_PROP_ARG_CALL_PROLOG()
 
402
 
 
403
    if ( p )
 
404
        m_pState->DoSetPropertyValueString(p, value);
 
405
}
 
406
 
 
407
// -----------------------------------------------------------------------
 
408
 
 
409
void wxPropertyGridInterface::SetValidationFailureBehavior( int vfbFlags )
 
410
{
 
411
    GetPropertyGrid()->m_permanentValidationFailureBehavior = vfbFlags;
 
412
}
 
413
 
 
414
// -----------------------------------------------------------------------
 
415
 
 
416
wxPGProperty* wxPropertyGridInterface::GetPropertyByNameA( const wxString& name ) const
 
417
{
 
418
    wxPGProperty* p = GetPropertyByName(name);
 
419
    wxASSERT_MSG(p,wxString::Format(wxT("no property with name '%s'"),name.c_str()));
 
420
    return p;
 
421
}
 
422
 
 
423
// ----------------------------------------------------------------------------
 
424
 
 
425
wxPGProperty* wxPropertyGridInterface::GetPropertyByLabel( const wxString& label ) const
 
426
{
 
427
    wxPGVIterator it;
 
428
 
 
429
    for ( it = GetVIterator( wxPG_ITERATE_PROPERTIES ); !it.AtEnd(); it.Next() )
 
430
    {
 
431
        if ( it.GetProperty()->GetLabel() == label )
 
432
            return it.GetProperty();
 
433
    }
 
434
 
 
435
    return wxNullProperty;
 
436
}
 
437
 
 
438
// ----------------------------------------------------------------------------
 
439
 
 
440
void wxPropertyGridInterface::DoSetPropertyAttribute( wxPGPropArg id, const wxString& name,
 
441
                                                      wxVariant& value, long argFlags )
 
442
{
 
443
    wxPG_PROP_ARG_CALL_PROLOG()
 
444
 
 
445
    p->SetAttribute( name, value );
 
446
 
 
447
    if ( argFlags & wxPG_RECURSE )
 
448
    {
 
449
        unsigned int i;
 
450
        for ( i = 0; i < p->GetChildCount(); i++ )
 
451
            DoSetPropertyAttribute(p->Item(i), name, value, argFlags);
 
452
    }
 
453
}
 
454
 
 
455
// -----------------------------------------------------------------------
 
456
 
 
457
void wxPropertyGridInterface::SetPropertyAttributeAll( const wxString& attrName,
 
458
                                                       wxVariant value )
 
459
{
 
460
    unsigned int pageIndex = 0;
 
461
 
 
462
    for (;;)
 
463
    {
 
464
        wxPropertyGridPageState* page = GetPageState(pageIndex);
 
465
        if ( !page ) break;
 
466
 
 
467
        DoSetPropertyAttribute(page->DoGetRoot(), attrName, value, wxPG_RECURSE);
 
468
 
 
469
        pageIndex++;
 
470
    }
 
471
}
 
472
 
 
473
// -----------------------------------------------------------------------
 
474
 
 
475
void wxPropertyGridInterface::GetPropertiesWithFlag( wxArrayPGProperty* targetArr,
 
476
                                                     wxPGProperty::FlagType flags,
 
477
                                                     bool inverse,
 
478
                                                     int iterFlags ) const
 
479
{
 
480
    wxASSERT( targetArr );
 
481
    wxPGVIterator it = GetVIterator( iterFlags );
 
482
 
 
483
    for ( ;
 
484
          !it.AtEnd();
 
485
          it.Next() )
 
486
    {
 
487
        const wxPGProperty* property = it.GetProperty();
 
488
 
 
489
        if ( !inverse )
 
490
        {
 
491
            if ( (property->GetFlags() & flags) == flags )
 
492
                targetArr->push_back((wxPGProperty*)property);
 
493
        }
 
494
        else
 
495
        {
 
496
            if ( (property->GetFlags() & flags) != flags )
 
497
                targetArr->push_back((wxPGProperty*)property);
 
498
        }
 
499
    }
 
500
}
 
501
 
 
502
// -----------------------------------------------------------------------
 
503
 
 
504
void wxPropertyGridInterface::SetBoolChoices( const wxString& trueChoice,
 
505
                                                 const wxString& falseChoice )
 
506
{
 
507
    wxPGGlobalVars->m_boolChoices[0] = falseChoice;
 
508
    wxPGGlobalVars->m_boolChoices[1] = trueChoice;
 
509
}
 
510
 
 
511
// -----------------------------------------------------------------------
 
512
 
 
513
wxPGProperty* wxPropertyGridInterface::DoGetPropertyByName( const wxString& name ) const
 
514
{
 
515
    return m_pState->BaseGetPropertyByName(name);
 
516
}
 
517
 
 
518
// -----------------------------------------------------------------------
 
519
 
 
520
wxPGProperty* wxPropertyGridInterface::GetPropertyByName( const wxString& name,
 
521
                                                             const wxString& subname ) const
 
522
{
 
523
    wxPGProperty* p = DoGetPropertyByName(name);
 
524
    if ( !p || !p->GetChildCount() )
 
525
        return wxNullProperty;
 
526
 
 
527
    return p->GetPropertyByName(subname);
 
528
}
 
529
 
 
530
// -----------------------------------------------------------------------
 
531
 
 
532
// Since GetPropertyByName is used *a lot*, this makes sense
 
533
// since non-virtual method can be called with less code.
 
534
wxPGProperty* wxPropertyGridInterface::GetPropertyByName( const wxString& name ) const
 
535
{
 
536
    wxPGProperty* p = DoGetPropertyByName(name);
 
537
    if ( p )
 
538
        return p;
 
539
 
 
540
    // Check if its "Property.SubProperty" format
 
541
    int pos = name.Find(wxT('.'));
 
542
    if ( pos <= 0 )
 
543
        return NULL;
 
544
 
 
545
    return GetPropertyByName(name.substr(0,pos),
 
546
                             name.substr(pos+1,name.length()-pos-1));
 
547
}
 
548
 
 
549
// -----------------------------------------------------------------------
 
550
 
 
551
bool wxPropertyGridInterface::HideProperty( wxPGPropArg id, bool hide, int flags )
 
552
{
 
553
    wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
 
554
 
 
555
    wxPropertyGrid* pg = m_pState->GetGrid();
 
556
 
 
557
    if ( pg == p->GetGrid() )
 
558
        return pg->DoHideProperty(p, hide, flags);
 
559
    else
 
560
        m_pState->DoHideProperty(p, hide, flags);
 
561
 
 
562
    return true;
 
563
}
 
564
 
 
565
// -----------------------------------------------------------------------
 
566
 
 
567
bool wxPropertyGridInterface::Collapse( wxPGPropArg id )
 
568
{
 
569
    wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
 
570
    wxPropertyGrid* pg = p->GetGridIfDisplayed();
 
571
    if ( pg )
 
572
        return pg->DoCollapse(p);
 
573
 
 
574
    return p->GetParentState()->DoCollapse(p);
 
575
}
 
576
 
 
577
// -----------------------------------------------------------------------
 
578
 
 
579
bool wxPropertyGridInterface::Expand( wxPGPropArg id )
 
580
{
 
581
    wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
 
582
    wxPropertyGrid* pg = p->GetGridIfDisplayed();
 
583
    if ( pg )
 
584
        return pg->DoExpand(p);
 
585
 
 
586
    return p->GetParentState()->DoExpand(p);
 
587
}
 
588
 
 
589
// -----------------------------------------------------------------------
 
590
 
 
591
void wxPropertyGridInterface::Sort( int flags )
 
592
{
 
593
    wxPropertyGrid* pg = GetPropertyGrid();
 
594
 
 
595
    unsigned int pageIndex = 0;
 
596
 
 
597
    for (;;)
 
598
    {
 
599
        wxPropertyGridPageState* page = GetPageState(pageIndex);
 
600
        if ( !page ) break;
 
601
        page->DoSort(flags);
 
602
        pageIndex++;
 
603
    }
 
604
 
 
605
    // Fix positions of any open editor controls
 
606
    if ( pg )
 
607
        pg->CorrectEditorWidgetPosY();
 
608
}
 
609
 
 
610
// -----------------------------------------------------------------------
 
611
 
 
612
void wxPropertyGridInterface::SetPropertyLabel( wxPGPropArg id, const wxString& newproplabel )
 
613
{
 
614
    wxPG_PROP_ARG_CALL_PROLOG()
 
615
 
 
616
    p->SetLabel( newproplabel );
 
617
 
 
618
    wxPropertyGridPageState* state = p->GetParentState();
 
619
    wxPropertyGrid* pg = state->GetGrid();
 
620
 
 
621
    if ( pg->HasFlag(wxPG_AUTO_SORT) )
 
622
        pg->SortChildren(p->GetParent());
 
623
 
 
624
    if ( pg->GetState() == state )
 
625
    {
 
626
        if ( pg->HasFlag(wxPG_AUTO_SORT) )
 
627
            pg->Refresh();
 
628
        else
 
629
            pg->DrawItem( p );
 
630
    }
 
631
}
 
632
 
 
633
// -----------------------------------------------------------------------
 
634
 
 
635
bool wxPropertyGridInterface::SetPropertyMaxLength( wxPGPropArg id, int maxLen )
 
636
{
 
637
    wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
 
638
 
 
639
    wxPropertyGrid* pg = m_pState->GetGrid();
 
640
 
 
641
    p->m_maxLen = (short) maxLen;
 
642
 
 
643
    // Adjust control if selected currently
 
644
    if ( pg == p->GetGrid() && p == m_pState->GetSelection() )
 
645
    {
 
646
        wxWindow* wnd = pg->GetEditorControl();
 
647
        wxTextCtrl* tc = wxDynamicCast(wnd,wxTextCtrl);
 
648
        if ( tc )
 
649
            tc->SetMaxLength( maxLen );
 
650
        else
 
651
        // Not a text ctrl
 
652
            return false;
 
653
    }
 
654
 
 
655
    return true;
 
656
}
 
657
 
 
658
// -----------------------------------------------------------------------
 
659
 
 
660
void
 
661
wxPropertyGridInterface::SetPropertyBackgroundColour( wxPGPropArg id,
 
662
                                                      const wxColour& colour,
 
663
                                                      int flags )
 
664
{
 
665
    wxPG_PROP_ARG_CALL_PROLOG()
 
666
    p->SetBackgroundColour(colour, flags);
 
667
    RefreshProperty(p);
 
668
}
 
669
 
 
670
// -----------------------------------------------------------------------
 
671
 
 
672
void wxPropertyGridInterface::SetPropertyTextColour( wxPGPropArg id,
 
673
                                                     const wxColour& colour,
 
674
                                                     int flags )
 
675
{
 
676
    wxPG_PROP_ARG_CALL_PROLOG()
 
677
    p->SetTextColour(colour, flags);
 
678
    RefreshProperty(p);
 
679
}
 
680
 
 
681
// -----------------------------------------------------------------------
 
682
 
 
683
void wxPropertyGridInterface::SetPropertyColoursToDefault( wxPGPropArg id )
 
684
{
 
685
    wxPG_PROP_ARG_CALL_PROLOG()
 
686
 
 
687
    p->m_cells.clear();
 
688
}
 
689
 
 
690
// -----------------------------------------------------------------------
 
691
 
 
692
void wxPropertyGridInterface::SetPropertyCell( wxPGPropArg id,
 
693
                                               int column,
 
694
                                               const wxString& text,
 
695
                                               const wxBitmap& bitmap,
 
696
                                               const wxColour& fgCol,
 
697
                                               const wxColour& bgCol )
 
698
{
 
699
    wxPG_PROP_ARG_CALL_PROLOG()
 
700
 
 
701
    wxPGCell& cell = p->GetCell(column);
 
702
    if ( !text.empty() && text != wxPG_LABEL )
 
703
        cell.SetText(text);
 
704
    if ( bitmap.IsOk() )
 
705
        cell.SetBitmap(bitmap);
 
706
    if ( fgCol != wxNullColour )
 
707
        cell.SetFgCol(fgCol);
 
708
    if ( bgCol != wxNullColour )
 
709
        cell.SetBgCol(bgCol);
 
710
}
 
711
 
 
712
// -----------------------------------------------------------------------
 
713
// GetPropertyValueAsXXX methods
 
714
 
 
715
#define IMPLEMENT_GET_VALUE(T,TRET,BIGNAME,DEFRETVAL) \
 
716
TRET wxPropertyGridInterface::GetPropertyValueAs##BIGNAME( wxPGPropArg id ) const \
 
717
{ \
 
718
    wxPG_PROP_ARG_CALL_PROLOG_RETVAL(DEFRETVAL) \
 
719
    wxVariant value = p->GetValue(); \
 
720
    if ( wxStrcmp(value.GetType(), wxPGTypeName_##T) != 0 ) \
 
721
    { \
 
722
        wxPGGetFailed(p,wxPGTypeName_##T); \
 
723
        return (TRET)DEFRETVAL; \
 
724
    } \
 
725
    return (TRET)value.Get##BIGNAME(); \
 
726
}
 
727
 
 
728
// String is different than others.
 
729
wxString wxPropertyGridInterface::GetPropertyValueAsString( wxPGPropArg id ) const
 
730
{
 
731
    wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxEmptyString)
 
732
    return p->GetValueAsString(wxPG_FULL_VALUE);
 
733
}
 
734
 
 
735
bool wxPropertyGridInterface::GetPropertyValueAsBool( wxPGPropArg id ) const
 
736
{
 
737
    wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
 
738
    wxVariant value = p->GetValue();
 
739
    if ( wxStrcmp(value.GetType(), wxPGTypeName_bool) == 0 )
 
740
    {
 
741
        return value.GetBool();
 
742
    }
 
743
    if ( wxStrcmp(value.GetType(), wxPGTypeName_long) == 0 )
 
744
    {
 
745
        return value.GetLong()?true:false;
 
746
    }
 
747
    wxPGGetFailed(p,wxPGTypeName_bool);
 
748
    return false;
 
749
}
 
750
 
 
751
IMPLEMENT_GET_VALUE(long,long,Long,0)
 
752
IMPLEMENT_GET_VALUE(double,double,Double,0.0)
 
753
 
 
754
bool wxPropertyGridInterface::IsPropertyExpanded( wxPGPropArg id ) const
 
755
{
 
756
    wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
 
757
    return p->IsExpanded();
 
758
}
 
759
 
 
760
// -----------------------------------------------------------------------
 
761
// wxPropertyGridInterface wrappers
 
762
// -----------------------------------------------------------------------
 
763
 
 
764
bool wxPropertyGridInterface::ChangePropertyValue( wxPGPropArg id, wxVariant newValue )
 
765
{
 
766
    return GetPropertyGrid()->ChangePropertyValue(id, newValue);
 
767
}
 
768
 
 
769
// -----------------------------------------------------------------------
 
770
 
 
771
void wxPropertyGridInterface::BeginAddChildren( wxPGPropArg id )
 
772
{
 
773
    wxPG_PROP_ARG_CALL_PROLOG()
 
774
    wxCHECK_RET( p->HasFlag(wxPG_PROP_AGGREGATE), wxT("only call on properties with fixed children") );
 
775
    p->ClearFlag(wxPG_PROP_AGGREGATE);
 
776
    p->SetFlag(wxPG_PROP_MISC_PARENT);
 
777
}
 
778
 
 
779
// -----------------------------------------------------------------------
 
780
 
 
781
bool wxPropertyGridInterface::EditorValidate()
 
782
{
 
783
    return GetPropertyGrid()->DoEditorValidate();
 
784
}
 
785
 
 
786
// -----------------------------------------------------------------------
 
787
 
 
788
void wxPropertyGridInterface::EndAddChildren( wxPGPropArg id )
 
789
{
 
790
    wxPG_PROP_ARG_CALL_PROLOG()
 
791
    wxCHECK_RET( p->HasFlag(wxPG_PROP_MISC_PARENT), wxT("only call on properties for which BeginAddChildren was called prior") );
 
792
    p->ClearFlag(wxPG_PROP_MISC_PARENT);
 
793
    p->SetFlag(wxPG_PROP_AGGREGATE);
 
794
}
 
795
 
 
796
// -----------------------------------------------------------------------
 
797
// wxPGVIterator_State
 
798
// -----------------------------------------------------------------------
 
799
 
 
800
// Default returned by wxPropertyGridInterface::GetVIterator().
 
801
class wxPGVIteratorBase_State : public wxPGVIteratorBase
 
802
{
 
803
public:
 
804
    wxPGVIteratorBase_State( wxPropertyGridPageState* state, int flags )
 
805
    {
 
806
        m_it.Init( state, flags );
 
807
    }
 
808
    virtual ~wxPGVIteratorBase_State() { }
 
809
    virtual void Next() { m_it.Next(); }
 
810
};
 
811
 
 
812
wxPGVIterator wxPropertyGridInterface::GetVIterator( int flags ) const
 
813
{
 
814
    return wxPGVIterator( new wxPGVIteratorBase_State( m_pState, flags ) );
 
815
}
 
816
 
 
817
// -----------------------------------------------------------------------
 
818
// wxPGEditableState related functions
 
819
// -----------------------------------------------------------------------
 
820
 
 
821
// EscapeDelimiters() changes ";" into "\;" and "|" into "\|"
 
822
// in the input string.  This is an internal functions which is
 
823
// used for saving states
 
824
// NB: Similar function exists in aui/framemanager.cpp
 
825
static wxString EscapeDelimiters(const wxString& s)
 
826
{
 
827
    wxString result;
 
828
    result.Alloc(s.length());
 
829
    const wxChar* ch = s.c_str();
 
830
    while (*ch)
 
831
    {
 
832
        if (*ch == wxT(';') || *ch == wxT('|') || *ch == wxT(','))
 
833
            result += wxT('\\');
 
834
        result += *ch;
 
835
        ++ch;
 
836
    }
 
837
    return result;
 
838
}
 
839
 
 
840
wxString wxPropertyGridInterface::SaveEditableState( int includedStates ) const
 
841
{
 
842
    wxString result;
 
843
 
 
844
    //
 
845
    // Save state on page basis
 
846
    unsigned int pageIndex = 0;
 
847
    wxArrayPtrVoid pageStates;
 
848
 
 
849
    for (;;)
 
850
    {
 
851
        wxPropertyGridPageState* page = GetPageState(pageIndex);
 
852
        if ( !page ) break;
 
853
 
 
854
        pageStates.Add(page);
 
855
 
 
856
        pageIndex++;
 
857
    }
 
858
 
 
859
    for ( pageIndex=0; pageIndex < pageStates.size(); pageIndex++ )
 
860
    {
 
861
        wxPropertyGridPageState* pageState = (wxPropertyGridPageState*) pageStates[pageIndex];
 
862
 
 
863
        if ( includedStates & SelectionState )
 
864
        {
 
865
            wxString sel;
 
866
            if ( pageState->GetSelection() )
 
867
                sel = pageState->GetSelection()->GetName();
 
868
            result += wxS("selection=");
 
869
            result += EscapeDelimiters(sel);
 
870
            result += wxS(";");
 
871
        }
 
872
        if ( includedStates & ExpandedState )
 
873
        {
 
874
            wxArrayPGProperty ptrs;
 
875
            wxPropertyGridConstIterator it =
 
876
                wxPropertyGridConstIterator( pageState,
 
877
                                             wxPG_ITERATE_ALL_PARENTS_RECURSIVELY|wxPG_ITERATE_HIDDEN,
 
878
                                             wxNullProperty );
 
879
 
 
880
            result += wxS("expanded=");
 
881
 
 
882
            for ( ;
 
883
                  !it.AtEnd();
 
884
                  it.Next() )
 
885
            {
 
886
                const wxPGProperty* p = it.GetProperty();
 
887
 
 
888
                if ( !p->HasFlag(wxPG_PROP_COLLAPSED) )
 
889
                    result += EscapeDelimiters(p->GetName());
 
890
                result += wxS(",");
 
891
 
 
892
            }
 
893
 
 
894
            if ( result.Last() == wxS(',') )
 
895
                result.RemoveLast();
 
896
 
 
897
            result += wxS(";");
 
898
        }
 
899
        if ( includedStates & ScrollPosState )
 
900
        {
 
901
            int x, y;
 
902
            GetPropertyGrid()->GetViewStart(&x,&y);
 
903
            result += wxString::Format(wxS("scrollpos=%i,%i;"), x, y);
 
904
        }
 
905
        if ( includedStates & SplitterPosState )
 
906
        {
 
907
            result += wxS("splitterpos=");
 
908
 
 
909
            for ( size_t i=0; i<pageState->GetColumnCount(); i++ )
 
910
                result += wxString::Format(wxS("%i,"), pageState->DoGetSplitterPosition(i));
 
911
 
 
912
            result.RemoveLast();  // Remove last comma
 
913
            result += wxS(";");
 
914
        }
 
915
        if ( includedStates & PageState )
 
916
        {
 
917
            result += wxS("ispageselected=");
 
918
 
 
919
            if ( GetPageState(-1) == pageState )
 
920
                result += wxS("1;");
 
921
            else
 
922
                result += wxS("0;");
 
923
        }
 
924
        if ( includedStates & DescBoxState )
 
925
        {
 
926
            wxVariant v = GetEditableStateItem(wxS("descboxheight"));
 
927
            if ( !v.IsNull() )
 
928
                result += wxString::Format(wxS("descboxheight=%i;"), (int)v.GetLong());
 
929
        }
 
930
        result.RemoveLast();  // Remove last semicolon
 
931
        result += wxS("|");
 
932
    }
 
933
 
 
934
    // Remove last '|'
 
935
    if ( !result.empty() )
 
936
        result.RemoveLast();
 
937
 
 
938
    return result;
 
939
}
 
940
 
 
941
bool wxPropertyGridInterface::RestoreEditableState( const wxString& src, int restoreStates )
 
942
{
 
943
    wxPropertyGrid* pg = GetPropertyGrid();
 
944
    wxPGProperty* newSelection = NULL;
 
945
    size_t pageIndex;
 
946
    long vx = -1;
 
947
    long vy = -1;
 
948
    long selectedPage = -1;
 
949
    bool pgSelectionSet = false;
 
950
    bool res = true;
 
951
 
 
952
    pg->Freeze();
 
953
    wxArrayString pageStrings = ::wxSplit(src, wxS('|'), wxS('\\'));
 
954
 
 
955
    for ( pageIndex=0; pageIndex<pageStrings.size(); pageIndex++ )
 
956
    {
 
957
        wxPropertyGridPageState* pageState = GetPageState(pageIndex);
 
958
        if ( !pageState )
 
959
            break;
 
960
 
 
961
        wxArrayString kvpairStrings = ::wxSplit(pageStrings[pageIndex], wxS(';'), wxS('\\'));
 
962
 
 
963
        for ( size_t i=0; i<kvpairStrings.size(); i++ )
 
964
        {
 
965
            const wxString& kvs = kvpairStrings[i];
 
966
            int eq_pos = kvs.Find(wxS('='));
 
967
            if ( eq_pos != wxNOT_FOUND )
 
968
            {
 
969
                wxString key = kvs.substr(0, eq_pos);
 
970
                wxString value = kvs.substr(eq_pos+1);
 
971
 
 
972
                // Further split value by commas
 
973
                wxArrayString values = ::wxSplit(value, wxS(','), wxS('\\'));
 
974
 
 
975
                if ( key == wxS("expanded") )
 
976
                {
 
977
                    if ( restoreStates & ExpandedState )
 
978
                    {
 
979
                        wxPropertyGridIterator it =
 
980
                            wxPropertyGridIterator( pageState,
 
981
                                                    wxPG_ITERATE_ALL,
 
982
                                                    wxNullProperty );
 
983
 
 
984
                        // First collapse all
 
985
                        for ( ; !it.AtEnd(); it.Next() )
 
986
                        {
 
987
                            wxPGProperty* p = it.GetProperty();
 
988
                            pageState->DoCollapse(p);
 
989
                        }
 
990
 
 
991
                        // Then expand those which names are in values
 
992
                        for ( size_t n=0; n<values.size(); n++ )
 
993
                        {
 
994
                            const wxString& name = values[n];
 
995
                            wxPGProperty* prop = GetPropertyByName(name);
 
996
                            if ( prop )
 
997
                                pageState->DoExpand(prop);
 
998
                        }
 
999
                    }
 
1000
                }
 
1001
                else if ( key == wxS("scrollpos") )
 
1002
                {
 
1003
                    if ( restoreStates & ScrollPosState )
 
1004
                    {
 
1005
                        if ( values.size() == 2 )
 
1006
                        {
 
1007
                            values[0].ToLong(&vx);
 
1008
                            values[1].ToLong(&vy);
 
1009
                        }
 
1010
                        else
 
1011
                        {
 
1012
                            res = false;
 
1013
                        }
 
1014
                    }
 
1015
                }
 
1016
                else if ( key == wxS("splitterpos") )
 
1017
                {
 
1018
                    if ( restoreStates & SplitterPosState )
 
1019
                    {
 
1020
                        for ( size_t n=1; n<values.size(); n++ )
 
1021
                        {
 
1022
                            long pos = 0;
 
1023
                            values[n].ToLong(&pos);
 
1024
                            if ( pos > 0 )
 
1025
                                pageState->DoSetSplitterPosition(pos, n);
 
1026
                        }
 
1027
                    }
 
1028
                }
 
1029
                else if ( key == wxS("selection") )
 
1030
                {
 
1031
                    if ( restoreStates & SelectionState )
 
1032
                    {
 
1033
                        if ( values.size() > 0 )
 
1034
                        {
 
1035
                            if ( pageState->IsDisplayed() )
 
1036
                            {
 
1037
                                if ( !values[0].empty() )
 
1038
                                    newSelection = GetPropertyByName(value);
 
1039
                                pgSelectionSet = true;
 
1040
                            }
 
1041
                            else
 
1042
                            {
 
1043
                                if ( !values[0].empty() )
 
1044
                                    pageState->DoSetSelection(GetPropertyByName(value));
 
1045
                                else
 
1046
                                    pageState->DoClearSelection();
 
1047
                            }
 
1048
                        }
 
1049
                    }
 
1050
                }
 
1051
                else if ( key == wxS("ispageselected") )
 
1052
                {
 
1053
                    if ( restoreStates & PageState )
 
1054
                    {
 
1055
                        long pageSelStatus;
 
1056
                        if ( values.size() == 1 && values[0].ToLong(&pageSelStatus) )
 
1057
                        {
 
1058
                            if ( pageSelStatus )
 
1059
                                selectedPage = pageIndex;
 
1060
                        }
 
1061
                        else
 
1062
                        {
 
1063
                            res = false;
 
1064
                        }
 
1065
                    }
 
1066
                }
 
1067
                else if ( key == wxS("descboxheight") )
 
1068
                {
 
1069
                    if ( restoreStates & DescBoxState )
 
1070
                    {
 
1071
                        long descBoxHeight;
 
1072
                        if ( values.size() == 1 && values[0].ToLong(&descBoxHeight) )
 
1073
                        {
 
1074
                            SetEditableStateItem(wxS("descboxheight"), descBoxHeight);
 
1075
                        }
 
1076
                        else
 
1077
                        {
 
1078
                            res = false;
 
1079
                        }
 
1080
                    }
 
1081
                }
 
1082
                else
 
1083
                {
 
1084
                    res = false;
 
1085
                }
 
1086
            }
 
1087
        }
 
1088
    }
 
1089
 
 
1090
    //
 
1091
    // Force recalculation of virtual heights of all pages
 
1092
    // (may be needed on unclean source string).
 
1093
    pageIndex = 0;
 
1094
    wxPropertyGridPageState* pageState = GetPageState(pageIndex);
 
1095
    while ( pageState )
 
1096
    {
 
1097
        pageState->VirtualHeightChanged();
 
1098
        pageIndex += 1;
 
1099
        pageState = GetPageState(pageIndex);
 
1100
    }
 
1101
 
 
1102
    pg->Thaw();
 
1103
 
 
1104
    //
 
1105
    // Selection of visible grid page must be set after Thaw() call
 
1106
    if ( pgSelectionSet )
 
1107
    {
 
1108
        if ( newSelection )
 
1109
            pg->DoSelectProperty(newSelection);
 
1110
        else
 
1111
            pg->DoClearSelection();
 
1112
    }
 
1113
 
 
1114
    if ( selectedPage != -1 )
 
1115
    {
 
1116
        DoSelectPage(selectedPage);
 
1117
    }
 
1118
 
 
1119
    if ( vx >= 0 )
 
1120
    {
 
1121
        pg->Scroll(vx, vy);
 
1122
    }
 
1123
 
 
1124
    return res;
 
1125
}
 
1126
 
 
1127
#endif  // wxUSE_PROPGRID
 
1128