Colour property with attribute wxPG_COLOUR_ALLOW_CUSTOM = false did not render correctly
[wxWidgets.git] / src / propgrid / advprops.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/propgrid/advprops.cpp
3 // Purpose: wxPropertyGrid Advanced Properties (font, colour, etc.)
4 // Author: Jaakko Salli
5 // Modified by:
6 // Created: 2004-09-25
7 // RCS-ID: $Id$
8 // Copyright: (c) Jaakko Salli
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 // For compilers that support precompilation, includes "wx/wx.h".
13 #include "wx/wxprec.h"
14
15 #ifdef __BORLANDC__
16 #pragma hdrstop
17 #endif
18
19 #if wxUSE_PROPGRID
20
21 #ifndef WX_PRECOMP
22 #include "wx/defs.h"
23 #include "wx/object.h"
24 #include "wx/hash.h"
25 #include "wx/string.h"
26 #include "wx/log.h"
27 #include "wx/event.h"
28 #include "wx/window.h"
29 #include "wx/panel.h"
30 #include "wx/dc.h"
31 #include "wx/dcclient.h"
32 #include "wx/button.h"
33 #include "wx/pen.h"
34 #include "wx/brush.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"
45 #include "wx/sizer.h"
46 #include "wx/textdlg.h"
47 #include "wx/filedlg.h"
48 #include "wx/intl.h"
49 #include "wx/wxcrtvararg.h"
50 #endif
51
52 #define __wxPG_SOURCE_FILE__
53
54 #include "wx/propgrid/propgrid.h"
55
56 #if wxPG_INCLUDE_ADVPROPS
57
58 #include "wx/propgrid/advprops.h"
59
60 #ifdef __WXMSW__
61 #include "wx/msw/private.h"
62 #include "wx/msw/dc.h"
63 #endif
64
65 // -----------------------------------------------------------------------
66
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
73 #else
74 #define wxPG_CAN_DRAW_CURSOR 0
75 #endif
76
77
78 // -----------------------------------------------------------------------
79 // Value type related
80 // -----------------------------------------------------------------------
81
82
83 // Implement dynamic class for type value.
84 IMPLEMENT_DYNAMIC_CLASS(wxColourPropertyValue, wxObject)
85
86 bool operator == (const wxColourPropertyValue& a, const wxColourPropertyValue& b)
87 {
88 return ( ( a.m_colour == b.m_colour ) && (a.m_type == b.m_type) );
89 }
90
91 bool operator == (const wxArrayInt& array1, const wxArrayInt& array2)
92 {
93 if ( array1.size() != array2.size() )
94 return false;
95 size_t i;
96 for ( i=0; i<array1.size(); i++ )
97 {
98 if ( array1[i] != array2[i] )
99 return false;
100 }
101 return true;
102 }
103
104 // -----------------------------------------------------------------------
105 // wxSpinCtrl-based property editor
106 // -----------------------------------------------------------------------
107
108 #if wxUSE_SPINBTN
109
110
111 #ifdef __WXMSW__
112 #define IS_MOTION_SPIN_SUPPORTED 1
113 #else
114 #define IS_MOTION_SPIN_SUPPORTED 0
115 #endif
116
117 #if IS_MOTION_SPIN_SUPPORTED
118
119 //
120 // This class implements ability to rapidly change "spin" value
121 // by moving mouse when one of the spin buttons is depressed.
122 class wxPGSpinButton : public wxSpinButton
123 {
124 public:
125 wxPGSpinButton() : wxSpinButton()
126 {
127 m_bLeftDown = false;
128 m_hasCapture = false;
129 m_spins = 1;
130
131 Connect( wxEVT_LEFT_DOWN,
132 wxMouseEventHandler(wxPGSpinButton::OnMouseEvent) );
133 Connect( wxEVT_LEFT_UP,
134 wxMouseEventHandler(wxPGSpinButton::OnMouseEvent) );
135 Connect( wxEVT_MOTION,
136 wxMouseEventHandler(wxPGSpinButton::OnMouseEvent) );
137 Connect( wxEVT_MOUSE_CAPTURE_LOST,
138 wxMouseCaptureLostEventHandler(wxPGSpinButton::OnMouseCaptureLost) );
139 }
140
141 int GetSpins() const
142 {
143 return m_spins;
144 }
145
146 private:
147 wxPoint m_ptPosition;
148
149 // Having a separate spins variable allows us to handle validation etc. for
150 // multiple spin events at once (with quick mouse movements there could be
151 // hundreds of 'spins' being done at once). Technically things like this
152 // should be stored in event (wxSpinEvent in this case), but there probably
153 // isn't anything there that can be reliably reused.
154 int m_spins;
155
156 bool m_bLeftDown;
157
158 // SpinButton seems to be a special for mouse capture, so we may need track
159 // privately whether mouse is actually captured.
160 bool m_hasCapture;
161
162 void Capture()
163 {
164 if ( !m_hasCapture )
165 {
166 CaptureMouse();
167 m_hasCapture = true;
168 }
169
170 SetCursor(wxCURSOR_SIZENS);
171 }
172 void Release()
173 {
174 m_bLeftDown = false;
175
176 if ( m_hasCapture )
177 {
178 ReleaseMouse();
179 m_hasCapture = false;
180 }
181
182 wxWindow *parent = GetParent();
183 if ( parent )
184 SetCursor(parent->GetCursor());
185 else
186 SetCursor(wxNullCursor);
187 }
188
189 void OnMouseEvent(wxMouseEvent& event)
190 {
191 if ( event.GetEventType() == wxEVT_LEFT_DOWN )
192 {
193 m_bLeftDown = true;
194 m_ptPosition = event.GetPosition();
195 }
196 else if ( event.GetEventType() == wxEVT_LEFT_UP )
197 {
198 Release();
199 m_bLeftDown = false;
200 }
201 else if ( event.GetEventType() == wxEVT_MOTION )
202 {
203 if ( m_bLeftDown )
204 {
205 int dy = m_ptPosition.y - event.GetPosition().y;
206 if ( dy )
207 {
208 Capture();
209 m_ptPosition = event.GetPosition();
210
211 wxSpinEvent evtscroll( (dy >= 0) ? wxEVT_SCROLL_LINEUP :
212 wxEVT_SCROLL_LINEDOWN,
213 GetId() );
214 evtscroll.SetEventObject(this);
215
216 wxASSERT( m_spins == 1 );
217
218 m_spins = abs(dy);
219 GetEventHandler()->ProcessEvent(evtscroll);
220 m_spins = 1;
221 }
222 }
223 }
224
225 event.Skip();
226 }
227 void OnMouseCaptureLost(wxMouseCaptureLostEvent& WXUNUSED(event))
228 {
229 Release();
230 }
231 };
232
233 #endif // IS_MOTION_SPIN_SUPPORTED
234
235
236 WX_PG_IMPLEMENT_INTERNAL_EDITOR_CLASS(SpinCtrl,
237 wxPGSpinCtrlEditor,
238 wxPGEditor)
239
240
241 // Trivial destructor.
242 wxPGSpinCtrlEditor::~wxPGSpinCtrlEditor()
243 {
244 }
245
246
247 // Create controls and initialize event handling.
248 wxPGWindowList wxPGSpinCtrlEditor::CreateControls( wxPropertyGrid* propgrid, wxPGProperty* property,
249 const wxPoint& pos, const wxSize& sz ) const
250 {
251 const int margin = 1;
252 wxSize butSz(18, sz.y);
253 wxSize tcSz(sz.x - butSz.x - margin, sz.y);
254 wxPoint butPos(pos.x + tcSz.x + margin, pos.y);
255
256 wxSpinButton* wnd2;
257
258 #if IS_MOTION_SPIN_SUPPORTED
259 if ( property->GetAttributeAsLong(wxT("MotionSpin"), 0) )
260 {
261 wnd2 = new wxPGSpinButton();
262 }
263 else
264 #endif
265 {
266 wnd2 = new wxSpinButton();
267 }
268
269 #ifdef __WXMSW__
270 wnd2->Hide();
271 #endif
272 wnd2->Create( propgrid->GetPanel(), wxPG_SUBID2, butPos, butSz, wxSP_VERTICAL );
273
274 wnd2->SetRange( INT_MIN, INT_MAX );
275 wnd2->SetValue( 0 );
276
277 // Let's add validator to make sure only numbers can be entered
278 wxTextValidator validator(wxFILTER_NUMERIC, &m_tempString);
279
280 wxTextCtrl* wnd1 = (wxTextCtrl*) wxPGTextCtrlEditor::CreateControls( propgrid, property, pos, tcSz ).m_primary;
281 wnd1->SetValidator(validator);
282
283 return wxPGWindowList(wnd1, wnd2);
284 }
285
286 // Control's events are redirected here
287 bool wxPGSpinCtrlEditor::OnEvent( wxPropertyGrid* propgrid, wxPGProperty* property,
288 wxWindow* wnd, wxEvent& event ) const
289 {
290 int evtType = event.GetEventType();
291 int keycode = -1;
292 int spins = 1;
293 bool bigStep = false;
294
295 if ( evtType == wxEVT_KEY_DOWN )
296 {
297 wxKeyEvent& keyEvent = (wxKeyEvent&)event;
298 keycode = keyEvent.GetKeyCode();
299
300 if ( keycode == WXK_UP )
301 evtType = wxEVT_SCROLL_LINEUP;
302 else if ( keycode == WXK_DOWN )
303 evtType = wxEVT_SCROLL_LINEDOWN;
304 else if ( keycode == WXK_PAGEUP )
305 {
306 evtType = wxEVT_SCROLL_LINEUP;
307 bigStep = true;
308 }
309 else if ( keycode == WXK_PAGEDOWN )
310 {
311 evtType = wxEVT_SCROLL_LINEDOWN;
312 bigStep = true;
313 }
314 }
315
316 if ( evtType == wxEVT_SCROLL_LINEUP || evtType == wxEVT_SCROLL_LINEDOWN )
317 {
318 #if IS_MOTION_SPIN_SUPPORTED
319 if ( property->GetAttributeAsLong(wxT("MotionSpin"), 0) )
320 {
321 wxPGSpinButton* spinButton =
322 (wxPGSpinButton*) propgrid->GetEditorControlSecondary();
323
324 if ( spinButton )
325 spins = spinButton->GetSpins();
326 }
327 #endif
328
329 wxString s;
330 // Can't use wnd since it might be clipper window
331 wxTextCtrl* tc = wxDynamicCast(propgrid->GetEditorControl(), wxTextCtrl);
332
333 if ( tc )
334 s = tc->GetValue();
335 else
336 s = property->GetValueAsString(wxPG_FULL_VALUE);
337
338 int mode = wxPG_PROPERTY_VALIDATION_SATURATE;
339
340 if ( property->GetAttributeAsLong(wxT("Wrap"), 0) )
341 mode = wxPG_PROPERTY_VALIDATION_WRAP;
342
343 if ( property->GetValueType() == wxT("double") )
344 {
345 double v_d;
346 double step = property->GetAttributeAsDouble(wxT("Step"), 1.0);
347
348 // Try double
349 if ( s.ToDouble(&v_d) )
350 {
351 if ( bigStep )
352 step *= 10.0;
353
354 step *= (double) spins;
355
356 if ( evtType == wxEVT_SCROLL_LINEUP ) v_d += step;
357 else v_d -= step;
358
359 // Min/Max check
360 wxFloatProperty::DoValidation(property, v_d, NULL, mode);
361
362 wxPropertyGrid::DoubleToString(s, v_d, 6, true, NULL);
363 }
364 else
365 {
366 return false;
367 }
368 }
369 else
370 {
371 wxLongLong_t v_ll;
372 wxLongLong_t step = property->GetAttributeAsLong(wxT("Step"), 1);
373
374 // Try (long) long
375 if ( s.ToLongLong(&v_ll, 10) )
376 {
377 if ( bigStep )
378 step *= 10;
379
380 step *= spins;
381
382 if ( evtType == wxEVT_SCROLL_LINEUP ) v_ll += step;
383 else v_ll -= step;
384
385 // Min/Max check
386 wxIntProperty::DoValidation(property, v_ll, NULL, mode);
387
388 s = wxLongLong(v_ll).ToString();
389 }
390 else
391 {
392 return false;
393 }
394 }
395
396 if ( tc )
397 {
398 int ip = tc->GetInsertionPoint();
399 int lp = tc->GetLastPosition();
400 tc->SetValue(s);
401 tc->SetInsertionPoint(ip+(tc->GetLastPosition()-lp));
402 }
403
404 return true;
405 }
406
407 return wxPGTextCtrlEditor::OnEvent(propgrid,property,wnd,event);
408 }
409
410 #endif // wxUSE_SPINBTN
411
412
413 // -----------------------------------------------------------------------
414 // wxDatePickerCtrl-based property editor
415 // -----------------------------------------------------------------------
416
417 #if wxUSE_DATEPICKCTRL
418
419
420 #include "wx/datectrl.h"
421 #include "wx/dateevt.h"
422
423 class wxPGDatePickerCtrlEditor : public wxPGEditor
424 {
425 DECLARE_DYNAMIC_CLASS(wxPGDatePickerCtrlEditor)
426 public:
427 virtual ~wxPGDatePickerCtrlEditor();
428
429 wxString GetName() const;
430 virtual wxPGWindowList CreateControls(wxPropertyGrid* propgrid,
431 wxPGProperty* property,
432 const wxPoint& pos,
433 const wxSize& size) const;
434 virtual void UpdateControl( wxPGProperty* property, wxWindow* wnd ) const;
435 virtual bool OnEvent( wxPropertyGrid* propgrid, wxPGProperty* property,
436 wxWindow* wnd, wxEvent& event ) const;
437 virtual bool GetValueFromControl( wxVariant& variant, wxPGProperty* property, wxWindow* wnd ) const;
438 virtual void SetValueToUnspecified( wxPGProperty* WXUNUSED(property), wxWindow* wnd ) const;
439 };
440
441
442 WX_PG_IMPLEMENT_INTERNAL_EDITOR_CLASS(DatePickerCtrl,
443 wxPGDatePickerCtrlEditor,
444 wxPGEditor)
445
446
447 wxPGDatePickerCtrlEditor::~wxPGDatePickerCtrlEditor()
448 {
449 }
450
451 wxPGWindowList wxPGDatePickerCtrlEditor::CreateControls( wxPropertyGrid* propgrid,
452 wxPGProperty* property,
453 const wxPoint& pos,
454 const wxSize& sz ) const
455 {
456 wxCHECK_MSG( property->IsKindOf(CLASSINFO(wxDateProperty)),
457 NULL,
458 wxT("DatePickerCtrl editor can only be used with wxDateProperty or derivative.") );
459
460 wxDateProperty* prop = wxDynamicCast(property, wxDateProperty);
461
462 // Use two stage creation to allow cleaner display on wxMSW
463 wxDatePickerCtrl* ctrl = new wxDatePickerCtrl();
464 #ifdef __WXMSW__
465 ctrl->Hide();
466 wxSize useSz = wxDefaultSize;
467 useSz.x = sz.x;
468 #else
469 wxSize useSz = sz;
470 #endif
471
472 wxDateTime dateValue(wxInvalidDateTime);
473
474 wxVariant value = prop->GetValue();
475 if ( value.GetType() == wxT("datetime") )
476 dateValue = value.GetDateTime();
477
478 ctrl->Create(propgrid->GetPanel(),
479 wxPG_SUBID1,
480 dateValue,
481 pos,
482 useSz,
483 prop->GetDatePickerStyle() | wxNO_BORDER);
484
485 #ifdef __WXMSW__
486 ctrl->Show();
487 #endif
488
489 return ctrl;
490 }
491
492 // Copies value from property to control
493 void wxPGDatePickerCtrlEditor::UpdateControl( wxPGProperty* property,
494 wxWindow* wnd ) const
495 {
496 wxDatePickerCtrl* ctrl = (wxDatePickerCtrl*) wnd;
497 wxASSERT( ctrl && ctrl->IsKindOf(CLASSINFO(wxDatePickerCtrl)) );
498
499 wxDateTime dateValue(wxInvalidDateTime);
500 wxVariant v(property->GetValue());
501 if ( v.GetType() == wxT("datetime") )
502 dateValue = v.GetDateTime();
503
504 ctrl->SetValue( dateValue );
505 }
506
507 // Control's events are redirected here
508 bool wxPGDatePickerCtrlEditor::OnEvent( wxPropertyGrid* WXUNUSED(propgrid),
509 wxPGProperty* WXUNUSED(property),
510 wxWindow* WXUNUSED(wnd),
511 wxEvent& event ) const
512 {
513 if ( event.GetEventType() == wxEVT_DATE_CHANGED )
514 return true;
515
516 return false;
517 }
518
519 bool wxPGDatePickerCtrlEditor::GetValueFromControl( wxVariant& variant, wxPGProperty* WXUNUSED(property), wxWindow* wnd ) const
520 {
521 wxDatePickerCtrl* ctrl = (wxDatePickerCtrl*) wnd;
522 wxASSERT( ctrl && ctrl->IsKindOf(CLASSINFO(wxDatePickerCtrl)) );
523
524 variant = ctrl->GetValue();
525
526 return true;
527 }
528
529 void wxPGDatePickerCtrlEditor::SetValueToUnspecified( wxPGProperty* property,
530 wxWindow* wnd ) const
531 {
532 wxDatePickerCtrl* ctrl = (wxDatePickerCtrl*) wnd;
533 wxASSERT( ctrl && ctrl->IsKindOf(CLASSINFO(wxDatePickerCtrl)) );
534
535 wxDateProperty* prop = wxDynamicCast(property, wxDateProperty);
536
537 if ( prop )
538 {
539 int datePickerStyle = prop->GetDatePickerStyle();
540 if ( datePickerStyle & wxDP_ALLOWNONE )
541 ctrl->SetValue(wxInvalidDateTime);
542 }
543 }
544
545 #endif // wxUSE_DATEPICKCTRL
546
547
548 // -----------------------------------------------------------------------
549 // wxFontProperty
550 // -----------------------------------------------------------------------
551
552 #include "wx/fontdlg.h"
553 #include "wx/fontenum.h"
554
555 static const wxChar* gs_fp_es_family_labels[] = {
556 wxT("Default"), wxT("Decorative"),
557 wxT("Roman"), wxT("Script"),
558 wxT("Swiss"), wxT("Modern"),
559 (const wxChar*) NULL
560 };
561
562 static long gs_fp_es_family_values[] = {
563 wxDEFAULT, wxDECORATIVE,
564 wxROMAN, wxSCRIPT,
565 wxSWISS, wxMODERN
566 };
567
568 static const wxChar* gs_fp_es_style_labels[] = {
569 wxT("Normal"),
570 wxT("Slant"),
571 wxT("Italic"),
572 (const wxChar*) NULL
573 };
574
575 static long gs_fp_es_style_values[] = {
576 wxNORMAL,
577 wxSLANT,
578 wxITALIC
579 };
580
581 static const wxChar* gs_fp_es_weight_labels[] = {
582 wxT("Normal"),
583 wxT("Light"),
584 wxT("Bold"),
585 (const wxChar*) NULL
586 };
587
588 static long gs_fp_es_weight_values[] = {
589 wxNORMAL,
590 wxLIGHT,
591 wxBOLD
592 };
593
594 // Class body is in advprops.h
595
596
597 WX_PG_IMPLEMENT_PROPERTY_CLASS(wxFontProperty,wxPGProperty,
598 wxFont,const wxFont&,TextCtrlAndButton)
599
600
601 wxFontProperty::wxFontProperty( const wxString& label, const wxString& name,
602 const wxFont& value )
603 : wxPGProperty(label,name)
604 {
605 SetValue(WXVARIANT(value));
606
607 // Initialize font family choices list
608 if ( !wxPGGlobalVars->m_fontFamilyChoices )
609 {
610 wxArrayString faceNames = wxFontEnumerator::GetFacenames();
611
612 faceNames.Sort();
613
614 wxPGGlobalVars->m_fontFamilyChoices = new wxPGChoices(faceNames);
615 }
616
617 wxString emptyString(wxEmptyString);
618
619 wxFont font;
620 font << m_value;
621
622 AddPrivateChild( new wxIntProperty( _("Point Size"),
623 wxS("Point Size"),(long)font.GetPointSize() ) );
624
625 AddPrivateChild( new wxEnumProperty(_("Family"), wxS("PointSize"),
626 gs_fp_es_family_labels,gs_fp_es_family_values,
627 font.GetFamily()) );
628
629 wxString faceName = font.GetFaceName();
630 // If font was not in there, add it now
631 if ( faceName.length() &&
632 wxPGGlobalVars->m_fontFamilyChoices->Index(faceName) == wxNOT_FOUND )
633 wxPGGlobalVars->m_fontFamilyChoices->AddAsSorted(faceName);
634
635 wxPGProperty* p = new wxEnumProperty(_("Face Name"), wxS("Face Name"),
636 *wxPGGlobalVars->m_fontFamilyChoices);
637
638 p->SetValueFromString(faceName, wxPG_FULL_VALUE);
639
640 AddPrivateChild( p );
641
642 AddPrivateChild( new wxEnumProperty(_("Style"), wxS("Style"),
643 gs_fp_es_style_labels,gs_fp_es_style_values,
644 font.GetStyle()) );
645
646 AddPrivateChild( new wxEnumProperty(_("Weight"), wxS("Weight"),
647 gs_fp_es_weight_labels,gs_fp_es_weight_values,
648 font.GetWeight()) );
649
650 AddPrivateChild( new wxBoolProperty(_("Underlined"), wxS("Underlined"),
651 font.GetUnderlined()) );
652 }
653
654 wxFontProperty::~wxFontProperty() { }
655
656 void wxFontProperty::OnSetValue()
657 {
658 wxFont font;
659 font << m_value;
660
661 if ( !font.Ok() )
662 {
663 m_value << *wxNORMAL_FONT;
664 }
665 }
666
667 wxString wxFontProperty::ValueToString( wxVariant& value,
668 int argFlags ) const
669 {
670 return wxPGProperty::ValueToString(value, argFlags);
671 }
672
673 bool wxFontProperty::OnEvent( wxPropertyGrid* propgrid, wxWindow* WXUNUSED(primary),
674 wxEvent& event )
675 {
676 if ( propgrid->IsMainButtonEvent(event) )
677 {
678 // Update value from last minute changes
679 wxVariant useValue = propgrid->GetUncommittedPropertyValue();
680
681 wxFontData data;
682 wxFont font;
683 font << useValue;
684 data.SetInitialFont( font );
685 data.SetColour(*wxBLACK);
686
687 wxFontDialog dlg(propgrid, data);
688 if ( dlg.ShowModal() == wxID_OK )
689 {
690 propgrid->EditorsValueWasModified();
691
692 wxVariant variant;
693 variant << dlg.GetFontData().GetChosenFont();
694 SetValueInEvent( variant );
695 return true;
696 }
697 }
698 return false;
699 }
700
701 void wxFontProperty::RefreshChildren()
702 {
703 if ( !GetChildCount() ) return;
704 wxFont font;
705 font << m_value;
706 Item(0)->SetValue( (long)font.GetPointSize() );
707 Item(1)->SetValue( (long)font.GetFamily() );
708 Item(2)->SetValueFromString( font.GetFaceName(), wxPG_FULL_VALUE );
709 Item(3)->SetValue( (long)font.GetStyle() );
710 Item(4)->SetValue( (long)font.GetWeight() );
711 Item(5)->SetValue( font.GetUnderlined() );
712 }
713
714 wxVariant wxFontProperty::ChildChanged( wxVariant& thisValue,
715 int ind,
716 wxVariant& childValue ) const
717 {
718 wxFont font;
719 font << thisValue;
720
721 if ( ind == 0 )
722 {
723 font.SetPointSize( childValue.GetLong() );
724 }
725 else if ( ind == 1 )
726 {
727 int fam = childValue.GetLong();
728 if ( fam < wxDEFAULT ||
729 fam > wxTELETYPE )
730 fam = wxDEFAULT;
731 font.SetFamily( fam );
732 }
733 else if ( ind == 2 )
734 {
735 wxString faceName;
736 int faceIndex = childValue.GetLong();
737
738 if ( faceIndex >= 0 )
739 faceName = wxPGGlobalVars->m_fontFamilyChoices->GetLabel(faceIndex);
740
741 font.SetFaceName( faceName );
742 }
743 else if ( ind == 3 )
744 {
745 int st = childValue.GetLong();
746 if ( st != wxFONTSTYLE_NORMAL &&
747 st != wxFONTSTYLE_SLANT &&
748 st != wxFONTSTYLE_ITALIC )
749 st = wxFONTWEIGHT_NORMAL;
750 font.SetStyle( st );
751 }
752 else if ( ind == 4 )
753 {
754 int wt = childValue.GetLong();
755 if ( wt != wxFONTWEIGHT_NORMAL &&
756 wt != wxFONTWEIGHT_LIGHT &&
757 wt != wxFONTWEIGHT_BOLD )
758 wt = wxFONTWEIGHT_NORMAL;
759 font.SetWeight( wt );
760 }
761 else if ( ind == 5 )
762 {
763 font.SetUnderlined( childValue.GetBool() );
764 }
765
766 wxVariant newVariant;
767 newVariant << font;
768 return newVariant;
769 }
770
771 /*
772 wxSize wxFontProperty::OnMeasureImage() const
773 {
774 return wxSize(-1,-1);
775 }
776
777 void wxFontProperty::OnCustomPaint(wxDC& dc,
778 const wxRect& rect,
779 wxPGPaintData& paintData)
780 {
781 wxString drawFace;
782 if ( paintData.m_choiceItem >= 0 )
783 drawFace = wxPGGlobalVars->m_fontFamilyChoices->GetLabel(paintData.m_choiceItem);
784 else
785 drawFace = m_value_wxFont.GetFaceName();
786
787 if ( drawFace.length() )
788 {
789 // Draw the background
790 dc.SetBrush( wxColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)) );
791 //dc.SetBrush( *wxWHITE_BRUSH );
792 //dc.SetPen( *wxMEDIUM_GREY_PEN );
793 dc.DrawRectangle( rect );
794
795 wxFont oldFont = dc.GetFont();
796 wxFont drawFont(oldFont.GetPointSize(),
797 wxDEFAULT,wxNORMAL,wxBOLD,false,drawFace);
798 dc.SetFont(drawFont);
799
800 dc.SetTextForeground( wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT) );
801 dc.DrawText( wxT("Aa"), rect.x+2, rect.y+1 );
802
803 dc.SetFont(oldFont);
804 }
805 else
806 {
807 // No file - just draw a white box
808 dc.SetBrush ( *wxWHITE_BRUSH );
809 dc.DrawRectangle ( rect );
810 }
811 }
812 */
813
814
815 // -----------------------------------------------------------------------
816 // wxSystemColourProperty
817 // -----------------------------------------------------------------------
818
819 // wxEnumProperty based classes cannot use wxPG_PROP_CLASS_SPECIFIC_1
820 #define wxPG_PROP_HIDE_CUSTOM_COLOUR wxPG_PROP_CLASS_SPECIFIC_2
821
822 #include "wx/colordlg.h"
823
824 //#define wx_cp_es_syscolours_len 25
825 static const wxChar* gs_cp_es_syscolour_labels[] = {
826 wxT("AppWorkspace"),
827 wxT("ActiveBorder"),
828 wxT("ActiveCaption"),
829 wxT("ButtonFace"),
830 wxT("ButtonHighlight"),
831 wxT("ButtonShadow"),
832 wxT("ButtonText"),
833 wxT("CaptionText"),
834 wxT("ControlDark"),
835 wxT("ControlLight"),
836 wxT("Desktop"),
837 wxT("GrayText"),
838 wxT("Highlight"),
839 wxT("HighlightText"),
840 wxT("InactiveBorder"),
841 wxT("InactiveCaption"),
842 wxT("InactiveCaptionText"),
843 wxT("Menu"),
844 wxT("Scrollbar"),
845 wxT("Tooltip"),
846 wxT("TooltipText"),
847 wxT("Window"),
848 wxT("WindowFrame"),
849 wxT("WindowText"),
850 wxT("Custom"),
851 (const wxChar*) NULL
852 };
853
854 static long gs_cp_es_syscolour_values[] = {
855 wxSYS_COLOUR_APPWORKSPACE,
856 wxSYS_COLOUR_ACTIVEBORDER,
857 wxSYS_COLOUR_ACTIVECAPTION,
858 wxSYS_COLOUR_BTNFACE,
859 wxSYS_COLOUR_BTNHIGHLIGHT,
860 wxSYS_COLOUR_BTNSHADOW,
861 wxSYS_COLOUR_BTNTEXT ,
862 wxSYS_COLOUR_CAPTIONTEXT,
863 wxSYS_COLOUR_3DDKSHADOW,
864 wxSYS_COLOUR_3DLIGHT,
865 wxSYS_COLOUR_BACKGROUND,
866 wxSYS_COLOUR_GRAYTEXT,
867 wxSYS_COLOUR_HIGHLIGHT,
868 wxSYS_COLOUR_HIGHLIGHTTEXT,
869 wxSYS_COLOUR_INACTIVEBORDER,
870 wxSYS_COLOUR_INACTIVECAPTION,
871 wxSYS_COLOUR_INACTIVECAPTIONTEXT,
872 wxSYS_COLOUR_MENU,
873 wxSYS_COLOUR_SCROLLBAR,
874 wxSYS_COLOUR_INFOBK,
875 wxSYS_COLOUR_INFOTEXT,
876 wxSYS_COLOUR_WINDOW,
877 wxSYS_COLOUR_WINDOWFRAME,
878 wxSYS_COLOUR_WINDOWTEXT,
879 wxPG_COLOUR_CUSTOM
880 };
881
882
883 IMPLEMENT_VARIANT_OBJECT_EXPORTED_SHALLOWCMP(wxColourPropertyValue, WXDLLIMPEXP_PROPGRID)
884
885
886 // Class body is in advprops.h
887
888 WX_PG_IMPLEMENT_PROPERTY_CLASS(wxSystemColourProperty,wxEnumProperty,
889 wxColourPropertyValue,const wxColourPropertyValue&,Choice)
890
891
892 void wxSystemColourProperty::Init( int type, const wxColour& colour )
893 {
894 wxColourPropertyValue cpv;
895
896 if ( colour.Ok() )
897 cpv.Init( type, colour );
898 else
899 cpv.Init( type, *wxWHITE );
900
901 m_flags |= wxPG_PROP_STATIC_CHOICES; // Colour selection cannot be changed.
902
903 m_value << cpv;
904
905 OnSetValue();
906 }
907
908
909 static wxPGChoices gs_wxSystemColourProperty_choicesCache;
910
911
912 wxSystemColourProperty::wxSystemColourProperty( const wxString& label, const wxString& name,
913 const wxColourPropertyValue& value )
914 : wxEnumProperty( label,
915 name,
916 gs_cp_es_syscolour_labels,
917 gs_cp_es_syscolour_values,
918 &gs_wxSystemColourProperty_choicesCache )
919 {
920 if ( &value )
921 Init( value.m_type, value.m_colour );
922 else
923 Init( wxPG_COLOUR_CUSTOM, *wxWHITE );
924 }
925
926
927 wxSystemColourProperty::wxSystemColourProperty( const wxString& label, const wxString& name,
928 const wxChar** labels, const long* values, wxPGChoices* choicesCache,
929 const wxColourPropertyValue& value )
930 : wxEnumProperty( label, name, labels, values, choicesCache )
931 {
932 if ( &value )
933 Init( value.m_type, value.m_colour );
934 else
935 Init( wxPG_COLOUR_CUSTOM, *wxWHITE );
936 }
937
938
939 wxSystemColourProperty::wxSystemColourProperty( const wxString& label, const wxString& name,
940 const wxChar** labels, const long* values, wxPGChoices* choicesCache,
941 const wxColour& value )
942 : wxEnumProperty( label, name, labels, values, choicesCache )
943 {
944 if ( &value )
945 Init( wxPG_COLOUR_CUSTOM, value );
946 else
947 Init( wxPG_COLOUR_CUSTOM, *wxWHITE );
948 }
949
950
951 wxSystemColourProperty::~wxSystemColourProperty() { }
952
953
954 wxColourPropertyValue wxSystemColourProperty::GetVal( const wxVariant* pVariant ) const
955 {
956 if ( !pVariant )
957 pVariant = &m_value;
958
959 if ( pVariant->IsNull() )
960 return wxColourPropertyValue(wxPG_COLOUR_UNSPECIFIED, wxColour());
961
962 if ( pVariant->GetType() == wxS("wxColourPropertyValue") )
963 {
964 wxColourPropertyValue v;
965 v << *pVariant;
966 return v;
967 }
968
969 wxColour col;
970 bool variantProcessed = true;
971
972 if ( pVariant->GetType() == wxS("wxColour*") )
973 {
974 wxColour* pCol = wxStaticCast(pVariant->GetWxObjectPtr(), wxColour);
975 col = *pCol;
976 }
977 else if ( pVariant->GetType() == wxS("wxColour") )
978 {
979 col << *pVariant;
980 }
981 else if ( pVariant->GetType() == wxArrayInt_VariantType )
982 {
983 // This code is mostly needed for wxPython bindings, which
984 // may offer tuple of integers as colour value.
985 wxArrayInt arr;
986 arr << *pVariant;
987
988 if ( arr.size() >= 3 )
989 {
990 int r, g, b;
991 int a = 255;
992
993 r = arr[0];
994 g = arr[1];
995 b = arr[2];
996 if ( arr.size() >= 4 )
997 a = arr[3];
998
999 col = wxColour(r, g, b, a);
1000 }
1001 else
1002 {
1003 variantProcessed = false;
1004 }
1005 }
1006 else
1007 {
1008 variantProcessed = false;
1009 }
1010
1011 if ( !variantProcessed )
1012 return wxColourPropertyValue(wxPG_COLOUR_UNSPECIFIED, wxColour());
1013
1014 wxColourPropertyValue v2( wxPG_COLOUR_CUSTOM, col );
1015
1016 int colInd = ColToInd(col);
1017 if ( colInd != wxNOT_FOUND )
1018 v2.m_type = colInd;
1019
1020 return v2;
1021 }
1022
1023 wxVariant wxSystemColourProperty::DoTranslateVal( wxColourPropertyValue& v ) const
1024 {
1025 wxVariant variant;
1026 variant << v;
1027 return variant;
1028 }
1029
1030 int wxSystemColourProperty::ColToInd( const wxColour& colour ) const
1031 {
1032 size_t i;
1033 size_t i_max = m_choices.GetCount() - 1;
1034
1035 for ( i=0; i<i_max; i++ )
1036 {
1037 int ind = m_choices[i].GetValue();
1038
1039 if ( colour == GetColour(ind) )
1040 {
1041 /*wxLogDebug(wxT("%s(%s): Index %i for ( getcolour(%i,%i,%i), colour(%i,%i,%i))"),
1042 GetClassName(),GetLabel().c_str(),
1043 (int)i,(int)GetColour(ind).Red(),(int)GetColour(ind).Green(),(int)GetColour(ind).Blue(),
1044 (int)colour.Red(),(int)colour.Green(),(int)colour.Blue());*/
1045 return ind;
1046 }
1047 }
1048 return wxNOT_FOUND;
1049 }
1050
1051 void wxSystemColourProperty::OnSetValue()
1052 {
1053 // Convert from generic wxobject ptr to wxPGVariantDataColour
1054 if ( m_value.GetType() == wxS("wxColour*") )
1055 {
1056 wxColour* pCol = wxStaticCast(m_value.GetWxObjectPtr(), wxColour);
1057 m_value << *pCol;
1058 }
1059
1060 wxColourPropertyValue val = GetVal(&m_value);
1061
1062 if ( val.m_type == wxPG_COLOUR_UNSPECIFIED )
1063 {
1064 m_value.MakeNull();
1065 return;
1066 }
1067 else
1068 {
1069
1070 if ( val.m_type < wxPG_COLOUR_WEB_BASE )
1071 val.m_colour = GetColour( val.m_type );
1072
1073 m_value = TranslateVal(val);
1074 }
1075
1076 int ind = wxNOT_FOUND;
1077
1078 if ( m_value.GetType() == wxS("wxColourPropertyValue") )
1079 {
1080 wxColourPropertyValue cpv;
1081 cpv << m_value;
1082 wxColour col = cpv.m_colour;
1083
1084 if ( !col.Ok() )
1085 {
1086 SetValueToUnspecified();
1087 SetIndex(wxNOT_FOUND);
1088 return;
1089 }
1090
1091 if ( cpv.m_type < wxPG_COLOUR_WEB_BASE )
1092 {
1093 ind = GetIndexForValue(cpv.m_type);
1094 }
1095 else
1096 {
1097 cpv.m_type = wxPG_COLOUR_CUSTOM;
1098 ind = GetCustomColourIndex();
1099 }
1100 }
1101 else
1102 {
1103 wxColour col;
1104 col << m_value;
1105
1106 if ( !col.Ok() )
1107 {
1108 SetValueToUnspecified();
1109 SetIndex(wxNOT_FOUND);
1110 return;
1111 }
1112
1113 ind = ColToInd(col);
1114
1115 if ( ind == wxNOT_FOUND )
1116 ind = GetCustomColourIndex();
1117 }
1118
1119 SetIndex(ind);
1120 }
1121
1122
1123 wxColour wxSystemColourProperty::GetColour( int index ) const
1124 {
1125 return wxSystemSettings::GetColour( (wxSystemColour)index );
1126 }
1127
1128 wxString wxSystemColourProperty::ColourToString( const wxColour& col, int index ) const
1129 {
1130 if ( index == wxNOT_FOUND )
1131 return wxString::Format(wxT("(%i,%i,%i)"),
1132 (int)col.Red(),
1133 (int)col.Green(),
1134 (int)col.Blue());
1135 else
1136 return m_choices.GetLabel(index);
1137 }
1138
1139 wxString wxSystemColourProperty::ValueToString( wxVariant& value,
1140 int argFlags ) const
1141 {
1142 wxColourPropertyValue val = GetVal(&value);
1143
1144 int index;
1145
1146 if ( argFlags & wxPG_VALUE_IS_CURRENT )
1147 {
1148 // GetIndex() only works reliably if wxPG_VALUE_IS_CURRENT flag is set,
1149 // but we should use it whenever possible.
1150 index = GetIndex();
1151
1152 // If custom colour was selected, use invalid index, so that
1153 // ColourToString() will return properly formatted colour text.
1154 if ( index == GetCustomColourIndex() )
1155 index = wxNOT_FOUND;
1156 }
1157 else
1158 {
1159 index = m_choices.Index(val.m_type);
1160 }
1161
1162 return ColourToString(val.m_colour, index);
1163 }
1164
1165
1166 wxSize wxSystemColourProperty::OnMeasureImage( int ) const
1167 {
1168 return wxPG_DEFAULT_IMAGE_SIZE;
1169 }
1170
1171
1172 int wxSystemColourProperty::GetCustomColourIndex() const
1173 {
1174 return m_choices.GetCount() - 1;
1175 }
1176
1177
1178 bool wxSystemColourProperty::QueryColourFromUser( wxVariant& variant ) const
1179 {
1180 wxASSERT( m_value.GetType() != wxPG_VARIANT_TYPE_STRING );
1181 bool res = false;
1182
1183 wxPropertyGrid* propgrid = GetGrid();
1184 wxASSERT( propgrid );
1185
1186 // Must only occur when user triggers event
1187 if ( !(propgrid->GetInternalFlags() & wxPG_FL_IN_HANDLECUSTOMEDITOREVENT) )
1188 return res;
1189
1190 wxColourPropertyValue val = GetVal();
1191
1192 val.m_type = wxPG_COLOUR_CUSTOM;
1193
1194 wxColourData data;
1195 data.SetChooseFull(true);
1196 data.SetColour(val.m_colour);
1197 int i;
1198 for ( i = 0; i < 16; i++)
1199 {
1200 wxColour colour(i*16, i*16, i*16);
1201 data.SetCustomColour(i, colour);
1202 }
1203
1204 wxColourDialog dialog(propgrid, &data);
1205 if ( dialog.ShowModal() == wxID_OK )
1206 {
1207 wxColourData retData = dialog.GetColourData();
1208 val.m_colour = retData.GetColour();
1209
1210 variant = DoTranslateVal(val);
1211
1212 SetValueInEvent(variant);
1213
1214 res = true;
1215 }
1216
1217 return res;
1218 }
1219
1220
1221 bool wxSystemColourProperty::IntToValue( wxVariant& variant, int number, int WXUNUSED(argFlags) ) const
1222 {
1223 int index = number;
1224 int type = m_choices.GetValue(index);
1225
1226 if ( type == wxPG_COLOUR_CUSTOM )
1227 {
1228 QueryColourFromUser(variant);
1229 }
1230 else
1231 {
1232 variant = TranslateVal( type, GetColour(type) );
1233 }
1234
1235 return true;
1236 }
1237
1238 // Need to do some extra event handling.
1239 bool wxSystemColourProperty::OnEvent( wxPropertyGrid* propgrid, wxWindow* WXUNUSED(primary), wxEvent& event )
1240 {
1241 if ( propgrid->IsMainButtonEvent(event) )
1242 {
1243 // We need to handle button click in case editor has been
1244 // switched to one that has wxButton as well.
1245 wxVariant variant;
1246 if ( QueryColourFromUser(variant) )
1247 return true;
1248 }
1249 return false;
1250 }
1251
1252 /*class wxPGColourPropertyRenderer : public wxPGDefaultRenderer
1253 {
1254 public:
1255 virtual void Render( wxDC& dc, const wxRect& rect,
1256 const wxPropertyGrid* propertyGrid, wxPGProperty* property,
1257 int WXUNUSED(column), int item, int WXUNUSED(flags) ) const
1258 {
1259 wxASSERT( property->IsKindOf(CLASSINFO(wxSystemColourProperty)) );
1260 wxSystemColourProperty* prop = wxStaticCast(property, wxSystemColourProperty);
1261
1262 dc.SetPen(*wxBLACK_PEN);
1263 if ( item >= 0 &&
1264 ( item < (int)(GetCustomColourIndex) || (prop->HasFlag(wxPG_PROP_HIDE_CUSTOM_COLOUR)))
1265 )
1266 {
1267 int colInd;
1268 const wxArrayInt& values = prop->GetValues();
1269 if ( values.GetChildCount() )
1270 colInd = values[item];
1271 else
1272 colInd = item;
1273 dc.SetBrush( wxColour( prop->GetColour( colInd ) ) );
1274 }
1275 else if ( !prop->IsValueUnspecified() )
1276 dc.SetBrush( prop->GetVal().m_colour );
1277 else
1278 dc.SetBrush( *wxWHITE );
1279
1280 wxRect imageRect = propertyGrid->GetImageRect(property, item);
1281 wxLogDebug(wxT("%i, %i"),imageRect.x,imageRect.y);
1282 dc.DrawRectangle( rect.x+imageRect.x, rect.y+imageRect.y,
1283 imageRect.width, imageRect.height );
1284
1285 wxString text;
1286 if ( item == -1 )
1287 text = property->GetValueAsString();
1288 else
1289 text = property->GetChoiceString(item);
1290 DrawText( dc, rect, imageRect.width, text );
1291 }
1292 protected:
1293 };
1294
1295 wxPGColourPropertyRenderer g_wxPGColourPropertyRenderer;
1296
1297 wxPGCellRenderer* wxSystemColourProperty::GetCellRenderer( int column ) const
1298 {
1299 if ( column == 1 )
1300 return &g_wxPGColourPropertyRenderer;
1301 return wxEnumProperty::GetCellRenderer(column);
1302 }*/
1303
1304 void wxSystemColourProperty::OnCustomPaint( wxDC& dc, const wxRect& rect,
1305 wxPGPaintData& paintdata )
1306 {
1307 wxColour col;
1308
1309 if ( paintdata.m_choiceItem >= 0 &&
1310 paintdata.m_choiceItem < (int)m_choices.GetCount() &&
1311 (paintdata.m_choiceItem != GetCustomColourIndex() ||
1312 m_flags & wxPG_PROP_HIDE_CUSTOM_COLOUR) )
1313 {
1314 int colInd = m_choices[paintdata.m_choiceItem].GetValue();
1315 col = GetColour( colInd );
1316 }
1317 else if ( !IsValueUnspecified() )
1318 {
1319 col = GetVal().m_colour;
1320 }
1321
1322 if ( col.Ok() )
1323 {
1324 dc.SetBrush(col);
1325 dc.DrawRectangle(rect);
1326 }
1327 }
1328
1329
1330 bool wxSystemColourProperty::StringToValue( wxVariant& value, const wxString& text, int argFlags ) const
1331 {
1332 //
1333 // Accept colour format "[Name] [(R,G,B)]"
1334 // Name takes precedence.
1335 //
1336 wxString colourName;
1337 wxString colourRGB;
1338
1339 int ppos = text.Find(wxT("("));
1340
1341 if ( ppos == wxNOT_FOUND )
1342 {
1343 colourName = text;
1344 }
1345 else
1346 {
1347 colourName = text.substr(0, ppos);
1348 colourRGB = text.substr(ppos, text.length()-ppos);
1349 }
1350
1351 // Strip spaces from extremities
1352 colourName.Trim(true);
1353 colourName.Trim(false);
1354 colourRGB.Trim(true);
1355
1356 // Validate colourRGB string - (1,1,1) is shortest allowed
1357 if ( colourRGB.length() < 7 )
1358 colourRGB.clear();
1359
1360 if ( colourRGB.length() == 0 && m_choices.GetCount() &&
1361 colourName == m_choices.GetLabel(GetCustomColourIndex()) )
1362 {
1363 if ( !(argFlags & wxPG_EDITABLE_VALUE ))
1364 {
1365 // This really should not occurr...
1366 // wxASSERT(false);
1367 ResetNextIndex();
1368 return false;
1369 }
1370
1371 QueryColourFromUser(value);
1372 }
1373 else
1374 {
1375 wxColourPropertyValue val;
1376
1377 bool done = false;
1378
1379 if ( colourName.length() )
1380 {
1381 // Try predefined colour first
1382 bool res = wxEnumProperty::StringToValue(value, colourName, argFlags);
1383 if ( res && GetIndex() >= 0 )
1384 {
1385 val.m_type = GetIndex();
1386 if ( val.m_type < m_choices.GetCount() )
1387 val.m_type = m_choices[val.m_type].GetValue();
1388
1389 // Get proper colour for type.
1390 val.m_colour = GetColour(val.m_type);
1391
1392 done = true;
1393 }
1394 }
1395 if ( colourRGB.length() && !done )
1396 {
1397 // Then check custom colour.
1398 val.m_type = wxPG_COLOUR_CUSTOM;
1399
1400 int r = -1, g = -1, b = -1;
1401 wxSscanf(colourRGB.c_str(),wxT("(%i,%i,%i)"),&r,&g,&b);
1402
1403 if ( r >= 0 && r <= 255 &&
1404 g >= 0 && g <= 255 &&
1405 b >= 0 && b <= 255 )
1406 {
1407 val.m_colour.Set(r,g,b);
1408
1409 done = true;
1410 }
1411 }
1412
1413 if ( !done )
1414 {
1415 ResetNextIndex();
1416 return false;
1417 }
1418
1419 value = DoTranslateVal(val);
1420 }
1421
1422 return true;
1423 }
1424
1425
1426 bool wxSystemColourProperty::DoSetAttribute( const wxString& name, wxVariant& value )
1427 {
1428 if ( name == wxPG_COLOUR_ALLOW_CUSTOM )
1429 {
1430 int ival = value.GetLong();
1431
1432 if ( ival && (m_flags & wxPG_PROP_HIDE_CUSTOM_COLOUR) )
1433 {
1434 // Show custom choice
1435 m_choices.Insert(wxT("Custom"), GetCustomColourIndex(), wxPG_COLOUR_CUSTOM);
1436 m_flags &= ~(wxPG_PROP_HIDE_CUSTOM_COLOUR);
1437 }
1438 else if ( !ival && !(m_flags & wxPG_PROP_HIDE_CUSTOM_COLOUR) )
1439 {
1440 // Hide custom choice
1441 m_choices.RemoveAt(GetCustomColourIndex());
1442 m_flags |= wxPG_PROP_HIDE_CUSTOM_COLOUR;
1443 }
1444 return true;
1445 }
1446 return false;
1447 }
1448
1449
1450 // -----------------------------------------------------------------------
1451 // wxColourProperty
1452 // -----------------------------------------------------------------------
1453
1454 static const wxChar* gs_cp_es_normcolour_labels[] = {
1455 wxT("Black"),
1456 wxT("Maroon"),
1457 wxT("Navy"),
1458 wxT("Purple"),
1459 wxT("Teal"),
1460 wxT("Gray"),
1461 wxT("Green"),
1462 wxT("Olive"),
1463 wxT("Brown"),
1464 wxT("Blue"),
1465 wxT("Fuchsia"),
1466 wxT("Red"),
1467 wxT("Orange"),
1468 wxT("Silver"),
1469 wxT("Lime"),
1470 wxT("Aqua"),
1471 wxT("Yellow"),
1472 wxT("White"),
1473 wxT("Custom"),
1474 (const wxChar*) NULL
1475 };
1476
1477 static unsigned long gs_cp_es_normcolour_colours[] = {
1478 wxPG_COLOUR(0,0,0),
1479 wxPG_COLOUR(128,0,0),
1480 wxPG_COLOUR(0,0,128),
1481 wxPG_COLOUR(128,0,128),
1482 wxPG_COLOUR(0,128,128),
1483 wxPG_COLOUR(128,128,128),
1484 wxPG_COLOUR(0,128,0),
1485 wxPG_COLOUR(128,128,0),
1486 wxPG_COLOUR(166,124,81),
1487 wxPG_COLOUR(0,0,255),
1488 wxPG_COLOUR(255,0,255),
1489 wxPG_COLOUR(255,0,0),
1490 wxPG_COLOUR(247,148,28),
1491 wxPG_COLOUR(192,192,192),
1492 wxPG_COLOUR(0,255,0),
1493 wxPG_COLOUR(0,255,255),
1494 wxPG_COLOUR(255,255,0),
1495 wxPG_COLOUR(255,255,255),
1496 wxPG_COLOUR(0,0,0)
1497 };
1498
1499 WX_PG_IMPLEMENT_PROPERTY_CLASS(wxColourProperty, wxSystemColourProperty,
1500 wxColour, const wxColour&, TextCtrlAndButton)
1501
1502 static wxPGChoices gs_wxColourProperty_choicesCache;
1503
1504 wxColourProperty::wxColourProperty( const wxString& label,
1505 const wxString& name,
1506 const wxColour& value )
1507 : wxSystemColourProperty(label, name, gs_cp_es_normcolour_labels,
1508 NULL,
1509 &gs_wxColourProperty_choicesCache, value )
1510 {
1511 Init( value );
1512
1513 m_flags |= wxPG_PROP_TRANSLATE_CUSTOM;
1514 }
1515
1516 wxColourProperty::~wxColourProperty()
1517 {
1518 }
1519
1520 void wxColourProperty::Init( wxColour colour )
1521 {
1522 if ( !colour.Ok() )
1523 colour = *wxWHITE;
1524 wxVariant variant;
1525 variant << colour;
1526 m_value = variant;
1527 int ind = ColToInd(colour);
1528 if ( ind < 0 )
1529 ind = m_choices.GetCount() - 1;
1530 SetIndex( ind );
1531 }
1532
1533 wxString wxColourProperty::ValueToString( wxVariant& value,
1534 int argFlags ) const
1535 {
1536 const wxPGEditor* editor = GetEditorClass();
1537 if ( editor != wxPGEditor_Choice &&
1538 editor != wxPGEditor_ChoiceAndButton &&
1539 editor != wxPGEditor_ComboBox )
1540 argFlags |= wxPG_PROPERTY_SPECIFIC;
1541
1542 return wxSystemColourProperty::ValueToString(value, argFlags);
1543 }
1544
1545 wxColour wxColourProperty::GetColour( int index ) const
1546 {
1547 return gs_cp_es_normcolour_colours[m_choices.GetValue(index)];
1548 }
1549
1550 wxVariant wxColourProperty::DoTranslateVal( wxColourPropertyValue& v ) const
1551 {
1552 wxVariant variant;
1553 variant << v.m_colour;
1554 return variant;
1555 }
1556
1557 // -----------------------------------------------------------------------
1558 // wxCursorProperty
1559 // -----------------------------------------------------------------------
1560
1561 #define wxPG_CURSOR_IMAGE_WIDTH 32
1562
1563 #define NUM_CURSORS 28
1564
1565 //#define wx_cp_es_syscursors_len 28
1566 static const wxChar* gs_cp_es_syscursors_labels[NUM_CURSORS+1] = {
1567 wxT("Default"),
1568 wxT("Arrow"),
1569 wxT("Right Arrow"),
1570 wxT("Blank"),
1571 wxT("Bullseye"),
1572 wxT("Character"),
1573 wxT("Cross"),
1574 wxT("Hand"),
1575 wxT("I-Beam"),
1576 wxT("Left Button"),
1577 wxT("Magnifier"),
1578 wxT("Middle Button"),
1579 wxT("No Entry"),
1580 wxT("Paint Brush"),
1581 wxT("Pencil"),
1582 wxT("Point Left"),
1583 wxT("Point Right"),
1584 wxT("Question Arrow"),
1585 wxT("Right Button"),
1586 wxT("Sizing NE-SW"),
1587 wxT("Sizing N-S"),
1588 wxT("Sizing NW-SE"),
1589 wxT("Sizing W-E"),
1590 wxT("Sizing"),
1591 wxT("Spraycan"),
1592 wxT("Wait"),
1593 wxT("Watch"),
1594 wxT("Wait Arrow"),
1595 (const wxChar*) NULL
1596 };
1597
1598 static long gs_cp_es_syscursors_values[NUM_CURSORS] = {
1599 wxCURSOR_NONE,
1600 wxCURSOR_ARROW,
1601 wxCURSOR_RIGHT_ARROW,
1602 wxCURSOR_BLANK,
1603 wxCURSOR_BULLSEYE,
1604 wxCURSOR_CHAR,
1605 wxCURSOR_CROSS,
1606 wxCURSOR_HAND,
1607 wxCURSOR_IBEAM,
1608 wxCURSOR_LEFT_BUTTON,
1609 wxCURSOR_MAGNIFIER,
1610 wxCURSOR_MIDDLE_BUTTON,
1611 wxCURSOR_NO_ENTRY,
1612 wxCURSOR_PAINT_BRUSH,
1613 wxCURSOR_PENCIL,
1614 wxCURSOR_POINT_LEFT,
1615 wxCURSOR_POINT_RIGHT,
1616 wxCURSOR_QUESTION_ARROW,
1617 wxCURSOR_RIGHT_BUTTON,
1618 wxCURSOR_SIZENESW,
1619 wxCURSOR_SIZENS,
1620 wxCURSOR_SIZENWSE,
1621 wxCURSOR_SIZEWE,
1622 wxCURSOR_SIZING,
1623 wxCURSOR_SPRAYCAN,
1624 wxCURSOR_WAIT,
1625 wxCURSOR_WATCH,
1626 wxCURSOR_ARROWWAIT
1627 };
1628
1629 IMPLEMENT_DYNAMIC_CLASS(wxCursorProperty, wxEnumProperty)
1630
1631 wxCursorProperty::wxCursorProperty( const wxString& label, const wxString& name,
1632 int value )
1633 : wxEnumProperty( label,
1634 name,
1635 gs_cp_es_syscursors_labels,
1636 gs_cp_es_syscursors_values,
1637 value )
1638 {
1639 m_flags |= wxPG_PROP_STATIC_CHOICES; // Cursor selection cannot be changed.
1640 }
1641
1642 wxCursorProperty::~wxCursorProperty()
1643 {
1644 }
1645
1646 wxSize wxCursorProperty::OnMeasureImage( int item ) const
1647 {
1648 #if wxPG_CAN_DRAW_CURSOR
1649 if ( item != -1 && item < NUM_CURSORS )
1650 return wxSize(wxPG_CURSOR_IMAGE_WIDTH,wxPG_CURSOR_IMAGE_WIDTH);
1651 #else
1652 wxUnusedVar(item);
1653 #endif
1654 return wxSize(0,0);
1655 }
1656
1657 #if wxPG_CAN_DRAW_CURSOR
1658
1659 void wxCursorProperty::OnCustomPaint( wxDC& dc,
1660 const wxRect& rect,
1661 wxPGPaintData& paintdata )
1662 {
1663 // Background brush
1664 dc.SetBrush( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE ) );
1665
1666 if ( paintdata.m_choiceItem >= 0 )
1667 {
1668 dc.DrawRectangle( rect );
1669
1670 if ( paintdata.m_choiceItem < NUM_CURSORS )
1671 {
1672 wxStockCursor cursorIndex =
1673 (wxStockCursor) gs_cp_es_syscursors_values[paintdata.m_choiceItem];
1674
1675 {
1676 if ( cursorIndex == wxCURSOR_NONE )
1677 cursorIndex = wxCURSOR_ARROW;
1678
1679 wxCursor cursor( cursorIndex );
1680
1681 #ifdef __WXMSW__
1682 HDC hDc = (HDC)((const wxMSWDCImpl *)dc.GetImpl())->GetHDC();
1683 ::DrawIconEx( hDc,
1684 rect.x,
1685 rect.y,
1686 (HICON)cursor.GetHandle(),
1687 0,
1688 0,
1689 0,
1690 NULL,
1691 #if !defined(__WXWINCE__)
1692 DI_COMPAT | DI_DEFAULTSIZE |
1693 #endif
1694 DI_NORMAL
1695 );
1696 #endif
1697 }
1698 }
1699 }
1700 }
1701
1702 #else
1703 void wxCursorProperty::OnCustomPaint( wxDC&, const wxRect&, wxPGPaintData& ) { }
1704 /*wxPGCellRenderer* wxCursorProperty::GetCellRenderer( int column ) const
1705 {
1706 return wxEnumProperty::GetCellRenderer(column);
1707 }*/
1708 #endif
1709
1710 // -----------------------------------------------------------------------
1711 // wxImageFileProperty
1712 // -----------------------------------------------------------------------
1713
1714 #if wxUSE_IMAGE
1715
1716 const wxString& wxPGGetDefaultImageWildcard()
1717 {
1718 // Form the wildcard, if not done yet
1719 if ( !wxPGGlobalVars->m_pDefaultImageWildcard.length() )
1720 {
1721
1722 wxString str;
1723
1724 // TODO: This section may require locking (using global).
1725
1726 wxList& handlers = wxImage::GetHandlers();
1727
1728 wxList::iterator node;
1729
1730 // Let's iterate over the image handler list.
1731 //for ( wxList::Node *node = handlers.GetFirst(); node; node = node->GetNext() )
1732 for ( node = handlers.begin(); node != handlers.end(); ++node )
1733 {
1734 wxImageHandler *handler = (wxImageHandler*)*node;
1735
1736 wxString ext_lo = handler->GetExtension();
1737 wxString ext_up = ext_lo.Upper();
1738
1739 str.append( ext_up );
1740 str.append( wxT(" files (*.") );
1741 str.append( ext_up );
1742 str.append( wxT(")|*.") );
1743 str.append( ext_lo );
1744 str.append( wxT("|") );
1745 }
1746
1747 str.append ( wxT("All files (*.*)|*.*") );
1748
1749 wxPGGlobalVars->m_pDefaultImageWildcard = str;
1750 }
1751
1752 return wxPGGlobalVars->m_pDefaultImageWildcard;
1753 }
1754
1755 IMPLEMENT_DYNAMIC_CLASS(wxImageFileProperty, wxFileProperty)
1756
1757 wxImageFileProperty::wxImageFileProperty( const wxString& label, const wxString& name,
1758 const wxString& value )
1759 : wxFileProperty(label,name,value)
1760 {
1761 SetAttribute( wxPG_FILE_WILDCARD, wxPGGetDefaultImageWildcard() );
1762
1763 m_pImage = NULL;
1764 m_pBitmap = NULL;
1765 }
1766
1767 wxImageFileProperty::~wxImageFileProperty()
1768 {
1769 if ( m_pBitmap )
1770 delete m_pBitmap;
1771 if ( m_pImage )
1772 delete m_pImage;
1773 }
1774
1775 void wxImageFileProperty::OnSetValue()
1776 {
1777 wxFileProperty::OnSetValue();
1778
1779 // Delete old image
1780 if ( m_pImage )
1781 {
1782 delete m_pImage;
1783 m_pImage = NULL;
1784 }
1785 if ( m_pBitmap )
1786 {
1787 delete m_pBitmap;
1788 m_pBitmap = NULL;
1789 }
1790
1791 wxFileName filename = GetFileName();
1792
1793 // Create the image thumbnail
1794 if ( filename.FileExists() )
1795 {
1796 m_pImage = new wxImage( filename.GetFullPath() );
1797 }
1798 }
1799
1800 wxSize wxImageFileProperty::OnMeasureImage( int ) const
1801 {
1802 return wxPG_DEFAULT_IMAGE_SIZE;
1803 }
1804
1805 void wxImageFileProperty::OnCustomPaint( wxDC& dc,
1806 const wxRect& rect,
1807 wxPGPaintData& )
1808 {
1809 if ( m_pBitmap || (m_pImage && m_pImage->Ok() ) )
1810 {
1811 // Draw the thumbnail
1812
1813 // Create the bitmap here because required size is not known in OnSetValue().
1814 if ( !m_pBitmap )
1815 {
1816 m_pImage->Rescale( rect.width, rect.height );
1817 m_pBitmap = new wxBitmap( *m_pImage );
1818 delete m_pImage;
1819 m_pImage = NULL;
1820 }
1821
1822 dc.DrawBitmap( *m_pBitmap, rect.x, rect.y, false );
1823 }
1824 else
1825 {
1826 // No file - just draw a white box
1827 dc.SetBrush( *wxWHITE_BRUSH );
1828 dc.DrawRectangle ( rect );
1829 }
1830 }
1831
1832 #endif // wxUSE_IMAGE
1833
1834 // -----------------------------------------------------------------------
1835 // wxMultiChoiceProperty
1836 // -----------------------------------------------------------------------
1837
1838 #if wxUSE_CHOICEDLG
1839
1840 #include "wx/choicdlg.h"
1841
1842 WX_PG_IMPLEMENT_PROPERTY_CLASS(wxMultiChoiceProperty,wxPGProperty,
1843 wxArrayInt,const wxArrayInt&,TextCtrlAndButton)
1844
1845 wxMultiChoiceProperty::wxMultiChoiceProperty( const wxString& label,
1846 const wxString& name,
1847 const wxPGChoices& choices,
1848 const wxArrayString& value)
1849 : wxPGProperty(label,name)
1850 {
1851 m_choices.Assign(choices);
1852 SetValue(value);
1853 }
1854
1855 wxMultiChoiceProperty::wxMultiChoiceProperty( const wxString& label,
1856 const wxString& name,
1857 const wxArrayString& strings,
1858 const wxArrayString& value)
1859 : wxPGProperty(label,name)
1860 {
1861 m_choices.Set(strings);
1862 SetValue(value);
1863 }
1864
1865 wxMultiChoiceProperty::wxMultiChoiceProperty( const wxString& label,
1866 const wxString& name,
1867 const wxArrayString& value)
1868 : wxPGProperty(label,name)
1869 {
1870 wxArrayString strings;
1871 m_choices.Set(strings);
1872 SetValue(value);
1873 }
1874
1875 wxMultiChoiceProperty::~wxMultiChoiceProperty()
1876 {
1877 }
1878
1879 void wxMultiChoiceProperty::OnSetValue()
1880 {
1881 GenerateValueAsString(m_value, &m_display);
1882 }
1883
1884 wxString wxMultiChoiceProperty::ValueToString( wxVariant& value,
1885 int argFlags ) const
1886 {
1887 // If possible, use cached string
1888 if ( argFlags & wxPG_VALUE_IS_CURRENT )
1889 return m_display;
1890
1891 wxString s;
1892 GenerateValueAsString(value, &s);
1893 return s;
1894 }
1895
1896 void wxMultiChoiceProperty::GenerateValueAsString( wxVariant& value,
1897 wxString* target ) const
1898 {
1899 wxArrayString strings;
1900
1901 if ( value.GetType() == wxPG_VARIANT_TYPE_ARRSTRING )
1902 strings = value.GetArrayString();
1903
1904 wxString& tempStr = *target;
1905 unsigned int i;
1906 unsigned int itemCount = strings.size();
1907
1908 tempStr.Empty();
1909
1910 if ( itemCount )
1911 tempStr.append( wxT("\"") );
1912
1913 for ( i = 0; i < itemCount; i++ )
1914 {
1915 tempStr.append( strings[i] );
1916 tempStr.append( wxT("\"") );
1917 if ( i < (itemCount-1) )
1918 tempStr.append ( wxT(" \"") );
1919 }
1920 }
1921
1922 wxArrayInt wxMultiChoiceProperty::GetValueAsIndices() const
1923 {
1924 wxVariant variant = GetValue();
1925 const wxArrayInt& valueArr = wxArrayIntRefFromVariant(variant);
1926 unsigned int i;
1927
1928 // Translate values to string indices.
1929 wxArrayInt selections;
1930
1931 if ( !m_choices.IsOk() || !m_choices.GetCount() || !(&valueArr) )
1932 {
1933 for ( i=0; i<valueArr.size(); i++ )
1934 selections.Add(-1);
1935 }
1936 else
1937 {
1938 for ( i=0; i<valueArr.size(); i++ )
1939 {
1940 int sIndex = m_choices.Index(valueArr[i]);
1941 if ( sIndex >= 0 )
1942 selections.Add(sIndex);
1943 }
1944 }
1945
1946 return selections;
1947 }
1948
1949 bool wxMultiChoiceProperty::OnEvent( wxPropertyGrid* propgrid,
1950 wxWindow* WXUNUSED(primary),
1951 wxEvent& event )
1952 {
1953 if ( propgrid->IsMainButtonEvent(event) )
1954 {
1955 // Update the value
1956 wxVariant useValue = propgrid->GetUncommittedPropertyValue();
1957
1958 wxArrayString labels = m_choices.GetLabels();
1959 unsigned int choiceCount;
1960
1961 if ( m_choices.IsOk() )
1962 choiceCount = m_choices.GetCount();
1963 else
1964 choiceCount = 0;
1965
1966 // launch editor dialog
1967 wxMultiChoiceDialog dlg( propgrid,
1968 _("Make a selection:"),
1969 m_label,
1970 choiceCount,
1971 choiceCount?&labels[0]:NULL,
1972 wxCHOICEDLG_STYLE );
1973
1974 dlg.Move( propgrid->GetGoodEditorDialogPosition(this,dlg.GetSize()) );
1975
1976 wxArrayString strings = useValue.GetArrayString();
1977 wxArrayString extraStrings;
1978
1979 dlg.SetSelections(m_choices.GetIndicesForStrings(strings, &extraStrings));
1980
1981 if ( dlg.ShowModal() == wxID_OK && choiceCount )
1982 {
1983 int userStringMode = GetAttributeAsLong(wxT("UserStringMode"), 0);
1984
1985 wxArrayInt arrInt = dlg.GetSelections();
1986
1987 wxVariant variant;
1988
1989 // Strings that were not in list of choices
1990 wxArrayString value;
1991
1992 // Translate string indices to strings
1993
1994 unsigned int n;
1995 if ( userStringMode == 1 )
1996 {
1997 for (n=0;n<extraStrings.size();n++)
1998 value.push_back(extraStrings[n]);
1999 }
2000
2001 unsigned int i;
2002 for ( i=0; i<arrInt.size(); i++ )
2003 value.Add(m_choices.GetLabel(arrInt.Item(i)));
2004
2005 if ( userStringMode == 2 )
2006 {
2007 for (n=0;n<extraStrings.size();n++)
2008 value.push_back(extraStrings[n]);
2009 }
2010
2011 variant = WXVARIANT(value);
2012
2013 SetValueInEvent(variant);
2014
2015 return true;
2016 }
2017 }
2018 return false;
2019 }
2020
2021 bool wxMultiChoiceProperty::StringToValue( wxVariant& variant, const wxString& text, int ) const
2022 {
2023 wxArrayString arr;
2024
2025 int userStringMode = GetAttributeAsLong(wxT("UserStringMode"), 0);
2026
2027 WX_PG_TOKENIZER2_BEGIN(text,wxT('"'))
2028 if ( userStringMode > 0 || (m_choices.IsOk() && m_choices.Index( token ) != wxNOT_FOUND) )
2029 arr.Add(token);
2030 WX_PG_TOKENIZER2_END()
2031
2032 wxVariant v( WXVARIANT(arr) );
2033 variant = v;
2034
2035 return true;
2036 }
2037
2038 #endif // wxUSE_CHOICEDLG
2039
2040
2041 // -----------------------------------------------------------------------
2042 // wxDateProperty
2043 // -----------------------------------------------------------------------
2044
2045 #if wxUSE_DATETIME
2046
2047
2048 #if wxUSE_DATEPICKCTRL
2049 #define dtCtrl DatePickerCtrl
2050 #else
2051 #define dtCtrl TextCtrl
2052 #endif
2053
2054 WX_PG_IMPLEMENT_PROPERTY_CLASS(wxDateProperty,
2055 wxPGProperty,
2056 wxDateTime,
2057 const wxDateTime&,
2058 dtCtrl)
2059
2060
2061 wxString wxDateProperty::ms_defaultDateFormat;
2062
2063
2064 wxDateProperty::wxDateProperty( const wxString& label,
2065 const wxString& name,
2066 const wxDateTime& value )
2067 : wxPGProperty(label,name)
2068 {
2069 //wxPGRegisterDefaultValueType(wxDateTime)
2070
2071 #if wxUSE_DATEPICKCTRL
2072 wxPGRegisterEditorClass(DatePickerCtrl);
2073
2074 m_dpStyle = wxDP_DEFAULT | wxDP_SHOWCENTURY;
2075 #else
2076 m_dpStyle = 0;
2077 #endif
2078
2079 SetValue( value );
2080 }
2081
2082 wxDateProperty::~wxDateProperty()
2083 {
2084 }
2085
2086 void wxDateProperty::OnSetValue()
2087 {
2088 //
2089 // Convert invalid dates to unspecified value
2090 if ( m_value.GetType() == wxT("datetime") )
2091 {
2092 if ( !m_value.GetDateTime().IsValid() )
2093 m_value.MakeNull();
2094 }
2095 }
2096
2097 bool wxDateProperty::StringToValue( wxVariant& variant, const wxString& text,
2098 int WXUNUSED(argFlags) ) const
2099 {
2100 wxDateTime dt;
2101
2102 // FIXME: do we really want to return true from here if only part of the
2103 // string was parsed?
2104 const char* c = dt.ParseFormat(text);
2105
2106 if ( c )
2107 {
2108 variant = dt;
2109 return true;
2110 }
2111
2112 return false;
2113 }
2114
2115 wxString wxDateProperty::ValueToString( wxVariant& value,
2116 int argFlags ) const
2117 {
2118 const wxChar* format = (const wxChar*) NULL;
2119
2120 wxDateTime dateTime = value.GetDateTime();
2121
2122 if ( !dateTime.IsValid() )
2123 return wxT("Invalid");
2124
2125 if ( !ms_defaultDateFormat.length() )
2126 {
2127 #if wxUSE_DATEPICKCTRL
2128 bool showCentury = m_dpStyle & wxDP_SHOWCENTURY ? true : false;
2129 #else
2130 bool showCentury = true;
2131 #endif
2132 ms_defaultDateFormat = DetermineDefaultDateFormat( showCentury );
2133 }
2134
2135 if ( m_format.length() &&
2136 !(argFlags & wxPG_FULL_VALUE) )
2137 format = m_format.c_str();
2138
2139 // Determine default from locale
2140 // NB: This is really simple stuff, but can't figure anything
2141 // better without proper support in wxLocale
2142 if ( !format )
2143 format = ms_defaultDateFormat.c_str();
2144
2145 return dateTime.Format(format);
2146 }
2147
2148 wxString wxDateProperty::DetermineDefaultDateFormat( bool showCentury )
2149 {
2150 // This code is basicly copied from datectlg.cpp's SetFormat
2151 //
2152 wxString format;
2153
2154 wxDateTime dt;
2155 dt.ParseFormat(wxT("2003-10-13"), wxT("%Y-%m-%d"));
2156 wxString str(dt.Format(wxT("%x")));
2157
2158 const wxChar *p = str.c_str();
2159 while ( *p )
2160 {
2161 int n=wxAtoi(p);
2162 if (n == dt.GetDay())
2163 {
2164 format.Append(wxT("%d"));
2165 p += 2;
2166 }
2167 else if (n == (int)dt.GetMonth()+1)
2168 {
2169 format.Append(wxT("%m"));
2170 p += 2;
2171 }
2172 else if (n == dt.GetYear())
2173 {
2174 format.Append(wxT("%Y"));
2175 p += 4;
2176 }
2177 else if (n == (dt.GetYear() % 100))
2178 {
2179 if (showCentury)
2180 format.Append(wxT("%Y"));
2181 else
2182 format.Append(wxT("%y"));
2183 p += 2;
2184 }
2185 else
2186 format.Append(*p++);
2187 }
2188
2189 return format;
2190 }
2191
2192 bool wxDateProperty::DoSetAttribute( const wxString& name, wxVariant& value )
2193 {
2194 if ( name == wxPG_DATE_FORMAT )
2195 {
2196 m_format = value.GetString();
2197 return true;
2198 }
2199 else if ( name == wxPG_DATE_PICKER_STYLE )
2200 {
2201 m_dpStyle = value.GetLong();
2202 ms_defaultDateFormat.clear(); // This may need recalculation
2203 return true;
2204 }
2205 return false;
2206 }
2207
2208 #endif // wxUSE_DATETIME
2209
2210
2211 // -----------------------------------------------------------------------
2212 // wxPropertyGridInterface
2213 // -----------------------------------------------------------------------
2214
2215 void wxPropertyGridInterface::InitAllTypeHandlers()
2216 {
2217 }
2218
2219 // -----------------------------------------------------------------------
2220
2221 void wxPropertyGridInterface::RegisterAdditionalEditors()
2222 {
2223 // Register editor classes, if necessary.
2224 if ( wxPGGlobalVars->m_mapEditorClasses.empty() )
2225 wxPropertyGrid::RegisterDefaultEditors();
2226
2227 #if wxUSE_SPINBTN
2228 wxPGRegisterEditorClass(SpinCtrl);
2229 #endif
2230 #if wxUSE_DATEPICKCTRL
2231 wxPGRegisterEditorClass(DatePickerCtrl);
2232 #endif
2233 }
2234
2235 // -----------------------------------------------------------------------
2236
2237 #endif // wxPG_INCLUDE_ADVPROPS
2238
2239 #endif // wxUSE_PROPGRID
2240