Patch #2877 2009-12-27 18:53

techy

CompilerOptionsDlg acesses tabs that don't exist (debug5)
Download
2877-CompilerOption.patch (9.2 KB)
Category
Application::Bugfix
Status
Accepted
Close date
2010-01-14 08:16
Assigned to
mortenmacfly
Index: src/plugins/compilergcc/compileroptionsdlg.cpp
===================================================================
--- src/plugins/compilergcc/compileroptionsdlg.cpp    (revision 5986)
+++ src/plugins/compilergcc/compileroptionsdlg.cpp    (working copy)
@@ -474,6 +474,9 @@
 
 void CompilerOptionsDlg::DoFillOthers()
 {
+    if (m_pProject)
+        return; // projects don't have Other tab
+        
     wxCheckBox* chk = XRCCTRL(*this, "chkIncludeFileCwd", wxCheckBox);
     if (chk)
         chk->SetValue(Manager::Get()->GetConfigManager(_T("compiler"))->ReadBool(_T("/include_file_cwd"), false));
@@ -825,7 +828,7 @@
     ArrayString2TextCtrl(m_LinkerOptions, XRCCTRL(*this, "txtLinkerOptions", wxTextCtrl));
 
     // only if "Commands" page exists
-    if (XRCCTRL(*this, "txtCmdBefore", wxTextCtrl))
+    if (m_pProject)
     {
         ArrayString2TextCtrl(CommandsBeforeBuild, XRCCTRL(*this, "txtCmdBefore", wxTextCtrl));
         ArrayString2TextCtrl(CommandsAfterBuild, XRCCTRL(*this, "txtCmdAfter", wxTextCtrl));
@@ -927,7 +930,7 @@
         wxArrayString CommandsBeforeBuild;
         wxArrayString CommandsAfterBuild;
         bool AlwaysUsePost = false;
-        if (XRCCTRL(*this, "txtCmdBefore", wxTextCtrl))
+        if (m_pProject)
         {
             AlwaysUsePost = XRCCTRL(*this, "chkAlwaysRunPost", wxCheckBox)->GetValue();
             DoGetCompileOptions(CommandsBeforeBuild, XRCCTRL(*this, "txtCmdBefore", wxTextCtrl));
@@ -2169,9 +2172,9 @@
         XRCCTRL(*this, "btnCopyLibs", wxButton)->Enable(lstLibs->GetCount() != 0);
         XRCCTRL(*this, "spnLibs",     wxSpinButton)->Enable(en);
     }
-
+    
     // edit/delete/clear/copy/moveup/movedown extra path
-    if (XRCCTRL(*this, "lstExtraPaths", wxListBox))
+    if (!m_pProject)
     {
         en = XRCCTRL(*this, "lstExtraPaths", wxListBox)->GetSelection() >= 0;
         XRCCTRL(*this, "btnExtraEdit",   wxButton)->Enable(en);
@@ -2180,13 +2183,10 @@
     }
 
     // add/edit/delete/clear vars
-    if (XRCCTRL(*this, "lstVars", wxListBox))
-    {
-        en = XRCCTRL(*this, "lstVars", wxListBox)->GetSelection() >= 0;
-        XRCCTRL(*this, "btnEditVar",   wxButton)->Enable(en);
-        XRCCTRL(*this, "btnDeleteVar", wxButton)->Enable(en);
-        XRCCTRL(*this, "btnClearVar",  wxButton)->Enable(XRCCTRL(*this, "lstVars", wxListBox)->GetCount() != 0);
-    }
+    en = XRCCTRL(*this, "lstVars", wxListBox)->GetSelection() >= 0;
+    XRCCTRL(*this, "btnEditVar",   wxButton)->Enable(en);
+    XRCCTRL(*this, "btnDeleteVar", wxButton)->Enable(en);
+    XRCCTRL(*this, "btnClearVar",  wxButton)->Enable(XRCCTRL(*this, "lstVars", wxListBox)->GetCount() != 0);
 
     // policies
     wxTreeCtrl* tc = XRCCTRL(*this, "tcScope", wxTreeCtrl);
@@ -2199,7 +2199,7 @@
     XRCCTRL(*this, "cmbResDirsPolicy",  wxChoice)->Enable(en);
 
     // compiler set buttons
-    if (XRCCTRL(*this, "btnAddCompiler", wxButton)) // only if exist
+    if (!m_pProject) 
     {
         en = !data; // global options selected
         int idx   = XRCCTRL(*this, "cmbCompiler", wxChoice)->GetSelection();
@@ -2215,21 +2215,9 @@
         XRCCTRL(*this, "btnResetCompiler",      wxButton)->Enable(en &&
                                                                   compiler &&
                                                                   compiler->GetParentID().IsEmpty());
-    }
 
-    // "others" tab
-    if (XRCCTRL(*this, "chkSaveHtmlLog", wxCheckBox)) // page exists?
-    {
         XRCCTRL(*this, "chkFullHtmlLog", wxCheckBox)->Enable(XRCCTRL(*this, "chkSaveHtmlLog", wxCheckBox)->IsChecked());
-    }
-    if (   XRCCTRL(*this, "lstIgnore",       wxListBox)
-        && XRCCTRL(*this, "btnIgnoreRemove", wxButton) ) // page exists?
-    {
         XRCCTRL(*this, "btnIgnoreRemove", wxButton)->Enable(XRCCTRL(*this, "lstIgnore", wxListBox)->GetCount()>0);
-    }
-    if (   XRCCTRL(*this, "txtIgnore",    wxTextCtrl)
-        && XRCCTRL(*this, "btnIgnoreAdd", wxButton) ) // page exists?
-    {
         XRCCTRL(*this, "btnIgnoreAdd", wxButton)->Enable(XRCCTRL(*this, "txtIgnore", wxTextCtrl)->GetValue().Trim().Len()>0);
     }
 } // OnUpdateUI
@@ -2240,57 +2228,60 @@
     DoSaveCompilerDependentSettings();
     CompilerFactory::SaveSettings();
 
-    //others
-    wxCheckBox* chk = XRCCTRL(*this, "chkIncludeFileCwd", wxCheckBox);
-    if (chk)
-        Manager::Get()->GetConfigManager(_T("compiler"))->Write(_T("/include_file_cwd"), (bool)chk->IsChecked());
-    chk = XRCCTRL(*this, "chkIncludePrjCwd", wxCheckBox);
-    if (chk)
-        Manager::Get()->GetConfigManager(_T("compiler"))->Write(_T("/include_prj_cwd"), (bool)chk->IsChecked());
-    chk = XRCCTRL(*this, "chkSaveHtmlLog", wxCheckBox);
-    if (chk)
-        Manager::Get()->GetConfigManager(_T("compiler"))->Write(_T("/save_html_build_log"), (bool)chk->IsChecked());
-    chk = XRCCTRL(*this, "chkFullHtmlLog", wxCheckBox);
-    if (chk)
-        Manager::Get()->GetConfigManager(_T("compiler"))->Write(_T("/save_html_bu
download for full patch...
techy 2009-12-27 18:53

CompilerOptionsDlg is used in three situations - 1. global options, 2. project options, 3. target options. Depending on its use, some tabs are deleted in the constructor. This patch makes sure that objects from the non-existing tabs are not accessed in the rest of the code.

mortenmacfly 2009-12-28 19:33

I don't really get whats wrong with trying to obtain the control instead of verifying a project is present. What if we change the possibilities to set in case (absense) of a project? I am not sure about this one...

techy 2009-12-28 23:37

The problem here is that XRCCTRL goes through the existing wxObjects and tries to find the object with the given id. If it doesn't find one, it raises an assertion (useful for instance if you called XRCCTRL on something you haven't loaded yet with wxXmlResource::Get()->LoadPanel() ). Because DeletePage() really physically deletes all the objects present in he page, you get the assertion here as well because these objects cannot be found in memory. From what I have seen, you don't even have guaranteed that you get NULL when the resource is not found:

// This macro returns pointer to particular control in dialog

// created using XML resources. You can use it to set/get values from

// controls.

// Example:

// wxDialog dlg;

// wxXmlResource::Get()->LoadDialog(&dlg, mainFrame, "my_dialog");

// XRCCTRL(dlg, "my_textctrl", wxTextCtrl)->SetValue(wxT("default value"));

#define XRCCTRL(window, id, type) \

(wxStaticCast((window).FindWindow(XRCID(id)), type))

An alternative solution would be to use some flags (initialized in constructor) determining the presence of a tab and have code like

if (m_thisPageIsPresent) {

//do this

}

if (m_thatPageIsPresent) {

//do that

}