X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/d8812c6e0e780fb2dae99bc352c5061f58793e14..c753eb9269d1e6c99b80a2d782ce49d9864ac1da:/src/propgrid/propgrid.cpp diff --git a/src/propgrid/propgrid.cpp b/src/propgrid/propgrid.cpp index 237158f0bb..964afd9c90 100644 --- a/src/propgrid/propgrid.cpp +++ b/src/propgrid/propgrid.cpp @@ -63,8 +63,6 @@ #include "wx/timer.h" #include "wx/dcbuffer.h" -#include "wx/clipbrd.h" -#include "wx/dataobj.h" #ifdef __WXMSW__ #include "wx/msw/private.h" @@ -154,7 +152,16 @@ public: IMPLEMENT_DYNAMIC_CLASS(wxPGGlobalVarsClassManager, wxModule) -wxPGGlobalVarsClass* wxPGGlobalVars = (wxPGGlobalVarsClass*) NULL; +// When wxPG is loaded dynamically after the application is already running +// then the built-in module system won't pick this one up. Add it manually. +void wxPGInitResourceModule() +{ + wxModule* module = new wxPGGlobalVarsClassManager; + module->Init(); + wxModule::RegisterModule(module); +} + +wxPGGlobalVarsClass* wxPGGlobalVars = NULL; wxPGGlobalVarsClass::wxPGGlobalVarsClass() @@ -164,7 +171,7 @@ wxPGGlobalVarsClass::wxPGGlobalVarsClass() m_boolChoices.Add(_("False")); m_boolChoices.Add(_("True")); - m_fontFamilyChoices = (wxPGChoices*) NULL; + m_fontFamilyChoices = NULL; m_defaultRenderer = new wxPGDefaultRenderer(); @@ -176,7 +183,7 @@ wxPGGlobalVarsClass::wxPGGlobalVarsClass() wxVariant v; - // Prepare some shared variants + // Prepare some shared variants m_vEmptyString = wxString(); m_vZero = (long) 0; m_vMinusOne = (long) -1; @@ -188,14 +195,13 @@ wxPGGlobalVarsClass::wxPGGlobalVarsClass() m_strlong = wxS("long"); m_strbool = wxS("bool"); m_strlist = wxS("list"); + m_strDefaultValue = wxS("DefaultValue"); m_strMin = wxS("Min"); m_strMax = wxS("Max"); m_strUnits = wxS("Units"); m_strInlineHelp = wxS("InlineHelp"); -#ifdef __WXDEBUG__ m_warnings = 0; -#endif } @@ -231,46 +237,6 @@ void wxPropertyGridInitGlobalsIfNeeded() { } -// ----------------------------------------------------------------------- -// wxPGTLWHandler -// Intercepts Close-events sent to wxPropertyGrid's top-level parent, -// and tries to commit property value. -// ----------------------------------------------------------------------- - -class wxPGTLWHandler : public wxEvtHandler -{ -public: - - wxPGTLWHandler( wxPropertyGrid* pg ) - : wxEvtHandler() - { - m_pg = pg; - } - -protected: - - void OnClose( wxCloseEvent& event ) - { - // ClearSelection forces value validation/commit. - if ( event.CanVeto() && !m_pg->ClearSelection() ) - { - event.Veto(); - return; - } - - event.Skip(); - } - -private: - wxPropertyGrid* m_pg; - - DECLARE_EVENT_TABLE() -}; - -BEGIN_EVENT_TABLE(wxPGTLWHandler, wxEvtHandler) - EVT_CLOSE(wxPGTLWHandler::OnClose) -END_EVENT_TABLE() - // ----------------------------------------------------------------------- // wxPGCanvas // ----------------------------------------------------------------------- @@ -364,6 +330,12 @@ void wxPGCanvas::OnPaint( wxPaintEvent& WXUNUSED(event) ) // Update everything inside the box wxRect r = GetUpdateRegion().GetBox(); + // FIXME: This is just a workaround for a bug that causes splitters not + // to paint when other windows are being dragged over the grid. + wxRect fullRect = GetRect(); + r.x = fullRect.x; + r.width = fullRect.width; + // Repaint this rectangle pg->DrawItems( dc, r.y, r.y + r.height, &r ); @@ -454,14 +426,13 @@ void wxPropertyGrid::Init1() wxPropertyGrid::RegisterDefaultEditors(); m_iFlags = 0; - m_pState = (wxPropertyGridPageState*) NULL; - m_wndEditor = m_wndEditor2 = (wxWindow*) NULL; - m_selected = (wxPGProperty*) NULL; + m_pState = NULL; + m_wndEditor = m_wndEditor2 = NULL; + m_selected = NULL; m_selColumn = -1; - m_propHover = (wxPGProperty*) NULL; + m_propHover = NULL; m_eventObject = this; - m_curFocused = (wxWindow*) NULL; - m_tlwHandler = NULL; + m_curFocused = NULL; m_sortFunction = NULL; m_inDoPropertyChanged = 0; m_inCommitChangesFromEditor = 0; @@ -488,14 +459,14 @@ void wxPropertyGrid::Init1() m_canvas = NULL; #if wxPG_DOUBLE_BUFFER - m_doubleBuffer = (wxBitmap*) NULL; + m_doubleBuffer = NULL; #endif #ifndef wxPG_ICON_WIDTH - m_expandbmp = NULL; - m_collbmp = NULL; - m_iconWidth = 11; - m_iconHeight = 11; + m_expandbmp = NULL; + m_collbmp = NULL; + m_iconWidth = 11; + m_iconHeight = 11; #else m_iconWidth = wxPG_ICON_WIDTH; #endif @@ -552,31 +523,22 @@ void wxPropertyGrid::Init2() #ifndef wxPG_ICON_WIDTH // create two bitmap nodes for drawing - m_expandbmp = new wxBitmap(expand_xpm); - m_collbmp = new wxBitmap(collapse_xpm); + m_expandbmp = new wxBitmap(expand_xpm); + m_collbmp = new wxBitmap(collapse_xpm); - // calculate average font height for bitmap centering + // calculate average font height for bitmap centering - m_iconWidth = m_expandbmp->GetWidth(); - m_iconHeight = m_expandbmp->GetHeight(); + m_iconWidth = m_expandbmp->GetWidth(); + m_iconHeight = m_expandbmp->GetHeight(); #endif m_curcursor = wxCURSOR_ARROW; m_cursorSizeWE = new wxCursor( wxCURSOR_SIZEWE ); - // adjust bitmap icon y position so they are centered + // adjust bitmap icon y position so they are centered m_vspacing = wxPG_DEFAULT_VSPACING; - if ( !m_font.Ok() ) - { - wxFont useFont = wxScrolledWindow::GetFont(); - wxScrolledWindow::SetOwnFont( useFont ); - } - else - { - // This should be otherwise called by SetOwnFont - CalculateFontAndBitmapStuff( wxPG_DEFAULT_VSPACING ); - } + CalculateFontAndBitmapStuff( wxPG_DEFAULT_VSPACING ); // Allocate cell datas indirectly by calling setter m_propertyDefaultCell.SetBgCol(*wxBLACK); @@ -587,15 +549,13 @@ void wxPropertyGrid::Init2() // This helps with flicker SetBackgroundStyle( wxBG_STYLE_CUSTOM ); - // Hook the TLW - wxPGTLWHandler* handler = new wxPGTLWHandler(this); - m_tlp = ::wxGetTopLevelParent(this); - m_tlwHandler = handler; - m_tlp->PushEventHandler(handler); + // Hook the top-level parent + m_tlp = NULL; + OnTLPChanging(NULL); - // set virtual size to this window size + // set virtual size to this window size wxSize wndsize = GetSize(); - SetVirtualSize(wndsize.GetWidth(), wndsize.GetWidth()); + SetVirtualSize(wndsize.GetWidth(), wndsize.GetWidth()); m_timeCreated = ::wxGetLocalTimeMillis(); @@ -628,22 +588,32 @@ wxPropertyGrid::~wxPropertyGrid() if ( m_iFlags & wxPG_FL_MOUSE_CAPTURED ) m_canvas->ReleaseMouse(); - wxPGTLWHandler* handler = (wxPGTLWHandler*) m_tlwHandler; - m_tlp->RemoveEventHandler(handler); - delete handler; + // Do TLP check, recommend use of OnTLPChanging() + wxWindow* tlp = ::wxGetTopLevelParent(this); + if ( tlp == m_tlp ) + { + m_tlp->Disconnect( wxEVT_CLOSE_WINDOW, + wxCloseEventHandler(wxPropertyGrid::OnTLPClose), + NULL, this ); + } + else if ( tlp ) + { + wxLogError("Top-level parent of wxPropertyGrid has changed. " + "Consider calling wxPropertyGrid::OnTLPChanging() " + "when appropriate."); + } -#ifdef __WXDEBUG__ - if ( IsEditorsValueModified() ) - ::wxMessageBox(wxS("Most recent change in property editor was lost!!!\n\n(if you don't want this to happen, close your frames and dialogs using Close(false).)"), - wxS("wxPropertyGrid Debug Warning") ); -#endif + wxASSERT_MSG( !IsEditorsValueModified(), + wxS("Most recent change in property editor was lost!!! ") + wxS("(if you don't want this to happen, close your frames ") + wxS("and dialogs using Close(false).)") ); #if wxPG_DOUBLE_BUFFER if ( m_doubleBuffer ) delete m_doubleBuffer; #endif - //m_selected = (wxPGProperty*) NULL; + //m_selected = NULL; if ( m_iFlags & wxPG_FL_CREATEDSTATE ) delete m_pState; @@ -651,8 +621,8 @@ wxPropertyGrid::~wxPropertyGrid() delete m_cursorSizeWE; #ifndef wxPG_ICON_WIDTH - delete m_expandbmp; - delete m_collbmp; + delete m_expandbmp; + delete m_collbmp; #endif // Delete common value records @@ -728,7 +698,7 @@ void wxPropertyGrid::SetWindowStyleFlag( long style ) // // Tooltips disabled // - m_canvas->SetToolTip( (wxToolTip*) NULL ); + m_canvas->SetToolTip( NULL ); } #endif } @@ -831,28 +801,86 @@ void wxPropertyGrid::SetExtraStyle( long exStyle ) // returns the best acceptable minimal size wxSize wxPropertyGrid::DoGetBestSize() const { - int hei = 15; - if ( m_lineHeight > hei ) - hei = m_lineHeight; - wxSize sz = wxSize( 60, hei+40 ); + int lineHeight = wxMax(15, m_lineHeight); + + // don't make the grid too tall (limit height to 10 items) but don't + // make it too small neither + int numLines = wxMin + ( + wxMax(m_pState->m_properties->GetChildCount(), 3), + 10 + ); + const wxSize sz = wxSize(60, lineHeight*numLines + 40); CacheBestSize(sz); return sz; } + // ----------------------------------------------------------------------- + +void wxPropertyGrid::OnTLPChanging( wxWindow* newTLP ) +{ + // + // Parent changed so let's redetermine and re-hook the + // correct top-level window. + if ( m_tlp ) + { + wxASSERT_MSG( m_tlp == ::wxGetTopLevelParent(this), + "You must call OnTLPChanging() before the " + "top-level parent has changed."); + + m_tlp->Disconnect( wxEVT_CLOSE_WINDOW, + wxCloseEventHandler(wxPropertyGrid::OnTLPClose), + NULL, this ); + } + + if ( !newTLP ) + newTLP = ::wxGetTopLevelParent(this); + + m_tlp = newTLP; + m_tlp->Connect( wxEVT_CLOSE_WINDOW, + wxCloseEventHandler(wxPropertyGrid::OnTLPClose), + NULL, this ); +} + +// ----------------------------------------------------------------------- + +void wxPropertyGrid::OnTLPClose( wxCloseEvent& event ) +{ + // ClearSelection forces value validation/commit. + if ( event.CanVeto() && !ClearSelection() ) + { + event.Veto(); + return; + } + + event.Skip(); +} + +// ----------------------------------------------------------------------- + +bool wxPropertyGrid::Reparent( wxWindowBase *newParent ) +{ + OnTLPChanging((wxWindow*)newParent); + + bool res = wxScrolledWindow::Reparent(newParent); + + return res; +} + // ----------------------------------------------------------------------- // wxPropertyGrid Font and Colour Methods // ----------------------------------------------------------------------- void wxPropertyGrid::CalculateFontAndBitmapStuff( int vspacing ) { - int x = 0, y = 0; + int x = 0, y = 0; m_captionFont = wxScrolledWindow::GetFont(); - GetTextExtent(wxS("jG"), &x, &y, 0, 0, &m_captionFont); + GetTextExtent(wxS("jG"), &x, &y, 0, 0, &m_captionFont); m_subgroup_extramargin = x + (x/2); - m_fontHeight = y; + m_fontHeight = y; #if wxPG_USE_RENDERER_NATIVE m_iconWidth = wxPG_ICON_WIDTH; @@ -881,7 +909,7 @@ void wxPropertyGrid::CalculateFontAndBitmapStuff( int vspacing ) m_marginWidth = m_gutterWidth*2 + m_iconWidth; m_captionFont.SetWeight(wxBOLD); - GetTextExtent(wxS("jG"), &x, &y, 0, 0, &m_captionFont); + GetTextExtent(wxS("jG"), &x, &y, 0, 0, &m_captionFont); m_lineHeight = m_fontHeight+(2*m_spacingy)+1; @@ -1039,32 +1067,14 @@ bool wxPropertyGrid::SetFont( const wxFont& font ) // Must disable active editor. ClearSelection(false); - // TODO: Following code is disabled with wxMac because - // it is reported to fail. I (JMS) cannot debug it - // personally right now. - // CS: should be fixed now, leaving old code in just in case, TODO: REMOVE -#if 1 // !defined(__WXMAC__) bool res = wxScrolledWindow::SetFont( font ); - if ( res ) + if ( res && GetParent()) // may not have been Create()ed yet { CalculateFontAndBitmapStuff( m_vspacing ); - - if ( m_pState ) - m_pState->CalculateFontAndBitmapStuff(m_vspacing); - Refresh(); } return res; -#else - // ** wxMAC Only ** - // TODO: Remove after SetFont crash fixed. - if ( m_iFlags & wxPG_FL_INITIALIZED ) - { - wxLogDebug(wxT("WARNING: propGrid.cpp: wxPropertyGrid::SetFont has been disabled on wxMac since there has been crash reported in it. If you are willing to debug the cause, replace line '#if !defined(__WXMAC__)' with line '#if 1' in wxPropertyGrid::SetFont.")); - } - return false; -#endif } // ----------------------------------------------------------------------- @@ -1404,7 +1414,7 @@ wxPGProperty* wxPropertyGrid::DoGetItemAtY( int y ) const { // Outside? if ( y < 0 ) - return (wxPGProperty*) NULL; + return NULL; unsigned int a = 0; return m_pState->m_properties->GetItemAtY(y, m_lineHeight, &a); @@ -1556,7 +1566,7 @@ void wxPropertyGrid::DrawItems( wxDC& dc, if ( dcPtr ) { dc.SetClippingRegion( *clipRect ); - paintFinishY = DoDrawItems( *dcPtr, NULL, NULL, clipRect, isBuffered ); + paintFinishY = DoDrawItems( *dcPtr, clipRect, isBuffered ); } #if wxPG_DOUBLE_BUFFER @@ -1582,30 +1592,17 @@ void wxPropertyGrid::DrawItems( wxDC& dc, // ----------------------------------------------------------------------- int wxPropertyGrid::DoDrawItems( wxDC& dc, - const wxPGProperty* firstItem, - const wxPGProperty* lastItem, const wxRect* clipRect, bool isBuffered ) const { - // TODO: This should somehow be eliminated. - wxRect tempClipRect; - if ( !clipRect ) - { - wxASSERT(firstItem); - wxASSERT(lastItem); - tempClipRect = GetPropertyRect(firstItem, lastItem); - clipRect = &tempClipRect; - } + const wxPGProperty* firstItem; + const wxPGProperty* lastItem; - if ( !firstItem ) - firstItem = DoGetItemAtY(clipRect->y); + firstItem = DoGetItemAtY(clipRect->y); + lastItem = DoGetItemAtY(clipRect->y+clipRect->height-1); if ( !lastItem ) - { - lastItem = DoGetItemAtY(clipRect->y+clipRect->height-1); - if ( !lastItem ) - lastItem = GetLastItem( wxPG_ITERATE_VISIBLE ); - } + lastItem = GetLastItem( wxPG_ITERATE_VISIBLE ); if ( m_frozen || m_height < 1 || firstItem == NULL ) return clipRect->y; @@ -1677,7 +1674,7 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc, int x = m_marginWidth - xRelMod; - const wxFont& normalfont = m_font; + wxFont normalFont = GetFont(); bool reallyFocused = (m_iFlags & wxPG_FL_FOCUSED) != 0; @@ -1714,7 +1711,7 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc, // TODO: Only render columns that are within clipping region. - dc.SetFont(normalfont); + dc.SetFont(normalFont); wxPropertyGridConstIterator it( state, wxPG_ITERATE_VISIBLE, firstItem ); int endScanBottomY = lastItemBottomY + lh; @@ -1914,7 +1911,8 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc, unsigned int ci; int cellX = x + 1; - int nextCellWidth = state->m_colWidths[0]; + int nextCellWidth = state->m_colWidths[0] - + (greyDepthX - m_marginWidth); wxRect cellRect(greyDepthX+1, y, 0, rowHeight-1); int textXAdd = textMarginHere - greyDepthX; @@ -1989,7 +1987,7 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc, } if ( fontChanged ) - dc.SetFont(normalfont); + dc.SetFont(normalFont); y += rowHeight; } @@ -2017,7 +2015,7 @@ wxRect wxPropertyGrid::GetPropertyRect( const wxPGProperty* p1, const wxPGProper if ( m_width < 10 || m_height < 10 || !m_pState->m_properties->GetChildCount() || - p1 == (wxPGProperty*) NULL ) + p1 == NULL ) return wxRect(0,0,0,0); int vy = 0; @@ -2147,8 +2145,6 @@ void wxPropertyGrid::Refresh( bool WXUNUSED(eraseBackground), void wxPropertyGrid::Clear() { - ClearSelection(false); - m_pState->DoClear(); m_propHover = NULL; @@ -2248,7 +2244,7 @@ void wxPropertyGrid::SwitchState( wxPropertyGridPageState* pNewState ) pNewState->OnClientWidthChange( pgWidth, pgWidth - pNewState->m_width ); } - m_propHover = (wxPGProperty*) NULL; + m_propHover = NULL; // If necessary, convert state to correct mode. if ( orig_mode != new_state_mode ) @@ -2877,10 +2873,10 @@ void wxPropertyGrid::HandleCustomEditorEvent( wxEvent &event ) wxVariant pendingValue(selected->GetValueRef()); wxWindow* wnd = GetEditorControl(); + wxWindow* editorWnd = wxDynamicCast(event.GetEventObject(), wxWindow); int selFlags = 0; bool wasUnspecified = selected->IsValueUnspecified(); int usesAutoUnspecified = selected->UsesAutoUnspecified(); - bool valueIsPending = false; m_chgInfo_changedProperty = NULL; @@ -2926,17 +2922,19 @@ void wxPropertyGrid::HandleCustomEditorEvent( wxEvent &event ) if ( !buttonWasHandled ) { - if ( wnd ) + if ( wnd || m_wndEditor2 ) { // First call editor class' event handler. const wxPGEditor* editor = selected->GetEditorClass(); - if ( editor->OnEvent( this, selected, wnd, event ) ) + if ( editor->OnEvent( this, selected, editorWnd, event ) ) { // If changes, validate them if ( DoEditorValidate() ) { - if ( editor->GetValueFromControl( pendingValue, m_selected, wnd ) ) + if ( editor->GetValueFromControl( pendingValue, + m_selected, + wnd ) ) valueIsPending = true; } else @@ -2949,7 +2947,7 @@ void wxPropertyGrid::HandleCustomEditorEvent( wxEvent &event ) // Then the property's custom handler (must be always called, unless // validation failed). if ( !validationFailure ) - buttonWasHandled = selected->OnEvent( this, wnd, event ); + buttonWasHandled = selected->OnEvent( this, editorWnd, event ); } // SetValueInEvent(), as called in one of the functions referred above @@ -3013,24 +3011,25 @@ wxRect wxPropertyGrid::GetEditorWidgetRect( wxPGProperty* p, int column ) const { int itemy = p->GetY2(m_lineHeight); int vy = 0; - int cust_img_space = 0; int splitterX = m_pState->DoGetSplitterPosition(column-1); int colEnd = splitterX + m_pState->m_colWidths[column]; + int imageOffset = 0; // TODO: If custom image detection changes from current, change this. - if ( m_iFlags & wxPG_FL_CUR_USES_CUSTOM_IMAGE /*p->m_flags & wxPG_PROP_CUSTOMIMAGE*/ ) + if ( m_iFlags & wxPG_FL_CUR_USES_CUSTOM_IMAGE ) { //m_iFlags |= wxPG_FL_CUR_USES_CUSTOM_IMAGE; - int imwid = p->OnMeasureImage().x; - if ( imwid < 1 ) imwid = wxPG_CUSTOM_IMAGE_WIDTH; - cust_img_space = imwid + wxCC_CUSTOM_IMAGE_MARGIN1 + wxCC_CUSTOM_IMAGE_MARGIN2; + int iw = p->OnMeasureImage().x; + if ( iw < 1 ) + iw = wxPG_CUSTOM_IMAGE_WIDTH; + imageOffset = p->GetImageOffset(iw); } return wxRect ( - splitterX+cust_img_space+wxPG_XBEFOREWIDGET+wxPG_CONTROL_MARGIN+1, + splitterX+imageOffset+wxPG_XBEFOREWIDGET+wxPG_CONTROL_MARGIN+1, itemy-vy, - colEnd-splitterX-wxPG_XBEFOREWIDGET-wxPG_CONTROL_MARGIN-cust_img_space-1, + colEnd-splitterX-wxPG_XBEFOREWIDGET-wxPG_CONTROL_MARGIN-imageOffset-1, m_lineHeight-1 ); } @@ -3218,18 +3217,20 @@ void wxPropertyGrid::FreeEditors() // Do not free editors immediately if processing events if ( m_wndEditor2 ) { - m_wndEditor2->PopEventHandler(true); + wxEvtHandler* handler = m_wndEditor2->PopEventHandler(false); m_wndEditor2->Hide(); + wxPendingDelete.Append( handler ); wxPendingDelete.Append( m_wndEditor2 ); - m_wndEditor2 = (wxWindow*) NULL; + m_wndEditor2 = NULL; } if ( m_wndEditor ) { - m_wndEditor->PopEventHandler(true); + wxEvtHandler* handler = m_wndEditor->PopEventHandler(false); m_wndEditor->Hide(); + wxPendingDelete.Append( handler ); wxPendingDelete.Append( m_wndEditor ); - m_wndEditor = (wxWindow*) NULL; + m_wndEditor = NULL; } } @@ -3283,7 +3284,7 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags ) FreeEditors(); // Prevent any further selection measures in this call - p = (wxPGProperty*) NULL; + p = NULL; } else { @@ -3334,8 +3335,8 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags ) FreeEditors(); m_selColumn = -1; - m_selected = (wxPGProperty*) NULL; - m_pState->m_selected = (wxPGProperty*) NULL; + m_selected = NULL; + m_pState->m_selected = NULL; // We need to always fully refresh the grid here Refresh(false); @@ -3360,7 +3361,7 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags ) if ( p != prev ) m_iFlags &= ~(wxPG_FL_VALIDATION_FAILED); - wxASSERT( m_wndEditor == (wxWindow*) NULL ); + wxASSERT( m_wndEditor == NULL ); // // Only create editor for non-disabled non-caption @@ -3559,7 +3560,7 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags ) if ( !(GetExtraStyle() & wxPG_EX_HELP_AS_TOOLTIPS) ) { - wxStatusBar* statusbar = (wxStatusBar*) NULL; + wxStatusBar* statusbar = NULL; if ( !(m_iFlags & wxPG_FL_NOSTATUSBARHELP) ) { wxFrame* frame = wxDynamicCast(::wxGetTopLevelParent(this),wxFrame); @@ -3654,7 +3655,7 @@ void wxPropertyGrid::RefreshEditor() // (i.e. two-arg function calls create smaller code size). bool wxPropertyGrid::DoClearSelection() { - return DoSelectProperty((wxPGProperty*)NULL); + return DoSelectProperty(NULL); } // ----------------------------------------------------------------------- @@ -3781,16 +3782,10 @@ void wxPropertyGrid::RecalculateVirtualSize( int forceXPos ) m_pState->EnsureVirtualHeight(); -#ifdef __WXDEBUG__ - int by1 = m_pState->GetVirtualHeight(); - int by2 = m_pState->GetActualVirtualHeight(); - if ( by1 != by2 ) - { - wxString s = wxString::Format(wxT("VirtualHeight=%i, ActualVirtualHeight=%i, should match!"), by1, by2); - wxFAIL_MSG(s.c_str()); - wxLogDebug(s); - } -#endif + wxASSERT_LEVEL_2_MSG( + m_pState->GetVirtualHeight() == m_pState->GetActualVirtualHeight(), + "VirtualHeight and ActualVirtualHeight should match" + ); m_iFlags |= wxPG_FL_RECALCULATING_VIRTUAL_SIZE; @@ -3801,7 +3796,7 @@ void wxPropertyGrid::RecalculateVirtualSize( int forceXPos ) GetClientSize(&width,&height); // Now adjust virtual size. - SetVirtualSize(x, y); + SetVirtualSize(x, y); int xAmount = 0; int xPos = 0; @@ -3820,7 +3815,7 @@ void wxPropertyGrid::RecalculateVirtualSize( int forceXPos ) else if ( xPos > (xAmount-(width/wxPG_PIXELS_PER_UNIT)) ) xPos = 0; - int yAmount = (y+wxPG_PIXELS_PER_UNIT+2)/wxPG_PIXELS_PER_UNIT; + int yAmount = y / wxPG_PIXELS_PER_UNIT; int yPos = GetScrollPos( wxVERTICAL ); SetScrollbars( wxPG_PIXELS_PER_UNIT, wxPG_PIXELS_PER_UNIT, @@ -4298,7 +4293,7 @@ bool wxPropertyGrid::HandleMouseMove( int x, unsigned int y, wxMouseEvent &event if ( space ) { int tw, th; - GetTextExtent( tipString, &tw, &th, 0, 0, &m_font ); + GetTextExtent( tipString, &tw, &th, 0, 0 ); if ( tw > space ) { SetToolTip( tipString ); @@ -4460,7 +4455,7 @@ bool wxPropertyGrid::OnMouseCommon( wxMouseEvent& event, int* px, int* py ) wxRect r; if ( wnd ) r = wnd->GetRect(); - if ( wnd == (wxWindow*) NULL || m_dragStatus || + if ( wnd == NULL || m_dragStatus || ( ux <= (splitterX + wxPG_SPLITTERX_DETECTMARGIN2) || ux >= (r.x+r.width) || @@ -4829,6 +4824,11 @@ void wxPropertyGrid::HandleKeyEvent( wxKeyEvent &event, bool fromChild ) // Except for TAB and ESC, handle child control events in child control if ( fromChild ) { + // Only propagate event if it had modifiers + if ( !event.HasModifiers() ) + { + event.StopPropagation(); + } event.Skip(); return; } @@ -4846,9 +4846,7 @@ void wxPropertyGrid::HandleKeyEvent( wxKeyEvent &event, bool fromChild ) // Travel and expand/collapse int selectDir = -2; - if ( p->GetChildCount() && - !(p->m_flags & wxPG_PROP_DISABLED) - ) + if ( p->GetChildCount() ) { if ( action == wxPG_ACTION_COLLAPSE_PROPERTY || secondAction == wxPG_ACTION_COLLAPSE_PROPERTY ) { @@ -4902,6 +4900,19 @@ void wxPropertyGrid::HandleKeyEvent( wxKeyEvent &event, bool fromChild ) void wxPropertyGrid::OnKey( wxKeyEvent &event ) { + // If there was editor open and focused, then this event should not + // really be processed here. + if ( IsEditorFocused() ) + { + // However, if event had modifiers, it is probably still best + // to skip it. + if ( event.HasModifiers() ) + event.Skip(); + else + event.StopPropagation(); + return; + } + HandleKeyEvent(event, false); } @@ -5045,11 +5056,7 @@ void wxPropertyGrid::OnFocusEvent( wxFocusEvent& event ) void wxPropertyGrid::OnChildFocusEvent( wxChildFocusEvent& event ) { HandleFocusChange((wxWindow*)event.GetEventObject()); - - // - // event.Skip() being commented out is aworkaround for bug reported - // in ticket #4840 (wxScrolledWindow problem with automatic scrolling). - //event.Skip(); + event.Skip(); } // ----------------------------------------------------------------------- @@ -5076,15 +5083,18 @@ void wxPropertyGrid::OnCaptureChange( wxMouseCaptureChangedEvent& WXUNUSED(event // ----------------------------------------------------------------------- // noDefCheck = true prevents infinite recursion. -wxPGEditor* wxPropertyGrid::RegisterEditorClass( wxPGEditor* editorClass, - bool noDefCheck ) +wxPGEditor* wxPropertyGrid::DoRegisterEditorClass( wxPGEditor* editorClass, + const wxString& editorName, + bool noDefCheck ) { wxASSERT( editorClass ); if ( !noDefCheck && wxPGGlobalVars->m_mapEditorClasses.empty() ) RegisterDefaultEditors(); - wxString name = editorClass->GetName(); + wxString name = editorName; + if ( name.length() == 0 ) + name = editorClass->GetName(); // Existing editor under this name? wxPGHashMapS2P::iterator vt_it = wxPGGlobalVars->m_mapEditorClasses.find(name); @@ -5107,7 +5117,7 @@ wxPGEditor* wxPropertyGrid::RegisterEditorClass( wxPGEditor* editorClass, // Use this in RegisterDefaultEditors. #define wxPGRegisterDefaultEditorClass(EDITOR) \ - if ( wxPGEditor_##EDITOR == (wxPGEditor*) NULL ) \ + if ( wxPGEditor_##EDITOR == NULL ) \ { \ wxPGEditor_##EDITOR = wxPropertyGrid::RegisterEditorClass( \ new wxPG##EDITOR##Editor, true ); \ @@ -5221,7 +5231,6 @@ wxPGChoiceEntry::wxPGChoiceEntry() wxPGChoicesData::wxPGChoicesData() { - m_refCount = 1; } wxPGChoicesData::~wxPGChoicesData() @@ -5266,241 +5275,6 @@ wxPGChoiceEntry& wxPGChoicesData::Insert( int index, return ownEntry; } -// ----------------------------------------------------------------------- -// wxPGChoices -// ----------------------------------------------------------------------- - -wxPGChoiceEntry& wxPGChoices::Add( const wxString& label, int value ) -{ - EnsureData(); - - wxPGChoiceEntry entry(label, value); - return m_data->Insert( -1, entry ); -} - -// ----------------------------------------------------------------------- - -wxPGChoiceEntry& wxPGChoices::Add( const wxString& label, const wxBitmap& bitmap, int value ) -{ - EnsureData(); - - wxPGChoiceEntry entry(label, value); - entry.SetBitmap(bitmap); - return m_data->Insert( -1, entry ); -} - -// ----------------------------------------------------------------------- - -wxPGChoiceEntry& wxPGChoices::Insert( const wxPGChoiceEntry& entry, int index ) -{ - EnsureData(); - return m_data->Insert( index, entry ); -} - -// ----------------------------------------------------------------------- - -wxPGChoiceEntry& wxPGChoices::Insert( const wxString& label, int index, int value ) -{ - EnsureData(); - - wxPGChoiceEntry entry(label, value); - return m_data->Insert( index, entry ); -} - -// ----------------------------------------------------------------------- - -wxPGChoiceEntry& wxPGChoices::AddAsSorted( const wxString& label, int value ) -{ - EnsureData(); - - size_t index = 0; - - while ( index < GetCount() ) - { - int cmpRes = GetLabel(index).Cmp(label); - if ( cmpRes > 0 ) - break; - index++; - } - - wxPGChoiceEntry entry(label, value); - return m_data->Insert( index, entry ); -} - -// ----------------------------------------------------------------------- - -void wxPGChoices::Add( const wxChar** labels, const ValArrItem* values ) -{ - EnsureData(); - - unsigned int itemcount = 0; - const wxChar** p = &labels[0]; - while ( *p ) { p++; itemcount++; } - - unsigned int i; - for ( i = 0; i < itemcount; i++ ) - { - int value = i; - if ( values ) - value = values[i]; - wxPGChoiceEntry entry(labels[i], value); - m_data->Insert( i, entry ); - } -} - -// ----------------------------------------------------------------------- - -void wxPGChoices::Add( const wxArrayString& arr, const wxArrayInt& arrint ) -{ - EnsureData(); - - unsigned int i; - unsigned int itemcount = arr.size(); - - for ( i = 0; i < itemcount; i++ ) - { - int value = i; - if ( &arrint && arrint.size() ) - value = arrint[i]; - wxPGChoiceEntry entry(arr[i], value); - m_data->Insert( i, entry ); - } -} - -// ----------------------------------------------------------------------- - -void wxPGChoices::RemoveAt(size_t nIndex, size_t count) -{ - wxASSERT( m_data->m_refCount != 0xFFFFFFF ); - m_data->m_items.erase(m_data->m_items.begin()+nIndex, - m_data->m_items.begin()+nIndex+count); -} - -// ----------------------------------------------------------------------- - -int wxPGChoices::Index( const wxString& str ) const -{ - if ( IsOk() ) - { - unsigned int i; - for ( i=0; i< m_data->GetCount(); i++ ) - { - const wxPGChoiceEntry& entry = m_data->Item(i); - if ( entry.HasText() && entry.GetText() == str ) - return i; - } - } - return -1; -} - -// ----------------------------------------------------------------------- - -int wxPGChoices::Index( int val ) const -{ - if ( IsOk() ) - { - unsigned int i; - for ( i=0; i< m_data->GetCount(); i++ ) - { - const wxPGChoiceEntry& entry = m_data->Item(i); - if ( entry.GetValue() == val ) - return i; - } - } - return -1; -} - -// ----------------------------------------------------------------------- - -wxArrayString wxPGChoices::GetLabels() const -{ - wxArrayString arr; - unsigned int i; - - if ( this && IsOk() ) - for ( i=0; i= 0 ) - arr.Add(GetValue(index)); - else - arr.Add(wxPG_INVALID_VALUE); - } - } - - return arr; -} - -// ----------------------------------------------------------------------- - -wxArrayInt wxPGChoices::GetIndicesForStrings( const wxArrayString& strings, - wxArrayString* unmatched ) const -{ - wxArrayInt arr; - - if ( IsOk() ) - { - unsigned int i; - for ( i=0; i< strings.size(); i++ ) - { - const wxString& str = strings[i]; - int index = Index(str); - if ( index >= 0 ) - arr.Add(index); - else if ( unmatched ) - unmatched->Add(str); - } - } - - return arr; -} - -// ----------------------------------------------------------------------- - -void wxPGChoices::AssignData( wxPGChoicesData* data ) -{ - Free(); - - if ( data != wxPGChoicesEmptyData ) - { - m_data = data; - data->m_refCount++; - } -} - -// ----------------------------------------------------------------------- - -void wxPGChoices::Init() -{ - m_data = wxPGChoicesEmptyData; -} - -// ----------------------------------------------------------------------- - -void wxPGChoices::Free() -{ - if ( m_data != wxPGChoicesEmptyData ) - { - m_data->DecRef(); - m_data = wxPGChoicesEmptyData; - } -} - // ----------------------------------------------------------------------- // wxPropertyGridEvent // ----------------------------------------------------------------------- @@ -5508,15 +5282,15 @@ void wxPGChoices::Free() IMPLEMENT_DYNAMIC_CLASS(wxPropertyGridEvent, wxCommandEvent) -wxDEFINE_EVENT( wxEVT_PG_SELECTED, wxPropertyGridEvent ) -wxDEFINE_EVENT( wxEVT_PG_CHANGING, wxPropertyGridEvent ) -wxDEFINE_EVENT( wxEVT_PG_CHANGED, wxPropertyGridEvent ) -wxDEFINE_EVENT( wxEVT_PG_HIGHLIGHTED, wxPropertyGridEvent ) -wxDEFINE_EVENT( wxEVT_PG_RIGHT_CLICK, wxPropertyGridEvent ) -wxDEFINE_EVENT( wxEVT_PG_PAGE_CHANGED, wxPropertyGridEvent ) -wxDEFINE_EVENT( wxEVT_PG_ITEM_EXPANDED, wxPropertyGridEvent ) -wxDEFINE_EVENT( wxEVT_PG_ITEM_COLLAPSED, wxPropertyGridEvent ) -wxDEFINE_EVENT( wxEVT_PG_DOUBLE_CLICK, wxPropertyGridEvent ) +wxDEFINE_EVENT( wxEVT_PG_SELECTED, wxPropertyGridEvent ); +wxDEFINE_EVENT( wxEVT_PG_CHANGING, wxPropertyGridEvent ); +wxDEFINE_EVENT( wxEVT_PG_CHANGED, wxPropertyGridEvent ); +wxDEFINE_EVENT( wxEVT_PG_HIGHLIGHTED, wxPropertyGridEvent ); +wxDEFINE_EVENT( wxEVT_PG_RIGHT_CLICK, wxPropertyGridEvent ); +wxDEFINE_EVENT( wxEVT_PG_PAGE_CHANGED, wxPropertyGridEvent ); +wxDEFINE_EVENT( wxEVT_PG_ITEM_EXPANDED, wxPropertyGridEvent ); +wxDEFINE_EVENT( wxEVT_PG_ITEM_COLLAPSED, wxPropertyGridEvent ); +wxDEFINE_EVENT( wxEVT_PG_DOUBLE_CLICK, wxPropertyGridEvent ); // -----------------------------------------------------------------------