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 // Implement dynamic class for type value.
84 IMPLEMENT_DYNAMIC_CLASS(wxColourPropertyValue
, wxObject
)
86 bool operator == (const wxColourPropertyValue
& a
, const wxColourPropertyValue
& b
)
88 return ( ( a
.m_colour
== b
.m_colour
) && (a
.m_type
== b
.m_type
) );
91 bool operator == (const wxArrayInt
& array1
, const wxArrayInt
& array2
)
93 if ( array1
.size() != array2
.size() )
96 for ( i
=0; i
<array1
.size(); i
++ )
98 if ( array1
[i
] != array2
[i
] )
104 // -----------------------------------------------------------------------
105 // wxSpinCtrl-based property editor
106 // -----------------------------------------------------------------------
111 WX_PG_IMPLEMENT_INTERNAL_EDITOR_CLASS(SpinCtrl
,
116 // Trivial destructor.
117 wxPGSpinCtrlEditor::~wxPGSpinCtrlEditor()
122 // Create controls and initialize event handling.
123 wxPGWindowList
wxPGSpinCtrlEditor::CreateControls( wxPropertyGrid
* propgrid
, wxPGProperty
* property
,
124 const wxPoint
& pos
, const wxSize
& sz
) const
126 const int margin
= 1;
127 wxSize
butSz(18, sz
.y
);
128 wxSize
tcSz(sz
.x
- butSz
.x
- margin
, sz
.y
);
129 wxPoint
butPos(pos
.x
+ tcSz
.x
+ margin
, pos
.y
);
131 wxSpinButton
* wnd2
= new wxSpinButton();
135 wnd2
->Create( propgrid
->GetPanel(), wxPG_SUBID2
, butPos
, butSz
, wxSP_VERTICAL
);
137 wnd2
->SetRange( INT_MIN
, INT_MAX
);
140 // Let's add validator to make sure only numbers can be entered
141 wxTextValidator
validator(wxFILTER_NUMERIC
, &m_tempString
);
143 wxTextCtrl
* wnd1
= (wxTextCtrl
*) wxPGTextCtrlEditor::CreateControls( propgrid
, property
, pos
, tcSz
).m_primary
;
144 wnd1
->SetValidator(validator
);
146 return wxPGWindowList(wnd1
, wnd2
);
149 // Control's events are redirected here
150 bool wxPGSpinCtrlEditor::OnEvent( wxPropertyGrid
* propgrid
, wxPGProperty
* property
,
151 wxWindow
* wnd
, wxEvent
& event
) const
153 int evtType
= event
.GetEventType();
155 bool bigStep
= false;
157 if ( evtType
== wxEVT_KEY_DOWN
)
159 wxKeyEvent
& keyEvent
= (wxKeyEvent
&)event
;
160 keycode
= keyEvent
.GetKeyCode();
162 if ( keycode
== WXK_UP
)
163 evtType
= wxEVT_SCROLL_LINEUP
;
164 else if ( keycode
== WXK_DOWN
)
165 evtType
= wxEVT_SCROLL_LINEDOWN
;
166 else if ( keycode
== WXK_PAGEUP
)
168 evtType
= wxEVT_SCROLL_LINEUP
;
171 else if ( keycode
== WXK_PAGEDOWN
)
173 evtType
= wxEVT_SCROLL_LINEDOWN
;
178 if ( evtType
== wxEVT_SCROLL_LINEUP
|| evtType
== wxEVT_SCROLL_LINEDOWN
)
181 // Can't use wnd since it might be clipper window
182 wxTextCtrl
* tc
= wxDynamicCast(propgrid
->GetEditorControl(), wxTextCtrl
);
187 s
= property
->GetValueAsString(wxPG_FULL_VALUE
);
189 int mode
= wxPG_PROPERTY_VALIDATION_SATURATE
;
191 if ( property
->GetAttributeAsLong(wxT("Wrap"), 0) )
192 mode
= wxPG_PROPERTY_VALIDATION_WRAP
;
194 if ( property
->GetValueType() == wxT("double") )
197 double step
= property
->GetAttributeAsDouble(wxT("Step"), 1.0);
200 if ( s
.ToDouble(&v_d
) )
205 if ( evtType
== wxEVT_SCROLL_LINEUP
) v_d
+= step
;
209 wxFloatProperty::DoValidation(property
, v_d
, NULL
, mode
);
211 wxPropertyGrid::DoubleToString(s
, v_d
, 6, true, NULL
);
221 wxLongLong_t step
= property
->GetAttributeAsLong(wxT("Step"), 1);
224 if ( s
.ToLongLong(&v_ll
, 10) )
229 if ( evtType
== wxEVT_SCROLL_LINEUP
) v_ll
+= step
;
233 wxIntProperty::DoValidation(property
, v_ll
, NULL
, mode
);
235 s
= wxLongLong(v_ll
).ToString();
245 int ip
= tc
->GetInsertionPoint();
246 int lp
= tc
->GetLastPosition();
248 tc
->SetInsertionPoint(ip
+(tc
->GetLastPosition()-lp
));
254 return wxPGTextCtrlEditor::OnEvent(propgrid
,property
,wnd
,event
);
257 #endif // wxUSE_SPINBTN
260 // -----------------------------------------------------------------------
261 // wxDatePickerCtrl-based property editor
262 // -----------------------------------------------------------------------
264 #if wxUSE_DATEPICKCTRL
267 #include "wx/datectrl.h"
268 #include "wx/dateevt.h"
270 class wxPGDatePickerCtrlEditor
: public wxPGEditor
272 DECLARE_DYNAMIC_CLASS(wxPGDatePickerCtrlEditor
)
274 virtual ~wxPGDatePickerCtrlEditor();
276 wxString
GetName() const;
277 virtual wxPGWindowList
CreateControls(wxPropertyGrid
* propgrid
,
278 wxPGProperty
* property
,
280 const wxSize
& size
) const;
281 virtual void UpdateControl( wxPGProperty
* property
, wxWindow
* wnd
) const;
282 virtual bool OnEvent( wxPropertyGrid
* propgrid
, wxPGProperty
* property
,
283 wxWindow
* wnd
, wxEvent
& event
) const;
284 virtual bool GetValueFromControl( wxVariant
& variant
, wxPGProperty
* property
, wxWindow
* wnd
) const;
285 virtual void SetValueToUnspecified( wxPGProperty
* WXUNUSED(property
), wxWindow
* wnd
) const;
289 WX_PG_IMPLEMENT_INTERNAL_EDITOR_CLASS(DatePickerCtrl
,
290 wxPGDatePickerCtrlEditor
,
294 wxPGDatePickerCtrlEditor::~wxPGDatePickerCtrlEditor()
298 wxPGWindowList
wxPGDatePickerCtrlEditor::CreateControls( wxPropertyGrid
* propgrid
,
299 wxPGProperty
* property
,
301 const wxSize
& sz
) const
303 wxCHECK_MSG( property
->IsKindOf(CLASSINFO(wxDateProperty
)),
305 wxT("DatePickerCtrl editor can only be used with wxDateProperty or derivative.") );
307 wxDateProperty
* prop
= (wxDateProperty
*) property
;
309 // Use two stage creation to allow cleaner display on wxMSW
310 wxDatePickerCtrl
* ctrl
= new wxDatePickerCtrl();
313 wxSize useSz
= wxDefaultSize
;
319 wxDateTime
dateValue(wxInvalidDateTime
);
321 wxVariant value
= prop
->GetValue();
322 if ( value
.GetType() == wxT("datetime") )
323 dateValue
= value
.GetDateTime();
325 ctrl
->Create(propgrid
->GetPanel(),
330 prop
->GetDatePickerStyle() | wxNO_BORDER
);
339 // Copies value from property to control
340 void wxPGDatePickerCtrlEditor::UpdateControl( wxPGProperty
* property
, wxWindow
* wnd
) const
342 wxDatePickerCtrl
* ctrl
= (wxDatePickerCtrl
*) wnd
;
343 wxASSERT( ctrl
&& ctrl
->IsKindOf(CLASSINFO(wxDatePickerCtrl
)) );
345 // We assume that property's data type is 'int' (or something similar),
346 // thus allowing us to get raw, unchecked value via DoGetValue.
347 ctrl
->SetValue( property
->GetValue().GetDateTime() );
350 // Control's events are redirected here
351 bool wxPGDatePickerCtrlEditor::OnEvent( wxPropertyGrid
* WXUNUSED(propgrid
),
352 wxPGProperty
* WXUNUSED(property
),
353 wxWindow
* WXUNUSED(wnd
),
354 wxEvent
& event
) const
356 if ( event
.GetEventType() == wxEVT_DATE_CHANGED
)
362 bool wxPGDatePickerCtrlEditor::GetValueFromControl( wxVariant
& variant
, wxPGProperty
* WXUNUSED(property
), wxWindow
* wnd
) const
364 wxDatePickerCtrl
* ctrl
= (wxDatePickerCtrl
*) wnd
;
365 wxASSERT( ctrl
&& ctrl
->IsKindOf(CLASSINFO(wxDatePickerCtrl
)) );
367 variant
= ctrl
->GetValue();
372 void wxPGDatePickerCtrlEditor::SetValueToUnspecified( wxPGProperty
* WXUNUSED(property
), wxWindow
* WXUNUSED(wnd
) ) const
375 //wxDateProperty* prop = (wxDateProperty*) property;
379 #endif // wxUSE_DATEPICKCTRL
382 // -----------------------------------------------------------------------
384 // -----------------------------------------------------------------------
386 #include "wx/fontdlg.h"
387 #include "wx/fontenum.h"
389 static const wxChar
* gs_fp_es_family_labels
[] = {
390 wxT("Default"), wxT("Decorative"),
391 wxT("Roman"), wxT("Script"),
392 wxT("Swiss"), wxT("Modern"),
396 static long gs_fp_es_family_values
[] = {
397 wxDEFAULT
, wxDECORATIVE
,
402 static const wxChar
* gs_fp_es_style_labels
[] = {
409 static long gs_fp_es_style_values
[] = {
415 static const wxChar
* gs_fp_es_weight_labels
[] = {
422 static long gs_fp_es_weight_values
[] = {
428 // Class body is in advprops.h
431 WX_PG_IMPLEMENT_PROPERTY_CLASS(wxFontProperty
,wxPGProperty
,
432 wxFont
,const wxFont
&,TextCtrlAndButton
)
435 wxFontProperty::wxFontProperty( const wxString
& label
, const wxString
& name
,
436 const wxFont
& value
)
437 : wxPGProperty(label
,name
)
439 SetValue(WXVARIANT(value
));
441 // Initialize font family choices list
442 if ( !wxPGGlobalVars
->m_fontFamilyChoices
)
444 wxArrayString faceNames
= wxFontEnumerator::GetFacenames();
448 wxPGGlobalVars
->m_fontFamilyChoices
= new wxPGChoices(faceNames
);
451 wxString
emptyString(wxEmptyString
);
456 SetParentalType(wxPG_PROP_AGGREGATE
);
458 AddChild( new wxIntProperty( _("Point Size"), wxS("Point Size"),(long)font
.GetPointSize() ) );
460 AddChild( new wxEnumProperty(_("Family"), wxS("PointSize"),
461 gs_fp_es_family_labels
,gs_fp_es_family_values
,
464 wxString faceName
= font
.GetFaceName();
465 // If font was not in there, add it now
466 if ( faceName
.length() &&
467 wxPGGlobalVars
->m_fontFamilyChoices
->Index(faceName
) == wxNOT_FOUND
)
468 wxPGGlobalVars
->m_fontFamilyChoices
->AddAsSorted(faceName
);
470 wxPGProperty
* p
= new wxEnumProperty(_("Face Name"), wxS("Face Name"),
471 *wxPGGlobalVars
->m_fontFamilyChoices
);
473 p
->SetValueFromString(faceName
, wxPG_FULL_VALUE
);
477 AddChild( new wxEnumProperty(_("Style"), wxS("Style"),
478 gs_fp_es_style_labels
,gs_fp_es_style_values
,font
.GetStyle()) );
480 AddChild( new wxEnumProperty(_("Weight"), wxS("Weight"),
481 gs_fp_es_weight_labels
,gs_fp_es_weight_values
,font
.GetWeight()) );
483 AddChild( new wxBoolProperty(_("Underlined"), wxS("Underlined"),
484 font
.GetUnderlined()) );
487 wxFontProperty::~wxFontProperty() { }
489 void wxFontProperty::OnSetValue()
496 font
= wxFont(10,wxSWISS
,wxNORMAL
,wxNORMAL
);
501 wxString
wxFontProperty::ValueToString( wxVariant
& value
,
504 return wxPGProperty::ValueToString(value
, argFlags
);
507 bool wxFontProperty::OnEvent( wxPropertyGrid
* propgrid
, wxWindow
* WXUNUSED(primary
),
510 if ( propgrid
->IsMainButtonEvent(event
) )
512 // Update value from last minute changes
513 wxVariant useValue
= propgrid
->GetUncommittedPropertyValue();
518 data
.SetInitialFont( font
);
519 data
.SetColour(*wxBLACK
);
521 wxFontDialog
dlg(propgrid
, data
);
522 if ( dlg
.ShowModal() == wxID_OK
)
524 propgrid
->EditorsValueWasModified();
527 variant
<< dlg
.GetFontData().GetChosenFont();
528 SetValueInEvent( variant
);
535 void wxFontProperty::RefreshChildren()
537 if ( !GetChildCount() ) return;
540 Item(0)->SetValue( (long)font
.GetPointSize() );
541 Item(1)->SetValue( (long)font
.GetFamily() );
542 Item(2)->SetValueFromString( font
.GetFaceName(), wxPG_FULL_VALUE
);
543 Item(3)->SetValue( (long)font
.GetStyle() );
544 Item(4)->SetValue( (long)font
.GetWeight() );
545 Item(5)->SetValue( font
.GetUnderlined() );
548 void wxFontProperty::ChildChanged( wxVariant
& thisValue
, int ind
, wxVariant
& childValue
) const
555 font
.SetPointSize( wxPGVariantToInt(childValue
) );
559 int fam
= childValue
.GetLong();
560 if ( fam
< wxDEFAULT
||
563 font
.SetFamily( fam
);
568 int faceIndex
= childValue
.GetLong();
570 if ( faceIndex
>= 0 )
571 faceName
= wxPGGlobalVars
->m_fontFamilyChoices
->GetLabel(faceIndex
);
573 font
.SetFaceName( faceName
);
577 int st
= childValue
.GetLong();
578 if ( st
!= wxFONTSTYLE_NORMAL
&&
579 st
!= wxFONTSTYLE_SLANT
&&
580 st
!= wxFONTSTYLE_ITALIC
)
581 st
= wxFONTWEIGHT_NORMAL
;
586 int wt
= childValue
.GetLong();
587 if ( wt
!= wxFONTWEIGHT_NORMAL
&&
588 wt
!= wxFONTWEIGHT_LIGHT
&&
589 wt
!= wxFONTWEIGHT_BOLD
)
590 wt
= wxFONTWEIGHT_NORMAL
;
591 font
.SetWeight( wt
);
595 font
.SetUnderlined( childValue
.GetBool() );
602 wxSize wxFontProperty::OnMeasureImage() const
604 return wxSize(-1,-1);
607 void wxFontProperty::OnCustomPaint(wxDC& dc,
609 wxPGPaintData& paintData)
612 if ( paintData.m_choiceItem >= 0 )
613 drawFace = wxPGGlobalVars->m_fontFamilyChoices->GetLabel(paintData.m_choiceItem);
615 drawFace = m_value_wxFont.GetFaceName();
617 if ( drawFace.length() )
619 // Draw the background
620 dc.SetBrush( wxColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)) );
621 //dc.SetBrush( *wxWHITE_BRUSH );
622 //dc.SetPen( *wxMEDIUM_GREY_PEN );
623 dc.DrawRectangle( rect );
625 wxFont oldFont = dc.GetFont();
626 wxFont drawFont(oldFont.GetPointSize(),
627 wxDEFAULT,wxNORMAL,wxBOLD,false,drawFace);
628 dc.SetFont(drawFont);
630 dc.SetTextForeground( wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT) );
631 dc.DrawText( wxT("Aa"), rect.x+2, rect.y+1 );
637 // No file - just draw a white box
638 dc.SetBrush ( *wxWHITE_BRUSH );
639 dc.DrawRectangle ( rect );
645 // -----------------------------------------------------------------------
646 // wxSystemColourProperty
647 // -----------------------------------------------------------------------
649 // wxEnumProperty based classes cannot use wxPG_PROP_CLASS_SPECIFIC_1
650 #define wxPG_PROP_HIDE_CUSTOM_COLOUR wxPG_PROP_CLASS_SPECIFIC_2
652 #include "wx/colordlg.h"
654 //#define wx_cp_es_syscolours_len 25
655 static const wxChar
* gs_cp_es_syscolour_labels
[] = {
658 wxT("ActiveCaption"),
660 wxT("ButtonHighlight"),
669 wxT("HighlightText"),
670 wxT("InactiveBorder"),
671 wxT("InactiveCaption"),
672 wxT("InactiveCaptionText"),
684 static long gs_cp_es_syscolour_values
[] = {
685 wxSYS_COLOUR_APPWORKSPACE
,
686 wxSYS_COLOUR_ACTIVEBORDER
,
687 wxSYS_COLOUR_ACTIVECAPTION
,
688 wxSYS_COLOUR_BTNFACE
,
689 wxSYS_COLOUR_BTNHIGHLIGHT
,
690 wxSYS_COLOUR_BTNSHADOW
,
691 wxSYS_COLOUR_BTNTEXT
,
692 wxSYS_COLOUR_CAPTIONTEXT
,
693 wxSYS_COLOUR_3DDKSHADOW
,
694 wxSYS_COLOUR_3DLIGHT
,
695 wxSYS_COLOUR_BACKGROUND
,
696 wxSYS_COLOUR_GRAYTEXT
,
697 wxSYS_COLOUR_HIGHLIGHT
,
698 wxSYS_COLOUR_HIGHLIGHTTEXT
,
699 wxSYS_COLOUR_INACTIVEBORDER
,
700 wxSYS_COLOUR_INACTIVECAPTION
,
701 wxSYS_COLOUR_INACTIVECAPTIONTEXT
,
703 wxSYS_COLOUR_SCROLLBAR
,
705 wxSYS_COLOUR_INFOTEXT
,
707 wxSYS_COLOUR_WINDOWFRAME
,
708 wxSYS_COLOUR_WINDOWTEXT
,
713 IMPLEMENT_VARIANT_OBJECT_EXPORTED_SHALLOWCMP(wxColourPropertyValue
, WXDLLIMPEXP_PROPGRID
)
716 // Class body is in advprops.h
718 WX_PG_IMPLEMENT_PROPERTY_CLASS(wxSystemColourProperty
,wxEnumProperty
,
719 wxColourPropertyValue
,const wxColourPropertyValue
&,Choice
)
722 void wxSystemColourProperty::Init( int type
, const wxColour
& colour
)
724 wxColourPropertyValue cpv
;
727 cpv
.Init( type
, colour
);
729 cpv
.Init( type
, *wxWHITE
);
731 m_flags
|= wxPG_PROP_STATIC_CHOICES
; // Colour selection cannot be changed.
739 static wxPGChoices gs_wxSystemColourProperty_choicesCache
;
742 wxSystemColourProperty::wxSystemColourProperty( const wxString
& label
, const wxString
& name
,
743 const wxColourPropertyValue
& value
)
744 : wxEnumProperty( label
,
746 gs_cp_es_syscolour_labels
,
747 gs_cp_es_syscolour_values
,
748 &gs_wxSystemColourProperty_choicesCache
)
751 Init( value
.m_type
, value
.m_colour
);
753 Init( wxPG_COLOUR_CUSTOM
, *wxWHITE
);
757 wxSystemColourProperty::wxSystemColourProperty( const wxString
& label
, const wxString
& name
,
758 const wxChar
** labels
, const long* values
, wxPGChoices
* choicesCache
,
759 const wxColourPropertyValue
& value
)
760 : wxEnumProperty( label
, name
, labels
, values
, choicesCache
)
763 Init( value
.m_type
, value
.m_colour
);
765 Init( wxPG_COLOUR_CUSTOM
, *wxWHITE
);
769 wxSystemColourProperty::wxSystemColourProperty( const wxString
& label
, const wxString
& name
,
770 const wxChar
** labels
, const long* values
, wxPGChoices
* choicesCache
,
771 const wxColour
& value
)
772 : wxEnumProperty( label
, name
, labels
, values
, choicesCache
)
775 Init( wxPG_COLOUR_CUSTOM
, value
);
777 Init( wxPG_COLOUR_CUSTOM
, *wxWHITE
);
781 wxSystemColourProperty::~wxSystemColourProperty() { }
784 wxColourPropertyValue
wxSystemColourProperty::GetVal( const wxVariant
* pVariant
) const
789 if ( pVariant
->IsNull() )
790 return wxColourPropertyValue(wxPG_COLOUR_UNSPECIFIED
, wxColour());
792 if ( pVariant
->GetType() == wxS("wxColourPropertyValue") )
794 wxColourPropertyValue v
;
800 bool variantProcessed
= true;
802 if ( pVariant
->GetType() == wxS("wxColour*") )
804 wxColour
* pCol
= wxStaticCast(pVariant
->GetWxObjectPtr(), wxColour
);
807 else if ( pVariant
->GetType() == wxS("wxColour") )
811 else if ( pVariant
->GetType() == wxArrayInt_VariantType
)
813 // This code is mostly needed for wxPython bindings, which
814 // may offer tuple of integers as colour value.
818 if ( arr
.size() >= 3 )
826 if ( arr
.size() >= 4 )
829 col
= wxColour(r
, g
, b
, a
);
833 variantProcessed
= false;
838 variantProcessed
= false;
841 if ( !variantProcessed
)
842 return wxColourPropertyValue(wxPG_COLOUR_UNSPECIFIED
, wxColour());
844 wxColourPropertyValue
v2( wxPG_COLOUR_CUSTOM
, col
);
846 int colInd
= ColToInd(col
);
847 if ( colInd
!= wxNOT_FOUND
)
853 wxVariant
wxSystemColourProperty::DoTranslateVal( wxColourPropertyValue
& v
) const
860 int wxSystemColourProperty::ColToInd( const wxColour
& colour
) const
863 size_t i_max
= m_choices
.GetCount() - 1;
865 for ( i
=0; i
<i_max
; i
++ )
867 int ind
= m_choices
[i
].GetValue();
869 if ( colour
== GetColour(ind
) )
871 /*wxLogDebug(wxT("%s(%s): Index %i for ( getcolour(%i,%i,%i), colour(%i,%i,%i))"),
872 GetClassName(),GetLabel().c_str(),
873 (int)i,(int)GetColour(ind).Red(),(int)GetColour(ind).Green(),(int)GetColour(ind).Blue(),
874 (int)colour.Red(),(int)colour.Green(),(int)colour.Blue());*/
881 void wxSystemColourProperty::OnSetValue()
883 // Convert from generic wxobject ptr to wxPGVariantDataColour
884 if ( m_value
.GetType() == wxS("wxColour*") )
886 wxColour
* pCol
= wxStaticCast(m_value
.GetWxObjectPtr(), wxColour
);
890 wxColourPropertyValue val
= GetVal(&m_value
);
892 if ( val
.m_type
== wxPG_COLOUR_UNSPECIFIED
)
900 if ( val
.m_type
< wxPG_COLOUR_WEB_BASE
)
901 val
.m_colour
= GetColour( val
.m_type
);
903 m_value
= TranslateVal(val
);
906 int ind
= wxNOT_FOUND
;
908 if ( m_value
.GetType() == wxS("wxColourPropertyValue") )
910 wxColourPropertyValue cpv
;
912 wxColour col
= cpv
.m_colour
;
916 SetValueToUnspecified();
917 SetIndex(wxNOT_FOUND
);
921 if ( cpv
.m_type
< wxPG_COLOUR_WEB_BASE
)
923 ind
= GetIndexForValue(cpv
.m_type
);
927 cpv
.m_type
= wxPG_COLOUR_CUSTOM
;
928 ind
= GetCustomColourIndex();
938 SetValueToUnspecified();
939 SetIndex(wxNOT_FOUND
);
945 if ( ind
== wxNOT_FOUND
)
946 ind
= GetCustomColourIndex();
953 wxColour
wxSystemColourProperty::GetColour( int index
) const
955 return wxSystemSettings::GetColour( (wxSystemColour
)index
);
958 wxString
wxSystemColourProperty::ColourToString( const wxColour
& col
, int index
) const
960 if ( index
== wxNOT_FOUND
)
961 return wxString::Format(wxT("(%i,%i,%i)"),
966 return m_choices
.GetLabel(index
);
969 wxString
wxSystemColourProperty::ValueToString( wxVariant
& value
,
972 wxColourPropertyValue val
= GetVal(&value
);
976 if ( argFlags
& wxPG_VALUE_IS_CURRENT
)
978 // GetIndex() only works reliably if wxPG_VALUE_IS_CURRENT flag is set,
979 // but we should use it whenever possible.
982 // If custom colour was selected, use invalid index, so that
983 // ColourToString() will return properly formatted colour text.
984 if ( index
== GetCustomColourIndex() )
989 index
= m_choices
.Index(val
.m_type
);
992 return ColourToString(val
.m_colour
, index
);
996 wxSize
wxSystemColourProperty::OnMeasureImage( int ) const
998 return wxPG_DEFAULT_IMAGE_SIZE
;
1002 int wxSystemColourProperty::GetCustomColourIndex() const
1004 return m_choices
.GetCount() - 1;
1008 bool wxSystemColourProperty::QueryColourFromUser( wxVariant
& variant
) const
1010 wxASSERT( m_value
.GetType() != wxPG_VARIANT_TYPE_STRING
);
1013 wxPropertyGrid
* propgrid
= GetGrid();
1014 wxASSERT( propgrid
);
1016 // Must only occur when user triggers event
1017 if ( !(propgrid
->GetInternalFlags() & wxPG_FL_IN_HANDLECUSTOMEDITOREVENT
) )
1020 wxColourPropertyValue val
= GetVal();
1022 val
.m_type
= wxPG_COLOUR_CUSTOM
;
1025 data
.SetChooseFull(true);
1026 data
.SetColour(val
.m_colour
);
1028 for ( i
= 0; i
< 16; i
++)
1030 wxColour
colour(i
*16, i
*16, i
*16);
1031 data
.SetCustomColour(i
, colour
);
1034 wxColourDialog
dialog(propgrid
, &data
);
1035 if ( dialog
.ShowModal() == wxID_OK
)
1037 wxColourData retData
= dialog
.GetColourData();
1038 val
.m_colour
= retData
.GetColour();
1040 variant
= DoTranslateVal(val
);
1042 SetValueInEvent(variant
);
1051 bool wxSystemColourProperty::IntToValue( wxVariant
& variant
, int number
, int WXUNUSED(argFlags
) ) const
1054 int type
= m_choices
.GetValue(index
);
1056 if ( type
== wxPG_COLOUR_CUSTOM
)
1058 QueryColourFromUser(variant
);
1062 variant
= TranslateVal( type
, GetColour(type
) );
1068 // Need to do some extra event handling.
1069 bool wxSystemColourProperty::OnEvent( wxPropertyGrid
* propgrid
, wxWindow
* WXUNUSED(primary
), wxEvent
& event
)
1071 if ( propgrid
->IsMainButtonEvent(event
) )
1073 // We need to handle button click in case editor has been
1074 // switched to one that has wxButton as well.
1076 if ( QueryColourFromUser(variant
) )
1082 /*class wxPGColourPropertyRenderer : public wxPGDefaultRenderer
1085 virtual void Render( wxDC& dc, const wxRect& rect,
1086 const wxPropertyGrid* propertyGrid, wxPGProperty* property,
1087 int WXUNUSED(column), int item, int WXUNUSED(flags) ) const
1089 wxASSERT( property->IsKindOf(CLASSINFO(wxSystemColourProperty)) );
1090 wxSystemColourProperty* prop = wxStaticCast(property, wxSystemColourProperty);
1092 dc.SetPen(*wxBLACK_PEN);
1094 ( item < (int)(GetCustomColourIndex) || (prop->HasFlag(wxPG_PROP_HIDE_CUSTOM_COLOUR)))
1098 const wxArrayInt& values = prop->GetValues();
1099 if ( values.GetChildCount() )
1100 colInd = values[item];
1103 dc.SetBrush( wxColour( prop->GetColour( colInd ) ) );
1105 else if ( !prop->IsValueUnspecified() )
1106 dc.SetBrush( prop->GetVal().m_colour );
1108 dc.SetBrush( *wxWHITE );
1110 wxRect imageRect = propertyGrid->GetImageRect(property, item);
1111 wxLogDebug(wxT("%i, %i"),imageRect.x,imageRect.y);
1112 dc.DrawRectangle( rect.x+imageRect.x, rect.y+imageRect.y,
1113 imageRect.width, imageRect.height );
1117 text = property->GetValueAsString();
1119 text = property->GetChoiceString(item);
1120 DrawText( dc, rect, imageRect.width, text );
1125 wxPGColourPropertyRenderer g_wxPGColourPropertyRenderer;
1127 wxPGCellRenderer* wxSystemColourProperty::GetCellRenderer( int column ) const
1130 return &g_wxPGColourPropertyRenderer;
1131 return wxEnumProperty::GetCellRenderer(column);
1134 void wxSystemColourProperty::OnCustomPaint( wxDC
& dc
, const wxRect
& rect
,
1135 wxPGPaintData
& paintdata
)
1139 if ( paintdata
.m_choiceItem
>= 0 && paintdata
.m_choiceItem
< (int)m_choices
.GetCount() &&
1140 paintdata
.m_choiceItem
!= GetCustomColourIndex() )
1142 int colInd
= m_choices
[paintdata
.m_choiceItem
].GetValue();
1143 col
= GetColour( colInd
);
1145 else if ( !IsValueUnspecified() )
1147 col
= GetVal().m_colour
;
1153 dc
.DrawRectangle(rect
);
1158 bool wxSystemColourProperty::StringToValue( wxVariant
& value
, const wxString
& text
, int argFlags
) const
1161 // Accept colour format "[Name] [(R,G,B)]"
1162 // Name takes precedence.
1164 wxString colourName
;
1167 int ppos
= text
.Find(wxT("("));
1169 if ( ppos
== wxNOT_FOUND
)
1175 colourName
= text
.substr(0, ppos
);
1176 colourRGB
= text
.substr(ppos
, text
.length()-ppos
);
1179 // Strip spaces from extremities
1180 colourName
.Trim(true);
1181 colourName
.Trim(false);
1182 colourRGB
.Trim(true);
1184 // Validate colourRGB string - (1,1,1) is shortest allowed
1185 if ( colourRGB
.length() < 7 )
1188 if ( colourRGB
.length() == 0 && m_choices
.GetCount() &&
1189 colourName
== m_choices
.GetLabel(GetCustomColourIndex()) )
1191 if ( !(argFlags
& wxPG_EDITABLE_VALUE
))
1193 // This really should not occurr...
1199 QueryColourFromUser(value
);
1203 wxColourPropertyValue val
;
1207 if ( colourName
.length() )
1209 // Try predefined colour first
1210 bool res
= wxEnumProperty::StringToValue(value
, colourName
, argFlags
);
1211 if ( res
&& GetIndex() >= 0 )
1213 val
.m_type
= GetIndex();
1214 if ( val
.m_type
< m_choices
.GetCount() )
1215 val
.m_type
= m_choices
[val
.m_type
].GetValue();
1217 // Get proper colour for type.
1218 val
.m_colour
= GetColour(val
.m_type
);
1223 if ( colourRGB
.length() && !done
)
1225 // Then check custom colour.
1226 val
.m_type
= wxPG_COLOUR_CUSTOM
;
1228 int r
= -1, g
= -1, b
= -1;
1229 wxSscanf(colourRGB
.c_str(),wxT("(%i,%i,%i)"),&r
,&g
,&b
);
1231 if ( r
>= 0 && r
<= 255 &&
1232 g
>= 0 && g
<= 255 &&
1233 b
>= 0 && b
<= 255 )
1235 val
.m_colour
.Set(r
,g
,b
);
1247 value
= DoTranslateVal(val
);
1254 bool wxSystemColourProperty::DoSetAttribute( const wxString
& name
, wxVariant
& value
)
1256 if ( name
== wxPG_COLOUR_ALLOW_CUSTOM
)
1258 int ival
= wxPGVariantToInt(value
);
1260 SetChoicesExclusive(); // Make sure we don't corrupt colour lists of other properties
1262 if ( ival
&& (m_flags
& wxPG_PROP_HIDE_CUSTOM_COLOUR
) )
1264 // Show custom choice
1265 m_choices
.Insert(wxT("Custom"), GetCustomColourIndex(), wxPG_COLOUR_CUSTOM
);
1266 m_flags
&= ~(wxPG_PROP_HIDE_CUSTOM_COLOUR
);
1268 else if ( !ival
&& !(m_flags
& wxPG_PROP_HIDE_CUSTOM_COLOUR
) )
1270 // Hide custom choice
1271 m_choices
.RemoveAt(GetCustomColourIndex());
1272 m_flags
|= wxPG_PROP_HIDE_CUSTOM_COLOUR
;
1280 // -----------------------------------------------------------------------
1282 // -----------------------------------------------------------------------
1284 static const wxChar
* gs_cp_es_normcolour_labels
[] = {
1304 (const wxChar
*) NULL
1307 static unsigned long gs_cp_es_normcolour_colours
[] = {
1309 wxPG_COLOUR(128,0,0),
1310 wxPG_COLOUR(0,0,128),
1311 wxPG_COLOUR(128,0,128),
1312 wxPG_COLOUR(0,128,128),
1313 wxPG_COLOUR(128,128,128),
1314 wxPG_COLOUR(0,128,0),
1315 wxPG_COLOUR(128,128,0),
1316 wxPG_COLOUR(166,124,81),
1317 wxPG_COLOUR(0,0,255),
1318 wxPG_COLOUR(255,0,255),
1319 wxPG_COLOUR(255,0,0),
1320 wxPG_COLOUR(247,148,28),
1321 wxPG_COLOUR(192,192,192),
1322 wxPG_COLOUR(0,255,0),
1323 wxPG_COLOUR(0,255,255),
1324 wxPG_COLOUR(255,255,0),
1325 wxPG_COLOUR(255,255,255),
1329 WX_PG_IMPLEMENT_PROPERTY_CLASS(wxColourProperty
, wxSystemColourProperty
,
1330 wxColour
, const wxColour
&, TextCtrlAndButton
)
1332 static wxPGChoices gs_wxColourProperty_choicesCache
;
1334 wxColourProperty::wxColourProperty( const wxString
& label
,
1335 const wxString
& name
,
1336 const wxColour
& value
)
1337 : wxSystemColourProperty(label
, name
, gs_cp_es_normcolour_labels
,
1339 &gs_wxColourProperty_choicesCache
, value
)
1343 m_flags
|= wxPG_PROP_TRANSLATE_CUSTOM
;
1346 wxColourProperty::~wxColourProperty()
1350 void wxColourProperty::Init( wxColour colour
)
1357 int ind
= ColToInd(colour
);
1359 ind
= m_choices
.GetCount() - 1;
1363 wxString
wxColourProperty::ValueToString( wxVariant
& value
,
1364 int argFlags
) const
1366 const wxPGEditor
* editor
= GetEditorClass();
1367 if ( editor
!= wxPGEditor_Choice
&&
1368 editor
!= wxPGEditor_ChoiceAndButton
&&
1369 editor
!= wxPGEditor_ComboBox
)
1370 argFlags
|= wxPG_PROPERTY_SPECIFIC
;
1372 return wxSystemColourProperty::ValueToString(value
, argFlags
);
1375 wxColour
wxColourProperty::GetColour( int index
) const
1377 return gs_cp_es_normcolour_colours
[m_choices
.GetValue(index
)];
1380 wxVariant
wxColourProperty::DoTranslateVal( wxColourPropertyValue
& v
) const
1383 variant
<< v
.m_colour
;
1387 // -----------------------------------------------------------------------
1389 // -----------------------------------------------------------------------
1391 #define wxPG_CURSOR_IMAGE_WIDTH 32
1393 #define NUM_CURSORS 28
1395 //#define wx_cp_es_syscursors_len 28
1396 static const wxChar
* gs_cp_es_syscursors_labels
[NUM_CURSORS
+1] = {
1408 wxT("Middle Button"),
1414 wxT("Question Arrow"),
1415 wxT("Right Button"),
1416 wxT("Sizing NE-SW"),
1418 wxT("Sizing NW-SE"),
1425 (const wxChar
*) NULL
1428 static long gs_cp_es_syscursors_values
[NUM_CURSORS
] = {
1431 wxCURSOR_RIGHT_ARROW
,
1438 wxCURSOR_LEFT_BUTTON
,
1440 wxCURSOR_MIDDLE_BUTTON
,
1442 wxCURSOR_PAINT_BRUSH
,
1444 wxCURSOR_POINT_LEFT
,
1445 wxCURSOR_POINT_RIGHT
,
1446 wxCURSOR_QUESTION_ARROW
,
1447 wxCURSOR_RIGHT_BUTTON
,
1459 IMPLEMENT_DYNAMIC_CLASS(wxCursorProperty
, wxEnumProperty
)
1461 wxCursorProperty::wxCursorProperty( const wxString
& label
, const wxString
& name
,
1463 : wxEnumProperty( label
,
1465 gs_cp_es_syscursors_labels
,
1466 gs_cp_es_syscursors_values
,
1469 m_flags
|= wxPG_PROP_STATIC_CHOICES
; // Cursor selection cannot be changed.
1472 wxCursorProperty::~wxCursorProperty()
1476 wxSize
wxCursorProperty::OnMeasureImage( int item
) const
1478 #if wxPG_CAN_DRAW_CURSOR
1479 if ( item
!= -1 && item
< NUM_CURSORS
)
1480 return wxSize(wxPG_CURSOR_IMAGE_WIDTH
,wxPG_CURSOR_IMAGE_WIDTH
);
1487 #if wxPG_CAN_DRAW_CURSOR
1489 void wxCursorProperty::OnCustomPaint( wxDC
& dc
,
1491 wxPGPaintData
& paintdata
)
1494 dc
.SetBrush( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE
) );
1496 if ( paintdata
.m_choiceItem
>= 0 )
1498 dc
.DrawRectangle( rect
);
1500 if ( paintdata
.m_choiceItem
< NUM_CURSORS
)
1502 wxStockCursor cursorIndex
=
1503 (wxStockCursor
) gs_cp_es_syscursors_values
[paintdata
.m_choiceItem
];
1506 if ( cursorIndex
== wxCURSOR_NONE
)
1507 cursorIndex
= wxCURSOR_ARROW
;
1509 wxCursor
cursor( cursorIndex
);
1512 HDC hDc
= (HDC
)((const wxMSWDCImpl
*)dc
.GetImpl())->GetHDC();
1516 (HICON
)cursor
.GetHandle(),
1521 #if !defined(__WXWINCE__)
1522 DI_COMPAT
| DI_DEFAULTSIZE
|
1533 void wxCursorProperty::OnCustomPaint( wxDC
&, const wxRect
&, wxPGPaintData
& ) { }
1534 /*wxPGCellRenderer* wxCursorProperty::GetCellRenderer( int column ) const
1536 return wxEnumProperty::GetCellRenderer(column);
1540 // -----------------------------------------------------------------------
1541 // wxImageFileProperty
1542 // -----------------------------------------------------------------------
1546 const wxString
& wxPGGetDefaultImageWildcard()
1548 // Form the wildcard, if not done yet
1549 if ( !wxPGGlobalVars
->m_pDefaultImageWildcard
.length() )
1554 // TODO: This section may require locking (using global).
1556 wxList
& handlers
= wxImage::GetHandlers();
1558 wxList::iterator node
;
1560 // Let's iterate over the image handler list.
1561 //for ( wxList::Node *node = handlers.GetFirst(); node; node = node->GetNext() )
1562 for ( node
= handlers
.begin(); node
!= handlers
.end(); ++node
)
1564 wxImageHandler
*handler
= (wxImageHandler
*)*node
;
1566 wxString ext_lo
= handler
->GetExtension();
1567 wxString ext_up
= ext_lo
.Upper();
1569 str
.append( ext_up
);
1570 str
.append( wxT(" files (*.") );
1571 str
.append( ext_up
);
1572 str
.append( wxT(")|*.") );
1573 str
.append( ext_lo
);
1574 str
.append( wxT("|") );
1577 str
.append ( wxT("All files (*.*)|*.*") );
1579 wxPGGlobalVars
->m_pDefaultImageWildcard
= str
;
1582 return wxPGGlobalVars
->m_pDefaultImageWildcard
;
1585 IMPLEMENT_DYNAMIC_CLASS(wxImageFileProperty
, wxFileProperty
)
1587 wxImageFileProperty::wxImageFileProperty( const wxString
& label
, const wxString
& name
,
1588 const wxString
& value
)
1589 : wxFileProperty(label
,name
,value
)
1591 SetAttribute( wxPG_FILE_WILDCARD
, wxPGGetDefaultImageWildcard() );
1593 m_pImage
= (wxImage
*) NULL
;
1594 m_pBitmap
= (wxBitmap
*) NULL
;
1597 wxImageFileProperty::~wxImageFileProperty()
1605 void wxImageFileProperty::OnSetValue()
1607 wxFileProperty::OnSetValue();
1621 wxFileName filename
= GetFileName();
1623 // Create the image thumbnail
1624 if ( filename
.FileExists() )
1626 m_pImage
= new wxImage( filename
.GetFullPath() );
1630 wxSize
wxImageFileProperty::OnMeasureImage( int ) const
1632 return wxPG_DEFAULT_IMAGE_SIZE
;
1635 void wxImageFileProperty::OnCustomPaint( wxDC
& dc
,
1639 if ( m_pBitmap
|| (m_pImage
&& m_pImage
->Ok() ) )
1641 // Draw the thumbnail
1643 // Create the bitmap here because required size is not known in OnSetValue().
1646 m_pImage
->Rescale( rect
.width
, rect
.height
);
1647 m_pBitmap
= new wxBitmap( *m_pImage
);
1652 dc
.DrawBitmap( *m_pBitmap
, rect
.x
, rect
.y
, false );
1656 // No file - just draw a white box
1657 dc
.SetBrush( *wxWHITE_BRUSH
);
1658 dc
.DrawRectangle ( rect
);
1662 #endif // wxUSE_IMAGE
1664 // -----------------------------------------------------------------------
1665 // wxMultiChoiceProperty
1666 // -----------------------------------------------------------------------
1670 #include "wx/choicdlg.h"
1672 WX_PG_IMPLEMENT_PROPERTY_CLASS(wxMultiChoiceProperty
,wxPGProperty
,
1673 wxArrayInt
,const wxArrayInt
&,TextCtrlAndButton
)
1675 wxMultiChoiceProperty::wxMultiChoiceProperty( const wxString
& label
,
1676 const wxString
& name
,
1677 const wxPGChoices
& choices
,
1678 const wxArrayString
& value
)
1679 : wxPGProperty(label
,name
)
1681 m_choices
.Assign(choices
);
1685 wxMultiChoiceProperty::wxMultiChoiceProperty( const wxString
& label
,
1686 const wxString
& name
,
1687 const wxArrayString
& strings
,
1688 const wxArrayString
& value
)
1689 : wxPGProperty(label
,name
)
1691 m_choices
.Set(strings
);
1695 wxMultiChoiceProperty::wxMultiChoiceProperty( const wxString
& label
,
1696 const wxString
& name
,
1697 const wxArrayString
& value
)
1698 : wxPGProperty(label
,name
)
1700 wxArrayString strings
;
1701 m_choices
.Set(strings
);
1705 wxMultiChoiceProperty::~wxMultiChoiceProperty()
1709 void wxMultiChoiceProperty::OnSetValue()
1711 GenerateValueAsString(m_value
, &m_display
);
1714 wxString
wxMultiChoiceProperty::ValueToString( wxVariant
& value
,
1715 int argFlags
) const
1717 // If possible, use cached string
1718 if ( argFlags
& wxPG_VALUE_IS_CURRENT
)
1722 GenerateValueAsString(value
, &s
);
1726 void wxMultiChoiceProperty::GenerateValueAsString( wxVariant
& value
,
1727 wxString
* target
) const
1729 wxArrayString strings
;
1731 if ( value
.GetType() == wxPG_VARIANT_TYPE_ARRSTRING
)
1732 strings
= value
.GetArrayString();
1734 wxString
& tempStr
= *target
;
1736 unsigned int itemCount
= strings
.size();
1741 tempStr
.append( wxT("\"") );
1743 for ( i
= 0; i
< itemCount
; i
++ )
1745 tempStr
.append( strings
[i
] );
1746 tempStr
.append( wxT("\"") );
1747 if ( i
< (itemCount
-1) )
1748 tempStr
.append ( wxT(" \"") );
1752 wxArrayInt
wxMultiChoiceProperty::GetValueAsIndices() const
1754 const wxArrayInt
& valueArr
= wxArrayIntRefFromVariant(GetValue());
1757 // Translate values to string indices.
1758 wxArrayInt selections
;
1760 if ( !m_choices
.IsOk() || !m_choices
.GetCount() || !(&valueArr
) )
1762 for ( i
=0; i
<valueArr
.size(); i
++ )
1767 for ( i
=0; i
<valueArr
.size(); i
++ )
1769 int sIndex
= m_choices
.Index(valueArr
[i
]);
1771 selections
.Add(sIndex
);
1778 bool wxMultiChoiceProperty::OnEvent( wxPropertyGrid
* propgrid
,
1779 wxWindow
* WXUNUSED(primary
),
1782 if ( propgrid
->IsMainButtonEvent(event
) )
1785 wxVariant useValue
= propgrid
->GetUncommittedPropertyValue();
1787 wxArrayString labels
= m_choices
.GetLabels();
1788 unsigned int choiceCount
;
1790 if ( m_choices
.IsOk() )
1791 choiceCount
= m_choices
.GetCount();
1795 // launch editor dialog
1796 wxMultiChoiceDialog
dlg( propgrid
,
1797 _("Make a selection:"),
1800 choiceCount
?&labels
[0]:NULL
,
1801 wxCHOICEDLG_STYLE
);
1803 dlg
.Move( propgrid
->GetGoodEditorDialogPosition(this,dlg
.GetSize()) );
1805 wxArrayString strings
= useValue
.GetArrayString();
1806 wxArrayString extraStrings
;
1808 dlg
.SetSelections(m_choices
.GetIndicesForStrings(strings
, &extraStrings
));
1810 if ( dlg
.ShowModal() == wxID_OK
&& choiceCount
)
1812 int userStringMode
= GetAttributeAsLong(wxT("UserStringMode"), 0);
1814 wxArrayInt arrInt
= dlg
.GetSelections();
1818 // Strings that were not in list of choices
1819 wxArrayString value
;
1821 // Translate string indices to strings
1824 if ( userStringMode
== 1 )
1826 for (n
=0;n
<extraStrings
.size();n
++)
1827 value
.push_back(extraStrings
[n
]);
1831 for ( i
=0; i
<arrInt
.size(); i
++ )
1832 value
.Add(m_choices
.GetLabel(arrInt
.Item(i
)));
1834 if ( userStringMode
== 2 )
1836 for (n
=0;n
<extraStrings
.size();n
++)
1837 value
.push_back(extraStrings
[n
]);
1840 variant
= WXVARIANT(value
);
1842 SetValueInEvent(variant
);
1850 bool wxMultiChoiceProperty::StringToValue( wxVariant
& variant
, const wxString
& text
, int ) const
1854 int userStringMode
= GetAttributeAsLong(wxT("UserStringMode"), 0);
1856 WX_PG_TOKENIZER2_BEGIN(text
,wxT('"'))
1857 if ( userStringMode
> 0 || (m_choices
.IsOk() && m_choices
.Index( token
) != wxNOT_FOUND
) )
1859 WX_PG_TOKENIZER2_END()
1861 wxVariant
v( WXVARIANT(arr
) );
1867 #endif // wxUSE_CHOICEDLG
1870 // -----------------------------------------------------------------------
1872 // -----------------------------------------------------------------------
1877 #if wxUSE_DATEPICKCTRL
1878 #define dtCtrl DatePickerCtrl
1880 #define dtCtrl TextCtrl
1883 WX_PG_IMPLEMENT_PROPERTY_CLASS(wxDateProperty
,
1890 wxString
wxDateProperty::ms_defaultDateFormat
;
1893 wxDateProperty::wxDateProperty( const wxString
& label
,
1894 const wxString
& name
,
1895 const wxDateTime
& value
)
1896 : wxPGProperty(label
,name
)
1898 //wxPGRegisterDefaultValueType(wxDateTime)
1900 #if wxUSE_DATEPICKCTRL
1901 wxPGRegisterEditorClass(DatePickerCtrl
);
1903 m_dpStyle
= wxDP_DEFAULT
| wxDP_SHOWCENTURY
;
1911 wxDateProperty::~wxDateProperty()
1915 bool wxDateProperty::StringToValue( wxVariant
& variant
, const wxString
& text
,
1916 int WXUNUSED(argFlags
) ) const
1920 const char* c
= dt
.ParseFormat(text
, wxString(wxDefaultDateTimeFormat
), wxDefaultDateTime
, NULL
);
1931 wxString
wxDateProperty::ValueToString( wxVariant
& value
,
1932 int argFlags
) const
1934 const wxChar
* format
= (const wxChar
*) NULL
;
1936 wxDateTime dateTime
= value
.GetDateTime();
1938 if ( !dateTime
.IsValid() )
1939 return wxT("Invalid");
1941 if ( !ms_defaultDateFormat
.length() )
1943 #if wxUSE_DATEPICKCTRL
1944 bool showCentury
= m_dpStyle
& wxDP_SHOWCENTURY
? true : false;
1946 bool showCentury
= true;
1948 ms_defaultDateFormat
= DetermineDefaultDateFormat( showCentury
);
1951 if ( m_format
.length() &&
1952 !(argFlags
& wxPG_FULL_VALUE
) )
1953 format
= m_format
.c_str();
1955 // Determine default from locale
1956 // NB: This is really simple stuff, but can't figure anything
1957 // better without proper support in wxLocale
1959 format
= ms_defaultDateFormat
.c_str();
1961 return dateTime
.Format(format
);
1964 wxString
wxDateProperty::DetermineDefaultDateFormat( bool showCentury
)
1966 // This code is basicly copied from datectlg.cpp's SetFormat
1971 dt
.ParseFormat(wxT("2003-10-13"), wxT("%Y-%m-%d"));
1972 wxString
str(dt
.Format(wxT("%x")));
1974 const wxChar
*p
= str
.c_str();
1978 if (n
== dt
.GetDay())
1980 format
.Append(wxT("%d"));
1983 else if (n
== (int)dt
.GetMonth()+1)
1985 format
.Append(wxT("%m"));
1988 else if (n
== dt
.GetYear())
1990 format
.Append(wxT("%Y"));
1993 else if (n
== (dt
.GetYear() % 100))
1996 format
.Append(wxT("%Y"));
1998 format
.Append(wxT("%y"));
2002 format
.Append(*p
++);
2008 bool wxDateProperty::DoSetAttribute( const wxString
& name
, wxVariant
& value
)
2010 if ( name
== wxPG_DATE_FORMAT
)
2012 m_format
= value
.GetString();
2015 else if ( name
== wxPG_DATE_PICKER_STYLE
)
2017 m_dpStyle
= value
.GetLong();
2018 ms_defaultDateFormat
.clear(); // This may need recalculation
2024 #endif // wxUSE_DATETIME
2027 // -----------------------------------------------------------------------
2028 // wxPropertyGridInterface
2029 // -----------------------------------------------------------------------
2031 void wxPropertyGridInterface::InitAllTypeHandlers()
2035 // -----------------------------------------------------------------------
2037 void wxPropertyGridInterface::RegisterAdditionalEditors()
2039 // Register editor classes, if necessary.
2040 if ( wxPGGlobalVars
->m_mapEditorClasses
.empty() )
2041 wxPropertyGrid::RegisterDefaultEditors();
2044 wxPGRegisterEditorClass(SpinCtrl
);
2046 #if wxUSE_DATEPICKCTRL
2047 wxPGRegisterEditorClass(DatePickerCtrl
);
2051 // -----------------------------------------------------------------------
2053 #endif // wxPG_INCLUDE_ADVPROPS
2055 #endif // wxUSE_PROPGRID