]>
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"
29 #include "wx/propform.h"
41 IMPLEMENT_DYNAMIC_CLASS(wxPropertyFormView
, wxPropertyView
)
43 BEGIN_EVENT_TABLE(wxPropertyFormView
, wxPropertyView
)
44 EVT_BUTTON(wxID_OK
, wxPropertyFormView::OnOk
)
45 EVT_BUTTON(wxID_CANCEL
, wxPropertyFormView::OnCancel
)
46 EVT_BUTTON(wxID_HELP
, wxPropertyFormView::OnHelp
)
47 EVT_BUTTON(wxID_PROP_REVERT
, wxPropertyFormView::OnRevert
)
48 EVT_BUTTON(wxID_PROP_UPDATE
, wxPropertyFormView::OnUpdate
)
51 bool wxPropertyFormView::sm_dialogCancelled
= FALSE
;
53 wxPropertyFormView::wxPropertyFormView(wxWindow
*propPanel
, long flags
):wxPropertyView(flags
)
55 m_propertyWindow
= propPanel
;
56 m_managedWindow
= NULL
;
58 m_windowCloseButton
= NULL
;
59 m_windowCancelButton
= NULL
;
60 m_windowHelpButton
= NULL
;
62 m_detailedEditing
= FALSE
;
65 wxPropertyFormView::~wxPropertyFormView(void)
69 void wxPropertyFormView::ShowView(wxPropertySheet
*ps
, wxWindow
*panel
)
73 AssociatePanel(panel
);
75 // UpdatePropertyList();
78 // Update this view of the viewed object, called e.g. by
80 bool wxPropertyFormView::OnUpdateView(void)
85 bool wxPropertyFormView::Check(void)
90 wxNode
*node
= m_propertySheet
->GetProperties().GetFirst();
93 wxProperty
*prop
= (wxProperty
*)node
->GetData();
94 wxPropertyValidator
*validator
= FindPropertyValidator(prop
);
95 if (validator
&& validator
->IsKindOf(CLASSINFO(wxPropertyFormValidator
)))
97 wxPropertyFormValidator
*formValidator
= (wxPropertyFormValidator
*)validator
;
98 if (!formValidator
->OnCheckValue(prop
, this, m_propertyWindow
))
101 node
= node
->GetNext();
106 bool wxPropertyFormView::TransferToPropertySheet(void)
108 if (!m_propertySheet
)
111 wxNode
*node
= m_propertySheet
->GetProperties().GetFirst();
114 wxProperty
*prop
= (wxProperty
*)node
->GetData();
115 wxPropertyValidator
*validator
= FindPropertyValidator(prop
);
116 if (validator
&& validator
->IsKindOf(CLASSINFO(wxPropertyFormValidator
)))
118 wxPropertyFormValidator
*formValidator
= (wxPropertyFormValidator
*)validator
;
119 formValidator
->OnRetrieveValue(prop
, this, m_propertyWindow
);
121 node
= node
->GetNext();
126 bool wxPropertyFormView::TransferToDialog(void)
128 if (!m_propertySheet
)
131 wxNode
*node
= m_propertySheet
->GetProperties().GetFirst();
134 wxProperty
*prop
= (wxProperty
*)node
->GetData();
135 wxPropertyValidator
*validator
= FindPropertyValidator(prop
);
136 if (validator
&& validator
->IsKindOf(CLASSINFO(wxPropertyFormValidator
)))
138 wxPropertyFormValidator
*formValidator
= (wxPropertyFormValidator
*)validator
;
139 formValidator
->OnDisplayValue(prop
, this, m_propertyWindow
);
141 node
= node
->GetNext();
146 bool wxPropertyFormView::AssociateNames(void)
148 if (!m_propertySheet
|| !m_propertyWindow
)
151 wxWindowList::Node
*node
= m_propertyWindow
->GetChildren().GetFirst();
154 wxWindow
*win
= node
->GetData();
155 if ( win
->GetName() != wxEmptyString
)
157 wxProperty
*prop
= m_propertySheet
->GetProperty(win
->GetName());
159 prop
->SetWindow(win
);
161 node
= node
->GetNext();
167 bool wxPropertyFormView::OnClose(void)
169 if (m_propertyWindow
->IsKindOf(CLASSINFO(wxPropertyFormPanel
)))
171 ((wxPropertyFormPanel
*)m_propertyWindow
)->SetView(NULL
);
177 void wxPropertyFormView::OnOk(wxCommandEvent
& WXUNUSED(event
))
179 // Retrieve the value if any
183 sm_dialogCancelled
= FALSE
;
184 TransferToPropertySheet();
186 m_managedWindow
->Close(TRUE
);
189 void wxPropertyFormView::OnCancel(wxCommandEvent
& WXUNUSED(event
))
191 sm_dialogCancelled
= TRUE
;
193 m_managedWindow
->Close(TRUE
);
196 void wxPropertyFormView::OnHelp(wxCommandEvent
& WXUNUSED(event
))
200 void wxPropertyFormView::OnUpdate(wxCommandEvent
& WXUNUSED(event
))
203 TransferToPropertySheet();
206 void wxPropertyFormView::OnRevert(wxCommandEvent
& WXUNUSED(event
))
211 void wxPropertyFormView::OnCommand(wxWindow
& win
, wxCommandEvent
& event
)
213 if (!m_propertySheet
)
216 if (win
.GetName() == wxT(""))
219 if (wxStrcmp(win
.GetName(), wxT("ok")) == 0)
221 else if (wxStrcmp(win
.GetName(), wxT("cancel")) == 0)
223 else if (wxStrcmp(win
.GetName(), wxT("help")) == 0)
225 else if (wxStrcmp(win
.GetName(), wxT("update")) == 0)
227 else if (wxStrcmp(win
.GetName(), wxT("revert")) == 0)
231 // Find a validator to route the command to.
232 wxNode
*node
= m_propertySheet
->GetProperties().GetFirst();
235 wxProperty
*prop
= (wxProperty
*)node
->GetData();
236 if (prop
->GetWindow() && (prop
->GetWindow() == &win
))
238 wxPropertyValidator
*validator
= FindPropertyValidator(prop
);
239 if (validator
&& validator
->IsKindOf(CLASSINFO(wxPropertyFormValidator
)))
241 wxPropertyFormValidator
*formValidator
= (wxPropertyFormValidator
*)validator
;
242 formValidator
->OnCommand(prop
, this, m_propertyWindow
, event
);
246 node
= node
->GetNext();
251 // Extend event processing to call OnCommand
252 bool wxPropertyFormView::ProcessEvent(wxEvent
& event
)
254 if (wxEvtHandler::ProcessEvent(event
))
256 else if (event
.IsCommandEvent() && !event
.IsKindOf(CLASSINFO(wxUpdateUIEvent
)) && event
.GetEventObject())
258 OnCommand(* ((wxWindow
*) event
.GetEventObject()), (wxCommandEvent
&) event
);
265 void wxPropertyFormView::OnDoubleClick(wxControl
*item
)
267 if (!m_propertySheet
)
270 // Find a validator to route the command to.
271 wxNode
*node
= m_propertySheet
->GetProperties().GetFirst();
274 wxProperty
*prop
= (wxProperty
*)node
->GetData();
275 if (prop
->GetWindow() && ((wxControl
*)prop
->GetWindow() == item
))
277 wxPropertyValidator
*validator
= FindPropertyValidator(prop
);
278 if (validator
&& validator
->IsKindOf(CLASSINFO(wxPropertyFormValidator
)))
280 wxPropertyFormValidator
*formValidator
= (wxPropertyFormValidator
*)validator
;
281 formValidator
->OnDoubleClick(prop
, this, m_propertyWindow
);
285 node
= node
->GetNext();
290 * Property form dialog box
293 IMPLEMENT_DYNAMIC_CLASS(wxPropertyFormDialog
, wxDialog
)
295 BEGIN_EVENT_TABLE(wxPropertyFormDialog
, wxDialog
)
296 EVT_CLOSE(wxPropertyFormDialog::OnCloseWindow
)
299 wxPropertyFormDialog::wxPropertyFormDialog(wxPropertyFormView
*v
, wxWindow
*parent
, const wxString
& title
,
300 const wxPoint
& pos
, const wxSize
& size
, long style
, const wxString
& name
):
301 wxDialog(parent
, -1, title
, pos
, size
, style
, name
)
304 m_view
->AssociatePanel(this);
305 m_view
->SetManagedWindow(this);
306 // SetAutoLayout(TRUE);
309 void wxPropertyFormDialog::OnCloseWindow(wxCloseEvent
& event
)
321 void wxPropertyFormDialog::OnDefaultAction(wxControl
*item
)
323 m_view
->OnDoubleClick(item
);
326 void wxPropertyFormDialog::OnCommand(wxWindow
& win
, wxCommandEvent
& event
)
329 m_view
->OnCommand(win
, event
);
332 // Extend event processing to search the view's event table
333 bool wxPropertyFormDialog::ProcessEvent(wxEvent
& event
)
335 if ( !m_view
|| ! m_view
->ProcessEvent(event
) )
336 return wxEvtHandler::ProcessEvent(event
);
343 * Property form panel
346 IMPLEMENT_DYNAMIC_CLASS(wxPropertyFormPanel
, wxPanel
)
348 void wxPropertyFormPanel::OnDefaultAction(wxControl
*item
)
350 m_view
->OnDoubleClick(item
);
353 void wxPropertyFormPanel::OnCommand(wxWindow
& win
, wxCommandEvent
& event
)
355 m_view
->OnCommand(win
, event
);
358 // Extend event processing to search the view's event table
359 bool wxPropertyFormPanel::ProcessEvent(wxEvent
& event
)
361 if ( !m_view
|| ! m_view
->ProcessEvent(event
) )
362 return wxEvtHandler::ProcessEvent(event
);
371 IMPLEMENT_DYNAMIC_CLASS(wxPropertyFormFrame
, wxFrame
)
373 BEGIN_EVENT_TABLE(wxPropertyFormFrame
, wxFrame
)
374 EVT_CLOSE(wxPropertyFormFrame::OnCloseWindow
)
377 void wxPropertyFormFrame::OnCloseWindow(wxCloseEvent
& event
)
379 if (m_view
&& m_view
->OnClose())
385 wxPanel
*wxPropertyFormFrame::OnCreatePanel(wxFrame
*parent
, wxPropertyFormView
*v
)
387 return new wxPropertyFormPanel(v
, parent
);
390 bool wxPropertyFormFrame::Initialize(void)
392 m_propertyPanel
= OnCreatePanel(this, m_view
);
395 m_view
->AssociatePanel(m_propertyPanel
);
396 m_view
->SetManagedWindow(this);
404 * Property form specific validator
407 IMPLEMENT_ABSTRACT_CLASS(wxPropertyFormValidator
, wxPropertyValidator
)
414 IMPLEMENT_DYNAMIC_CLASS(wxRealFormValidator
, wxPropertyFormValidator
)
417 /// Real number form validator
419 bool wxRealFormValidator::OnCheckValue( wxProperty
*property
, wxPropertyFormView
*WXUNUSED(view
),
420 wxWindow
*parentWindow
)
422 if (m_realMin
== 0.0 && m_realMax
== 0.0)
425 // The item used for viewing the real number: should be a text item.
426 wxWindow
*m_propertyWindow
= property
->GetWindow();
427 if (!m_propertyWindow
|| !m_propertyWindow
->IsKindOf(CLASSINFO(wxTextCtrl
)))
430 wxString
value(((wxTextCtrl
*)m_propertyWindow
)->GetValue());
433 if (!StringToFloat(WXSTRINGCAST value
, &val
))
436 wxSprintf(buf
, wxT("Value %s is not a valid real number!"), (const wxChar
*)value
);
437 wxMessageBox(buf
, wxT("Property value error"), wxOK
| wxICON_EXCLAMATION
, parentWindow
);
441 if (val
< m_realMin
|| val
> m_realMax
)
444 wxSprintf(buf
, wxT("Value must be a real number between %.2f and %.2f!"), m_realMin
, m_realMax
);
445 wxMessageBox(buf
, wxT("Property value error"), wxOK
| wxICON_EXCLAMATION
, parentWindow
);
451 bool wxRealFormValidator::OnRetrieveValue(wxProperty
*property
, wxPropertyFormView
*WXUNUSED(view
),
452 wxWindow
*WXUNUSED(parentWindow
) )
454 // The item used for viewing the real number: should be a text item.
455 wxWindow
*m_propertyWindow
= property
->GetWindow();
456 if (!m_propertyWindow
|| !m_propertyWindow
->IsKindOf(CLASSINFO(wxTextCtrl
)))
459 wxString
value(((wxTextCtrl
*)m_propertyWindow
)->GetValue());
461 if (value
.Length() == 0)
464 float f
= (float)wxAtof((const wxChar
*)value
);
465 property
->GetValue() = f
;
469 bool wxRealFormValidator::OnDisplayValue(wxProperty
*property
, wxPropertyFormView
*WXUNUSED(view
),
470 wxWindow
*WXUNUSED(parentWindow
) )
472 // The item used for viewing the real number: should be a text item.
473 wxWindow
*m_propertyWindow
= property
->GetWindow();
474 if (!m_propertyWindow
|| !m_propertyWindow
->IsKindOf(CLASSINFO(wxTextCtrl
)))
477 wxTextCtrl
*textItem
= (wxTextCtrl
*)m_propertyWindow
;
478 textItem
->SetValue(FloatToString(property
->GetValue().RealValue()));
483 /// Integer validator
485 IMPLEMENT_DYNAMIC_CLASS(wxIntegerFormValidator
, wxPropertyFormValidator
)
487 bool wxIntegerFormValidator::OnCheckValue(wxProperty
*property
, wxPropertyFormView
*WXUNUSED(view
),
488 wxWindow
*parentWindow
)
490 if (m_integerMin
== 0.0 && m_integerMax
== 0.0)
493 // The item used for viewing the real number: should be a text item or a slider
494 wxWindow
*m_propertyWindow
= property
->GetWindow();
495 if (!m_propertyWindow
)
500 if (m_propertyWindow
->IsKindOf(CLASSINFO(wxTextCtrl
)))
502 wxString
value(((wxTextCtrl
*)m_propertyWindow
)->GetValue());
504 if (!StringToLong(WXSTRINGCAST value
, &val
))
507 wxSprintf(buf
, wxT("Value %s is not a valid integer!"), (const wxChar
*)value
);
508 wxMessageBox(buf
, wxT("Property value error"), wxOK
| wxICON_EXCLAMATION
, parentWindow
);
512 else if (m_propertyWindow
->IsKindOf(CLASSINFO(wxSlider
)))
514 val
= (long)((wxSlider
*)m_propertyWindow
)->GetValue();
519 if (val
< m_integerMin
|| val
> m_integerMax
)
522 wxSprintf(buf
, wxT("Value must be an integer between %ld and %ld!"), m_integerMin
, m_integerMax
);
523 wxMessageBox(buf
, wxT("Property value error"), wxOK
| wxICON_EXCLAMATION
, parentWindow
);
529 bool wxIntegerFormValidator::OnRetrieveValue(wxProperty
*property
, wxPropertyFormView
*WXUNUSED(view
),
530 wxWindow
*WXUNUSED(parentWindow
))
532 // The item used for viewing the real number: should be a text item or a slider
533 wxWindow
*m_propertyWindow
= property
->GetWindow();
534 if (!m_propertyWindow
)
537 if (m_propertyWindow
->IsKindOf(CLASSINFO(wxTextCtrl
)))
539 wxString
value(((wxTextCtrl
*)m_propertyWindow
)->GetValue());
541 if (value
.Length() == 0)
544 long i
= wxAtol((const wxChar
*)value
);
545 property
->GetValue() = i
;
547 else if (m_propertyWindow
->IsKindOf(CLASSINFO(wxSlider
)))
549 property
->GetValue() = (long)((wxSlider
*)m_propertyWindow
)->GetValue();
557 bool wxIntegerFormValidator::OnDisplayValue( wxProperty
*property
, wxPropertyFormView
*WXUNUSED(view
),
558 wxWindow
*WXUNUSED(parentWindow
))
560 // The item used for viewing the real number: should be a text item or a slider
561 wxWindow
*m_propertyWindow
= property
->GetWindow();
562 if (!m_propertyWindow
)
565 if (m_propertyWindow
->IsKindOf(CLASSINFO(wxTextCtrl
)))
567 wxTextCtrl
*textItem
= (wxTextCtrl
*)m_propertyWindow
;
568 textItem
->SetValue(LongToString(property
->GetValue().IntegerValue()));
570 else if (m_propertyWindow
->IsKindOf(CLASSINFO(wxSlider
)))
572 ((wxSlider
*)m_propertyWindow
)->SetValue((int)property
->GetValue().IntegerValue());
580 /// Boolean validator
582 IMPLEMENT_DYNAMIC_CLASS(wxBoolFormValidator
, wxPropertyFormValidator
)
584 bool wxBoolFormValidator::OnCheckValue(wxProperty
*property
, wxPropertyFormView
*WXUNUSED(view
),
585 wxWindow
*WXUNUSED(parentWindow
))
587 // The item used for viewing the boolean: should be a checkbox
588 wxWindow
*m_propertyWindow
= property
->GetWindow();
589 if (!m_propertyWindow
|| !m_propertyWindow
->IsKindOf(CLASSINFO(wxCheckBox
)))
595 bool wxBoolFormValidator::OnRetrieveValue(wxProperty
*property
, wxPropertyFormView
*WXUNUSED(view
),
596 wxWindow
*WXUNUSED(parentWindow
) )
598 // The item used for viewing the boolean: should be a checkbox.
599 wxWindow
*m_propertyWindow
= property
->GetWindow();
600 if (!m_propertyWindow
|| !m_propertyWindow
->IsKindOf(CLASSINFO(wxCheckBox
)))
603 wxCheckBox
*checkBox
= (wxCheckBox
*)m_propertyWindow
;
605 property
->GetValue() = (bool)checkBox
->GetValue();
609 bool wxBoolFormValidator::OnDisplayValue(wxProperty
*property
, wxPropertyFormView
*WXUNUSED(view
),
610 wxWindow
*WXUNUSED(parentWindow
))
612 // The item used for viewing the boolean: should be a checkbox.
613 wxWindow
*m_propertyWindow
= property
->GetWindow();
614 if (!m_propertyWindow
|| !m_propertyWindow
->IsKindOf(CLASSINFO(wxCheckBox
)))
617 wxCheckBox
*checkBox
= (wxCheckBox
*)m_propertyWindow
;
618 checkBox
->SetValue((bool)property
->GetValue().BoolValue());
625 IMPLEMENT_DYNAMIC_CLASS(wxStringFormValidator
, wxPropertyFormValidator
)
627 wxStringFormValidator::wxStringFormValidator(wxStringList
*list
, long flags
):
628 wxPropertyFormValidator(flags
)
633 bool wxStringFormValidator::OnCheckValue(wxProperty
*property
, wxPropertyFormView
*WXUNUSED(view
),
634 wxWindow
*parentWindow
)
639 // The item used for viewing the string: should be a text item, choice item or listbox.
640 wxWindow
*m_propertyWindow
= property
->GetWindow();
641 if (!m_propertyWindow
)
643 if (m_propertyWindow
->IsKindOf(CLASSINFO(wxTextCtrl
)))
645 wxTextCtrl
*text
= (wxTextCtrl
*)m_propertyWindow
;
646 if (!m_strings
->Member(text
->GetValue()))
648 wxString
str( wxT("Value ") );
649 str
+= text
->GetValue();
650 str
+= wxT(" is not valid.");
651 wxMessageBox(str
, wxT("Property value error"), wxOK
| wxICON_EXCLAMATION
, parentWindow
);
657 // Any other item constrains the string value,
658 // so we don't have to check it.
663 bool wxStringFormValidator::OnRetrieveValue(wxProperty
*property
, wxPropertyFormView
*WXUNUSED(view
),
664 wxWindow
*WXUNUSED(parentWindow
) )
666 // The item used for viewing the string: should be a text item, choice item or listbox.
667 wxWindow
*m_propertyWindow
= property
->GetWindow();
668 if (!m_propertyWindow
)
670 if (m_propertyWindow
->IsKindOf(CLASSINFO(wxTextCtrl
)))
672 wxTextCtrl
*text
= (wxTextCtrl
*)m_propertyWindow
;
673 property
->GetValue() = text
->GetValue();
675 else if (m_propertyWindow
->IsKindOf(CLASSINFO(wxListBox
)))
677 wxListBox
*lbox
= (wxListBox
*)m_propertyWindow
;
678 if (lbox
->GetSelection() > -1)
679 property
->GetValue() = lbox
->GetStringSelection();
682 else if (m_propertyWindow->IsKindOf(CLASSINFO(wxRadioBox)))
684 wxRadioBox *rbox = (wxRadioBox *)m_propertyWindow;
686 if ((n = rbox->GetSelection()) > -1)
687 property->GetValue() = rbox->GetString(n);
690 else if (m_propertyWindow
->IsKindOf(CLASSINFO(wxChoice
)))
692 wxChoice
*choice
= (wxChoice
*)m_propertyWindow
;
693 if (choice
->GetSelection() > -1)
694 property
->GetValue() = choice
->GetStringSelection();
701 bool wxStringFormValidator::OnDisplayValue(wxProperty
*property
, wxPropertyFormView
*WXUNUSED(view
),
702 wxWindow
*WXUNUSED(parentWindow
) )
704 // The item used for viewing the string: should be a text item, choice item or listbox.
705 wxWindow
*m_propertyWindow
= property
->GetWindow();
706 if (!m_propertyWindow
)
708 if (m_propertyWindow
->IsKindOf(CLASSINFO(wxTextCtrl
)))
710 wxTextCtrl
*text
= (wxTextCtrl
*)m_propertyWindow
;
711 text
->SetValue(property
->GetValue().StringValue());
713 else if (m_propertyWindow
->IsKindOf(CLASSINFO(wxListBox
)))
715 wxListBox
*lbox
= (wxListBox
*)m_propertyWindow
;
716 if (lbox
->GetCount() == 0 && m_strings
)
718 // Try to initialize the listbox from 'strings'
719 wxStringList::Node
*node
= m_strings
->GetFirst();
722 wxChar
*s
= node
->GetData();
724 node
= node
->GetNext();
727 lbox
->SetStringSelection(property
->GetValue().StringValue());
730 else if (m_propertyWindow->IsKindOf(CLASSINFO(wxRadioBox)))
732 wxRadioBox *rbox = (wxRadioBox *)m_propertyWindow;
733 rbox->SetStringSelection(property->GetValue().StringValue());
736 else if (m_propertyWindow
->IsKindOf(CLASSINFO(wxChoice
)))
738 wxChoice
*choice
= (wxChoice
*)m_propertyWindow
;
739 if (choice
->GetCount() == 0 && m_strings
)
741 // Try to initialize the choice item from 'strings'
742 // XView doesn't allow this kind of thing.
743 wxStringList::Node
*node
= m_strings
->GetFirst();
746 wxChar
*s
= node
->GetData();
748 node
= node
->GetNext();
751 choice
->SetStringSelection(property
->GetValue().StringValue());
758 #endif // wxUSE_PROPSHEET