1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/propgrid/advprops.cpp
3 // Purpose: wxPropertyGrid Advanced Properties (font, colour, etc.)
4 // Author: Jaakko Salli
8 // Copyright: (c) Jaakko Salli
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
12 // For compilers that support precompilation, includes "wx/wx.h".
13 #include "wx/wxprec.h"
23 #include "wx/object.h"
25 #include "wx/string.h"
28 #include "wx/window.h"
31 #include "wx/dcclient.h"
32 #include "wx/button.h"
35 #include "wx/cursor.h"
36 #include "wx/dialog.h"
37 #include "wx/settings.h"
38 #include "wx/msgdlg.h"
39 #include "wx/choice.h"
40 #include "wx/stattext.h"
41 #include "wx/textctrl.h"
42 #include "wx/scrolwin.h"
43 #include "wx/dirdlg.h"
44 #include "wx/combobox.h"
46 #include "wx/textdlg.h"
47 #include "wx/filedlg.h"
49 #include "wx/wxcrtvararg.h"
52 #define __wxPG_SOURCE_FILE__
54 #include "wx/propgrid/propgrid.h"
56 #if wxPG_INCLUDE_ADVPROPS
58 #include "wx/propgrid/advprops.h"
61 #include "wx/msw/private.h"
62 #include "wx/msw/dc.h"
65 // -----------------------------------------------------------------------
67 #if defined(__WXMSW__)
68 #define wxPG_CAN_DRAW_CURSOR 1
69 #elif defined(__WXGTK__)
70 #define wxPG_CAN_DRAW_CURSOR 0
71 #elif defined(__WXMAC__)
72 #define wxPG_CAN_DRAW_CURSOR 0
74 #define wxPG_CAN_DRAW_CURSOR 0
78 // -----------------------------------------------------------------------
80 // -----------------------------------------------------------------------
83 bool operator == (const wxFont
&, const wxFont
&)
88 // Implement dynamic class for type value.
89 IMPLEMENT_DYNAMIC_CLASS(wxColourPropertyValue
, wxObject
)
91 bool operator == (const wxColourPropertyValue
& a
, const wxColourPropertyValue
& b
)
93 return ( ( a
.m_colour
== b
.m_colour
) && (a
.m_type
== b
.m_type
) );
96 bool operator == (const wxArrayInt
& array1
, const wxArrayInt
& array2
)
98 if ( array1
.size() != array2
.size() )
101 for ( i
=0; i
<array1
.size(); i
++ )
103 if ( array1
[i
] != array2
[i
] )
109 // -----------------------------------------------------------------------
110 // wxSpinCtrl-based property editor
111 // -----------------------------------------------------------------------
116 WX_PG_IMPLEMENT_INTERNAL_EDITOR_CLASS(SpinCtrl
,
121 // Trivial destructor.
122 wxPGSpinCtrlEditor::~wxPGSpinCtrlEditor()
127 // Create controls and initialize event handling.
128 wxPGWindowList
wxPGSpinCtrlEditor::CreateControls( wxPropertyGrid
* propgrid
, wxPGProperty
* property
,
129 const wxPoint
& pos
, const wxSize
& sz
) const
131 const int margin
= 1;
132 wxSize
butSz(18, sz
.y
);
133 wxSize
tcSz(sz
.x
- butSz
.x
- margin
, sz
.y
);
134 wxPoint
butPos(pos
.x
+ tcSz
.x
+ margin
, pos
.y
);
136 wxSpinButton
* wnd2
= new wxSpinButton();
140 wnd2
->Create( propgrid
->GetPanel(), wxPG_SUBID2
, butPos
, butSz
, wxSP_VERTICAL
);
142 wnd2
->SetRange( INT_MIN
, INT_MAX
);
145 wxWindowID id
= wnd2
->GetId();
146 wnd2
->Connect( id
, wxEVT_SCROLL_LINEUP
,
147 wxCommandEventHandler(wxPropertyGrid::OnCustomEditorEvent
),
149 wnd2
->Connect( id
, wxEVT_SCROLL_LINEDOWN
,
150 wxCommandEventHandler(wxPropertyGrid::OnCustomEditorEvent
),
153 // Let's add validator to make sure only numbers can be entered
154 wxTextValidator
validator(wxFILTER_NUMERIC
, &m_tempString
);
156 wxTextCtrl
* wnd1
= (wxTextCtrl
*) wxPGTextCtrlEditor::CreateControls( propgrid
, property
, pos
, tcSz
).m_primary
;
157 wnd1
->SetValidator(validator
);
159 wnd1
->Connect( wnd1
->GetId(), wxEVT_KEY_DOWN
,
160 wxCommandEventHandler(wxPropertyGrid::OnCustomEditorEvent
),
163 return wxPGWindowList(wnd1
, wnd2
);
166 // Control's events are redirected here
167 bool wxPGSpinCtrlEditor::OnEvent( wxPropertyGrid
* propgrid
, wxPGProperty
* property
,
168 wxWindow
* wnd
, wxEvent
& event
) const
170 int evtType
= event
.GetEventType();
172 bool bigStep
= false;
174 if ( evtType
== wxEVT_KEY_DOWN
)
176 wxKeyEvent
& keyEvent
= (wxKeyEvent
&)event
;
177 keycode
= keyEvent
.GetKeyCode();
179 if ( keycode
== WXK_UP
)
180 evtType
= wxEVT_SCROLL_LINEUP
;
181 else if ( keycode
== WXK_DOWN
)
182 evtType
= wxEVT_SCROLL_LINEDOWN
;
183 else if ( keycode
== WXK_PAGEUP
)
185 evtType
= wxEVT_SCROLL_LINEUP
;
188 else if ( keycode
== WXK_PAGEDOWN
)
190 evtType
= wxEVT_SCROLL_LINEDOWN
;
195 if ( evtType
== wxEVT_SCROLL_LINEUP
|| evtType
== wxEVT_SCROLL_LINEDOWN
)
198 // Can't use wnd since it might be clipper window
199 wxTextCtrl
* tc
= wxDynamicCast(propgrid
->GetEditorControl(), wxTextCtrl
);
204 s
= property
->GetValueAsString(wxPG_FULL_VALUE
);
206 int mode
= wxPG_PROPERTY_VALIDATION_SATURATE
;
208 if ( property
->GetAttributeAsLong(wxT("Wrap"), 0) )
209 mode
= wxPG_PROPERTY_VALIDATION_WRAP
;
211 if ( property
->GetValueType() == wxT("double") )
214 double step
= property
->GetAttributeAsDouble(wxT("Step"), 1.0);
217 if ( s
.ToDouble(&v_d
) )
222 if ( evtType
== wxEVT_SCROLL_LINEUP
) v_d
+= step
;
226 wxFloatProperty::DoValidation(property
, v_d
, NULL
, mode
);
228 wxPropertyGrid::DoubleToString(s
, v_d
, 6, true, NULL
);
238 wxLongLong_t step
= property
->GetAttributeAsLong(wxT("Step"), 1);
241 if ( s
.ToLongLong(&v_ll
, 10) )
246 if ( evtType
== wxEVT_SCROLL_LINEUP
) v_ll
+= step
;
250 wxIntProperty::DoValidation(property
, v_ll
, NULL
, mode
);
252 s
= wxLongLong(v_ll
).ToString();
262 int ip
= tc
->GetInsertionPoint();
263 int lp
= tc
->GetLastPosition();
265 tc
->SetInsertionPoint(ip
+(tc
->GetLastPosition()-lp
));
271 return wxPGTextCtrlEditor::OnEvent(propgrid
,property
,wnd
,event
);
274 #endif // wxUSE_SPINBTN
277 // -----------------------------------------------------------------------
278 // wxDatePickerCtrl-based property editor
279 // -----------------------------------------------------------------------
281 #if wxUSE_DATEPICKCTRL
284 #include "wx/datectrl.h"
285 #include "wx/dateevt.h"
287 class wxPGDatePickerCtrlEditor
: public wxPGEditor
289 DECLARE_DYNAMIC_CLASS(wxPGDatePickerCtrlEditor
)
291 virtual ~wxPGDatePickerCtrlEditor();
293 wxString
GetName() const;
294 virtual wxPGWindowList
CreateControls(wxPropertyGrid
* propgrid
,
295 wxPGProperty
* property
,
297 const wxSize
& size
) const;
298 virtual void UpdateControl( wxPGProperty
* property
, wxWindow
* wnd
) const;
299 virtual bool OnEvent( wxPropertyGrid
* propgrid
, wxPGProperty
* property
,
300 wxWindow
* wnd
, wxEvent
& event
) const;
301 virtual bool GetValueFromControl( wxVariant
& variant
, wxPGProperty
* property
, wxWindow
* wnd
) const;
302 virtual void SetValueToUnspecified( wxPGProperty
* WXUNUSED(property
), wxWindow
* wnd
) const;
306 WX_PG_IMPLEMENT_INTERNAL_EDITOR_CLASS(DatePickerCtrl
,
307 wxPGDatePickerCtrlEditor
,
311 wxPGDatePickerCtrlEditor::~wxPGDatePickerCtrlEditor()
315 wxPGWindowList
wxPGDatePickerCtrlEditor::CreateControls( wxPropertyGrid
* propgrid
,
316 wxPGProperty
* property
,
318 const wxSize
& sz
) const
320 wxCHECK_MSG( property
->IsKindOf(CLASSINFO(wxDateProperty
)),
322 wxT("DatePickerCtrl editor can only be used with wxDateProperty or derivative.") );
324 wxDateProperty
* prop
= (wxDateProperty
*) property
;
326 // Use two stage creation to allow cleaner display on wxMSW
327 wxDatePickerCtrl
* ctrl
= new wxDatePickerCtrl();
330 wxSize useSz
= wxDefaultSize
;
335 ctrl
->Create(propgrid
->GetPanel(),
337 prop
->GetDateValue(),
340 prop
->GetDatePickerStyle() | wxNO_BORDER
);
342 // Connect all required events to grid's OnCustomEditorEvent
343 // (all relevenat wxTextCtrl, wxComboBox and wxButton events are
344 // already connected)
345 ctrl
->Connect( wxPG_SUBID1
, wxEVT_DATE_CHANGED
,
346 wxCommandEventHandler(wxPropertyGrid::OnCustomEditorEvent
),
356 // Copies value from property to control
357 void wxPGDatePickerCtrlEditor::UpdateControl( wxPGProperty
* property
, wxWindow
* wnd
) const
359 wxDatePickerCtrl
* ctrl
= (wxDatePickerCtrl
*) wnd
;
360 wxASSERT( ctrl
&& ctrl
->IsKindOf(CLASSINFO(wxDatePickerCtrl
)) );
362 // We assume that property's data type is 'int' (or something similar),
363 // thus allowing us to get raw, unchecked value via DoGetValue.
364 ctrl
->SetValue( property
->GetValue().GetDateTime() );
367 // Control's events are redirected here
368 bool wxPGDatePickerCtrlEditor::OnEvent( wxPropertyGrid
* WXUNUSED(propgrid
),
369 wxPGProperty
* WXUNUSED(property
),
370 wxWindow
* WXUNUSED(wnd
),
371 wxEvent
& event
) const
373 if ( event
.GetEventType() == wxEVT_DATE_CHANGED
)
379 bool wxPGDatePickerCtrlEditor::GetValueFromControl( wxVariant
& variant
, wxPGProperty
* WXUNUSED(property
), wxWindow
* wnd
) const
381 wxDatePickerCtrl
* ctrl
= (wxDatePickerCtrl
*) wnd
;
382 wxASSERT( ctrl
&& ctrl
->IsKindOf(CLASSINFO(wxDatePickerCtrl
)) );
384 variant
= ctrl
->GetValue();
389 void wxPGDatePickerCtrlEditor::SetValueToUnspecified( wxPGProperty
* WXUNUSED(property
), wxWindow
* WXUNUSED(wnd
) ) const
392 //wxDateProperty* prop = (wxDateProperty*) property;
396 #endif // wxUSE_DATEPICKCTRL
399 // -----------------------------------------------------------------------
401 // -----------------------------------------------------------------------
403 #include "wx/fontdlg.h"
404 #include "wx/fontenum.h"
406 static const wxChar
* gs_fp_es_family_labels
[] = {
407 wxT("Default"), wxT("Decorative"),
408 wxT("Roman"), wxT("Script"),
409 wxT("Swiss"), wxT("Modern"),
413 static long gs_fp_es_family_values
[] = {
414 wxDEFAULT
, wxDECORATIVE
,
419 static const wxChar
* gs_fp_es_style_labels
[] = {
426 static long gs_fp_es_style_values
[] = {
432 static const wxChar
* gs_fp_es_weight_labels
[] = {
439 static long gs_fp_es_weight_values
[] = {
445 // Class body is in advprops.h
448 WX_PG_IMPLEMENT_PROPERTY_CLASS(wxFontProperty
,wxPGProperty
,
449 wxFont
,const wxFont
&,TextCtrlAndButton
)
452 wxFontProperty::wxFontProperty( const wxString
& label
, const wxString
& name
,
453 const wxFont
& value
)
454 : wxPGProperty(label
,name
)
456 SetValue(WXVARIANT(value
));
458 // Initialize font family choices list
459 if ( !wxPGGlobalVars
->m_fontFamilyChoices
)
461 wxFontEnumerator enumerator
;
462 enumerator
.EnumerateFacenames();
464 #if wxMINOR_VERSION > 6
465 wxArrayString faceNames
= enumerator
.GetFacenames();
467 wxArrayString
& faceNames
= *enumerator
.GetFacenames();
472 wxPGGlobalVars
->m_fontFamilyChoices
= new wxPGChoices(faceNames
);
475 wxString
emptyString(wxEmptyString
);
480 SetParentalType(wxPG_PROP_AGGREGATE
);
482 AddChild( new wxIntProperty( _("Point Size"), wxS("Point Size"),(long)font
.GetPointSize() ) );
484 AddChild( new wxEnumProperty(_("Family"), wxS("PointSize"),
485 gs_fp_es_family_labels
,gs_fp_es_family_values
,
488 wxString faceName
= font
.GetFaceName();
489 // If font was not in there, add it now
490 if ( faceName
.length() &&
491 wxPGGlobalVars
->m_fontFamilyChoices
->Index(faceName
) == wxNOT_FOUND
)
492 wxPGGlobalVars
->m_fontFamilyChoices
->AddAsSorted(faceName
);
494 wxPGProperty
* p
= new wxEnumProperty(_("Face Name"), wxS("Face Name"),
495 *wxPGGlobalVars
->m_fontFamilyChoices
);
497 p
->SetValueFromString(faceName
, wxPG_FULL_VALUE
);
501 AddChild( new wxEnumProperty(_("Style"), wxS("Style"),
502 gs_fp_es_style_labels
,gs_fp_es_style_values
,font
.GetStyle()) );
504 AddChild( new wxEnumProperty(_("Weight"), wxS("Weight"),
505 gs_fp_es_weight_labels
,gs_fp_es_weight_values
,font
.GetWeight()) );
507 AddChild( new wxBoolProperty(_("Underlined"), wxS("Underlined"),
508 font
.GetUnderlined()) );
511 wxFontProperty::~wxFontProperty() { }
513 void wxFontProperty::OnSetValue()
520 font
= wxFont(10,wxSWISS
,wxNORMAL
,wxNORMAL
);
525 wxString
wxFontProperty::GetValueAsString( int argFlags
) const
527 return wxPGProperty::GetValueAsString(argFlags
);
530 bool wxFontProperty::OnEvent( wxPropertyGrid
* propgrid
, wxWindow
* WXUNUSED(primary
),
533 if ( propgrid
->IsMainButtonEvent(event
) )
535 // Update value from last minute changes
536 wxVariant useValue
= propgrid
->GetUncommittedPropertyValue();
541 data
.SetInitialFont( font
);
542 data
.SetColour(*wxBLACK
);
544 wxFontDialog
dlg(propgrid
, data
);
545 if ( dlg
.ShowModal() == wxID_OK
)
547 propgrid
->EditorsValueWasModified();
550 variant
<< dlg
.GetFontData().GetChosenFont();
551 SetValueInEvent( variant
);
558 void wxFontProperty::RefreshChildren()
560 if ( !GetChildCount() ) return;
563 Item(0)->SetValue( (long)font
.GetPointSize() );
564 Item(1)->SetValue( (long)font
.GetFamily() );
565 Item(2)->SetValueFromString( font
.GetFaceName(), wxPG_FULL_VALUE
);
566 Item(3)->SetValue( (long)font
.GetStyle() );
567 Item(4)->SetValue( (long)font
.GetWeight() );
568 Item(5)->SetValue( font
.GetUnderlined() );
571 void wxFontProperty::ChildChanged( wxVariant
& thisValue
, int ind
, wxVariant
& childValue
) const
578 font
.SetPointSize( wxPGVariantToInt(childValue
) );
582 int fam
= childValue
.GetLong();
583 if ( fam
< wxDEFAULT
||
586 font
.SetFamily( fam
);
591 int faceIndex
= childValue
.GetLong();
593 if ( faceIndex
>= 0 )
594 faceName
= wxPGGlobalVars
->m_fontFamilyChoices
->GetLabel(faceIndex
);
596 font
.SetFaceName( faceName
);
600 int st
= childValue
.GetLong();
601 if ( st
!= wxFONTSTYLE_NORMAL
&&
602 st
!= wxFONTSTYLE_SLANT
&&
603 st
!= wxFONTSTYLE_ITALIC
)
604 st
= wxFONTWEIGHT_NORMAL
;
609 int wt
= childValue
.GetLong();
610 if ( wt
!= wxFONTWEIGHT_NORMAL
&&
611 wt
!= wxFONTWEIGHT_LIGHT
&&
612 wt
!= wxFONTWEIGHT_BOLD
)
613 wt
= wxFONTWEIGHT_NORMAL
;
614 font
.SetWeight( wt
);
618 font
.SetUnderlined( childValue
.GetBool() );
625 wxSize wxFontProperty::OnMeasureImage() const
627 return wxSize(-1,-1);
630 void wxFontProperty::OnCustomPaint(wxDC& dc,
632 wxPGPaintData& paintData)
635 if ( paintData.m_choiceItem >= 0 )
636 drawFace = wxPGGlobalVars->m_fontFamilyChoices->GetLabel(paintData.m_choiceItem);
638 drawFace = m_value_wxFont.GetFaceName();
640 if ( drawFace.length() )
642 // Draw the background
643 dc.SetBrush( wxColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)) );
644 //dc.SetBrush( *wxWHITE_BRUSH );
645 //dc.SetPen( *wxMEDIUM_GREY_PEN );
646 dc.DrawRectangle( rect );
648 wxFont oldFont = dc.GetFont();
649 wxFont drawFont(oldFont.GetPointSize(),
650 wxDEFAULT,wxNORMAL,wxBOLD,false,drawFace);
651 dc.SetFont(drawFont);
653 dc.SetTextForeground( wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT) );
654 dc.DrawText( wxT("Aa"), rect.x+2, rect.y+1 );
660 // No file - just draw a white box
661 dc.SetBrush ( *wxWHITE_BRUSH );
662 dc.DrawRectangle ( rect );
668 // -----------------------------------------------------------------------
669 // wxSystemColourProperty
670 // -----------------------------------------------------------------------
672 // wxEnumProperty based classes cannot use wxPG_PROP_CLASS_SPECIFIC_1
673 #define wxPG_PROP_HIDE_CUSTOM_COLOUR wxPG_PROP_CLASS_SPECIFIC_2
675 #include "wx/colordlg.h"
677 //#define wx_cp_es_syscolours_len 25
678 static const wxChar
* gs_cp_es_syscolour_labels
[] = {
681 wxT("ActiveCaption"),
683 wxT("ButtonHighlight"),
692 wxT("HighlightText"),
693 wxT("InactiveBorder"),
694 wxT("InactiveCaption"),
695 wxT("InactiveCaptionText"),
707 static long gs_cp_es_syscolour_values
[] = {
708 wxSYS_COLOUR_APPWORKSPACE
,
709 wxSYS_COLOUR_ACTIVEBORDER
,
710 wxSYS_COLOUR_ACTIVECAPTION
,
711 wxSYS_COLOUR_BTNFACE
,
712 wxSYS_COLOUR_BTNHIGHLIGHT
,
713 wxSYS_COLOUR_BTNSHADOW
,
714 wxSYS_COLOUR_BTNTEXT
,
715 wxSYS_COLOUR_CAPTIONTEXT
,
716 wxSYS_COLOUR_3DDKSHADOW
,
717 wxSYS_COLOUR_3DLIGHT
,
718 wxSYS_COLOUR_BACKGROUND
,
719 wxSYS_COLOUR_GRAYTEXT
,
720 wxSYS_COLOUR_HIGHLIGHT
,
721 wxSYS_COLOUR_HIGHLIGHTTEXT
,
722 wxSYS_COLOUR_INACTIVEBORDER
,
723 wxSYS_COLOUR_INACTIVECAPTION
,
724 wxSYS_COLOUR_INACTIVECAPTIONTEXT
,
726 wxSYS_COLOUR_SCROLLBAR
,
728 wxSYS_COLOUR_INFOTEXT
,
730 wxSYS_COLOUR_WINDOWFRAME
,
731 wxSYS_COLOUR_WINDOWTEXT
,
736 IMPLEMENT_VARIANT_OBJECT_EXPORTED_SHALLOWCMP(wxColourPropertyValue
, WXDLLIMPEXP_PROPGRID
)
739 // Class body is in advprops.h
741 WX_PG_IMPLEMENT_PROPERTY_CLASS(wxSystemColourProperty
,wxEnumProperty
,
742 wxColourPropertyValue
,const wxColourPropertyValue
&,Choice
)
745 void wxSystemColourProperty::Init( int type
, const wxColour
& colour
)
747 wxColourPropertyValue cpv
;
750 cpv
.Init( type
, colour
);
752 cpv
.Init( type
, *wxWHITE
);
754 m_flags
|= wxPG_PROP_STATIC_CHOICES
; // Colour selection cannot be changed.
762 static wxPGChoices gs_wxSystemColourProperty_choicesCache
;
765 wxSystemColourProperty::wxSystemColourProperty( const wxString
& label
, const wxString
& name
,
766 const wxColourPropertyValue
& value
)
767 : wxEnumProperty( label
,
769 gs_cp_es_syscolour_labels
,
770 gs_cp_es_syscolour_values
,
771 &gs_wxSystemColourProperty_choicesCache
)
774 Init( value
.m_type
, value
.m_colour
);
776 Init( wxPG_COLOUR_CUSTOM
, *wxWHITE
);
780 wxSystemColourProperty::wxSystemColourProperty( const wxString
& label
, const wxString
& name
,
781 const wxChar
** labels
, const long* values
, wxPGChoices
* choicesCache
,
782 const wxColourPropertyValue
& value
)
783 : wxEnumProperty( label
, name
, labels
, values
, choicesCache
)
786 Init( value
.m_type
, value
.m_colour
);
788 Init( wxPG_COLOUR_CUSTOM
, *wxWHITE
);
792 wxSystemColourProperty::wxSystemColourProperty( const wxString
& label
, const wxString
& name
,
793 const wxChar
** labels
, const long* values
, wxPGChoices
* choicesCache
,
794 const wxColour
& value
)
795 : wxEnumProperty( label
, name
, labels
, values
, choicesCache
)
798 Init( wxPG_COLOUR_CUSTOM
, value
);
800 Init( wxPG_COLOUR_CUSTOM
, *wxWHITE
);
804 wxSystemColourProperty::~wxSystemColourProperty() { }
807 wxColourPropertyValue
wxSystemColourProperty::GetVal( const wxVariant
* pVariant
) const
812 if ( pVariant
->IsNull() )
813 return wxColourPropertyValue(wxPG_COLOUR_UNSPECIFIED
, wxColour());
815 if ( pVariant
->GetType() == wxS("wxColourPropertyValue") )
817 wxColourPropertyValue v
;
823 bool variantProcessed
= true;
825 if ( pVariant
->GetType() == wxS("wxColour*") )
827 wxColour
* pCol
= wxStaticCast(pVariant
->GetWxObjectPtr(), wxColour
);
830 else if ( pVariant
->GetType() == wxS("wxColour") )
834 else if ( pVariant
->GetType() == wxArrayInt_VariantType
)
836 // This code is mostly needed for wxPython bindings, which
837 // may offer tuple of integers as colour value.
841 if ( arr
.size() >= 3 )
849 if ( arr
.size() >= 4 )
852 col
= wxColour(r
, g
, b
, a
);
856 variantProcessed
= false;
861 variantProcessed
= false;
864 if ( !variantProcessed
)
865 return wxColourPropertyValue(wxPG_COLOUR_UNSPECIFIED
, wxColour());
867 wxColourPropertyValue
v2( wxPG_COLOUR_CUSTOM
, col
);
869 int colInd
= ColToInd(col
);
870 if ( colInd
!= wxNOT_FOUND
)
876 wxVariant
wxSystemColourProperty::DoTranslateVal( wxColourPropertyValue
& v
) const
883 int wxSystemColourProperty::ColToInd( const wxColour
& colour
) const
886 size_t i_max
= m_choices
.GetCount() - 1;
888 for ( i
=0; i
<i_max
; i
++ )
890 int ind
= m_choices
[i
].GetValue();
892 if ( colour
== GetColour(ind
) )
894 /*wxLogDebug(wxT("%s(%s): Index %i for ( getcolour(%i,%i,%i), colour(%i,%i,%i))"),
895 GetClassName(),GetLabel().c_str(),
896 (int)i,(int)GetColour(ind).Red(),(int)GetColour(ind).Green(),(int)GetColour(ind).Blue(),
897 (int)colour.Red(),(int)colour.Green(),(int)colour.Blue());*/
905 static inline wxColour
wxColourFromPGLong( long col
)
907 return wxColour((col
&0xFF),((col
>>8)&0xFF),((col
>>16)&0xFF));
911 void wxSystemColourProperty::OnSetValue()
913 // Convert from generic wxobject ptr to wxPGVariantDataColour
914 if ( m_value
.GetType() == wxS("wxColour*") )
916 wxColour
* pCol
= wxStaticCast(m_value
.GetWxObjectPtr(), wxColour
);
920 wxColourPropertyValue val
= GetVal(&m_value
);
922 if ( val
.m_type
== wxPG_COLOUR_UNSPECIFIED
)
930 if ( val
.m_type
< wxPG_COLOUR_WEB_BASE
)
931 val
.m_colour
= GetColour( val
.m_type
);
933 m_value
= TranslateVal(val
);
938 if ( m_value
.GetType() == wxS("wxColourPropertyValue") )
940 wxColourPropertyValue cpv
;
942 wxColour col
= cpv
.m_colour
;
946 SetValueToUnspecified();
947 SetIndex(wxNOT_FOUND
);
951 if ( cpv
.m_type
< wxPG_COLOUR_WEB_BASE
)
953 if ( m_choices
.HasValues() )
954 ind
= GetIndexForValue(cpv
.m_type
);
960 cpv
.m_type
= wxPG_COLOUR_CUSTOM
;
961 ind
= GetCustomColourIndex();
971 SetValueToUnspecified();
972 SetIndex(wxNOT_FOUND
);
978 if ( ind
== wxNOT_FOUND
)
979 ind
= GetCustomColourIndex();
986 wxColour
wxSystemColourProperty::GetColour( int index
) const
988 return wxSystemSettings::GetColour( (wxSystemColour
)index
);
991 wxString
wxSystemColourProperty::ColourToString( const wxColour
& col
, int index
) const
993 if ( index
== wxNOT_FOUND
)
994 return wxString::Format(wxT("(%i,%i,%i)"),
999 return m_choices
.GetLabel(index
);
1002 wxString
wxSystemColourProperty::GetValueAsString( int argFlags
) const
1004 wxColourPropertyValue val
= GetVal();
1006 int ind
= GetIndex();
1008 // Always show custom colour for textctrl-editor
1009 if ( val
.m_type
== wxPG_COLOUR_CUSTOM
||
1010 ind
== GetCustomColourIndex() ||
1011 (argFlags
& wxPG_PROPERTY_SPECIFIC
) )
1013 return ColourToString(val
.m_colour
, wxNOT_FOUND
);
1017 return wxEmptyString
;
1019 return ColourToString(val
.m_colour
, ind
);
1023 wxSize
wxSystemColourProperty::OnMeasureImage( int ) const
1025 return wxPG_DEFAULT_IMAGE_SIZE
;
1029 int wxSystemColourProperty::GetCustomColourIndex() const
1031 return m_choices
.GetCount() - 1;
1035 bool wxSystemColourProperty::QueryColourFromUser( wxVariant
& variant
) const
1037 wxASSERT( m_value
.GetType() != wxPG_VARIANT_TYPE_STRING
);
1040 wxPropertyGrid
* propgrid
= GetGrid();
1041 wxASSERT( propgrid
);
1043 // Must only occur when user triggers event
1044 if ( !(propgrid
->GetInternalFlags() & wxPG_FL_IN_ONCUSTOMEDITOREVENT
) )
1047 wxColourPropertyValue val
= GetVal();
1049 val
.m_type
= wxPG_COLOUR_CUSTOM
;
1052 data
.SetChooseFull(true);
1053 data
.SetColour(val
.m_colour
);
1055 for ( i
= 0; i
< 16; i
++)
1057 wxColour
colour(i
*16, i
*16, i
*16);
1058 data
.SetCustomColour(i
, colour
);
1061 wxColourDialog
dialog(propgrid
, &data
);
1062 if ( dialog
.ShowModal() == wxID_OK
)
1064 wxColourData retData
= dialog
.GetColourData();
1065 val
.m_colour
= retData
.GetColour();
1067 variant
= DoTranslateVal(val
);
1069 SetValueInEvent(variant
);
1078 bool wxSystemColourProperty::IntToValue( wxVariant
& variant
, int number
, int WXUNUSED(argFlags
) ) const
1081 int type
= GetValueForIndex(index
);
1082 bool hasValue
= m_choices
[index
].HasValue();
1084 if ( ( hasValue
&& type
== wxPG_COLOUR_CUSTOM
) ||
1085 ( !hasValue
&& (index
== (int)GetCustomColourIndex() &&
1086 !(m_flags
& wxPG_PROP_HIDE_CUSTOM_COLOUR
))
1090 QueryColourFromUser(variant
);
1094 variant
= TranslateVal( type
, GetColour(type
) );
1100 // Need to do some extra event handling.
1101 bool wxSystemColourProperty::OnEvent( wxPropertyGrid
* propgrid
, wxWindow
* WXUNUSED(primary
), wxEvent
& event
)
1103 if ( propgrid
->IsMainButtonEvent(event
) )
1105 // We need to handle button click in case editor has been
1106 // switched to one that has wxButton as well.
1108 if ( QueryColourFromUser(variant
) )
1114 /*class wxPGColourPropertyRenderer : public wxPGDefaultRenderer
1117 virtual void Render( wxDC& dc, const wxRect& rect,
1118 const wxPropertyGrid* propertyGrid, wxPGProperty* property,
1119 int WXUNUSED(column), int item, int WXUNUSED(flags) ) const
1121 wxASSERT( property->IsKindOf(CLASSINFO(wxSystemColourProperty)) );
1122 wxSystemColourProperty* prop = wxStaticCast(property, wxSystemColourProperty);
1124 dc.SetPen(*wxBLACK_PEN);
1126 ( item < (int)(GetCustomColourIndex) || (prop->HasFlag(wxPG_PROP_HIDE_CUSTOM_COLOUR)))
1130 const wxArrayInt& values = prop->GetValues();
1131 if ( values.GetChildCount() )
1132 colInd = values[item];
1135 dc.SetBrush( wxColour( prop->GetColour( colInd ) ) );
1137 else if ( !prop->IsValueUnspecified() )
1138 dc.SetBrush( prop->GetVal().m_colour );
1140 dc.SetBrush( *wxWHITE );
1142 wxRect imageRect = propertyGrid->GetImageRect(property, item);
1143 wxLogDebug(wxT("%i, %i"),imageRect.x,imageRect.y);
1144 dc.DrawRectangle( rect.x+imageRect.x, rect.y+imageRect.y,
1145 imageRect.width, imageRect.height );
1149 text = property->GetValueAsString();
1151 text = property->GetChoiceString(item);
1152 DrawText( dc, rect, imageRect.width, text );
1157 wxPGColourPropertyRenderer g_wxPGColourPropertyRenderer;
1159 wxPGCellRenderer* wxSystemColourProperty::GetCellRenderer( int column ) const
1162 return &g_wxPGColourPropertyRenderer;
1163 return wxEnumProperty::GetCellRenderer(column);
1166 void wxSystemColourProperty::OnCustomPaint( wxDC
& dc
, const wxRect
& rect
,
1167 wxPGPaintData
& paintdata
)
1171 if ( paintdata
.m_choiceItem
>= 0 && paintdata
.m_choiceItem
< (int)m_choices
.GetCount() &&
1172 paintdata
.m_choiceItem
!= GetCustomColourIndex() )
1174 int colInd
= m_choices
[paintdata
.m_choiceItem
].GetValue();
1175 col
= GetColour( colInd
);
1177 else if ( !IsValueUnspecified() )
1179 col
= GetVal().m_colour
;
1185 dc
.DrawRectangle(rect
);
1190 bool wxSystemColourProperty::StringToValue( wxVariant
& value
, const wxString
& text
, int argFlags
) const
1193 // Accept colour format "[Name] [(R,G,B)]"
1194 // Name takes precedence.
1196 wxString colourName
;
1199 int ppos
= text
.Find(wxT("("));
1201 if ( ppos
== wxNOT_FOUND
)
1207 colourName
= text
.substr(0, ppos
);
1208 colourRGB
= text
.substr(ppos
, text
.length()-ppos
);
1211 // Strip spaces from extremities
1212 colourName
.Trim(true);
1213 colourName
.Trim(false);
1214 colourRGB
.Trim(true);
1216 // Validate colourRGB string - (1,1,1) is shortest allowed
1217 if ( colourRGB
.length() < 7 )
1220 if ( colourRGB
.length() == 0 && m_choices
.GetCount() &&
1221 colourName
== m_choices
.GetLabel(GetCustomColourIndex()) )
1223 if ( !(argFlags
& wxPG_EDITABLE_VALUE
))
1225 // This really should not occurr...
1231 QueryColourFromUser(value
);
1235 wxColourPropertyValue val
;
1239 if ( colourName
.length() )
1241 // Try predefined colour first
1242 bool res
= wxEnumProperty::StringToValue(value
, colourName
, argFlags
);
1243 if ( res
&& GetIndex() >= 0 )
1245 val
.m_type
= GetIndex();
1246 if ( val
.m_type
>= 0 && val
.m_type
< m_choices
.GetCount() && m_choices
[val
.m_type
].HasValue() )
1247 val
.m_type
= m_choices
[val
.m_type
].GetValue();
1249 // Get proper colour for type.
1250 val
.m_colour
= GetColour(val
.m_type
);
1255 if ( colourRGB
.length() && !done
)
1257 // Then check custom colour.
1258 val
.m_type
= wxPG_COLOUR_CUSTOM
;
1260 int r
= -1, g
= -1, b
= -1;
1261 wxSscanf(colourRGB
.c_str(),wxT("(%i,%i,%i)"),&r
,&g
,&b
);
1263 if ( r
>= 0 && r
<= 255 &&
1264 g
>= 0 && g
<= 255 &&
1265 b
>= 0 && b
<= 255 )
1267 val
.m_colour
.Set(r
,g
,b
);
1279 value
= DoTranslateVal(val
);
1286 bool wxSystemColourProperty::DoSetAttribute( const wxString
& name
, wxVariant
& value
)
1288 if ( name
== wxPG_COLOUR_ALLOW_CUSTOM
)
1290 int ival
= wxPGVariantToInt(value
);
1292 SetChoicesExclusive(); // Make sure we don't corrupt colour lists of other properties
1294 if ( ival
&& (m_flags
& wxPG_PROP_HIDE_CUSTOM_COLOUR
) )
1296 // Show custom choice
1297 m_choices
.Insert(wxT("Custom"), GetCustomColourIndex(), wxPG_COLOUR_CUSTOM
);
1298 m_flags
&= ~(wxPG_PROP_HIDE_CUSTOM_COLOUR
);
1300 else if ( !ival
&& !(m_flags
& wxPG_PROP_HIDE_CUSTOM_COLOUR
) )
1302 // Hide custom choice
1303 m_choices
.RemoveAt(GetCustomColourIndex());
1304 m_flags
|= wxPG_PROP_HIDE_CUSTOM_COLOUR
;
1312 // -----------------------------------------------------------------------
1314 // -----------------------------------------------------------------------
1316 static const wxChar
* gs_cp_es_normcolour_labels
[] = {
1336 (const wxChar
*) NULL
1339 static unsigned long gs_cp_es_normcolour_colours
[] = {
1341 wxPG_COLOUR(128,0,0),
1342 wxPG_COLOUR(0,0,128),
1343 wxPG_COLOUR(128,0,128),
1344 wxPG_COLOUR(0,128,128),
1345 wxPG_COLOUR(128,128,128),
1346 wxPG_COLOUR(0,128,0),
1347 wxPG_COLOUR(128,128,0),
1348 wxPG_COLOUR(166,124,81),
1349 wxPG_COLOUR(0,0,255),
1350 wxPG_COLOUR(255,0,255),
1351 wxPG_COLOUR(255,0,0),
1352 wxPG_COLOUR(247,148,28),
1353 wxPG_COLOUR(192,192,192),
1354 wxPG_COLOUR(0,255,0),
1355 wxPG_COLOUR(0,255,255),
1356 wxPG_COLOUR(255,255,0),
1357 wxPG_COLOUR(255,255,255),
1361 WX_PG_IMPLEMENT_PROPERTY_CLASS(wxColourProperty
, wxSystemColourProperty
,
1362 wxColour
, const wxColour
&, TextCtrlAndButton
)
1364 static wxPGChoices gs_wxColourProperty_choicesCache
;
1366 wxColourProperty::wxColourProperty( const wxString
& label
,
1367 const wxString
& name
,
1368 const wxColour
& value
)
1369 : wxSystemColourProperty(label
, name
, gs_cp_es_normcolour_labels
,
1371 &gs_wxColourProperty_choicesCache
, value
)
1375 m_flags
|= wxPG_PROP_TRANSLATE_CUSTOM
;
1378 wxColourProperty::~wxColourProperty()
1382 void wxColourProperty::Init( wxColour colour
)
1389 int ind
= ColToInd(colour
);
1391 ind
= m_choices
.GetCount() - 1;
1395 wxString
wxColourProperty::GetValueAsString( int argFlags
) const
1397 const wxPGEditor
* editor
= GetEditorClass();
1398 if ( editor
!= wxPGEditor_Choice
&&
1399 editor
!= wxPGEditor_ChoiceAndButton
&&
1400 editor
!= wxPGEditor_ComboBox
)
1401 argFlags
|= wxPG_PROPERTY_SPECIFIC
;
1403 return wxSystemColourProperty::GetValueAsString(argFlags
);
1406 wxColour
wxColourProperty::GetColour( int index
) const
1408 if ( !m_choices
.HasValue(index
) )
1410 wxASSERT( index
< (int)GetItemCount() );
1411 return gs_cp_es_normcolour_colours
[index
];
1413 return gs_cp_es_normcolour_colours
[m_choices
.GetValue(index
)];
1416 wxVariant
wxColourProperty::DoTranslateVal( wxColourPropertyValue
& v
) const
1419 variant
<< v
.m_colour
;
1423 // -----------------------------------------------------------------------
1425 // -----------------------------------------------------------------------
1427 #define wxPG_CURSOR_IMAGE_WIDTH 32
1429 #define NUM_CURSORS 28
1431 //#define wx_cp_es_syscursors_len 28
1432 static const wxChar
* gs_cp_es_syscursors_labels
[NUM_CURSORS
+1] = {
1444 wxT("Middle Button"),
1450 wxT("Question Arrow"),
1451 wxT("Right Button"),
1452 wxT("Sizing NE-SW"),
1454 wxT("Sizing NW-SE"),
1461 (const wxChar
*) NULL
1464 static long gs_cp_es_syscursors_values
[NUM_CURSORS
] = {
1467 wxCURSOR_RIGHT_ARROW
,
1474 wxCURSOR_LEFT_BUTTON
,
1476 wxCURSOR_MIDDLE_BUTTON
,
1478 wxCURSOR_PAINT_BRUSH
,
1480 wxCURSOR_POINT_LEFT
,
1481 wxCURSOR_POINT_RIGHT
,
1482 wxCURSOR_QUESTION_ARROW
,
1483 wxCURSOR_RIGHT_BUTTON
,
1495 IMPLEMENT_DYNAMIC_CLASS(wxCursorProperty
, wxEnumProperty
)
1497 wxCursorProperty::wxCursorProperty( const wxString
& label
, const wxString
& name
,
1499 : wxEnumProperty( label
,
1501 gs_cp_es_syscursors_labels
,
1502 gs_cp_es_syscursors_values
,
1505 m_flags
|= wxPG_PROP_STATIC_CHOICES
; // Cursor selection cannot be changed.
1508 wxCursorProperty::~wxCursorProperty()
1512 wxSize
wxCursorProperty::OnMeasureImage( int item
) const
1514 #if wxPG_CAN_DRAW_CURSOR
1515 if ( item
!= -1 && item
< NUM_CURSORS
)
1516 return wxSize(wxPG_CURSOR_IMAGE_WIDTH
,wxPG_CURSOR_IMAGE_WIDTH
);
1523 #if wxPG_CAN_DRAW_CURSOR
1525 void wxCursorProperty::OnCustomPaint( wxDC
& dc
,
1527 wxPGPaintData
& paintdata
)
1530 dc
.SetBrush( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE
) );
1532 if ( paintdata
.m_choiceItem
>= 0 )
1534 dc
.DrawRectangle( rect
);
1536 if ( paintdata
.m_choiceItem
< NUM_CURSORS
)
1538 wxStockCursor cursorIndex
=
1539 (wxStockCursor
) gs_cp_es_syscursors_values
[paintdata
.m_choiceItem
];
1542 if ( cursorIndex
== wxCURSOR_NONE
)
1543 cursorIndex
= wxCURSOR_ARROW
;
1545 wxCursor
cursor( cursorIndex
);
1548 HDC hDc
= (HDC
)((const wxMSWDCImpl
*)dc
.GetImpl())->GetHDC();
1552 (HICON
)cursor
.GetHandle(),
1557 DI_COMPAT
| DI_DEFAULTSIZE
| DI_NORMAL
1566 void wxCursorProperty::OnCustomPaint( wxDC
&, const wxRect
&, wxPGPaintData
& ) { }
1567 /*wxPGCellRenderer* wxCursorProperty::GetCellRenderer( int column ) const
1569 return wxEnumProperty::GetCellRenderer(column);
1573 // -----------------------------------------------------------------------
1574 // wxImageFileProperty
1575 // -----------------------------------------------------------------------
1579 const wxString
& wxPGGetDefaultImageWildcard()
1581 // Form the wildcard, if not done yet
1582 if ( !wxPGGlobalVars
->m_pDefaultImageWildcard
.length() )
1587 // TODO: This section may require locking (using global).
1589 wxList
& handlers
= wxImage::GetHandlers();
1591 wxList::iterator node
;
1593 // Let's iterate over the image handler list.
1594 //for ( wxList::Node *node = handlers.GetFirst(); node; node = node->GetNext() )
1595 for ( node
= handlers
.begin(); node
!= handlers
.end(); node
++ )
1597 wxImageHandler
*handler
= (wxImageHandler
*)*node
;
1599 wxString ext_lo
= handler
->GetExtension();
1600 wxString ext_up
= ext_lo
.Upper();
1602 str
.append( ext_up
);
1603 str
.append( wxT(" files (*.") );
1604 str
.append( ext_up
);
1605 str
.append( wxT(")|*.") );
1606 str
.append( ext_lo
);
1607 str
.append( wxT("|") );
1610 str
.append ( wxT("All files (*.*)|*.*") );
1612 wxPGGlobalVars
->m_pDefaultImageWildcard
= str
;
1615 return wxPGGlobalVars
->m_pDefaultImageWildcard
;
1618 IMPLEMENT_DYNAMIC_CLASS(wxImageFileProperty
, wxFileProperty
)
1620 wxImageFileProperty::wxImageFileProperty( const wxString
& label
, const wxString
& name
,
1621 const wxString
& value
)
1622 : wxFileProperty(label
,name
,value
)
1624 SetAttribute( wxPG_FILE_WILDCARD
, wxPGGetDefaultImageWildcard() );
1626 m_pImage
= (wxImage
*) NULL
;
1627 m_pBitmap
= (wxBitmap
*) NULL
;
1630 wxImageFileProperty::~wxImageFileProperty()
1638 void wxImageFileProperty::OnSetValue()
1640 wxFileProperty::OnSetValue();
1654 // Create the image thumbnail
1655 if ( m_filename
.FileExists() )
1657 m_pImage
= new wxImage( m_filename
.GetFullPath() );
1661 wxSize
wxImageFileProperty::OnMeasureImage( int ) const
1663 return wxPG_DEFAULT_IMAGE_SIZE
;
1666 void wxImageFileProperty::OnCustomPaint( wxDC
& dc
,
1670 if ( m_pBitmap
|| (m_pImage
&& m_pImage
->Ok() ) )
1672 // Draw the thumbnail
1674 // Create the bitmap here because required size is not known in OnSetValue().
1677 m_pImage
->Rescale( rect
.width
, rect
.height
);
1678 m_pBitmap
= new wxBitmap( *m_pImage
);
1683 dc
.DrawBitmap( *m_pBitmap
, rect
.x
, rect
.y
, false );
1687 // No file - just draw a white box
1688 dc
.SetBrush( *wxWHITE_BRUSH
);
1689 dc
.DrawRectangle ( rect
);
1693 #endif // wxUSE_IMAGE
1695 // -----------------------------------------------------------------------
1696 // wxMultiChoiceProperty
1697 // -----------------------------------------------------------------------
1701 #include "wx/choicdlg.h"
1703 WX_PG_IMPLEMENT_PROPERTY_CLASS(wxMultiChoiceProperty
,wxPGProperty
,
1704 wxArrayInt
,const wxArrayInt
&,TextCtrlAndButton
)
1706 wxMultiChoiceProperty::wxMultiChoiceProperty( const wxString
& label
,
1707 const wxString
& name
,
1708 const wxPGChoices
& choices
,
1709 const wxArrayString
& value
)
1710 : wxPGProperty(label
,name
)
1712 m_choices
.Assign(choices
);
1716 wxMultiChoiceProperty::wxMultiChoiceProperty( const wxString
& label
,
1717 const wxString
& name
,
1718 const wxArrayString
& strings
,
1719 const wxArrayString
& value
)
1720 : wxPGProperty(label
,name
)
1722 m_choices
.Set(strings
);
1726 wxMultiChoiceProperty::wxMultiChoiceProperty( const wxString
& label
,
1727 const wxString
& name
,
1728 const wxArrayString
& value
)
1729 : wxPGProperty(label
,name
)
1731 wxArrayString strings
;
1732 m_choices
.Set(strings
);
1736 wxMultiChoiceProperty::~wxMultiChoiceProperty()
1740 void wxMultiChoiceProperty::OnSetValue()
1742 GenerateValueAsString();
1745 wxString
wxMultiChoiceProperty::GetValueAsString( int ) const
1750 void wxMultiChoiceProperty::GenerateValueAsString()
1752 wxArrayString strings
;
1754 if ( m_value
.GetType() == wxPG_VARIANT_TYPE_ARRSTRING
)
1755 strings
= m_value
.GetArrayString();
1757 wxString
& tempStr
= m_display
;
1759 unsigned int itemCount
= strings
.size();
1764 tempStr
.append( wxT("\"") );
1766 for ( i
= 0; i
< itemCount
; i
++ )
1768 tempStr
.append( strings
[i
] );
1769 tempStr
.append( wxT("\"") );
1770 if ( i
< (itemCount
-1) )
1771 tempStr
.append ( wxT(" \"") );
1775 wxArrayInt
wxMultiChoiceProperty::GetValueAsIndices() const
1777 const wxArrayInt
& valueArr
= wxArrayIntRefFromVariant(GetValue());
1780 // Translate values to string indices.
1781 wxArrayInt selections
;
1783 if ( !m_choices
.IsOk() || !m_choices
.GetCount() || !(&valueArr
) )
1785 for ( i
=0; i
<valueArr
.size(); i
++ )
1790 for ( i
=0; i
<valueArr
.size(); i
++ )
1792 int sIndex
= m_choices
.Index(valueArr
[i
]);
1794 selections
.Add(sIndex
);
1801 bool wxMultiChoiceProperty::OnEvent( wxPropertyGrid
* propgrid
,
1802 wxWindow
* WXUNUSED(primary
),
1805 if ( propgrid
->IsMainButtonEvent(event
) )
1808 wxVariant useValue
= propgrid
->GetUncommittedPropertyValue();
1810 wxArrayString labels
= m_choices
.GetLabels();
1811 unsigned int choiceCount
;
1813 if ( m_choices
.IsOk() )
1814 choiceCount
= m_choices
.GetCount();
1818 // launch editor dialog
1819 wxMultiChoiceDialog
dlg( propgrid
,
1820 _("Make a selection:"),
1823 choiceCount
?&labels
[0]:NULL
,
1824 wxCHOICEDLG_STYLE
);
1826 dlg
.Move( propgrid
->GetGoodEditorDialogPosition(this,dlg
.GetSize()) );
1828 wxArrayString strings
= useValue
.GetArrayString();
1829 wxArrayString extraStrings
;
1831 dlg
.SetSelections(m_choices
.GetIndicesForStrings(strings
, &extraStrings
));
1833 if ( dlg
.ShowModal() == wxID_OK
&& choiceCount
)
1835 int userStringMode
= GetAttributeAsLong(wxT("UserStringMode"), 0);
1837 wxArrayInt arrInt
= dlg
.GetSelections();
1841 // Strings that were not in list of choices
1842 wxArrayString value
;
1844 // Translate string indices to strings
1847 if ( userStringMode
== 1 )
1849 for (n
=0;n
<extraStrings
.size();n
++)
1850 value
.push_back(extraStrings
[n
]);
1854 for ( i
=0; i
<arrInt
.size(); i
++ )
1855 value
.Add(m_choices
.GetLabel(arrInt
.Item(i
)));
1857 if ( userStringMode
== 2 )
1859 for (n
=0;n
<extraStrings
.size();n
++)
1860 value
.push_back(extraStrings
[n
]);
1863 variant
= WXVARIANT(value
);
1865 SetValueInEvent(variant
);
1873 bool wxMultiChoiceProperty::StringToValue( wxVariant
& variant
, const wxString
& text
, int ) const
1877 int userStringMode
= GetAttributeAsLong(wxT("UserStringMode"), 0);
1879 WX_PG_TOKENIZER2_BEGIN(text
,wxT('"'))
1880 if ( userStringMode
> 0 || (m_choices
.IsOk() && m_choices
.Index( token
) != wxNOT_FOUND
) )
1882 WX_PG_TOKENIZER2_END()
1884 wxVariant
v( WXVARIANT(arr
) );
1890 #endif // wxUSE_CHOICEDLG
1893 // -----------------------------------------------------------------------
1895 // -----------------------------------------------------------------------
1900 #if wxUSE_DATEPICKCTRL
1901 #define dtCtrl DatePickerCtrl
1903 #define dtCtrl TextCtrl
1906 WX_PG_IMPLEMENT_PROPERTY_CLASS(wxDateProperty
,
1913 wxString
wxDateProperty::ms_defaultDateFormat
;
1916 wxDateProperty::wxDateProperty( const wxString
& label
,
1917 const wxString
& name
,
1918 const wxDateTime
& value
)
1919 : wxPGProperty(label
,name
)
1921 //wxPGRegisterDefaultValueType(wxDateTime)
1923 #if wxUSE_DATEPICKCTRL
1924 wxPGRegisterEditorClass(DatePickerCtrl
);
1926 m_dpStyle
= wxDP_DEFAULT
| wxDP_SHOWCENTURY
;
1934 wxDateProperty::~wxDateProperty()
1938 bool wxDateProperty::StringToValue( wxVariant
& variant
, const wxString
& text
,
1939 int WXUNUSED(argFlags
) ) const
1943 const char* c
= dt
.ParseFormat(text
, wxString(wxDefaultDateTimeFormat
), wxDefaultDateTime
, NULL
);
1954 wxString
wxDateProperty::GetValueAsString( int argFlags
) const
1956 const wxChar
* format
= (const wxChar
*) NULL
;
1958 wxDateTime dateTime
= m_value
.GetDateTime();
1960 if ( !dateTime
.IsValid() )
1961 return wxT("Invalid");
1963 if ( !ms_defaultDateFormat
.length() )
1965 #if wxUSE_DATEPICKCTRL
1966 bool showCentury
= m_dpStyle
& wxDP_SHOWCENTURY
? true : false;
1968 bool showCentury
= true;
1970 ms_defaultDateFormat
= DetermineDefaultDateFormat( showCentury
);
1973 if ( m_format
.length() &&
1974 !(argFlags
& wxPG_FULL_VALUE
) )
1975 format
= m_format
.c_str();
1977 // Determine default from locale
1978 // NB: This is really simple stuff, but can't figure anything
1979 // better without proper support in wxLocale
1981 format
= ms_defaultDateFormat
.c_str();
1983 return dateTime
.Format(format
);
1986 wxString
wxDateProperty::DetermineDefaultDateFormat( bool showCentury
)
1988 // This code is basicly copied from datectlg.cpp's SetFormat
1993 dt
.ParseFormat(wxT("2003-10-13"), wxT("%Y-%m-%d"));
1994 wxString
str(dt
.Format(wxT("%x")));
1996 const wxChar
*p
= str
.c_str();
2000 if (n
== dt
.GetDay())
2002 format
.Append(wxT("%d"));
2005 else if (n
== (int)dt
.GetMonth()+1)
2007 format
.Append(wxT("%m"));
2010 else if (n
== dt
.GetYear())
2012 format
.Append(wxT("%Y"));
2015 else if (n
== (dt
.GetYear() % 100))
2018 format
.Append(wxT("%Y"));
2020 format
.Append(wxT("%y"));
2024 format
.Append(*p
++);
2030 bool wxDateProperty::DoSetAttribute( const wxString
& name
, wxVariant
& value
)
2032 if ( name
== wxPG_DATE_FORMAT
)
2034 m_format
= value
.GetString();
2037 else if ( name
== wxPG_DATE_PICKER_STYLE
)
2039 m_dpStyle
= value
.GetLong();
2040 ms_defaultDateFormat
.clear(); // This may need recalculation
2046 #endif // wxUSE_DATETIME
2049 // -----------------------------------------------------------------------
2050 // wxPropertyGridInterface
2051 // -----------------------------------------------------------------------
2053 void wxPropertyGridInterface::InitAllTypeHandlers()
2057 // -----------------------------------------------------------------------
2059 void wxPropertyGridInterface::RegisterAdditionalEditors()
2061 // Register editor classes, if necessary.
2062 if ( wxPGGlobalVars
->m_mapEditorClasses
.empty() )
2063 wxPropertyGrid::RegisterDefaultEditors();
2066 wxPGRegisterEditorClass(SpinCtrl
);
2068 #if wxUSE_DATEPICKCTRL
2069 wxPGRegisterEditorClass(DatePickerCtrl
);
2073 // -----------------------------------------------------------------------
2075 #endif // wxPG_INCLUDE_ADVPROPS
2077 #endif // wxUSE_PROPGRID