// Created: 2004-09-25
// RCS-ID: $Id$
// Copyright: (c) Jaakko Salli
-// Licence: wxWindows license
+// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/timer.h"
#include "wx/dcbuffer.h"
+#include "wx/scopeguard.h"
// Two pics for the expand / collapse buttons.
// Files are not supplied with this project (since it is
m_curFocused = NULL;
m_processedEvent = NULL;
m_sortFunction = NULL;
- m_inDoPropertyChanged = 0;
- m_inCommitChangesFromEditor = 0;
- m_inDoSelectProperty = 0;
+ m_inDoPropertyChanged = false;
+ m_inCommitChangesFromEditor = false;
+ m_inDoSelectProperty = false;
+ m_inOnValidationFailure = false;
m_permanentValidationFailureBehavior = wxPG_VFB_DEFAULT;
m_dragStatus = 0;
m_mouseSide = 16;
(m_iFlags & wxPG_FL_INITIALIZED) &&
selected )
{
- m_inCommitChangesFromEditor = 1;
+ m_inCommitChangesFromEditor = true;
wxVariant variant(selected->GetValueRef());
bool valueIsPending = false;
EditorsValueWasNotModified();
}
- bool res = true;
+ m_inCommitChangesFromEditor = false;
- m_inCommitChangesFromEditor = 0;
+ bool res = true;
if ( validationFailure && !forceSuccess )
{
//
m_validationInfo.m_failureBehavior = m_permanentValidationFailureBehavior;
+ m_validationInfo.m_isFailing = true;
//
// Variant list a special value that cannot be validated
pendingValue = value;
}
+ m_validationInfo.m_isFailing = false;
+
return true;
}
// -----------------------------------------------------------------------
+#if wxUSE_STATUSBAR
+wxStatusBar* wxPropertyGrid::GetStatusBar()
+{
+ wxWindow* topWnd = ::wxGetTopLevelParent(this);
+ if ( topWnd && topWnd->IsKindOf(CLASSINFO(wxFrame)) )
+ {
+ wxFrame* pFrame = wxStaticCast(topWnd, wxFrame);
+ if ( pFrame )
+ return pFrame->GetStatusBar();
+ }
+ return NULL;
+}
+#endif
+
+// -----------------------------------------------------------------------
+
void wxPropertyGrid::DoShowPropertyError( wxPGProperty* WXUNUSED(property), const wxString& msg )
{
if ( !msg.length() )
#if wxUSE_STATUSBAR
if ( !wxPGGlobalVars->m_offline )
{
- wxWindow* topWnd = ::wxGetTopLevelParent(this);
- if ( topWnd )
+ wxStatusBar* pStatusBar = GetStatusBar();
+ if ( pStatusBar )
{
- wxFrame* pFrame = wxDynamicCast(topWnd, wxFrame);
- if ( pFrame )
- {
- wxStatusBar* pStatusBar = pFrame->GetStatusBar();
- if ( pStatusBar )
- {
- pStatusBar->SetStatusText(msg);
- return;
- }
- }
+ pStatusBar->SetStatusText(msg);
+ return;
}
}
#endif
- ::wxMessageBox(msg, wxT("Property Error"));
+ ::wxMessageBox(msg, _("Property Error"));
+}
+
+// -----------------------------------------------------------------------
+
+void wxPropertyGrid::DoHidePropertyError( wxPGProperty* WXUNUSED(property) )
+{
+#if wxUSE_STATUSBAR
+ if ( !wxPGGlobalVars->m_offline )
+ {
+ wxStatusBar* pStatusBar = GetStatusBar();
+ if ( pStatusBar )
+ {
+ pStatusBar->SetStatusText(wxEmptyString);
+ return;
+ }
+ }
+#endif
}
// -----------------------------------------------------------------------
bool wxPropertyGrid::OnValidationFailure( wxPGProperty* property,
wxVariant& invalidValue )
{
+ if ( m_inOnValidationFailure )
+ return true;
+
+ m_inOnValidationFailure = true;
+ wxON_BLOCK_EXIT_SET(m_inOnValidationFailure, false);
+
wxWindow* editor = GetEditorControl();
+ int vfb = m_validationInfo.m_failureBehavior;
+
+ if ( m_inDoSelectProperty )
+ {
+ // When property selection is being changed, do not display any
+ // messages, if some were already shown for this property.
+ if ( property->HasFlag(wxPG_PROP_INVALID_VALUE) )
+ {
+ m_validationInfo.m_failureBehavior =
+ vfb & ~(wxPG_VFB_SHOW_MESSAGE |
+ wxPG_VFB_SHOW_MESSAGEBOX |
+ wxPG_VFB_SHOW_MESSAGE_ON_STATUSBAR);
+ }
+ }
// First call property's handler
property->OnValidationFailure(invalidValue);
}
}
- if ( vfb & wxPG_VFB_SHOW_MESSAGE )
+ if ( vfb & (wxPG_VFB_SHOW_MESSAGE |
+ wxPG_VFB_SHOW_MESSAGEBOX |
+ wxPG_VFB_SHOW_MESSAGE_ON_STATUSBAR) )
{
wxString msg = m_validationInfo.m_failureMessage;
if ( !msg.length() )
- msg = wxT("You have entered invalid value. Press ESC to cancel editing.");
+ msg = _("You have entered invalid value. Press ESC to cancel editing.");
+
+ #if wxUSE_STATUSBAR
+ if ( vfb & wxPG_VFB_SHOW_MESSAGE_ON_STATUSBAR )
+ {
+ if ( !wxPGGlobalVars->m_offline )
+ {
+ wxStatusBar* pStatusBar = GetStatusBar();
+ if ( pStatusBar )
+ pStatusBar->SetStatusText(msg);
+ }
+ }
+ #endif
+
+ if ( vfb & wxPG_VFB_SHOW_MESSAGE )
+ DoShowPropertyError(property, msg);
- DoShowPropertyError(property, msg);
+ if ( vfb & wxPG_VFB_SHOW_MESSAGEBOX )
+ ::wxMessageBox(msg, _("Property Error"));
}
return (vfb & wxPG_VFB_STAY_IN_PROPERTY) ? false : true;
DrawItemAndChildren(property);
}
}
+
+#if wxUSE_STATUSBAR
+ if ( vfb & wxPG_VFB_SHOW_MESSAGE_ON_STATUSBAR )
+ {
+ if ( !wxPGGlobalVars->m_offline )
+ {
+ wxStatusBar* pStatusBar = GetStatusBar();
+ if ( pStatusBar )
+ pStatusBar->SetStatusText(wxEmptyString);
+ }
+ }
+#endif
+
+ if ( vfb & wxPG_VFB_SHOW_MESSAGE )
+ {
+ DoHidePropertyError(property);
+ }
+
+ m_validationInfo.m_isFailing = false;
}
// -----------------------------------------------------------------------
if ( m_inDoPropertyChanged )
return true;
+ m_inDoPropertyChanged = true;
+ wxON_BLOCK_EXIT_SET(m_inDoPropertyChanged, false);
+
wxPGProperty* selected = GetSelection();
m_pState->m_anyModified = 1;
- m_inDoPropertyChanged = 1;
+ // If property's value is being changed, assume it is valid
+ OnValidationFailureReset(selected);
// Maybe need to update control
wxASSERT( m_chgInfo_changedProperty != NULL );
SendEvent( wxEVT_PG_CHANGED, changedProperty, NULL );
- m_inDoPropertyChanged = 0;
-
return true;
}
// Possibly, but very rare.
if ( !selected ||
selected->HasFlag(wxPG_PROP_BEING_DELETED) ||
+ m_inOnValidationFailure ||
// Also don't handle editor event if wxEVT_PG_CHANGED or
// similar is currently doing something (showing a
// message box, for instance).
selected,
wnd ) )
valueIsPending = true;
+
+ // Mark value always as pending if validation is currently
+ // failing and value was not unspecified
+ if ( !valueIsPending &&
+ !pendingValue.IsNull() &&
+ m_validationInfo.m_isFailing )
+ valueIsPending = true;
}
else
{
if ( m_inDoSelectProperty )
return true;
- m_inDoSelectProperty = 1;
+ m_inDoSelectProperty = true;
+ wxON_BLOCK_EXIT_SET(m_inDoSelectProperty, false);
if ( !m_pState )
- {
- m_inDoSelectProperty = 0;
return false;
- }
wxArrayPGProperty prevSelection = m_pState->m_selection;
wxPGProperty* prevFirstSel;
}
}
- m_inDoSelectProperty = 0;
return true;
}
// First, deactivate previous
if ( prevFirstSel )
{
- OnValidationFailureReset(prevFirstSel);
-
// Must double-check if this is an selected in case of forceswitch
if ( p != prevFirstSel )
{
// Validation has failed, so we can't exit the previous editor
//::wxMessageBox(_("Please correct the value or press ESC to cancel the edit."),
// _("Invalid Value"),wxOK|wxICON_ERROR);
- m_inDoSelectProperty = 0;
return false;
}
}
+ // This should be called after CommitChangesFromEditor(), so that
+ // OnValidationFailure() still has information on property's
+ // validation state.
+ OnValidationFailureReset(prevFirstSel);
+
FreeEditors();
m_iFlags &= ~(wxPG_FL_ABNORMAL_EDITOR);
if ( !(GetExtraStyle() & wxPG_EX_HELP_AS_TOOLTIPS) )
{
- wxStatusBar* statusbar = NULL;
- if ( !(m_iFlags & wxPG_FL_NOSTATUSBARHELP) )
- {
- wxFrame* frame = wxDynamicCast(::wxGetTopLevelParent(this),wxFrame);
- if ( frame )
- statusbar = frame->GetStatusBar();
- }
-
+ wxStatusBar* statusbar = GetStatusBar();
if ( statusbar )
{
const wxString* pHelpString = (const wxString*) NULL;
}
#endif
- m_inDoSelectProperty = 0;
-
// call wx event handler (here so that it also occurs on deselection)
if ( !(flags & wxPG_SEL_DONT_SEND_EVENT) )
SendEvent( wxEVT_PG_SELECTED, p, NULL );
// Called by focus event handlers. newFocused is the window that becomes focused.
void wxPropertyGrid::HandleFocusChange( wxWindow* newFocused )
{
+ //
+ // Never allow focus to be changed when handling editor event.
+ // Especially because they may be displaing a dialog which
+ // could cause all kinds of weird (native) focus changes.
+ if ( HasInternalFlag(wxPG_FL_IN_HANDLECUSTOMEDITOREVENT) )
+ return;
+
unsigned int oldFlags = m_iFlags;
bool wasEditorFocused = false;
wxWindow* wndEditor = m_wndEditor;