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"
21 #include "wx/object.h"
23 #include "wx/string.h"
26 #include "wx/window.h"
29 #include "wx/dcclient.h"
30 #include "wx/button.h"
33 #include "wx/cursor.h"
34 #include "wx/dialog.h"
35 #include "wx/settings.h"
36 #include "wx/msgdlg.h"
37 #include "wx/choice.h"
38 #include "wx/stattext.h"
39 #include "wx/textctrl.h"
40 #include "wx/scrolwin.h"
41 #include "wx/dirdlg.h"
42 #include "wx/combobox.h"
43 #include "wx/layout.h"
45 #include "wx/textdlg.h"
46 #include "wx/filedlg.h"
50 #define __wxPG_SOURCE_FILE__
52 #include <wx/propgrid/propgrid.h>
54 #if wxPG_INCLUDE_ADVPROPS
56 #include <wx/propgrid/advprops.h>
59 #include <wx/msw/private.h>
60 #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 // This macro also defines global wxPGEditor_SpinCtrl for storing
117 // the singleton class instance.
118 WX_PG_IMPLEMENT_EDITOR_CLASS(SpinCtrl
,wxPGSpinCtrlEditor
,wxPGEditor
)
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 propgrid
->Connect( wxPG_SUBID2
, wxEVT_SCROLL_LINEUP
,
146 (wxObjectEventFunction
) (wxEventFunction
) (wxCommandEventFunction
)
147 &wxPropertyGrid::OnCustomEditorEvent
, NULL
, propgrid
);
148 propgrid
->Connect( wxPG_SUBID2
, wxEVT_SCROLL_LINEDOWN
,
149 (wxObjectEventFunction
) (wxEventFunction
) (wxCommandEventFunction
)
150 &wxPropertyGrid::OnCustomEditorEvent
, NULL
, propgrid
);
151 propgrid
->Connect( wxPG_SUBID1
, wxEVT_KEY_DOWN
,
152 (wxObjectEventFunction
) (wxEventFunction
) (wxCommandEventFunction
)
153 &wxPropertyGrid::OnCustomEditorEvent
, NULL
, propgrid
);
155 // Let's add validator to make sure only numbers can be entered
156 wxTextValidator
validator(wxFILTER_NUMERIC
, &m_tempString
);
158 wxTextCtrl
* wnd1
= (wxTextCtrl
*) wxPGTextCtrlEditor::CreateControls( propgrid
, property
, pos
, tcSz
).m_primary
;
159 wnd1
->SetValidator(validator
);
161 return wxPGWindowList(wnd1
, wnd2
);
164 // Control's events are redirected here
165 bool wxPGSpinCtrlEditor::OnEvent( wxPropertyGrid
* propgrid
, wxPGProperty
* property
,
166 wxWindow
* wnd
, wxEvent
& event
) const
168 int evtType
= event
.GetEventType();
170 bool bigStep
= false;
172 if ( evtType
== wxEVT_KEY_DOWN
)
174 wxKeyEvent
& keyEvent
= (wxKeyEvent
&)event
;
175 keycode
= keyEvent
.GetKeyCode();
177 if ( keycode
== WXK_UP
)
178 evtType
= wxEVT_SCROLL_LINEUP
;
179 else if ( keycode
== WXK_DOWN
)
180 evtType
= wxEVT_SCROLL_LINEDOWN
;
181 else if ( keycode
== WXK_PAGEUP
)
183 evtType
= wxEVT_SCROLL_LINEUP
;
186 else if ( keycode
== WXK_PAGEDOWN
)
188 evtType
= wxEVT_SCROLL_LINEDOWN
;
193 if ( evtType
== wxEVT_SCROLL_LINEUP
|| evtType
== wxEVT_SCROLL_LINEDOWN
)
196 // Can't use wnd since it might be clipper window
197 wxTextCtrl
* tc
= wxDynamicCast(propgrid
->GetEditorControl(), wxTextCtrl
);
202 s
= property
->GetValueAsString(wxPG_FULL_VALUE
);
204 int mode
= wxPG_PROPERTY_VALIDATION_SATURATE
;
206 if ( property
->GetAttributeAsLong(wxT("Wrap"), 0) )
207 mode
= wxPG_PROPERTY_VALIDATION_WRAP
;
209 if ( property
->GetValueType() == wxT("double") )
212 double step
= property
->GetAttributeAsDouble(wxT("Step"), 1.0);
215 if ( s
.ToDouble(&v_d
) )
220 if ( evtType
== wxEVT_SCROLL_LINEUP
) v_d
+= step
;
224 wxFloatProperty::DoValidation(property
, v_d
, NULL
, mode
);
226 wxPropertyGrid::DoubleToString(s
, v_d
, 6, true, NULL
);
236 wxLongLong_t step
= property
->GetAttributeAsLong(wxT("Step"), 1);
239 if ( s
.ToLongLong(&v_ll
, 10) )
244 if ( evtType
== wxEVT_SCROLL_LINEUP
) v_ll
+= step
;
248 wxIntProperty::DoValidation(property
, v_ll
, NULL
, mode
);
250 s
= wxLongLong(v_ll
).ToString();
260 int ip
= tc
->GetInsertionPoint();
261 int lp
= tc
->GetLastPosition();
263 tc
->SetInsertionPoint(ip
+(tc
->GetLastPosition()-lp
));
269 return wxPGTextCtrlEditor::OnEvent(propgrid
,property
,wnd
,event
);
272 #endif // wxUSE_SPINBTN
275 // -----------------------------------------------------------------------
276 // wxDatePickerCtrl-based property editor
277 // -----------------------------------------------------------------------
279 #if wxUSE_DATEPICKCTRL
282 #include <wx/datectrl.h>
283 #include <wx/dateevt.h>
285 class wxPGDatePickerCtrlEditor
: public wxPGEditor
287 WX_PG_DECLARE_EDITOR_CLASS(wxPGDatePickerCtrlEditor
)
289 virtual ~wxPGDatePickerCtrlEditor();
291 wxPG_DECLARE_CREATECONTROLS
293 virtual void UpdateControl( wxPGProperty
* property
, wxWindow
* wnd
) const;
294 virtual bool OnEvent( wxPropertyGrid
* propgrid
, wxPGProperty
* property
,
295 wxWindow
* wnd
, wxEvent
& event
) const;
296 virtual bool GetValueFromControl( wxVariant
& variant
, wxPGProperty
* property
, wxWindow
* wnd
) const;
297 virtual void SetValueToUnspecified( wxPGProperty
* WXUNUSED(property
), wxWindow
* wnd
) const;
301 WX_PG_IMPLEMENT_EDITOR_CLASS(DatePickerCtrl
,wxPGDatePickerCtrlEditor
,wxPGEditor
)
304 wxPGDatePickerCtrlEditor::~wxPGDatePickerCtrlEditor()
308 wxPGWindowList
wxPGDatePickerCtrlEditor::CreateControls( wxPropertyGrid
* propgrid
,
309 wxPGProperty
* property
,
311 const wxSize
& sz
) const
313 wxCHECK_MSG( property
->IsKindOf(CLASSINFO(wxDateProperty
)),
315 wxT("DatePickerCtrl editor can only be used with wxDateProperty or derivative.") );
317 wxDateProperty
* prop
= (wxDateProperty
*) property
;
319 // Use two stage creation to allow cleaner display on wxMSW
320 wxDatePickerCtrl
* ctrl
= new wxDatePickerCtrl();
323 wxSize useSz
= wxDefaultSize
;
328 ctrl
->Create(propgrid
->GetPanel(),
330 prop
->GetDateValue(),
333 prop
->GetDatePickerStyle() | wxNO_BORDER
);
335 // Connect all required events to grid's OnCustomEditorEvent
336 // (all relevenat wxTextCtrl, wxComboBox and wxButton events are
337 // already connected)
338 propgrid
->Connect( wxPG_SUBID1
, wxEVT_DATE_CHANGED
,
339 (wxObjectEventFunction
) (wxEventFunction
) (wxCommandEventFunction
)
340 &wxPropertyGrid::OnCustomEditorEvent
);
349 // Copies value from property to control
350 void wxPGDatePickerCtrlEditor::UpdateControl( wxPGProperty
* property
, wxWindow
* wnd
) const
352 wxDatePickerCtrl
* ctrl
= (wxDatePickerCtrl
*) wnd
;
353 wxASSERT( ctrl
&& ctrl
->IsKindOf(CLASSINFO(wxDatePickerCtrl
)) );
355 // We assume that property's data type is 'int' (or something similar),
356 // thus allowing us to get raw, unchecked value via DoGetValue.
357 ctrl
->SetValue( property
->GetValue().GetDateTime() );
360 // Control's events are redirected here
361 bool wxPGDatePickerCtrlEditor::OnEvent( wxPropertyGrid
* WXUNUSED(propgrid
),
362 wxPGProperty
* WXUNUSED(property
),
363 wxWindow
* WXUNUSED(wnd
),
364 wxEvent
& event
) const
366 if ( event
.GetEventType() == wxEVT_DATE_CHANGED
)
372 bool wxPGDatePickerCtrlEditor::GetValueFromControl( wxVariant
& variant
, wxPGProperty
* WXUNUSED(property
), wxWindow
* wnd
) const
374 wxDatePickerCtrl
* ctrl
= (wxDatePickerCtrl
*) wnd
;
375 wxASSERT( ctrl
&& ctrl
->IsKindOf(CLASSINFO(wxDatePickerCtrl
)) );
377 variant
= ctrl
->GetValue();
382 void wxPGDatePickerCtrlEditor::SetValueToUnspecified( wxPGProperty
* WXUNUSED(property
), wxWindow
* WXUNUSED(wnd
) ) const
385 //wxDateProperty* prop = (wxDateProperty*) property;
389 #endif // wxUSE_DATEPICKCTRL
392 // -----------------------------------------------------------------------
394 // -----------------------------------------------------------------------
396 #include <wx/fontdlg.h>
397 #include <wx/fontenum.h>
399 static const wxChar
* gs_fp_es_family_labels
[] = {
400 wxT("Default"), wxT("Decorative"),
401 wxT("Roman"), wxT("Script"),
402 wxT("Swiss"), wxT("Modern"),
406 static long gs_fp_es_family_values
[] = {
407 wxDEFAULT
, wxDECORATIVE
,
412 static const wxChar
* gs_fp_es_style_labels
[] = {
419 static long gs_fp_es_style_values
[] = {
425 static const wxChar
* gs_fp_es_weight_labels
[] = {
432 static long gs_fp_es_weight_values
[] = {
438 // Class body is in advprops.h
441 WX_PG_IMPLEMENT_PROPERTY_CLASS(wxFontProperty
,wxPGProperty
,
442 wxFont
,const wxFont
&,TextCtrlAndButton
)
445 wxFontProperty::wxFontProperty( const wxString
& label
, const wxString
& name
,
446 const wxFont
& value
)
447 : wxPGProperty(label
,name
)
449 SetValue( wxFontToVariant(value
) );
451 // Initialize font family choices list
452 if ( !wxPGGlobalVars
->m_fontFamilyChoices
)
454 wxFontEnumerator enumerator
;
455 enumerator
.EnumerateFacenames();
457 #if wxMINOR_VERSION > 6
458 wxArrayString faceNames
= enumerator
.GetFacenames();
460 wxArrayString
& faceNames
= *enumerator
.GetFacenames();
465 wxPGGlobalVars
->m_fontFamilyChoices
= new wxPGChoices(faceNames
);
468 wxString
emptyString(wxEmptyString
);
470 wxFont
& font
= wxFontFromVariant(m_value
);
472 AddChild( new wxIntProperty( _("Point Size"),emptyString
,(long)font
.GetPointSize() ) );
474 AddChild( new wxEnumProperty(_("Family"), emptyString
,
475 gs_fp_es_family_labels
,gs_fp_es_family_values
,
478 wxString faceName
= font
.GetFaceName();
479 // If font was not in there, add it now
480 if ( faceName
.length() &&
481 wxPGGlobalVars
->m_fontFamilyChoices
->Index(faceName
) == wxNOT_FOUND
)
482 wxPGGlobalVars
->m_fontFamilyChoices
->AddAsSorted(faceName
);
484 wxPGProperty
* p
= new wxEnumProperty(_("Face Name"),emptyString
,
485 *wxPGGlobalVars
->m_fontFamilyChoices
);
487 p
->SetValueFromString(faceName
, wxPG_FULL_VALUE
);
491 AddChild( new wxEnumProperty(_("Style"),emptyString
,
492 gs_fp_es_style_labels
,gs_fp_es_style_values
,font
.GetStyle()) );
494 AddChild( new wxEnumProperty(_("Weight"),emptyString
,
495 gs_fp_es_weight_labels
,gs_fp_es_weight_values
,font
.GetWeight()) );
497 AddChild( new wxBoolProperty(_("Underlined"),emptyString
,
498 font
.GetUnderlined()) );
501 wxFontProperty::~wxFontProperty() { }
503 void wxFontProperty::OnSetValue()
505 wxFont
& font
= wxFontFromVariant(m_value
);
510 font2
= wxFont(10,wxSWISS
,wxNORMAL
,wxNORMAL
);
514 m_value
= wxFontToVariant(font2
);
517 wxString
wxFontProperty::GetValueAsString( int argFlags
) const
519 return wxPGProperty::GetValueAsString(argFlags
);
522 bool wxFontProperty::OnEvent( wxPropertyGrid
* propgrid
, wxWindow
* WXUNUSED(primary
),
525 if ( propgrid
->IsMainButtonEvent(event
) )
527 // Update value from last minute changes
528 PrepareValueForDialogEditing(propgrid
);
531 data
.SetInitialFont( wxFontFromVariant(m_value
) );
532 data
.SetColour(*wxBLACK
);
534 wxFontDialog
dlg(propgrid
, data
);
535 if ( dlg
.ShowModal() == wxID_OK
)
537 propgrid
->EditorsValueWasModified();
539 wxVariant variant
= wxFontToVariant(dlg
.GetFontData().GetChosenFont());
540 SetValueInEvent( variant
);
547 void wxFontProperty::RefreshChildren()
549 if ( !GetChildCount() ) return;
550 const wxFont
& font
= wxFontFromVariant(m_value
);
551 Item(0)->SetValue( (long)font
.GetPointSize() );
552 Item(1)->SetValue( (long)font
.GetFamily() );
553 Item(2)->SetValueFromString( font
.GetFaceName(), wxPG_FULL_VALUE
);
554 Item(3)->SetValue( (long)font
.GetStyle() );
555 Item(4)->SetValue( (long)font
.GetWeight() );
556 Item(5)->SetValue( font
.GetUnderlined() );
559 void wxFontProperty::ChildChanged( wxVariant
& thisValue
, int ind
, wxVariant
& childValue
) const
561 wxFont
& font
= wxFontFromVariant(thisValue
);
565 font
.SetPointSize( wxPGVariantToInt(childValue
) );
569 int fam
= childValue
.GetLong();
570 if ( fam
< wxDEFAULT
||
573 font
.SetFamily( fam
);
578 int faceIndex
= childValue
.GetLong();
580 if ( faceIndex
>= 0 )
581 faceName
= wxPGGlobalVars
->m_fontFamilyChoices
->GetLabel(faceIndex
);
583 font
.SetFaceName( faceName
);
587 int st
= childValue
.GetLong();
588 if ( st
!= wxFONTSTYLE_NORMAL
&&
589 st
!= wxFONTSTYLE_SLANT
&&
590 st
!= wxFONTSTYLE_ITALIC
)
591 st
= wxFONTWEIGHT_NORMAL
;
596 int wt
= childValue
.GetLong();
597 if ( wt
!= wxFONTWEIGHT_NORMAL
&&
598 wt
!= wxFONTWEIGHT_LIGHT
&&
599 wt
!= wxFONTWEIGHT_BOLD
)
600 wt
= wxFONTWEIGHT_NORMAL
;
601 font
.SetWeight( wt
);
605 font
.SetUnderlined( childValue
.GetBool() );
610 wxSize wxFontProperty::OnMeasureImage() const
612 return wxSize(-1,-1);
615 void wxFontProperty::OnCustomPaint(wxDC& dc,
617 wxPGPaintData& paintData)
620 if ( paintData.m_choiceItem >= 0 )
621 drawFace = wxPGGlobalVars->m_fontFamilyChoices->GetLabel(paintData.m_choiceItem);
623 drawFace = m_value_wxFont.GetFaceName();
625 if ( drawFace.length() )
627 // Draw the background
628 dc.SetBrush( wxColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)) );
629 //dc.SetBrush( *wxWHITE_BRUSH );
630 //dc.SetPen( *wxMEDIUM_GREY_PEN );
631 dc.DrawRectangle( rect );
633 wxFont oldFont = dc.GetFont();
634 wxFont drawFont(oldFont.GetPointSize(),
635 wxDEFAULT,wxNORMAL,wxBOLD,false,drawFace);
636 dc.SetFont(drawFont);
638 dc.SetTextForeground( wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT) );
639 dc.DrawText( wxT("Aa"), rect.x+2, rect.y+1 );
645 // No file - just draw a white box
646 dc.SetBrush ( *wxWHITE_BRUSH );
647 dc.DrawRectangle ( rect );
653 // -----------------------------------------------------------------------
654 // wxSystemColourProperty
655 // -----------------------------------------------------------------------
657 // wxEnumProperty based classes cannot use wxPG_PROP_CLASS_SPECIFIC_1
658 #define wxPG_PROP_HIDE_CUSTOM_COLOUR wxPG_PROP_CLASS_SPECIFIC_2
660 #include <wx/colordlg.h>
662 //#define wx_cp_es_syscolours_len 25
663 static const wxChar
* gs_cp_es_syscolour_labels
[] = {
666 wxT("ActiveCaption"),
668 wxT("ButtonHighlight"),
677 wxT("HighlightText"),
678 wxT("InactiveBorder"),
679 wxT("InactiveCaption"),
680 wxT("InactiveCaptionText"),
692 static long gs_cp_es_syscolour_values
[] = {
693 wxSYS_COLOUR_APPWORKSPACE
,
694 wxSYS_COLOUR_ACTIVEBORDER
,
695 wxSYS_COLOUR_ACTIVECAPTION
,
696 wxSYS_COLOUR_BTNFACE
,
697 wxSYS_COLOUR_BTNHIGHLIGHT
,
698 wxSYS_COLOUR_BTNSHADOW
,
699 wxSYS_COLOUR_BTNTEXT
,
700 wxSYS_COLOUR_CAPTIONTEXT
,
701 wxSYS_COLOUR_3DDKSHADOW
,
702 wxSYS_COLOUR_3DLIGHT
,
703 wxSYS_COLOUR_BACKGROUND
,
704 wxSYS_COLOUR_GRAYTEXT
,
705 wxSYS_COLOUR_HIGHLIGHT
,
706 wxSYS_COLOUR_HIGHLIGHTTEXT
,
707 wxSYS_COLOUR_INACTIVEBORDER
,
708 wxSYS_COLOUR_INACTIVECAPTION
,
709 wxSYS_COLOUR_INACTIVECAPTIONTEXT
,
711 wxSYS_COLOUR_SCROLLBAR
,
713 wxSYS_COLOUR_INFOTEXT
,
715 wxSYS_COLOUR_WINDOWFRAME
,
716 wxSYS_COLOUR_WINDOWTEXT
,
721 WX_PG_IMPLEMENT_WXOBJECT_VARIANT_DATA(wxPGVariantDataColourPropertyValue
, wxColourPropertyValue
)
724 // Class body is in advprops.h
726 WX_PG_IMPLEMENT_PROPERTY_CLASS(wxSystemColourProperty
,wxEnumProperty
,
727 wxColourPropertyValue
,const wxColourPropertyValue
&,Choice
)
730 void wxSystemColourProperty::Init( int type
, const wxColour
& colour
)
732 wxColourPropertyValue cpv
;
735 cpv
.Init( type
, colour
);
737 cpv
.Init( type
, *wxWHITE
);
739 m_flags
|= wxPG_PROP_STATIC_CHOICES
; // Colour selection cannot be changed.
741 m_value
= wxColourPropertyValueToVariant(cpv
);
747 static wxPGChoices gs_wxSystemColourProperty_choicesCache
;
750 wxSystemColourProperty::wxSystemColourProperty( const wxString
& label
, const wxString
& name
,
751 const wxColourPropertyValue
& value
)
752 : wxEnumProperty( label
,
754 gs_cp_es_syscolour_labels
,
755 gs_cp_es_syscolour_values
,
756 &gs_wxSystemColourProperty_choicesCache
)
759 Init( value
.m_type
, value
.m_colour
);
761 Init( wxPG_COLOUR_CUSTOM
, *wxWHITE
);
765 wxSystemColourProperty::wxSystemColourProperty( const wxString
& label
, const wxString
& name
,
766 const wxChar
** labels
, const long* values
, wxPGChoices
* choicesCache
,
767 const wxColourPropertyValue
& value
)
768 : wxEnumProperty( label
, name
, labels
, values
, choicesCache
)
771 Init( value
.m_type
, value
.m_colour
);
773 Init( wxPG_COLOUR_CUSTOM
, *wxWHITE
);
777 wxSystemColourProperty::wxSystemColourProperty( const wxString
& label
, const wxString
& name
,
778 const wxChar
** labels
, const long* values
, wxPGChoices
* choicesCache
,
779 const wxColour
& value
)
780 : wxEnumProperty( label
, name
, labels
, values
, choicesCache
)
783 Init( wxPG_COLOUR_CUSTOM
, value
);
785 Init( wxPG_COLOUR_CUSTOM
, *wxWHITE
);
789 wxSystemColourProperty::~wxSystemColourProperty() { }
792 wxColourPropertyValue
wxSystemColourProperty::GetVal( const wxVariant
* pVariant
) const
797 if ( pVariant
->IsNull() )
798 return wxColourPropertyValue(wxPG_COLOUR_UNSPECIFIED
, wxColour());
800 wxColourPropertyValue
* v1
= &wxColourPropertyValueFromVariant(*pVariant
);
804 wxColour
* pCol
= wxGetVariantCast(*pVariant
, wxColour
);
806 bool variantProcessed
= true;
812 else if ( pVariant
->GetType() == wxT("wxArrayInt") )
817 if ( arr
.size() >= 3 )
825 if ( arr
.size() >= 4 )
828 col
= wxColour(r
, g
, b
, a
);
832 variantProcessed
= false;
835 else if ( pVariant
->GetType() == wxT("wxColour") )
841 variantProcessed
= false;
844 if ( !variantProcessed
)
845 return wxColourPropertyValue(wxPG_COLOUR_UNSPECIFIED
, wxColour());
847 wxColourPropertyValue
v2( wxPG_COLOUR_CUSTOM
, col
);
849 int colInd
= ColToInd(col
);
850 if ( colInd
!= wxNOT_FOUND
)
856 wxVariant
wxSystemColourProperty::DoTranslateVal( wxColourPropertyValue
& v
) const
858 return wxColourPropertyValueToVariant(v
);
861 int wxSystemColourProperty::ColToInd( const wxColour
& colour
) const
864 size_t i_max
= m_choices
.GetCount() - 1;
866 for ( i
=0; i
<i_max
; i
++ )
868 int ind
= m_choices
[i
].GetValue();
870 if ( colour
== GetColour(ind
) )
872 /*wxLogDebug(wxT("%s(%s): Index %i for ( getcolour(%i,%i,%i), colour(%i,%i,%i))"),
873 GetClassName(),GetLabel().c_str(),
874 (int)i,(int)GetColour(ind).Red(),(int)GetColour(ind).Green(),(int)GetColour(ind).Blue(),
875 (int)colour.Red(),(int)colour.Green(),(int)colour.Blue());*/
883 static inline wxColour
wxColourFromPGLong( long col
)
885 return wxColour((col
&0xFF),((col
>>8)&0xFF),((col
>>16)&0xFF));
889 void wxSystemColourProperty::OnSetValue()
891 // Convert from generic wxobject ptr to wxPGVariantDataColour
892 if ( wxPGIsVariantType(m_value
, wxobject
) )
894 wxASSERT( m_value
.IsValueKindOf(CLASSINFO(wxColour
)) );
895 wxColour
* pCol
= (wxColour
*) m_value
.GetWxObjectPtr();
899 wxColourPropertyValue val
= GetVal(&m_value
);
901 if ( val
.m_type
== wxPG_COLOUR_UNSPECIFIED
)
909 if ( val
.m_type
< wxPG_COLOUR_WEB_BASE
)
910 val
.m_colour
= GetColour( val
.m_type
);
912 m_value
= TranslateVal(val
);
915 wxColourPropertyValue
* pCpv
= &wxColourPropertyValueFromVariant(m_value
);
918 col
= pCpv
->m_colour
;
924 SetValueToUnspecified();
925 SetIndex(wxNOT_FOUND
);
933 if ( pCpv
->m_type
< wxPG_COLOUR_WEB_BASE
)
935 if ( m_choices
.HasValues() )
936 ind
= GetIndexForValue(pCpv
->m_type
);
942 pCpv
->m_type
= wxPG_COLOUR_CUSTOM
;
943 ind
= GetCustomColourIndex();
950 if ( ind
== wxNOT_FOUND
)
951 ind
= GetCustomColourIndex();
958 wxColour
wxSystemColourProperty::GetColour( int index
) const
960 return wxSystemSettings::GetColour( (wxSystemColour
)index
);
963 wxString
wxSystemColourProperty::ColourToString( const wxColour
& col
, int index
) const
965 if ( index
== wxNOT_FOUND
)
966 return wxString::Format(wxT("(%i,%i,%i)"),
971 return m_choices
.GetLabel(index
);
974 wxString
wxSystemColourProperty::GetValueAsString( int argFlags
) const
976 wxColourPropertyValue val
= GetVal();
978 int ind
= GetIndex();
980 // Always show custom colour for textctrl-editor
981 if ( val
.m_type
== wxPG_COLOUR_CUSTOM
||
982 ind
== GetCustomColourIndex() ||
983 (argFlags
& wxPG_PROPERTY_SPECIFIC
) )
985 return ColourToString(val
.m_colour
, wxNOT_FOUND
);
989 return wxEmptyString
;
991 return ColourToString(val
.m_colour
, ind
);
995 wxSize
wxSystemColourProperty::OnMeasureImage( int ) const
997 return wxPG_DEFAULT_IMAGE_SIZE
;
1001 int wxSystemColourProperty::GetCustomColourIndex() const
1003 return m_choices
.GetCount() - 1;
1007 bool wxSystemColourProperty::QueryColourFromUser( wxVariant
& variant
) const
1009 wxASSERT( m_value
.GetType() != wxT("string") );
1012 wxPropertyGrid
* propgrid
= GetGrid();
1013 wxASSERT( propgrid
);
1015 // Must only occur when user triggers event
1016 if ( !(propgrid
->GetInternalFlags() & wxPG_FL_IN_ONCUSTOMEDITOREVENT
) )
1019 wxColourPropertyValue val
= GetVal();
1021 val
.m_type
= wxPG_COLOUR_CUSTOM
;
1024 data
.SetChooseFull(true);
1025 data
.SetColour(val
.m_colour
);
1027 for ( i
= 0; i
< 16; i
++)
1029 wxColour
colour(i
*16, i
*16, i
*16);
1030 data
.SetCustomColour(i
, colour
);
1033 wxColourDialog
dialog(propgrid
, &data
);
1034 if ( dialog
.ShowModal() == wxID_OK
)
1036 wxColourData retData
= dialog
.GetColourData();
1037 val
.m_colour
= retData
.GetColour();
1039 variant
= DoTranslateVal(val
);
1041 SetValueInEvent(variant
);
1050 bool wxSystemColourProperty::IntToValue( wxVariant
& variant
, int number
, int WXUNUSED(argFlags
) ) const
1053 int type
= GetValueForIndex(index
);
1054 bool hasValue
= m_choices
[index
].HasValue();
1056 if ( ( hasValue
&& type
== wxPG_COLOUR_CUSTOM
) ||
1057 ( !hasValue
&& (index
== (int)GetCustomColourIndex() &&
1058 !(m_flags
& wxPG_PROP_HIDE_CUSTOM_COLOUR
))
1062 QueryColourFromUser(variant
);
1066 variant
= TranslateVal( type
, GetColour(type
) );
1072 // Need to do some extra event handling.
1073 bool wxSystemColourProperty::OnEvent( wxPropertyGrid
* propgrid
, wxWindow
* WXUNUSED(primary
), wxEvent
& event
)
1075 if ( propgrid
->IsMainButtonEvent(event
) )
1077 // We need to handle button click in case editor has been
1078 // switched to one that has wxButton as well.
1080 if ( QueryColourFromUser(variant
) )
1086 /*class wxPGColourPropertyRenderer : public wxPGDefaultRenderer
1089 virtual void Render( wxDC& dc, const wxRect& rect,
1090 const wxPropertyGrid* propertyGrid, wxPGProperty* property,
1091 int WXUNUSED(column), int item, int WXUNUSED(flags) ) const
1093 wxASSERT( property->IsKindOf(CLASSINFO(wxSystemColourProperty)) );
1094 wxSystemColourProperty* prop = wxStaticCast(property, wxSystemColourProperty);
1096 dc.SetPen(*wxBLACK_PEN);
1098 ( item < (int)(GetCustomColourIndex) || (prop->HasFlag(wxPG_PROP_HIDE_CUSTOM_COLOUR)))
1102 const wxArrayInt& values = prop->GetValues();
1103 if ( values.GetChildCount() )
1104 colInd = values[item];
1107 dc.SetBrush( wxColour( prop->GetColour( colInd ) ) );
1109 else if ( !prop->IsValueUnspecified() )
1110 dc.SetBrush( prop->GetVal().m_colour );
1112 dc.SetBrush( *wxWHITE );
1114 wxRect imageRect = propertyGrid->GetImageRect(property, item);
1115 wxLogDebug(wxT("%i, %i"),imageRect.x,imageRect.y);
1116 dc.DrawRectangle( rect.x+imageRect.x, rect.y+imageRect.y,
1117 imageRect.width, imageRect.height );
1121 text = property->GetValueAsString();
1123 text = property->GetChoiceString(item);
1124 DrawText( dc, rect, imageRect.width, text );
1129 wxPGColourPropertyRenderer g_wxPGColourPropertyRenderer;
1131 wxPGCellRenderer* wxSystemColourProperty::GetCellRenderer( int column ) const
1134 return &g_wxPGColourPropertyRenderer;
1135 return wxEnumProperty::GetCellRenderer(column);
1138 void wxSystemColourProperty::OnCustomPaint( wxDC
& dc
, const wxRect
& rect
,
1139 wxPGPaintData
& paintdata
)
1143 if ( paintdata
.m_choiceItem
>= 0 && paintdata
.m_choiceItem
< (int)m_choices
.GetCount() &&
1144 paintdata
.m_choiceItem
!= GetCustomColourIndex() )
1146 int colInd
= m_choices
[paintdata
.m_choiceItem
].GetValue();
1147 col
= GetColour( colInd
);
1149 else if ( !IsValueUnspecified() )
1151 col
= GetVal().m_colour
;
1157 dc
.DrawRectangle(rect
);
1162 bool wxSystemColourProperty::StringToValue( wxVariant
& value
, const wxString
& text
, int argFlags
) const
1165 // Accept colour format "[Name] [(R,G,B)]"
1166 // Name takes precedence.
1168 wxString colourName
;
1171 int ppos
= text
.Find(wxT("("));
1173 if ( ppos
== wxNOT_FOUND
)
1179 colourName
= text
.substr(0, ppos
);
1180 colourRGB
= text
.substr(ppos
, text
.length()-ppos
);
1183 // Strip spaces from extremities
1184 colourName
.Trim(true);
1185 colourName
.Trim(false);
1186 colourRGB
.Trim(true);
1188 // Validate colourRGB string - (1,1,1) is shortest allowed
1189 if ( colourRGB
.length() < 7 )
1192 if ( colourRGB
.length() == 0 && m_choices
.GetCount() &&
1193 colourName
== m_choices
.GetLabel(GetCustomColourIndex()) )
1195 if ( !(argFlags
& wxPG_EDITABLE_VALUE
))
1197 // This really should not occurr...
1203 QueryColourFromUser(value
);
1207 wxColourPropertyValue val
;
1211 if ( colourName
.length() )
1213 // Try predefined colour first
1214 bool res
= wxEnumProperty::StringToValue(value
, colourName
, argFlags
);
1215 if ( res
&& GetIndex() >= 0 )
1217 val
.m_type
= GetIndex();
1218 if ( val
.m_type
>= 0 && val
.m_type
< m_choices
.GetCount() && m_choices
[val
.m_type
].HasValue() )
1219 val
.m_type
= m_choices
[val
.m_type
].GetValue();
1221 // Get proper colour for type.
1222 val
.m_colour
= GetColour(val
.m_type
);
1227 if ( colourRGB
.length() && !done
)
1229 // Then check custom colour.
1230 val
.m_type
= wxPG_COLOUR_CUSTOM
;
1232 int r
= -1, g
= -1, b
= -1;
1233 wxSscanf(colourRGB
.c_str(),wxT("(%i,%i,%i)"),&r
,&g
,&b
);
1235 if ( r
>= 0 && r
<= 255 &&
1236 g
>= 0 && g
<= 255 &&
1237 b
>= 0 && b
<= 255 )
1239 val
.m_colour
.Set(r
,g
,b
);
1251 value
= DoTranslateVal(val
);
1258 bool wxSystemColourProperty::DoSetAttribute( const wxString
& name
, wxVariant
& value
)
1260 if ( name
== wxPG_COLOUR_ALLOW_CUSTOM
)
1262 int ival
= wxPGVariantToInt(value
);
1264 SetChoicesExclusive(); // Make sure we don't corrupt colour lists of other properties
1266 if ( ival
&& (m_flags
& wxPG_PROP_HIDE_CUSTOM_COLOUR
) )
1268 // Show custom choice
1269 m_choices
.Insert(wxT("Custom"), GetCustomColourIndex(), wxPG_COLOUR_CUSTOM
);
1270 m_flags
&= ~(wxPG_PROP_HIDE_CUSTOM_COLOUR
);
1272 else if ( !ival
&& !(m_flags
& wxPG_PROP_HIDE_CUSTOM_COLOUR
) )
1274 // Hide custom choice
1275 m_choices
.RemoveAt(GetCustomColourIndex());
1276 m_flags
|= wxPG_PROP_HIDE_CUSTOM_COLOUR
;
1284 // -----------------------------------------------------------------------
1286 // -----------------------------------------------------------------------
1288 static const wxChar
* gs_cp_es_normcolour_labels
[] = {
1308 (const wxChar
*) NULL
1311 static unsigned long gs_cp_es_normcolour_colours
[] = {
1313 wxPG_COLOUR(128,0,0),
1314 wxPG_COLOUR(0,0,128),
1315 wxPG_COLOUR(128,0,128),
1316 wxPG_COLOUR(0,128,128),
1317 wxPG_COLOUR(128,128,128),
1318 wxPG_COLOUR(0,128,0),
1319 wxPG_COLOUR(128,128,0),
1320 wxPG_COLOUR(166,124,81),
1321 wxPG_COLOUR(0,0,255),
1322 wxPG_COLOUR(255,0,255),
1323 wxPG_COLOUR(255,0,0),
1324 wxPG_COLOUR(247,148,28),
1325 wxPG_COLOUR(192,192,192),
1326 wxPG_COLOUR(0,255,0),
1327 wxPG_COLOUR(0,255,255),
1328 wxPG_COLOUR(255,255,0),
1329 wxPG_COLOUR(255,255,255),
1333 WX_PG_IMPLEMENT_CUSTOM_COLOUR_PROPERTY_USES_WXCOLOUR2(wxColourProperty
,
1334 gs_cp_es_normcolour_labels
,
1336 gs_cp_es_normcolour_colours
,
1339 // -----------------------------------------------------------------------
1341 // -----------------------------------------------------------------------
1343 #define wxPG_CURSOR_IMAGE_WIDTH 32
1345 #define NUM_CURSORS 28
1347 //#define wx_cp_es_syscursors_len 28
1348 static const wxChar
* gs_cp_es_syscursors_labels
[NUM_CURSORS
+1] = {
1360 wxT("Middle Button"),
1366 wxT("Question Arrow"),
1367 wxT("Right Button"),
1368 wxT("Sizing NE-SW"),
1370 wxT("Sizing NW-SE"),
1377 (const wxChar
*) NULL
1380 static long gs_cp_es_syscursors_values
[NUM_CURSORS
] = {
1383 wxCURSOR_RIGHT_ARROW
,
1390 wxCURSOR_LEFT_BUTTON
,
1392 wxCURSOR_MIDDLE_BUTTON
,
1394 wxCURSOR_PAINT_BRUSH
,
1396 wxCURSOR_POINT_LEFT
,
1397 wxCURSOR_POINT_RIGHT
,
1398 wxCURSOR_QUESTION_ARROW
,
1399 wxCURSOR_RIGHT_BUTTON
,
1411 IMPLEMENT_DYNAMIC_CLASS(wxCursorProperty
, wxEnumProperty
)
1413 wxCursorProperty::wxCursorProperty( const wxString
& label
, const wxString
& name
,
1415 : wxEnumProperty( label
,
1417 gs_cp_es_syscursors_labels
,
1418 gs_cp_es_syscursors_values
,
1421 m_flags
|= wxPG_PROP_STATIC_CHOICES
; // Cursor selection cannot be changed.
1424 wxCursorProperty::~wxCursorProperty()
1428 wxSize
wxCursorProperty::OnMeasureImage( int item
) const
1430 #if wxPG_CAN_DRAW_CURSOR
1431 if ( item
!= -1 && item
< NUM_CURSORS
)
1432 return wxSize(wxPG_CURSOR_IMAGE_WIDTH
,wxPG_CURSOR_IMAGE_WIDTH
);
1439 #if wxPG_CAN_DRAW_CURSOR
1441 void wxCursorProperty::OnCustomPaint( wxDC
& dc
,
1443 wxPGPaintData
& paintdata
)
1446 dc
.SetBrush( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE
) );
1448 if ( paintdata
.m_choiceItem
>= 0 )
1450 dc
.DrawRectangle( rect
);
1452 if ( paintdata
.m_choiceItem
< NUM_CURSORS
)
1454 int cursorindex
= gs_cp_es_syscursors_values
[paintdata
.m_choiceItem
];
1457 if ( cursorindex
== wxCURSOR_NONE
)
1458 cursorindex
= wxCURSOR_ARROW
;
1460 wxCursor
cursor( cursorindex
);
1463 HDC hDc
= (HDC
)((const wxMSWDCImpl
*)dc
.GetImpl())->GetHDC();
1467 (HICON
)cursor
.GetHandle(),
1472 DI_COMPAT
| DI_DEFAULTSIZE
| DI_NORMAL
1481 void wxCursorProperty::OnCustomPaint( wxDC
&, const wxRect
&, wxPGPaintData
& ) { }
1482 /*wxPGCellRenderer* wxCursorProperty::GetCellRenderer( int column ) const
1484 return wxEnumProperty::GetCellRenderer(column);
1488 // -----------------------------------------------------------------------
1489 // wxImageFileProperty
1490 // -----------------------------------------------------------------------
1494 const wxString
& wxPGGetDefaultImageWildcard()
1496 // Form the wildcard, if not done yet
1497 if ( !wxPGGlobalVars
->m_pDefaultImageWildcard
.length() )
1502 // TODO: This section may require locking (using global).
1504 wxList
& handlers
= wxImage::GetHandlers();
1506 wxList::iterator node
;
1508 // Let's iterate over the image handler list.
1509 //for ( wxList::Node *node = handlers.GetFirst(); node; node = node->GetNext() )
1510 for ( node
= handlers
.begin(); node
!= handlers
.end(); node
++ )
1512 wxImageHandler
*handler
= (wxImageHandler
*)*node
;
1514 wxString ext_lo
= handler
->GetExtension();
1515 wxString ext_up
= ext_lo
.Upper();
1517 str
.append( ext_up
);
1518 str
.append( wxT(" files (*.") );
1519 str
.append( ext_up
);
1520 str
.append( wxT(")|*.") );
1521 str
.append( ext_lo
);
1522 str
.append( wxT("|") );
1525 str
.append ( wxT("All files (*.*)|*.*") );
1527 wxPGGlobalVars
->m_pDefaultImageWildcard
= str
;
1530 return wxPGGlobalVars
->m_pDefaultImageWildcard
;
1533 WX_PG_IMPLEMENT_DERIVED_PROPERTY_CLASS(wxImageFileProperty
,
1537 wxImageFileProperty::wxImageFileProperty( const wxString
& label
, const wxString
& name
,
1538 const wxString
& value
)
1539 : wxFileProperty(label
,name
,value
)
1541 SetAttribute( wxPG_FILE_WILDCARD
, wxPGGetDefaultImageWildcard() );
1543 m_pImage
= (wxImage
*) NULL
;
1544 m_pBitmap
= (wxBitmap
*) NULL
;
1547 wxImageFileProperty::~wxImageFileProperty()
1555 void wxImageFileProperty::OnSetValue()
1557 wxFileProperty::OnSetValue();
1571 // Create the image thumbnail
1572 if ( m_filename
.FileExists() )
1574 m_pImage
= new wxImage( m_filename
.GetFullPath() );
1578 wxSize
wxImageFileProperty::OnMeasureImage( int ) const
1580 return wxPG_DEFAULT_IMAGE_SIZE
;
1583 void wxImageFileProperty::OnCustomPaint( wxDC
& dc
,
1587 if ( m_pBitmap
|| (m_pImage
&& m_pImage
->Ok() ) )
1589 // Draw the thumbnail
1591 // Create the bitmap here because required size is not known in OnSetValue().
1594 m_pImage
->Rescale( rect
.width
, rect
.height
);
1595 m_pBitmap
= new wxBitmap( *m_pImage
);
1600 dc
.DrawBitmap( *m_pBitmap
, rect
.x
, rect
.y
, false );
1604 // No file - just draw a white box
1605 dc
.SetBrush( *wxWHITE_BRUSH
);
1606 dc
.DrawRectangle ( rect
);
1610 #endif // wxUSE_IMAGE
1612 // -----------------------------------------------------------------------
1613 // wxMultiChoiceProperty
1614 // -----------------------------------------------------------------------
1618 #include <wx/choicdlg.h>
1620 WX_PG_IMPLEMENT_PROPERTY_CLASS(wxMultiChoiceProperty
,wxPGProperty
,
1621 wxArrayInt
,const wxArrayInt
&,TextCtrlAndButton
)
1623 wxMultiChoiceProperty::wxMultiChoiceProperty( const wxString
& label
,
1624 const wxString
& name
,
1625 const wxPGChoices
& choices
,
1626 const wxArrayString
& value
)
1627 : wxPGProperty(label
,name
)
1629 m_choices
.Assign(choices
);
1633 wxMultiChoiceProperty::wxMultiChoiceProperty( const wxString
& label
,
1634 const wxString
& name
,
1635 const wxArrayString
& strings
,
1636 const wxArrayString
& value
)
1637 : wxPGProperty(label
,name
)
1639 m_choices
.Set(strings
);
1643 wxMultiChoiceProperty::wxMultiChoiceProperty( const wxString
& label
,
1644 const wxString
& name
,
1645 const wxArrayString
& value
)
1646 : wxPGProperty(label
,name
)
1648 wxArrayString strings
;
1649 m_choices
.Set(strings
);
1653 wxMultiChoiceProperty::~wxMultiChoiceProperty()
1657 void wxMultiChoiceProperty::OnSetValue()
1659 GenerateValueAsString();
1662 wxString
wxMultiChoiceProperty::GetValueAsString( int ) const
1667 void wxMultiChoiceProperty::GenerateValueAsString()
1669 wxArrayString strings
;
1671 if ( wxPGIsVariantType(m_value
, arrstring
) )
1672 strings
= m_value
.GetArrayString();
1674 wxString
& tempStr
= m_display
;
1676 unsigned int itemCount
= strings
.size();
1681 tempStr
.append( wxT("\"") );
1683 for ( i
= 0; i
< itemCount
; i
++ )
1685 tempStr
.append( strings
[i
] );
1686 tempStr
.append( wxT("\"") );
1687 if ( i
< (itemCount
-1) )
1688 tempStr
.append ( wxT(" \"") );
1692 wxArrayInt
wxMultiChoiceProperty::GetValueAsIndices() const
1694 const wxArrayInt
& valueArr
= wxArrayIntFromVariant(GetValue());
1697 // Translate values to string indices.
1698 wxArrayInt selections
;
1700 if ( !m_choices
.IsOk() || !m_choices
.GetCount() || !(&valueArr
) )
1702 for ( i
=0; i
<valueArr
.size(); i
++ )
1707 for ( i
=0; i
<valueArr
.size(); i
++ )
1709 int sIndex
= m_choices
.Index(valueArr
[i
]);
1711 selections
.Add(sIndex
);
1718 bool wxMultiChoiceProperty::OnEvent( wxPropertyGrid
* propgrid
,
1719 wxWindow
* WXUNUSED(primary
),
1722 if ( propgrid
->IsMainButtonEvent(event
) )
1725 PrepareValueForDialogEditing(propgrid
);
1727 wxArrayString labels
= m_choices
.GetLabels();
1728 unsigned int choiceCount
;
1730 if ( m_choices
.IsOk() )
1731 choiceCount
= m_choices
.GetCount();
1735 // launch editor dialog
1736 wxMultiChoiceDialog
dlg( propgrid
,
1737 _("Make a selection:"),
1740 choiceCount
?&labels
[0]:NULL
,
1741 wxCHOICEDLG_STYLE
);
1743 dlg
.Move( propgrid
->GetGoodEditorDialogPosition(this,dlg
.GetSize()) );
1745 wxArrayString strings
= m_value
.GetArrayString();
1746 wxArrayString extraStrings
;
1748 dlg
.SetSelections(m_choices
.GetIndicesForStrings(strings
, &extraStrings
));
1750 if ( dlg
.ShowModal() == wxID_OK
&& choiceCount
)
1752 int userStringMode
= GetAttributeAsLong(wxT("UserStringMode"), 0);
1754 wxArrayInt arrInt
= dlg
.GetSelections();
1758 // Strings that were not in list of choices
1759 wxArrayString value
;
1761 // Translate string indices to strings
1764 if ( userStringMode
== 1 )
1766 for (n
=0;n
<extraStrings
.size();n
++)
1767 value
.push_back(extraStrings
[n
]);
1771 for ( i
=0; i
<arrInt
.size(); i
++ )
1772 value
.Add(m_choices
.GetLabel(arrInt
.Item(i
)));
1774 if ( userStringMode
== 2 )
1776 for (n
=0;n
<extraStrings
.size();n
++)
1777 value
.push_back(extraStrings
[n
]);
1780 variant
= WXVARIANT(value
);
1782 SetValueInEvent(variant
);
1790 int wxMultiChoiceProperty::GetChoiceInfo( wxPGChoiceInfo
* choiceinfo
)
1793 choiceinfo
->m_choices
= &m_choices
;
1797 bool wxMultiChoiceProperty::StringToValue( wxVariant
& variant
, const wxString
& text
, int ) const
1801 int userStringMode
= GetAttributeAsLong(wxT("UserStringMode"), 0);
1803 WX_PG_TOKENIZER2_BEGIN(text
,wxT('"'))
1804 if ( userStringMode
> 0 || (m_choices
.IsOk() && m_choices
.Index( token
) != wxNOT_FOUND
) )
1806 WX_PG_TOKENIZER2_END()
1808 wxVariant
v( WXVARIANT(arr
) );
1814 #endif // wxUSE_CHOICEDLG
1817 // -----------------------------------------------------------------------
1819 // -----------------------------------------------------------------------
1824 #if wxUSE_DATEPICKCTRL
1825 #define dtCtrl DatePickerCtrl
1827 #define dtCtrl TextCtrl
1830 WX_PG_IMPLEMENT_PROPERTY_CLASS(wxDateProperty
,
1837 wxString
wxDateProperty::ms_defaultDateFormat
;
1840 wxDateProperty::wxDateProperty( const wxString
& label
,
1841 const wxString
& name
,
1842 const wxDateTime
& value
)
1843 : wxPGProperty(label
,name
)
1845 //wxPGRegisterDefaultValueType(wxDateTime)
1847 #if wxUSE_DATEPICKCTRL
1848 wxPGRegisterEditorClass(DatePickerCtrl
);
1850 m_dpStyle
= wxDP_DEFAULT
| wxDP_SHOWCENTURY
;
1858 wxDateProperty::~wxDateProperty()
1862 bool wxDateProperty::StringToValue( wxVariant
& variant
, const wxString
& text
,
1863 int WXUNUSED(argFlags
) ) const
1867 const char* c
= dt
.ParseFormat(text
, wxString(wxDefaultDateTimeFormat
), wxDefaultDateTime
, NULL
);
1878 wxString
wxDateProperty::GetValueAsString( int argFlags
) const
1880 const wxChar
* format
= (const wxChar
*) NULL
;
1882 wxDateTime dateTime
= m_value
.GetDateTime();
1884 if ( !dateTime
.IsValid() )
1885 return wxT("Invalid");
1887 if ( !ms_defaultDateFormat
.length() )
1889 #if wxUSE_DATEPICKCTRL
1890 bool showCentury
= m_dpStyle
& wxDP_SHOWCENTURY
? true : false;
1892 bool showCentury
= true;
1894 ms_defaultDateFormat
= DetermineDefaultDateFormat( showCentury
);
1897 if ( m_format
.length() &&
1898 !(argFlags
& wxPG_FULL_VALUE
) )
1899 format
= m_format
.c_str();
1901 // Determine default from locale
1902 // NB: This is really simple stuff, but can't figure anything
1903 // better without proper support in wxLocale
1905 format
= ms_defaultDateFormat
.c_str();
1907 return dateTime
.Format(format
);
1910 wxString
wxDateProperty::DetermineDefaultDateFormat( bool showCentury
)
1912 // This code is basicly copied from datectlg.cpp's SetFormat
1917 dt
.ParseFormat(wxT("2003-10-13"), wxT("%Y-%m-%d"));
1918 wxString
str(dt
.Format(wxT("%x")));
1920 const wxChar
*p
= str
.c_str();
1924 if (n
== dt
.GetDay())
1926 format
.Append(wxT("%d"));
1929 else if (n
== (int)dt
.GetMonth()+1)
1931 format
.Append(wxT("%m"));
1934 else if (n
== dt
.GetYear())
1936 format
.Append(wxT("%Y"));
1939 else if (n
== (dt
.GetYear() % 100))
1942 format
.Append(wxT("%Y"));
1944 format
.Append(wxT("%y"));
1948 format
.Append(*p
++);
1954 bool wxDateProperty::DoSetAttribute( const wxString
& name
, wxVariant
& value
)
1956 if ( name
== wxPG_DATE_FORMAT
)
1958 m_format
= value
.GetString();
1961 else if ( name
== wxPG_DATE_PICKER_STYLE
)
1963 m_dpStyle
= value
.GetLong();
1964 ms_defaultDateFormat
.clear(); // This may need recalculation
1970 #endif // wxUSE_DATETIME
1973 // -----------------------------------------------------------------------
1974 // wxPropertyGridInterface
1975 // -----------------------------------------------------------------------
1977 void wxPropertyGridInterface::InitAllTypeHandlers()
1981 // -----------------------------------------------------------------------
1983 void wxPropertyGridInterface::RegisterAdditionalEditors()
1986 wxPGRegisterEditorClass(SpinCtrl
);
1988 #if wxUSE_DATEPICKCTRL
1989 wxPGRegisterEditorClass(DatePickerCtrl
);
1993 // -----------------------------------------------------------------------
1995 #endif // wxPG_INCLUDE_ADVPROPS