]> git.saurik.com Git - wxWidgets.git/blobdiff - src/propgrid/propgrid.cpp
Misc XRC format docs corrections.
[wxWidgets.git] / src / propgrid / propgrid.cpp
index 947380709ff47abba1e6c1a74b788142080b80ba..63b5099321f10ed3c11ebb34beebd5bcf0323ad6 100644 (file)
@@ -4,7 +4,6 @@
 // Author:      Jaakko Salli
 // Modified by:
 // Created:     2004-09-25
-// RCS-ID:      $Id$
 // Copyright:   (c) Jaakko Salli
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
@@ -159,8 +158,8 @@ IMPLEMENT_DYNAMIC_CLASS(wxPGGlobalVarsClassManager, wxModule)
 void wxPGInitResourceModule()
 {
     wxModule* module = new wxPGGlobalVarsClassManager;
-    module->Init();
     wxModule::RegisterModule(module);
+    wxModule::InitializeModules();
 }
 
 wxPGGlobalVarsClass* wxPGGlobalVars = NULL;
@@ -348,6 +347,7 @@ void wxPropertyGrid::Init1()
     m_eventObject = this;
     m_curFocused = NULL;
     m_processedEvent = NULL;
+    m_tlp = NULL;
     m_sortFunction = NULL;
     m_inDoPropertyChanged = false;
     m_inCommitChangesFromEditor = false;
@@ -375,9 +375,7 @@ void wxPropertyGrid::Init1()
     m_coloursCustomized = 0;
     m_frozen = 0;
 
-#if wxPG_DOUBLE_BUFFER
     m_doubleBuffer = NULL;
-#endif
 
 #ifndef wxPG_ICON_WIDTH
     m_expandbmp = NULL;
@@ -467,7 +465,6 @@ void wxPropertyGrid::Init2()
     SetBackgroundStyle( wxBG_STYLE_CUSTOM );
 
     // Hook the top-level parent
-    m_tlp = NULL;
     m_tlpClosed = NULL;
     m_tlpClosedTime = 0;
 
@@ -544,10 +541,8 @@ wxPropertyGrid::~wxPropertyGrid()
                       wxS("Close(false).)") );
     }
 
-#if wxPG_DOUBLE_BUFFER
     if ( m_doubleBuffer )
         delete m_doubleBuffer;
-#endif
 
     if ( m_iFlags & wxPG_FL_CREATEDSTATE )
         delete m_pState;
