]>
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"
26 #include "wx/choice.h"
27 #include "wx/checkbox.h"
28 #include "wx/slider.h"
29 #include "wx/msgdlg.h"
32 #include "wx/propform.h"
44 IMPLEMENT_DYNAMIC_CLASS(wxPropertyFormView
, wxPropertyView
)
46 BEGIN_EVENT_TABLE(wxPropertyFormView
, wxPropertyView
)
47 EVT_BUTTON(wxID_OK
, wxPropertyFormView::OnOk
)
48 EVT_BUTTON(wxID_CANCEL
, wxPropertyFormView::OnCancel
)
49 EVT_BUTTON(wxID_HELP
, wxPropertyFormView::OnHelp
)
50 EVT_BUTTON(wxID_PROP_REVERT
, wxPropertyFormView::OnRevert
)
51 EVT_BUTTON(wxID_PROP_UPDATE
, wxPropertyFormView::OnUpdate
)
54 bool wxPropertyFormView::sm_dialogCancelled
= FALSE
;
56 wxPropertyFormView::wxPropertyFormView(wxWindow
*propPanel
, long flags
):wxPropertyView(flags
)
58 m_propertyWindow
= propPanel
;
59 m_managedWindow
= NULL
;
61 m_windowCloseButton
= NULL
;
62 m_windowCancelButton
= NULL
;
63 m_windowHelpButton
= NULL
;
65 m_detailedEditing
= FALSE
;
68 wxPropertyFormView::~wxPropertyFormView(void)
72 void wxPropertyFormView::ShowView(wxPropertySheet
*ps
, wxWindow
*panel
)
76 AssociatePanel(panel
);
78 // UpdatePropertyList();
81 // Update this view of the viewed object, called e.g. by
83 bool wxPropertyFormView::OnUpdateView(void)
88 bool wxPropertyFormView::Check(void)
93 wxNode
*node
= m_propertySheet
->GetProperties().GetFirst();
96 wxProperty
*prop
= (wxProperty
*)node
->GetData();
97 wxPropertyValidator
*validator
= FindPropertyValidator(prop
);
98 if (validator
&& validator
->IsKindOf(CLASSINFO(wxPropertyFormValidator
)))
100 wxPropertyFormValidator
*formValidator
= (wxPropertyFormValidator
*)validator
;
101 if (!formValidator
->OnCheckValue(prop
, this, m_propertyWindow
))
104 node
= node
->GetNext();
109 bool wxPropertyFormView::TransferToPropertySheet(void)
111 if (!m_propertySheet
)
114 wxNode
*node
= m_propertySheet
->GetProperties().GetFirst();
117 wxProperty
*prop
= (wxProperty
*)node
->GetData();
118 wxPropertyValidator
*validator
= FindPropertyValidator(prop
);
119 if (validator
&& validator
->IsKindOf(CLASSINFO(wxPropertyFormValidator
)))
121 wxPropertyFormValidator
*formValidator
= (wxPropertyFormValidator
*)validator
;
122 formValidator
->OnRetrieveValue(prop
, this, m_propertyWindow
);
124 node
= node
->GetNext();
129 bool wxPropertyFormView::TransferToDialog(void)
131 if (!m_propertySheet
)
134 wxNode
*node
= m_propertySheet
->GetProperties().GetFirst();
137 wxProperty
*prop
= (wxProperty
*)node
->GetData();
138 wxPropertyValidator
*validator
= FindPropertyValidator(prop
);
139 if (validator
&& validator
->IsKindOf(CLASSINFO(wxPropertyFormValidator
)))
141 wxPropertyFormValidator
*formValidator
= (wxPropertyFormValidator
*)validator
;
142 formValidator
->OnDisplayValue(prop
, this, m_propertyWindow
);
144 node
= node
->GetNext();
149 bool wxPropertyFormView::AssociateNames(void)
151 if (!m_propertySheet
|| !m_propertyWindow
)
154 wxWindowList::Node
*node
= m_propertyWindow
->GetChildren().GetFirst();
157 wxWindow
*win
= node
->GetData();
158 if ( win
->GetName() != wxEmptyString
)
160 wxProperty
*prop
= m_propertySheet
->GetProperty(win
->GetName());
162 prop
->SetWindow(win
);
164 node
= node
->GetNext();
170 bool wxPropertyFormView::OnClose(void)
172 if (m_propertyWindow
->IsKindOf(CLASSINFO(wxPropertyFormPanel
)))
174 ((wxPropertyFormPanel
*)m_propertyWindow
)->SetView(NULL
);
180 void wxPropertyFormView::OnOk(wxCommandEvent
& WXUNUSED(event
))
182 // Retrieve the value if any
186 sm_dialogCancelled
= FALSE
;
187 TransferToPropertySheet();
189 m_managedWindow
->Close(TRUE
);
192 void wxPropertyFormView::OnCancel(wxCommandEvent
& WXUNUSED(event
))
194 sm_dialogCancelled
= TRUE
;
196 m_managedWindow
->Close(TRUE
);
199 void wxPropertyFormView::OnHelp(wxCommandEvent
& WXUNUSED(event
))
203 void wxPropertyFormView::OnUpdate(wxCommandEvent
& WXUNUSED(event
))
206 TransferToPropertySheet();
209 void wxPropertyFormView::OnRevert(wxCommandEvent
& WXUNUSED(event
))
214 void wxPropertyFormView::OnCommand(wxWindow
& win
, wxCommandEvent
& event
)
216 if (!m_propertySheet
)
219 if (win
.GetName() == wxT(""))
222 if (wxStrcmp(win
.GetName(), wxT("ok")) == 0)
224 else if (wxStrcmp(win
.GetName(), wxT("cancel")) == 0)
226 else if (wxStrcmp(win
.GetName(), wxT("help")) == 0)
228 else if (wxStrcmp(win
.GetName(), wxT("update")) == 0)
230 else if (wxStrcmp(win
.GetName(), wxT("revert")) == 0)
234 // Find a validator to route the command to.
235 wxNode
*node
= m_propertySheet
->GetProperties().GetFirst();
238 wxProperty
*prop
= (wxProperty
*)node
->GetData();
239 if (prop
->GetWindow() && (prop
->GetWindow() == &win
))
241 wxPropertyValidator
*validator
= FindPropertyValidator(prop
);
242 if (validator
&& validator
->IsKindOf(CLASSINFO(wxPropertyFormValidator
)))
244 wxPropertyFormValidator
*formValidator
= (wxPropertyFormValidator
*)validator
;
245 formValidator
->OnCommand(prop
, this, m_propertyWindow
, event
);
249 node
= node
->GetNext();
254 // Extend event processing to call OnCommand
255 bool wxPropertyFormView::ProcessEvent(wxEvent
& event
)
257 if (wxEvtHandler::ProcessEvent(event
))
259 else if (event
.IsCommandEvent() && !event
.IsKindOf(CLASSINFO(wxUpdateUIEvent
)) && event
.GetEventObject())
261 OnCommand(* ((wxWindow
*) event
.GetEventObject()), (wxCommandEvent
&) event
);
268 void wxPropertyFormView::OnDoubleClick(wxControl
*item
)
270 if (!m_propertySheet
)
273 // Find a validator to route the command to.
274 wxNode
*node
= m_propertySheet
->GetProperties().GetFirst();
277 wxProperty
*prop
= (wxProperty
*)node
->GetData();
278 if (prop
->GetWindow() && ((wxControl
*)prop
->GetWindow() == item
))
280 wxPropertyValidator
*validator
= FindPropertyValidator(prop
);
281 if (validator
&& validator
->IsKindOf(CLASSINFO(wxPropertyFormValidator
)))
283 wxPropertyFormValidator
*formValidator
= (wxPropertyFormValidator
*)validator
;
284 formValidator
->OnDoubleClick(prop
, this, m_propertyWindow
);
288 node
= node
->GetNext();
293 * Property form dialog box
296 IMPLEMENT_DYNAMIC_CLASS(wxPropertyFormDialog
, wxDialog
)
298 BEGIN_EVENT_TABLE(wxPropertyFormDialog
, wxDialog
)
299 EVT_CLOSE(wxPropertyFormDialog::OnCloseWindow
)
302 wxPropertyFormDialog::wxPropertyFormDialog(wxPropertyFormView
*v
, wxWindow
*parent
, const wxString
& title
,
303 const wxPoint
& pos
, const wxSize
& size
, long style
, const wxString
& name
):
304 wxDialog(parent
, -1, title
, pos
, size
, style
, name
)
307 m_view
->AssociatePanel(this);
308 m_view
->SetManagedWindow(this);
309 // SetAutoLayout(TRUE);
312 void wxPropertyFormDialog::OnCloseWindow(wxCloseEvent
& event
)
324 void wxPropertyFormDialog::OnDefaultAction(wxControl
*item
)
326 m_view
->OnDoubleClick(item
);
329 void wxPropertyFormDialog::OnCommand(wxWindow
& win
, wxCommandEvent
& event
)
332 m_view
->OnCommand(win
, event
);
335 // Extend event processing to search the view's event table
336 bool wxPropertyFormDialog::ProcessEvent(wxEvent
& event
)
338 if ( !m_view
|| ! m_view
->ProcessEvent(event
) )
339 return wxEvtHandler::ProcessEvent(event
);
346 * Property form panel
349 IMPLEMENT_DYNAMIC_CLASS(wxPropertyFormPanel
, wxPanel
)
351 void wxPropertyFormPanel::OnDefaultAction(wxControl
*item
)
353 m_view
->OnDoubleClick(item
);
356 void wxPropertyFormPanel::OnCommand(wxWindow
& win
, wxCommandEvent
& event
)
358 m_view
->OnCommand(win
, event
);
361 // Extend event processing to search the view's event table
362 bool wxPropertyFormPanel::ProcessEvent(wxEvent
& event
)
364 if ( !m_view
|| ! m_view
->ProcessEvent(event
) )
365 return wxEvtHandler::ProcessEvent(event
);
374 IMPLEMENT_DYNAMIC_CLASS(wxPropertyFormFrame
, wxFrame
)
376 BEGIN_EVENT_TABLE(wxPropertyFormFrame
, wxFrame
)
377 EVT_CLOSE(wxPropertyFormFrame::OnCloseWindow
)
380 void wxPropertyFormFrame::OnCloseWindow(wxCloseEvent
& event
)
382 if (m_view
&& m_view
->OnClose())
388 wxPanel
*wxPropertyFormFrame::OnCreatePanel(wxFrame
*parent
, wxPropertyFormView
*v
)
390 return new wxPropertyFormPanel(v
, parent
);
393 bool wxPropertyFormFrame::Initialize(void)
395 m_propertyPanel
= OnCreatePanel(this, m_view
);
398 m_view
->AssociatePanel(m_propertyPanel
);
399 m_view
->SetManagedWindow(this);
407 * Property form specific validator
410 IMPLEMENT_ABSTRACT_CLASS(wxPropertyFormValidator
, wxPropertyValidator
)
417 IMPLEMENT_DYNAMIC_CLASS(wxRealFormValidator
, wxPropertyFormValidator
)
420 /// Real number form validator
422 bool wxRealFormValidator::OnCheckValue( wxProperty
*property
, wxPropertyFormView
*WXUNUSED(view
),
423 wxWindow
*parentWindow
)
425 if (m_realMin
== 0.0 && m_realMax
== 0.0)
428 // The item used for viewing the real number: should be a text item.
429 wxWindow
*m_propertyWindow
= property
->GetWindow();
430 if (!m_propertyWindow
|| !m_propertyWindow
->IsKindOf(CLASSINFO(wxTextCtrl
)))
433 wxString
value(((wxTextCtrl
*)m_propertyWindow
)->GetValue());
436 if (!StringToFloat(WXSTRINGCAST value
, &val
))
439 wxSprintf(buf
, wxT("Value %s is not a valid real number!"), (const wxChar
*)value
);
440 wxMessageBox(buf
, wxT("Property value error"), wxOK
| wxICON_EXCLAMATION
, parentWindow
);
444 if (val
< m_realMin
|| val
> m_realMax
)
447 wxSprintf(buf
, wxT("Value must be a real number between %.2f and %.2f!"), m_realMin
, m_realMax
);
448 wxMessageBox(buf
, wxT("Property value error"), wxOK
| wxICON_EXCLAMATION
, parentWindow
);
454 bool wxRealFormValidator::OnRetrieveValue(wxProperty
*property
, wxPropertyFormView
*WXUNUSED(view
),
455 wxWindow
*WXUNUSED(parentWindow
) )
457 // The item used for viewing the real number: should be a text item.
458 wxWindow
*m_propertyWindow
= property
->GetWindow();
459 if (!m_propertyWindow
|| !m_propertyWindow
->IsKindOf(CLASSINFO(wxTextCtrl
)))
462 wxString
value(((wxTextCtrl
*)m_propertyWindow
)->GetValue());
464 if (value
.Length() == 0)
467 float f
= (float)wxAtof((const wxChar
*)value
);
468 property
->GetValue() = f
;
472 bool wxRealFormValidator::OnDisplayValue(wxProperty
*property
, wxPropertyFormView
*WXUNUSED(view
),
473 wxWindow
*WXUNUSED(parentWindow
) )
475 // The item used for viewing the real number: should be a text item.
476 wxWindow
*m_propertyWindow
= property
->GetWindow();
477 if (!m_propertyWindow
|| !m_propertyWindow
->IsKindOf(CLASSINFO(wxTextCtrl
)))
480 wxTextCtrl
*textItem
= (wxTextCtrl
*)m_propertyWindow
;
481 textItem
->SetValue(FloatToString(property
->GetValue().RealValue()));
486 /// Integer validator
488 IMPLEMENT_DYNAMIC_CLASS(wxIntegerFormValidator
, wxPropertyFormValidator
)
490 bool wxIntegerFormValidator::OnCheckValue(wxProperty
*property
, wxPropertyFormView
*WXUNUSED(view
),
491 wxWindow
*parentWindow
)
493 if (m_integerMin
== 0.0 && m_integerMax
== 0.0)
496 // The item used for viewing the real number: should be a text item or a slider
497 wxWindow
*m_propertyWindow
= property
->GetWindow();
498 if (!m_propertyWindow
)
503 if (m_propertyWindow
->IsKindOf(CLASSINFO(wxTextCtrl
)))
505 wxString
value(((wxTextCtrl
*)m_propertyWindow
)->GetValue());
507 if (!StringToLong(WXSTRINGCAST value
, &val
))
510 wxSprintf(buf
, wxT("Value %s is not a valid integer!"), (const wxChar
*)value
);
511 wxMessageBox(buf
, wxT("Property value error"), wxOK
| wxICON_EXCLAMATION
, parentWindow
);
515 else if (m_propertyWindow
->IsKindOf(CLASSINFO(wxSlider
)))
517 val
= (long)((wxSlider
*)m_propertyWindow
)->GetValue();
522 if (val
< m_integerMin
|| val
> m_integerMax
)
525 wxSprintf(buf
, wxT("Value must be an integer between %ld and %ld!"), m_integerMin
, m_integerMax
);
526 wxMessageBox(buf
, wxT("Property value error"), wxOK
| wxICON_EXCLAMATION
, parentWindow
);
532 bool wxIntegerFormValidator::OnRetrieveValue(wxProperty
*property
, wxPropertyFormView
*WXUNUSED(view
),
533 wxWindow
*WXUNUSED(parentWindow
))
535 // The item used for viewing the real number: should be a text item or a slider
536 wxWindow
*m_propertyWindow
= property
->GetWindow();
537 if (!m_propertyWindow
)
540 if (m_propertyWindow
->IsKindOf(CLASSINFO(wxTextCtrl
)))
542 wxString
value(((wxTextCtrl
*)m_propertyWindow
)->GetValue());
544 if (value
.Length() == 0)
547 long i
= wxAtol((const wxChar
*)value
);
548 property
->GetValue() = i
;
550 else if (m_propertyWindow
->IsKindOf(CLASSINFO(wxSlider
)))
552 property
->GetValue() = (long)((wxSlider
*)m_propertyWindow
)->GetValue();
560 bool wxIntegerFormValidator::OnDisplayValue( wxProperty
*property
, wxPropertyFormView
*WXUNUSED(view
),
561 wxWindow
*WXUNUSED(parentWindow
))
563 // The item used for viewing the real number: should be a text item or a slider
564 wxWindow
*m_propertyWindow
= property
->GetWindow();
565 if (!m_propertyWindow
)
568 if (m_propertyWindow
->IsKindOf(CLASSINFO(wxTextCtrl
)))
570 wxTextCtrl
*textItem
= (wxTextCtrl
*)m_propertyWindow
;
571 textItem
->SetValue(LongToString(property
->GetValue().IntegerValue()));
573 else if (m_propertyWindow
->IsKindOf(CLASSINFO(wxSlider
)))
575 ((wxSlider
*)m_propertyWindow
)->SetValue((int)property
->GetValue().IntegerValue());
583 /// Boolean validator
585 IMPLEMENT_DYNAMIC_CLASS(wxBoolFormValidator
, wxPropertyFormValidator
)
587 bool wxBoolFormValidator::OnCheckValue(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
)))
598 bool wxBoolFormValidator::OnRetrieveValue(wxProperty
*property
, wxPropertyFormView
*WXUNUSED(view
),
599 wxWindow
*WXUNUSED(parentWindow
) )
601 // The item used for viewing the boolean: should be a checkbox.
602 wxWindow
*m_propertyWindow
= property
->GetWindow();
603 if (!m_propertyWindow
|| !m_propertyWindow
->IsKindOf(CLASSINFO(wxCheckBox
)))
606 wxCheckBox
*checkBox
= (wxCheckBox
*)m_propertyWindow
;
608 property
->GetValue() = (bool)checkBox
->GetValue();
612 bool wxBoolFormValidator::OnDisplayValue(wxProperty
*property
, wxPropertyFormView
*WXUNUSED(view
),
613 wxWindow
*WXUNUSED(parentWindow
))
615 // The item used for viewing the boolean: should be a checkbox.
616 wxWindow
*m_propertyWindow
= property
->GetWindow();
617 if (!m_propertyWindow
|| !m_propertyWindow
->IsKindOf(CLASSINFO(wxCheckBox
)))
620 wxCheckBox
*checkBox
= (wxCheckBox
*)m_propertyWindow
;
621 checkBox
->SetValue((bool)property
->GetValue().BoolValue());
628 IMPLEMENT_DYNAMIC_CLASS(wxStringFormValidator
, wxPropertyFormValidator
)
630 wxStringFormValidator::wxStringFormValidator(wxStringList
*list
, long flags
):
631 wxPropertyFormValidator(flags
)
636 bool wxStringFormValidator::OnCheckValue(wxProperty
*property
, wxPropertyFormView
*WXUNUSED(view
),
637 wxWindow
*parentWindow
)
642 // The item used for viewing the string: should be a text item, choice item or listbox.
643 wxWindow
*m_propertyWindow
= property
->GetWindow();
644 if (!m_propertyWindow
)
646 if (m_propertyWindow
->IsKindOf(CLASSINFO(wxTextCtrl
)))
648 wxTextCtrl
*text
= (wxTextCtrl
*)m_propertyWindow
;
649 if (!m_strings
->Member(text
->GetValue()))
651 wxString
str( wxT("Value ") );
652 str
+= text
->GetValue();
653 str
+= wxT(" is not valid.");
654 wxMessageBox(str
, wxT("Property value error"), wxOK
| wxICON_EXCLAMATION
, parentWindow
);
660 // Any other item constrains the string value,
661 // so we don't have to check it.
666 bool wxStringFormValidator::OnRetrieveValue(wxProperty
*property
, wxPropertyFormView
*WXUNUSED(view
),
667 wxWindow
*WXUNUSED(parentWindow
) )
669 // The item used for viewing the string: should be a text item, choice item or listbox.
670 wxWindow
*m_propertyWindow
= property
->GetWindow();
671 if (!m_propertyWindow
)
673 if (m_propertyWindow
->IsKindOf(CLASSINFO(wxTextCtrl
)))
675 wxTextCtrl
*text
= (wxTextCtrl
*)m_propertyWindow
;
676 property
->GetValue() = text
->GetValue();
678 else if (m_propertyWindow
->IsKindOf(CLASSINFO(wxListBox
)))
680 wxListBox
*lbox
= (wxListBox
*)m_propertyWindow
;
681 if (lbox
->GetSelection() > -1)
682 property
->GetValue() = lbox
->GetStringSelection();
685 else if (m_propertyWindow->IsKindOf(CLASSINFO(wxRadioBox)))
687 wxRadioBox *rbox = (wxRadioBox *)m_propertyWindow;
689 if ((n = rbox->GetSelection()) > -1)
690 property->GetValue() = rbox->GetString(n);
693 else if (m_propertyWindow
->IsKindOf(CLASSINFO(wxChoice
)))
695 wxChoice
*choice
= (wxChoice
*)m_propertyWindow
;
696 if (choice
->GetSelection() > -1)
697 property
->GetValue() = choice
->GetStringSelection();
704 bool wxStringFormValidator::OnDisplayValue(wxProperty
*property
, wxPropertyFormView
*WXUNUSED(view
),
705 wxWindow
*WXUNUSED(parentWindow
) )
707 // The item used for viewing the string: should be a text item, choice item or listbox.
708 wxWindow
*m_propertyWindow
= property
->GetWindow();
709 if (!m_propertyWindow
)
711 if (m_propertyWindow
->IsKindOf(CLASSINFO(wxTextCtrl
)))
713 wxTextCtrl
*text
= (wxTextCtrl
*)m_propertyWindow
;
714 text
->SetValue(property
->GetValue().StringValue());
716 else if (m_propertyWindow
->IsKindOf(CLASSINFO(wxListBox
)))
718 wxListBox
*lbox
= (wxListBox
*)m_propertyWindow
;
719 if (lbox
->GetCount() == 0 && m_strings
)
721 // Try to initialize the listbox from 'strings'
722 wxStringList::Node
*node
= m_strings
->GetFirst();
725 wxChar
*s
= node
->GetData();
727 node
= node
->GetNext();
730 lbox
->SetStringSelection(property
->GetValue().StringValue());
733 else if (m_propertyWindow->IsKindOf(CLASSINFO(wxRadioBox)))
735 wxRadioBox *rbox = (wxRadioBox *)m_propertyWindow;
736 rbox->SetStringSelection(property->GetValue().StringValue());
739 else if (m_propertyWindow
->IsKindOf(CLASSINFO(wxChoice
)))
741 wxChoice
*choice
= (wxChoice
*)m_propertyWindow
;
742 if (choice
->GetCount() == 0 && m_strings
)
744 // Try to initialize the choice item from 'strings'
745 // XView doesn't allow this kind of thing.
746 wxStringList::Node
*node
= m_strings
->GetFirst();
749 wxChar
*s
= node
->GetData();
751 node
= node
->GetNext();
754 choice
->SetStringSelection(property
->GetValue().StringValue());
761 #endif // wxUSE_PROPSHEET