]>
git.saurik.com Git - wxWidgets.git/blob - src/generic/propform.cpp
1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Property form classes
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "propform.h"
16 // For compilers that support precompilation, includes "wx/wx.h".
17 #include "wx/wxprec.h"
33 #if defined(__WXMSW__) && !defined(__GNUWIN32__) && !defined(__WXWINE__)
36 #include <strstream.h>
42 #include "wx/window.h"
45 #include "wx/propform.h"
51 IMPLEMENT_DYNAMIC_CLASS(wxPropertyFormView
, wxPropertyView
)
53 BEGIN_EVENT_TABLE(wxPropertyFormView
, wxPropertyView
)
54 EVT_BUTTON(wxID_OK
, wxPropertyFormView::OnOk
)
55 EVT_BUTTON(wxID_CANCEL
, wxPropertyFormView::OnCancel
)
56 EVT_BUTTON(wxID_HELP
, wxPropertyFormView::OnHelp
)
57 EVT_BUTTON(wxID_PROP_REVERT
, wxPropertyFormView::OnRevert
)
58 EVT_BUTTON(wxID_PROP_UPDATE
, wxPropertyFormView::OnUpdate
)
61 bool wxPropertyFormView::sm_dialogCancelled
= FALSE
;
63 wxPropertyFormView::wxPropertyFormView(wxWindow
*propPanel
, long flags
):wxPropertyView(flags
)
65 m_propertyWindow
= propPanel
;
66 m_managedWindow
= NULL
;
68 m_windowCloseButton
= NULL
;
69 m_windowCancelButton
= NULL
;
70 m_windowHelpButton
= NULL
;
72 m_detailedEditing
= FALSE
;
75 wxPropertyFormView::~wxPropertyFormView(void)
79 void wxPropertyFormView::ShowView(wxPropertySheet
*ps
, wxWindow
*panel
)
83 AssociatePanel(panel
);
85 // UpdatePropertyList();
88 // Update this view of the viewed object, called e.g. by
90 bool wxPropertyFormView::OnUpdateView(void)
95 bool wxPropertyFormView::Check(void)
100 wxNode
*node
= m_propertySheet
->GetProperties().First();
103 wxProperty
*prop
= (wxProperty
*)node
->Data();
104 wxPropertyValidator
*validator
= FindPropertyValidator(prop
);
105 if (validator
&& validator
->IsKindOf(CLASSINFO(wxPropertyFormValidator
)))
107 wxPropertyFormValidator
*formValidator
= (wxPropertyFormValidator
*)validator
;
108 if (!formValidator
->OnCheckValue(prop
, this, m_propertyWindow
))
116 bool wxPropertyFormView::TransferToPropertySheet(void)
118 if (!m_propertySheet
)
121 wxNode
*node
= m_propertySheet
->GetProperties().First();
124 wxProperty
*prop
= (wxProperty
*)node
->Data();
125 wxPropertyValidator
*validator
= FindPropertyValidator(prop
);
126 if (validator
&& validator
->IsKindOf(CLASSINFO(wxPropertyFormValidator
)))
128 wxPropertyFormValidator
*formValidator
= (wxPropertyFormValidator
*)validator
;
129 formValidator
->OnRetrieveValue(prop
, this, m_propertyWindow
);
136 bool wxPropertyFormView::TransferToDialog(void)
138 if (!m_propertySheet
)
141 wxNode
*node
= m_propertySheet
->GetProperties().First();
144 wxProperty
*prop
= (wxProperty
*)node
->Data();
145 wxPropertyValidator
*validator
= FindPropertyValidator(prop
);
146 if (validator
&& validator
->IsKindOf(CLASSINFO(wxPropertyFormValidator
)))
148 wxPropertyFormValidator
*formValidator
= (wxPropertyFormValidator
*)validator
;
149 formValidator
->OnDisplayValue(prop
, this, m_propertyWindow
);
156 bool wxPropertyFormView::AssociateNames(void)
158 if (!m_propertySheet
|| !m_propertyWindow
)
161 wxNode
*node
= m_propertyWindow
->GetChildren().First();
164 wxWindow
*win
= (wxWindow
*)node
->Data();
165 if (win
->GetName() != _T(""))
167 wxProperty
*prop
= m_propertySheet
->GetProperty(win
->GetName());
169 prop
->SetWindow(win
);
177 bool wxPropertyFormView::OnClose(void)
183 void wxPropertyFormView::OnOk(wxCommandEvent
& WXUNUSED(event
))
185 // Retrieve the value if any
189 sm_dialogCancelled
= FALSE
;
190 TransferToPropertySheet();
192 m_managedWindow
->Close(TRUE
);
195 void wxPropertyFormView::OnCancel(wxCommandEvent
& WXUNUSED(event
))
197 sm_dialogCancelled
= TRUE
;
199 m_managedWindow
->Close(TRUE
);
202 void wxPropertyFormView::OnHelp(wxCommandEvent
& WXUNUSED(event
))
206 void wxPropertyFormView::OnUpdate(wxCommandEvent
& WXUNUSED(event
))
209 TransferToPropertySheet();
212 void wxPropertyFormView::OnRevert(wxCommandEvent
& WXUNUSED(event
))
217 void wxPropertyFormView::OnCommand(wxWindow
& win
, wxCommandEvent
& event
)
219 if (!m_propertySheet
)
222 if (win
.GetName() == _T(""))
225 if (wxStrcmp(win
.GetName(), _T("ok")) == 0)
227 else if (wxStrcmp(win
.GetName(), _T("cancel")) == 0)
229 else if (wxStrcmp(win
.GetName(), _T("help")) == 0)
231 else if (wxStrcmp(win
.GetName(), _T("update")) == 0)
233 else if (wxStrcmp(win
.GetName(), _T("revert")) == 0)
237 // Find a validator to route the command to.
238 wxNode
*node
= m_propertySheet
->GetProperties().First();
241 wxProperty
*prop
= (wxProperty
*)node
->Data();
242 if (prop
->GetWindow() && (prop
->GetWindow() == &win
))
244 wxPropertyValidator
*validator
= FindPropertyValidator(prop
);
245 if (validator
&& validator
->IsKindOf(CLASSINFO(wxPropertyFormValidator
)))
247 wxPropertyFormValidator
*formValidator
= (wxPropertyFormValidator
*)validator
;
248 formValidator
->OnCommand(prop
, this, m_propertyWindow
, event
);
257 void wxPropertyFormView::OnDoubleClick(wxControl
*item
)
259 if (!m_propertySheet
)
262 // Find a validator to route the command to.
263 wxNode
*node
= m_propertySheet
->GetProperties().First();
266 wxProperty
*prop
= (wxProperty
*)node
->Data();
267 if (prop
->GetWindow() && ((wxControl
*)prop
->GetWindow() == item
))
269 wxPropertyValidator
*validator
= FindPropertyValidator(prop
);
270 if (validator
&& validator
->IsKindOf(CLASSINFO(wxPropertyFormValidator
)))
272 wxPropertyFormValidator
*formValidator
= (wxPropertyFormValidator
*)validator
;
273 formValidator
->OnDoubleClick(prop
, this, m_propertyWindow
);
282 * Property form dialog box
285 IMPLEMENT_CLASS(wxPropertyFormDialog
, wxDialog
)
287 BEGIN_EVENT_TABLE(wxPropertyFormDialog
, wxDialog
)
288 EVT_CLOSE(wxPropertyFormDialog::OnCloseWindow
)
291 wxPropertyFormDialog::wxPropertyFormDialog(wxPropertyFormView
*v
, wxWindow
*parent
, const wxString
& title
,
292 const wxPoint
& pos
, const wxSize
& size
, long style
, const wxString
& name
):
293 wxDialog(parent
, -1, title
, pos
, size
, style
, name
)
296 m_view
->AssociatePanel(this);
297 m_view
->SetManagedWindow(this);
298 // SetAutoLayout(TRUE);
301 void wxPropertyFormDialog::OnCloseWindow(wxCloseEvent
& event
)
313 void wxPropertyFormDialog::OnDefaultAction(wxControl
*item
)
315 m_view
->OnDoubleClick(item
);
318 void wxPropertyFormDialog::OnCommand(wxWindow
& win
, wxCommandEvent
& event
)
321 m_view
->OnCommand(win
, event
);
324 // Extend event processing to search the view's event table
325 bool wxPropertyFormDialog::ProcessEvent(wxEvent
& event
)
327 if ( !m_view
|| ! m_view
->ProcessEvent(event
) )
328 return wxEvtHandler::ProcessEvent(event
);
335 * Property form panel
338 IMPLEMENT_CLASS(wxPropertyFormPanel
, wxPanel
)
340 void wxPropertyFormPanel::OnDefaultAction(wxControl
*item
)
342 m_view
->OnDoubleClick(item
);
345 void wxPropertyFormPanel::OnCommand(wxWindow
& win
, wxCommandEvent
& event
)
347 m_view
->OnCommand(win
, event
);
350 // Extend event processing to search the view's event table
351 bool wxPropertyFormPanel::ProcessEvent(wxEvent
& event
)
353 if ( !m_view
|| ! m_view
->ProcessEvent(event
) )
354 return wxEvtHandler::ProcessEvent(event
);
363 IMPLEMENT_CLASS(wxPropertyFormFrame
, wxFrame
)
365 BEGIN_EVENT_TABLE(wxPropertyFormFrame
, wxFrame
)
366 EVT_CLOSE(wxPropertyFormFrame::OnCloseWindow
)
369 void wxPropertyFormFrame::OnCloseWindow(wxCloseEvent
& event
)
371 if (m_view
&& m_view
->OnClose())
377 wxPanel
*wxPropertyFormFrame::OnCreatePanel(wxFrame
*parent
, wxPropertyFormView
*v
)
379 return new wxPropertyFormPanel(v
, parent
);
382 bool wxPropertyFormFrame::Initialize(void)
384 m_propertyPanel
= OnCreatePanel(this, m_view
);
387 m_view
->AssociatePanel(m_propertyPanel
);
388 m_view
->SetManagedWindow(this);
396 * Property form specific validator
399 IMPLEMENT_ABSTRACT_CLASS(wxPropertyFormValidator
, wxPropertyValidator
)
406 IMPLEMENT_DYNAMIC_CLASS(wxRealFormValidator
, wxPropertyFormValidator
)
409 /// Real number form validator
411 bool wxRealFormValidator::OnCheckValue( wxProperty
*property
, wxPropertyFormView
*WXUNUSED(view
),
412 wxWindow
*parentWindow
)
414 if (m_realMin
== 0.0 && m_realMax
== 0.0)
417 // The item used for viewing the real number: should be a text item.
418 wxWindow
*m_propertyWindow
= property
->GetWindow();
419 if (!m_propertyWindow
|| !m_propertyWindow
->IsKindOf(CLASSINFO(wxTextCtrl
)))
422 wxString
value(((wxTextCtrl
*)m_propertyWindow
)->GetValue());
425 if (!StringToFloat(WXSTRINGCAST value
, &val
))
428 wxSprintf(buf
, _T("Value %s is not a valid real number!"), (const wxChar
*)value
);
429 wxMessageBox(buf
, _T("Property value error"), wxOK
| wxICON_EXCLAMATION
, parentWindow
);
433 if (val
< m_realMin
|| val
> m_realMax
)
436 wxSprintf(buf
, _T("Value must be a real number between %.2f and %.2f!"), m_realMin
, m_realMax
);
437 wxMessageBox(buf
, _T("Property value error"), wxOK
| wxICON_EXCLAMATION
, parentWindow
);
443 bool wxRealFormValidator::OnRetrieveValue(wxProperty
*property
, wxPropertyFormView
*WXUNUSED(view
),
444 wxWindow
*WXUNUSED(parentWindow
) )
446 // The item used for viewing the real number: should be a text item.
447 wxWindow
*m_propertyWindow
= property
->GetWindow();
448 if (!m_propertyWindow
|| !m_propertyWindow
->IsKindOf(CLASSINFO(wxTextCtrl
)))
451 wxString
value(((wxTextCtrl
*)m_propertyWindow
)->GetValue());
453 if (value
.Length() == 0)
456 float f
= (float)wxAtof((const wxChar
*)value
);
457 property
->GetValue() = f
;
461 bool wxRealFormValidator::OnDisplayValue(wxProperty
*property
, wxPropertyFormView
*WXUNUSED(view
),
462 wxWindow
*WXUNUSED(parentWindow
) )
464 // The item used for viewing the real number: should be a text item.
465 wxWindow
*m_propertyWindow
= property
->GetWindow();
466 if (!m_propertyWindow
|| !m_propertyWindow
->IsKindOf(CLASSINFO(wxTextCtrl
)))
469 wxTextCtrl
*textItem
= (wxTextCtrl
*)m_propertyWindow
;
470 textItem
->SetValue(FloatToString(property
->GetValue().RealValue()));
475 /// Integer validator
477 IMPLEMENT_DYNAMIC_CLASS(wxIntegerFormValidator
, wxPropertyFormValidator
)
479 bool wxIntegerFormValidator::OnCheckValue(wxProperty
*property
, wxPropertyFormView
*WXUNUSED(view
),
480 wxWindow
*parentWindow
)
482 if (m_integerMin
== 0.0 && m_integerMax
== 0.0)
485 // The item used for viewing the real number: should be a text item or a slider
486 wxWindow
*m_propertyWindow
= property
->GetWindow();
487 if (!m_propertyWindow
)
492 if (m_propertyWindow
->IsKindOf(CLASSINFO(wxTextCtrl
)))
494 wxString
value(((wxTextCtrl
*)m_propertyWindow
)->GetValue());
496 if (!StringToLong(WXSTRINGCAST value
, &val
))
499 wxSprintf(buf
, _T("Value %s is not a valid integer!"), (const wxChar
*)value
);
500 wxMessageBox(buf
, _T("Property value error"), wxOK
| wxICON_EXCLAMATION
, parentWindow
);
504 else if (m_propertyWindow
->IsKindOf(CLASSINFO(wxSlider
)))
506 val
= (long)((wxSlider
*)m_propertyWindow
)->GetValue();
511 if (val
< m_integerMin
|| val
> m_integerMax
)
514 sprintf(buf
, "Value must be an integer between %ld and %ld!", m_integerMin
, m_integerMax
);
515 wxMessageBox(buf
, "Property value error", wxOK
| wxICON_EXCLAMATION
, parentWindow
);
521 bool wxIntegerFormValidator::OnRetrieveValue(wxProperty
*property
, wxPropertyFormView
*WXUNUSED(view
),
522 wxWindow
*WXUNUSED(parentWindow
))
524 // The item used for viewing the real number: should be a text item or a slider
525 wxWindow
*m_propertyWindow
= property
->GetWindow();
526 if (!m_propertyWindow
)
529 if (m_propertyWindow
->IsKindOf(CLASSINFO(wxTextCtrl
)))
531 wxString
value(((wxTextCtrl
*)m_propertyWindow
)->GetValue());
533 if (value
.Length() == 0)
536 long i
= wxAtol((const wxChar
*)value
);
537 property
->GetValue() = i
;
539 else if (m_propertyWindow
->IsKindOf(CLASSINFO(wxSlider
)))
541 property
->GetValue() = (long)((wxSlider
*)m_propertyWindow
)->GetValue();
549 bool wxIntegerFormValidator::OnDisplayValue( wxProperty
*property
, wxPropertyFormView
*WXUNUSED(view
),
550 wxWindow
*WXUNUSED(parentWindow
))
552 // The item used for viewing the real number: should be a text item or a slider
553 wxWindow
*m_propertyWindow
= property
->GetWindow();
554 if (!m_propertyWindow
)
557 if (m_propertyWindow
->IsKindOf(CLASSINFO(wxTextCtrl
)))
559 wxTextCtrl
*textItem
= (wxTextCtrl
*)m_propertyWindow
;
560 textItem
->SetValue(LongToString(property
->GetValue().IntegerValue()));
562 else if (m_propertyWindow
->IsKindOf(CLASSINFO(wxSlider
)))
564 ((wxSlider
*)m_propertyWindow
)->SetValue((int)property
->GetValue().IntegerValue());
572 /// Boolean validator
574 IMPLEMENT_DYNAMIC_CLASS(wxBoolFormValidator
, wxPropertyFormValidator
)
576 bool wxBoolFormValidator::OnCheckValue(wxProperty
*property
, wxPropertyFormView
*WXUNUSED(view
),
577 wxWindow
*WXUNUSED(parentWindow
))
579 // The item used for viewing the boolean: should be a checkbox
580 wxWindow
*m_propertyWindow
= property
->GetWindow();
581 if (!m_propertyWindow
|| !m_propertyWindow
->IsKindOf(CLASSINFO(wxCheckBox
)))
587 bool wxBoolFormValidator::OnRetrieveValue(wxProperty
*property
, wxPropertyFormView
*WXUNUSED(view
),
588 wxWindow
*WXUNUSED(parentWindow
) )
590 // The item used for viewing the boolean: should be a checkbox.
591 wxWindow
*m_propertyWindow
= property
->GetWindow();
592 if (!m_propertyWindow
|| !m_propertyWindow
->IsKindOf(CLASSINFO(wxCheckBox
)))
595 wxCheckBox
*checkBox
= (wxCheckBox
*)m_propertyWindow
;
597 property
->GetValue() = (bool)checkBox
->GetValue();
601 bool wxBoolFormValidator::OnDisplayValue(wxProperty
*property
, wxPropertyFormView
*WXUNUSED(view
),
602 wxWindow
*WXUNUSED(parentWindow
))
604 // The item used for viewing the boolean: should be a checkbox.
605 wxWindow
*m_propertyWindow
= property
->GetWindow();
606 if (!m_propertyWindow
|| !m_propertyWindow
->IsKindOf(CLASSINFO(wxCheckBox
)))
609 wxCheckBox
*checkBox
= (wxCheckBox
*)m_propertyWindow
;
610 checkBox
->SetValue((bool)property
->GetValue().BoolValue());
617 IMPLEMENT_DYNAMIC_CLASS(wxStringFormValidator
, wxPropertyFormValidator
)
619 wxStringFormValidator::wxStringFormValidator(wxStringList
*list
, long flags
):
620 wxPropertyFormValidator(flags
)
625 bool wxStringFormValidator::OnCheckValue(wxProperty
*property
, wxPropertyFormView
*WXUNUSED(view
),
626 wxWindow
*parentWindow
)
631 // The item used for viewing the string: should be a text item, choice item or listbox.
632 wxWindow
*m_propertyWindow
= property
->GetWindow();
633 if (!m_propertyWindow
)
635 if (m_propertyWindow
->IsKindOf(CLASSINFO(wxTextCtrl
)))
637 wxTextCtrl
*text
= (wxTextCtrl
*)m_propertyWindow
;
638 if (!m_strings
->Member(text
->GetValue()))
640 wxString
s("Value ");
641 s
+= text
->GetValue();
642 s
+= " is not valid.";
643 wxMessageBox(s
, "Property value error", wxOK
| wxICON_EXCLAMATION
, parentWindow
);
649 // Any other item constrains the string value,
650 // so we don't have to check it.
655 bool wxStringFormValidator::OnRetrieveValue(wxProperty
*property
, wxPropertyFormView
*WXUNUSED(view
),
656 wxWindow
*WXUNUSED(parentWindow
) )
658 // The item used for viewing the string: should be a text item, choice item or listbox.
659 wxWindow
*m_propertyWindow
= property
->GetWindow();
660 if (!m_propertyWindow
)
662 if (m_propertyWindow
->IsKindOf(CLASSINFO(wxTextCtrl
)))
664 wxTextCtrl
*text
= (wxTextCtrl
*)m_propertyWindow
;
665 property
->GetValue() = text
->GetValue();
667 else if (m_propertyWindow
->IsKindOf(CLASSINFO(wxListBox
)))
669 wxListBox
*lbox
= (wxListBox
*)m_propertyWindow
;
670 if (lbox
->GetSelection() > -1)
671 property
->GetValue() = lbox
->GetStringSelection();
674 else if (m_propertyWindow->IsKindOf(CLASSINFO(wxRadioBox)))
676 wxRadioBox *rbox = (wxRadioBox *)m_propertyWindow;
678 if ((n = rbox->GetSelection()) > -1)
679 property->GetValue() = rbox->GetString(n);
682 else if (m_propertyWindow
->IsKindOf(CLASSINFO(wxChoice
)))
684 wxChoice
*choice
= (wxChoice
*)m_propertyWindow
;
685 if (choice
->GetSelection() > -1)
686 property
->GetValue() = choice
->GetStringSelection();
693 bool wxStringFormValidator::OnDisplayValue(wxProperty
*property
, wxPropertyFormView
*WXUNUSED(view
),
694 wxWindow
*WXUNUSED(parentWindow
) )
696 // The item used for viewing the string: should be a text item, choice item or listbox.
697 wxWindow
*m_propertyWindow
= property
->GetWindow();
698 if (!m_propertyWindow
)
700 if (m_propertyWindow
->IsKindOf(CLASSINFO(wxTextCtrl
)))
702 wxTextCtrl
*text
= (wxTextCtrl
*)m_propertyWindow
;
703 text
->SetValue(property
->GetValue().StringValue());
705 else if (m_propertyWindow
->IsKindOf(CLASSINFO(wxListBox
)))
707 wxListBox
*lbox
= (wxListBox
*)m_propertyWindow
;
708 if (lbox
->Number() == 0 && m_strings
)
710 // Try to initialize the listbox from 'strings'
711 wxNode
*node
= m_strings
->First();
714 char *s
= (char *)node
->Data();
719 lbox
->SetStringSelection(property
->GetValue().StringValue());
722 else if (m_propertyWindow->IsKindOf(CLASSINFO(wxRadioBox)))
724 wxRadioBox *rbox = (wxRadioBox *)m_propertyWindow;
725 rbox->SetStringSelection(property->GetValue().StringValue());
728 else if (m_propertyWindow
->IsKindOf(CLASSINFO(wxChoice
)))
730 wxChoice
*choice
= (wxChoice
*)m_propertyWindow
;
732 if (choice
->Number() == 0 && m_strings
)
734 // Try to initialize the choice item from 'strings'
735 // XView doesn't allow this kind of thing.
736 wxNode
*node
= m_strings
->First();
739 char *s
= (char *)node
->Data();
745 choice
->SetStringSelection(property
->GetValue().StringValue());