@@ -672,9 +667,7 @@ void wxPropertyGrid::Thaw()
     {
         wxControl::Thaw();
         RecalculateVirtualSize();
-    #if wxPG_REFRESH_CONTROLS_AFTER_REPAINT
         Refresh();
-    #endif
 
         // Force property re-selection
         // NB: We must copy the selection.
@@ -1000,7 +993,7 @@ void wxPropertyGrid::DoBeginLabelEdit( unsigned int colIndex,
                                           colIndex);
 
     wxWindowID id = tc->GetId();
-    tc->Connect(id, wxEVT_COMMAND_TEXT_ENTER,
+    tc->Connect(id, wxEVT_TEXT_ENTER,
         wxCommandEventHandler(wxPropertyGrid::OnLabelEditorEnterPress),
         NULL, this);
     tc->Connect(id, wxEVT_KEY_DOWN,
@@ -1127,9 +1120,7 @@ void wxPropertyGrid::SetExtraStyle( long exStyle )
         }
         else
         {
-        #if wxPG_DOUBLE_BUFFER
             wxDELETE(m_doubleBuffer);
-        #endif
         }
     }
 
@@ -1688,7 +1679,7 @@ wxPoint wxPropertyGrid::GetGoodEditorDialogPosition( wxPGProperty* p,
 
 wxString& wxPropertyGrid::ExpandEscapeSequences( wxString& dst_str, wxString& src_str )
 {
-    if ( src_str.length() == 0 )
+    if ( src_str.empty() )
     {
         dst_str = src_str;
         return src_str;
@@ -1747,7 +1738,7 @@ wxString& wxPropertyGrid::ExpandEscapeSequences( wxString& dst_str, wxString& sr
 
 wxString& wxPropertyGrid::CreateEscapeSequences( wxString& dst_str, wxString& src_str )
 {
-    if ( src_str.length() == 0 )
+    if ( src_str.empty() )
     {
         dst_str = src_str;
         return src_str;
@@ -1965,7 +1956,6 @@ void wxPropertyGrid::DrawItems( wxDC& dc,
         wxDC* dcPtr = &dc;
         bool isBuffered = false;
 
-    #if wxPG_DOUBLE_BUFFER
         wxMemoryDC* bufferDC = NULL;
 
         if ( !(GetExtraStyle() & wxPG_EX_NATIVE_DOUBLE_BUFFERING) )
@@ -1986,7 +1976,6 @@ void wxPropertyGrid::DrawItems( wxDC& dc,
                 isBuffered = true;
             }
         }
-    #endif
 
         if ( dcPtr )
         {
@@ -2005,7 +1994,6 @@ void wxPropertyGrid::DrawItems( wxDC& dc,
             }
         }
 
-    #if wxPG_DOUBLE_BUFFER
         if ( bufferDC )
         {
             dc.Blit( drawRect.x, drawRect.y, drawRect.width,
@@ -2013,7 +2001,6 @@ void wxPropertyGrid::DrawItems( wxDC& dc,
                      bufferDC, 0, 0, wxCOPY );
             delete bufferDC;
         }
-    #endif
     }
     else
     {
@@ -2085,10 +2072,11 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
     int xRelMod = 0;
 
     //
-    // With wxPG_DOUBLE_BUFFER, do double buffering
+    // For now, do some manual calculation for double buffering
     // - buffer's y = 0, so align itemsRect and coordinates to that
     //
-#if wxPG_DOUBLE_BUFFER
+    // TODO: In future use wxAutoBufferedPaintDC (for example)
+    //
     int yRelMod = 0;
 
     wxRect cr2;
@@ -2107,9 +2095,6 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
         firstItemTopY -= yRelMod;
         lastItemBottomY -= yRelMod;
     }
-#else
-    wxUnusedVar(isBuffered);
-#endif
 
     int x = m_marginWidth - xRelMod;
 
@@ -2151,10 +2136,6 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
     const wxPropertyGridPageState* state = m_pState;
     const wxArrayInt& colWidths = state->m_colWidths;
 
-#if wxPG_REFRESH_CONTROLS_AFTER_REPAINT
-    bool wasSelectedPainted = false;
-#endif
-
     // TODO: Only render columns that are within clipping region.
 
     dc.SetFont(normalFont);
@@ -2282,11 +2263,6 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
         }
         else
         {
-#if wxPG_REFRESH_CONTROLS_AFTER_REPAINT
-            if ( p == firstSelected )
-                wasSelectedPainted = true;
-#endif
-
             renderFlags |= wxPGCellRenderer::Selected;
 
             if ( !p->IsCategory() )
@@ -2523,18 +2499,6 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
         y += rowHeight;
     }
 
-    // Refresh editor controls (seems not needed on msw)
-    // NOTE: This code is mandatory for GTK!
-#if wxPG_REFRESH_CONTROLS_AFTER_REPAINT
-    if ( wasSelectedPainted )
-    {
-        if ( m_wndEditor )
-            m_wndEditor->Refresh();
-        if ( m_wndEditor2 )
-            m_wndEditor2->Refresh();
-    }
-#endif
-
     return y;
 }
 
@@ -2612,7 +2576,7 @@ void wxPropertyGrid::DrawItems( const wxPGProperty* p1, const wxPGProperty* p2 )
 
 void wxPropertyGrid::RefreshProperty( wxPGProperty* p )
 {
-    if ( m_pState->DoIsPropertySelected(p) )
+    if ( m_pState->DoIsPropertySelected(p) || p->IsChildSelected(true) )
     {
         // NB: We must copy the selection.
         wxArrayPGProperty selection = m_pState->m_selection;
@@ -2674,7 +2638,7 @@ void wxPropertyGrid::Refresh( bool WXUNUSED(eraseBackground),
 
     wxWindow::Refresh(false, rect);
 
-#if wxPG_REFRESH_CONTROLS_AFTER_REPAINT
+#if wxPG_REFRESH_CONTROLS
     // I think this really helps only GTK+1.2
     if ( m_wndEditor ) m_wndEditor->Refresh();
     if ( m_wndEditor2 ) m_wndEditor2->Refresh();
@@ -3093,7 +3057,7 @@ bool wxPropertyGrid::PerformValidation( wxPGProperty* p, wxVariant& pendingValue
             if ( changedProperty == GetSelection() )
             {
                 wxWindow* editor = GetEditorControl();
-                wxASSERT( editor->IsKindOf(CLASSINFO(wxTextCtrl)) );
+                wxASSERT( wxDynamicCast(editor, wxTextCtrl) );
                 evtChangingValue = wxStaticCast(editor, wxTextCtrl)->GetValue();
             }
             else
@@ -3148,7 +3112,7 @@ bool wxPropertyGrid::PerformValidation( wxPGProperty* p, wxVariant& pendingValue
 wxStatusBar* wxPropertyGrid::GetStatusBar()
 {
     wxWindow* topWnd = ::wxGetTopLevelParent(this);
-    if ( topWnd && topWnd->IsKindOf(CLASSINFO(wxFrame)) )
+    if ( wxDynamicCast(topWnd, wxFrame) )
     {
         wxFrame* pFrame = wxStaticCast(topWnd, wxFrame);
         if ( pFrame )
@@ -3162,7 +3126,7 @@ wxStatusBar* wxPropertyGrid::GetStatusBar()
 
 void wxPropertyGrid::DoShowPropertyError( wxPGProperty* WXUNUSED(property), const wxString& msg )
 {
-    if ( !msg.length() )
+    if ( msg.empty() )
         return;
 
 #if wxUSE_STATUSBAR
@@ -3231,7 +3195,7 @@ bool wxPropertyGrid::OnValidationFailure( wxPGProperty* property,
 
     //
     // For non-wxTextCtrl editors, we do need to revert the value
-    if ( !editor->IsKindOf(CLASSINFO(wxTextCtrl)) &&
+    if ( !wxDynamicCast(editor, wxTextCtrl) &&
          property == GetSelection() )
     {
         property->GetEditorClass()->UpdateControl(property, editor);
@@ -3290,7 +3254,7 @@ bool wxPropertyGrid::DoOnValidationFailure( wxPGProperty* property, wxVariant& W
     {
         wxString msg = m_validationInfo.m_failureMessage;
 
-        if ( !msg.length() )
+        if ( msg.empty() )
             msg = _("You have entered invalid value. Press ESC to cancel editing.");
 
     #if wxUSE_STATUSBAR
@@ -3441,7 +3405,7 @@ bool wxPropertyGrid::DoPropertyChanged( wxPGProperty* p, unsigned int selFlags )
     }
     else
     {
-#if wxPG_REFRESH_CONTROLS_AFTER_REPAINT
+#if wxPG_REFRESH_CONTROLS
         if ( m_wndEditor ) m_wndEditor->Refresh();
         if ( m_wndEditor2 ) m_wndEditor2->Refresh();
 #endif
@@ -3595,9 +3559,9 @@ bool wxPropertyGrid::HandleCustomEditorEvent( wxEvent &event )
 
     //
     // Filter out excess wxTextCtrl modified events
-    if ( event.GetEventType() == wxEVT_COMMAND_TEXT_UPDATED && wnd )
+    if ( event.GetEventType() == wxEVT_TEXT && wnd )
     {
-        if ( wnd->IsKindOf(CLASSINFO(wxTextCtrl)) )
+        if ( wxDynamicCast(wnd, wxTextCtrl) )
         {
             wxTextCtrl* tc = (wxTextCtrl*) wnd;
 
@@ -3606,8 +3570,14 @@ bool wxPropertyGrid::HandleCustomEditorEvent( wxEvent &event )
                 return true;
             m_prevTcValue = newTcValue;
         }
-        else if ( wnd->IsKindOf(CLASSINFO(wxComboCtrl)) )
+        else if ( wxDynamicCast(wnd, wxComboCtrl) )
         {
+            // In some cases we might stumble unintentionally on
+            // wxComboCtrl's embedded wxTextCtrl's events. Let's
+            // avoid them.
+            if ( wxDynamicCast(editorWnd, wxTextCtrl) )
+                return false;
+
             wxComboCtrl* cc = (wxComboCtrl*) wnd;
 
             wxString newTcValue = cc->GetTextCtrl()->GetValue();
@@ -3625,7 +3595,7 @@ bool wxPropertyGrid::HandleCustomEditorEvent( wxEvent &event )
 
     //
     // Try common button handling
-    if ( m_wndEditor2 && event.GetEventType() == wxEVT_COMMAND_BUTTON_CLICKED )
+    if ( m_wndEditor2 && event.GetEventType() == wxEVT_BUTTON )
     {
         wxPGEditorDialogAdapter* adapter = selected->GetEditorDialog();
 
@@ -3633,7 +3603,7 @@ bool wxPropertyGrid::HandleCustomEditorEvent( wxEvent &event )
         {
             buttonWasHandled = true;
             // Store as res2, as previously (and still currently alternatively)
-            // dialogs can be shown by handling wxEVT_COMMAND_BUTTON_CLICKED
+            // dialogs can be shown by handling wxEVT_BUTTON
             // in wxPGProperty::OnEvent().
             adapter->ShowDialog( this, selected );
             delete adapter;
@@ -3705,7 +3675,7 @@ bool wxPropertyGrid::HandleCustomEditorEvent( wxEvent &event )
 
         // Regardless of editor type, unfocus editor on
         // text-editing related enter press.
-        if ( event.GetEventType() == wxEVT_COMMAND_TEXT_ENTER )
+        if ( event.GetEventType() == wxEVT_TEXT_ENTER )
         {
             SetFocusOnCanvas();
         }
@@ -3716,16 +3686,16 @@ bool wxPropertyGrid::HandleCustomEditorEvent( wxEvent &event )
 
         // Regardless of editor type, unfocus editor on
         // text-editing related enter press.
-        if ( event.GetEventType() == wxEVT_COMMAND_TEXT_ENTER )
+        if ( event.GetEventType() == wxEVT_TEXT_ENTER )
         {
             SetFocusOnCanvas();
         }
 
         // Let unhandled button click events go to the parent
-        if ( !buttonWasHandled && event.GetEventType() == wxEVT_COMMAND_BUTTON_CLICKED )
+        if ( !buttonWasHandled && event.GetEventType() == wxEVT_BUTTON )
         {
             result = true;
-            wxCommandEvent evt(wxEVT_COMMAND_BUTTON_CLICKED,GetId());
+            wxCommandEvent evt(wxEVT_BUTTON,GetId());
             GetEventHandler()->AddPendingEvent(evt);
         }
     }
@@ -3906,8 +3876,7 @@ private:
         // Always skip
         event.Skip();
 
-        if ( m_propGrid->HandleCustomEditorEvent(event) )
-            return true;
+        m_propGrid->HandleCustomEditorEvent(event);
 
         //
         // NB: We should return true if the event was recognized as
@@ -3921,7 +3890,7 @@ private:
         // NB: On wxMSW, a wxTextCtrl with wxTE_PROCESS_ENTER
         //     may beep annoyingly if that event is skipped
         //     and passed to parent event handler.
-        if ( event.GetEventType() == wxEVT_COMMAND_TEXT_ENTER )
+        if ( event.GetEventType() == wxEVT_TEXT_ENTER )
             return true;
 
         return wxEvtHandler::ProcessEvent(event);
@@ -3983,20 +3952,7 @@ void wxPropertyGrid::FreeEditors()
     // Return focus back to canvas from children (this is required at least for
     // GTK+, which, unlike Windows, clears focus when control is destroyed
     // instead of moving it to closest parent).
-    wxWindow* focus = wxWindow::FindFocus();
-    if ( focus )
-    {
-        wxWindow* parent = focus->GetParent();
-        while ( parent )
-        {
-            if ( parent == this )
-            {
-                SetFocusOnCanvas();
-                break;
-            }
-            parent = parent->GetParent();
-        }
-    }
+    SetFocusOnCanvas();
 
     // Do not free editors immediately if processing events
     if ( m_wndEditor2 )
@@ -4340,7 +4296,7 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
         wxStatusBar* statusbar = GetStatusBar();
         if ( statusbar )
         {
-            if ( pHelpString && pHelpString->length() )
+            if ( pHelpString && !pHelpString->empty() )
             {
                 // Set help box text.
                 statusbar->SetStatusText( *pHelpString );
@@ -4362,7 +4318,7 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
         //
         // Show help as a tool tip on the editor control.
         //
-        if ( pHelpString && pHelpString->length() &&
+        if ( pHelpString && !pHelpString->empty() &&
              primaryCtrl )
         {
             primaryCtrl->SetToolTip(*pHelpString);
@@ -4600,7 +4556,6 @@ void wxPropertyGrid::RecalculateVirtualSize( int forceXPos )
     if ( !HasVirtualWidth() )
     {
         m_pState->SetVirtualWidth(width);
-        x = width;
     }
 
     m_width = width;
@@ -4627,7 +4582,6 @@ void wxPropertyGrid::OnResize( wxSizeEvent& event )
     m_width = width;
     m_height = height;
 
-#if wxPG_DOUBLE_BUFFER
     if ( !(GetExtraStyle() & wxPG_EX_NATIVE_DOUBLE_BUFFERING) )
     {
         int dblh = (m_lineHeight*2);
@@ -4655,8 +4609,6 @@ void wxPropertyGrid::OnResize( wxSizeEvent& event )
         }
     }
 
-#endif
-
     m_pState->OnClientWidthChange( width, event.GetSize().x - m_ncWidth, true );
     m_ncWidth = event.GetSize().x;
 
@@ -4692,7 +4644,24 @@ void wxPropertyGrid::SetVirtualWidth( int width )
 
 void wxPropertyGrid::SetFocusOnCanvas()
 {
-    SetFocus();
+    // To prevent wxPropertyGrid from stealing focus from other controls,
+    // only move focus to the grid if it was already in one if its child
+    // controls.
+    wxWindow* focus = wxWindow::FindFocus();
+    if ( focus )
+    {
+        wxWindow* parent = focus->GetParent();
+        while ( parent )
+        {
+            if ( parent == this )
+            {
+                SetFocus();
+                break;
+            }
+            parent = parent->GetParent();
+        }
+    }
+
     m_editorFocused = 0;
 }
 
@@ -4825,7 +4794,7 @@ bool wxPropertyGrid::HandleMouseClick( int x, unsigned int y, wxMouseEvent &even
                     }
 
                 // Do not Skip() the event after selection has been made.
-                // Otherwise default event handling behavior kicks in
+                // Otherwise default event handling behaviour kicks in
                 // and may revert focus back to the main canvas.
                 res = true;
             }
@@ -4882,7 +4851,7 @@ bool wxPropertyGrid::HandleMouseClick( int x, unsigned int y, wxMouseEvent &even
                             m_draggedSplitter = splitterHit;
                             m_dragOffset = splitterHitOffset;
 
-                        #if wxPG_REFRESH_CONTROLS_AFTER_REPAINT
+                        #if wxPG_REFRESH_CONTROLS
                             // Fixes button disappearance bug
                             if ( m_wndEditor2 )
                                 m_wndEditor2->Show ( false );
@@ -5194,7 +5163,7 @@ bool wxPropertyGrid::HandleMouseUp( int x, unsigned int WXUNUSED(y),
     int splitterHitOffset;
     state->HitTestH( x, &splitterHit, &splitterHitOffset );
 
-    // No event type check - basicly calling this method should
+    // No event type check - basically calling this method should
     // just stop dragging.
     // Left up after dragged?
     if ( m_dragStatus >= 1 )
@@ -5247,7 +5216,7 @@ bool wxPropertyGrid::HandleMouseUp( int x, unsigned int WXUNUSED(y),
             m_wndEditor->Show ( true );
         }
 
-    #if wxPG_REFRESH_CONTROLS_AFTER_REPAINT
+    #if wxPG_REFRESH_CONTROLS
         // Fixes button disappearance bug
         if ( m_wndEditor2 )
             m_wndEditor2->Show ( true );
@@ -5273,7 +5242,7 @@ bool wxPropertyGrid::OnMouseCommon( wxMouseEvent& event, int* px, int* py )
 
     // Hide popup on clicks
     if ( event.GetEventType() != wxEVT_MOTION )
-        if ( wnd && wnd->IsKindOf(CLASSINFO(wxOwnerDrawnComboBox)) )
+        if ( wxDynamicCast(wnd, wxOwnerDrawnComboBox) )
         {
             ((wxOwnerDrawnComboBox*)wnd)->HidePopup();
         }
@@ -5582,12 +5551,14 @@ void wxPropertyGrid::HandleKeyEvent( wxKeyEvent &event, bool fromChild )
 
     if ( keycode == WXK_TAB )
     {
+#if defined(__WXGTK__)
         wxWindow* mainControl;
 
         if ( HasInternalFlag(wxPG_FL_IN_MANAGER) )
             mainControl = GetParent();
         else
             mainControl = this;
+#endif
 
         if ( !event.ShiftDown() )
         {
@@ -5688,6 +5659,12 @@ void wxPropertyGrid::HandleKeyEvent( wxKeyEvent &event, bool fromChild )
 
         wxPGProperty* p = selected;
 
+        if ( action == wxPG_ACTION_EDIT && !editorFocused )
+        {
+            DoSelectProperty( p, wxPG_SEL_FOCUS );
+            wasHandled = true;
+        }
+
         // Travel and expand/collapse
         int selectDir = -2;
 
@@ -5796,7 +5773,7 @@ bool wxPropertyGrid::ButtonTriggerKeyTest( int action, wxKeyEvent& event )
     if ( action == wxPG_ACTION_PRESS_BUTTON &&
          m_wndEditor2 )
     {
-        wxCommandEvent evt(wxEVT_COMMAND_BUTTON_CLICKED, m_wndEditor2->GetId());
+        wxCommandEvent evt(wxEVT_BUTTON, m_wndEditor2->GetId());
         GetEventHandler()->AddPendingEvent(evt);
         return true;
     }
@@ -6015,7 +5992,7 @@ wxPGEditor* wxPropertyGrid::DoRegisterEditorClass( wxPGEditor* editorClass,
         RegisterDefaultEditors();
 
     wxString name = editorName;
-    if ( name.length() == 0 )
+    if ( name.empty() )
         name = editorClass->GetName();
 
     // Existing editor under this name?
@@ -6227,6 +6204,7 @@ void wxPropertyGridEvent::Init()
     m_column = 1;
     m_canVeto = false;
     m_wasVetoed = false;
+    m_pg = NULL;
 }
 
 // -----------------------------------------------------------------------
@@ -6364,7 +6342,7 @@ wxPGProperty* wxPropertyGridPopulator::Add( const wxString& propClass,
         return NULL;
     }
 
-    if ( !classInfo || !classInfo->IsKindOf(CLASSINFO(wxPGProperty)) )
+    if ( !classInfo || !classInfo->IsKindOf(wxCLASSINFO(wxPGProperty)) )
     {
         ProcessError(wxString::Format(wxT("'%s' is not valid property class"),propClass.c_str()));
         return NULL;
@@ -6416,7 +6394,7 @@ wxPGChoices wxPropertyGridPopulator::ParseChoices( const wxString& choicesString
     else
     {
         bool found = false;
-        if ( idString.length() )
+        if ( !idString.empty() )
         {
             wxPGHashMapS2P::iterator it = m_dictIdChoices.find(idString);
             if ( it != m_dictIdChoices.end() )
@@ -6492,7 +6470,7 @@ wxPGChoices wxPropertyGridPopulator::ParseChoices( const wxString& choicesString
             }
 
             // Assign to id
-            if ( idString.length() )
+            if ( !idString.empty() )
                 m_dictIdChoices[idString] = choices.GetData();
         }
     }
@@ -6533,7 +6511,7 @@ bool wxPropertyGridPopulator::AddAttribute( const wxString& name,
     wxString valuel = value.Lower();
     wxVariant variant;
 
-    if ( type.length() == 0 )
+    if ( type.empty() )
     {
         long v;