* Determine whether to use a 3-state or 2-state
* checkbox. 3-state enables to differentiate
* between 'unchecked', 'checked' and 'undetermined'.
+ *
+ * In addition to the styles here it is also possible to specify just 0 which
+ * is treated the same as wxCHK_2STATE for compatibility (but using explicit
+ * flag is preferred).
*/
-#define wxCHK_2STATE 0x0000
+#define wxCHK_2STATE 0x4000
#define wxCHK_3STATE 0x1000
/*
return wxCHK_UNCHECKED;
}
+ // Helper function to be called from derived classes Create()
+ // implementations: it checks that the style doesn't contain any
+ // incompatible bits and modifies it to be sane if it does.
+ static void WXValidateStyle(long *stylePtr)
+ {
+ long& style = *stylePtr;
+
+ if ( style == 0 )
+ {
+ // For compatibility we use absence of style flags as wxCHK_2STATE
+ // because wxCHK_2STATE used to have the value of 0 and some
+ // existing code may use 0 instead of it.
+ style = wxCHK_2STATE;
+ }
+ else if ( style & wxCHK_3STATE )
+ {
+ if ( style & wxCHK_2STATE )
+ {
+ wxFAIL_MSG( "wxCHK_2STATE and wxCHK_3STATE can't be used "
+ "together" );
+ style &= ~wxCHK_3STATE;
+ }
+ }
+ else // No wxCHK_3STATE
+ {
+ if ( !(style & wxCHK_2STATE) )
+ {
+ wxFAIL_MSG( "Either wxCHK_2STATE or wxCHK_3STATE must be "
+ "specified" );
+ style |= wxCHK_2STATE;
+ }
+
+ if ( style & wxCHK_ALLOW_3RD_STATE_FOR_USER )
+ {
+ wxFAIL_MSG( "wxCHK_ALLOW_3RD_STATE_FOR_USER doesn't make sense "
+ "without wxCHK_3STATE" );
+ style &= ~wxCHK_ALLOW_3RD_STATE_FOR_USER;
+ }
+ }
+ }
+
private:
wxDECLARE_NO_COPY_CLASS(wxCheckBoxBase);
};
const wxValidator& validator,
const wxString &name )
{
+ WXValidateStyle( &style );
if (!PreCreation( parent, pos, size ) ||
!CreateBase( parent, id, pos, size, style, validator, name ))
{
return false;
}
- wxASSERT_MSG( (style & wxCHK_ALLOW_3RD_STATE_FOR_USER) == 0 ||
- (style & wxCHK_3STATE) != 0,
- wxT("Using wxCHK_ALLOW_3RD_STATE_FOR_USER")
- wxT(" style flag for a 2-state checkbox is useless") );
-
if ( style & wxALIGN_RIGHT )
{
// VZ: as I don't know a way to create a right aligned checkbox with
m_acceptsFocus = true;
m_blockEvent = false;
+ WXValidateStyle(&style);
if (!PreCreation( parent, pos, size ) ||
!CreateBase( parent, id, pos, size, style, validator, name ))
{
return false;
}
- wxASSERT_MSG( (style & wxCHK_ALLOW_3RD_STATE_FOR_USER) == 0 ||
- (style & wxCHK_3STATE) != 0,
- wxT("Using wxCHK_ALLOW_3RD_STATE_FOR_USER")
- wxT(" style flag for a 2-state checkbox is useless") );
-
if ( style & wxALIGN_RIGHT )
{
// VZ: as I don't know a way to create a right aligned checkbox with
{
Init();
+ WXValidateStyle(&style);
if ( !CreateControl(parent, id, pos, size, style, validator, name) )
return false;
long msStyle = WS_TABSTOP;
if ( style & wxCHK_3STATE )
- {
msStyle |= BS_3STATE;
- }
else
- {
- wxASSERT_MSG( !Is3rdStateAllowedForUser(),
- wxT("Using wxCH_ALLOW_3RD_STATE_FOR_USER")
- wxT(" style flag for a 2-state checkbox is useless") );
msStyle |= BS_CHECKBOX;
- }
if ( style & wxALIGN_RIGHT )
{
m_labelOrig = m_label = label ;
+ WXValidateStyle( &style );
m_peer = wxWidgetImpl::CreateCheckBox( this, parent, id, label, pos, size, style, GetExtraStyle() ) ;
MacPostControlCreate(pos, size) ;
const wxValidator& validator,
const wxString &name)
{
+ WXValidateStyle( &style );
if ( !wxControl::Create(parent, id, pos, size, style, validator, name) )
return false;
CPPUNIT_TEST( Check );
CPPUNIT_TEST( ThirdState );
CPPUNIT_TEST( ThirdStateUser );
+ CPPUNIT_TEST( InvalidStyles );
CPPUNIT_TEST_SUITE_END();
void Check();
void ThirdState();
void ThirdStateUser();
+ void InvalidStyles();
+
+ // Initialize m_check with a new checkbox with the specified style
+ //
+ // This function always returns false just to make it more convenient to
+ // use inside WX_ASSERT_FAILS_WITH_ASSERT(), its return value doesn't have
+ // any meaning otherwise.
+ bool CreateCheckBox(long style)
+ {
+ m_check = new wxCheckBox(wxTheApp->GetTopWindow(), wxID_ANY, "Check box",
+ wxDefaultPosition, wxDefaultSize, style);
+ return false;
+ }
+
wxCheckBox* m_check;
{
#if !defined(__WXMGL__) && !defined(__WXPM__) && !defined(__WXGTK12__)
wxDELETE(m_check);
- m_check = new wxCheckBox(wxTheApp->GetTopWindow(), wxID_ANY, "Check box",
- wxDefaultPosition, wxDefaultSize, wxCHK_3STATE);
+ CreateCheckBox(wxCHK_3STATE);
CPPUNIT_ASSERT_EQUAL(wxCHK_UNCHECKED, m_check->Get3StateValue());
CPPUNIT_ASSERT(m_check->Is3State());
{
#if !defined(__WXMGL__) && !defined(__WXPM__) && !defined(__WXGTK12__)
wxDELETE(m_check);
- m_check = new wxCheckBox(wxTheApp->GetTopWindow(), wxID_ANY, "Check box",
- wxDefaultPosition, wxDefaultSize,
- wxCHK_3STATE | wxCHK_ALLOW_3RD_STATE_FOR_USER);
+ CreateCheckBox(wxCHK_3STATE | wxCHK_ALLOW_3RD_STATE_FOR_USER);
CPPUNIT_ASSERT_EQUAL(wxCHK_UNCHECKED, m_check->Get3StateValue());
CPPUNIT_ASSERT(m_check->Is3State());
#endif
}
+void CheckBoxTestCase::InvalidStyles()
+{
+ // Check that using incompatible styles doesn't work.
+ wxDELETE( m_check );
+ WX_ASSERT_FAILS_WITH_ASSERT( CreateCheckBox(wxCHK_2STATE | wxCHK_3STATE) );
+#if !wxDEBUG_LEVEL
+ CPPUNIT_ASSERT( !m_check->Is3State() );
+ CPPUNIT_ASSERT( !m_check->Is3rdStateAllowedForUser() );
+#endif
+
+ wxDELETE( m_check );
+ WX_ASSERT_FAILS_WITH_ASSERT(
+ CreateCheckBox(wxCHK_2STATE | wxCHK_ALLOW_3RD_STATE_FOR_USER) );
+#if !wxDEBUG_LEVEL
+ CPPUNIT_ASSERT( !m_check->Is3State() );
+ CPPUNIT_ASSERT( !m_check->Is3rdStateAllowedForUser() );
+#endif
+
+ // wxCHK_ALLOW_3RD_STATE_FOR_USER without wxCHK_3STATE doesn't work.
+ wxDELETE( m_check );
+ WX_ASSERT_FAILS_WITH_ASSERT( CreateCheckBox(wxCHK_ALLOW_3RD_STATE_FOR_USER) );
+}
+
#endif //wxUSE_CHECKBOX