Esempio n. 1
0
WXDLLEXPORT bool
wxConvertOleToVariant(const VARIANTARG& oleVariant, wxVariant& variant)
{
    bool ok = true;
    if ( oleVariant.vt & VT_ARRAY )
    {

        // Compute the total number of elements in all array dimensions
        int cElements = 1;
        for ( int cDims = 0; cDims < oleVariant.parray->cDims; cDims++ )
            cElements *= oleVariant.parray->rgsabound[cDims].cElements;

        // Get a pointer to the data
        void* pvdata;
        HRESULT hr = SafeArrayAccessData(oleVariant.parray, &pvdata);
        if ( FAILED(hr) )
            return false;

        switch (oleVariant.vt & VT_TYPEMASK)
        {
            case VT_VARIANT:
                {
                    variant.ClearList();
                    VARIANTARG *variant_data=(VARIANTARG*)pvdata;
                    for ( int i = 0; i < cElements; i++ )
                    {
                        VARIANTARG& oleElement = variant_data[i];
                        wxVariant vElement;
                        if ( !wxConvertOleToVariant(oleElement, vElement) )
                        {
                            ok = false;
                            variant.ClearList();
                            break;
                        }

                        variant.Append(vElement);
                    }
                }
                break;

            case VT_BSTR:
                {
                    wxArrayString strings;
                    BSTR *string_val=(BSTR*)pvdata;
                    for ( int i = 0; i < cElements; ++i )
                    {
                        wxString str=wxConvertStringFromOle(*string_val);
                        strings.Add(str);
                        ++string_val;
                    }
                    variant=strings;
                }
                break;

            default:
                wxLogDebug(wxT("unhandled VT_ARRAY type %x in wxConvertOleToVariant"),
                           oleVariant.vt & VT_TYPEMASK);
                variant = wxVariant();
                ok = false;
                break;
        }

        SafeArrayUnaccessData(oleVariant.parray);
    }
    else if ( oleVariant.vt & VT_BYREF )
    {
        switch ( oleVariant.vt & VT_TYPEMASK )
        {
            case VT_VARIANT:
                {
                    VARIANTARG& oleReference = *((LPVARIANT)oleVariant.byref);
                    if (!wxConvertOleToVariant(oleReference,variant))
                        return false;
                    break;
                }

            default:
                wxLogError(wxT("wxAutomationObject::ConvertOleToVariant: [as yet] unhandled reference %X"),
                            oleVariant.vt);
                return false;
        }
    }
    else // simply type (not array or reference)
    {
        switch ( oleVariant.vt & VT_TYPEMASK )
        {
            case VT_BSTR:
                {
                    wxString str(wxConvertStringFromOle(oleVariant.bstrVal));
                    variant = str;
                }
                break;

            case VT_DATE:
#if wxUSE_DATETIME
                {
                    SYSTEMTIME st;
                    VariantTimeToSystemTime(oleVariant.date, &st);

                    wxDateTime date;
                    date.SetFromMSWSysTime(st);
                    variant = date;
                }
#endif // wxUSE_DATETIME
                break;

            case VT_I4:
                variant = (long) oleVariant.lVal;
                break;

            case VT_I2:
                variant = (long) oleVariant.iVal;
                break;

            case VT_BOOL:
                variant = oleVariant.boolVal != 0;
                break;

            case VT_R8:
                variant = oleVariant.dblVal;
                break;

            case VT_DISPATCH:
                variant = (void*) oleVariant.pdispVal;
                break;

            case VT_NULL:
                variant.MakeNull();
                break;

            case VT_EMPTY:
                break;    // Ignore Empty Variant, used only during destruction of objects

            default:
                wxLogError(wxT("wxAutomationObject::ConvertOleToVariant: Unknown variant value type %X -> %X"),
                           oleVariant.vt,oleVariant.vt&VT_TYPEMASK);
                return false;
        }
    }

    return ok;
}
// Populate tree view
void AddPropertyDialog::populateTreeView()
{
	wxIcon folderIcon;
	folderIcon.CopyFromBitmap(wxArtProvider::GetBitmap(GlobalUIManager().ArtIdPrefix() + FOLDER_ICON));

	// DEF-DEFINED PROPERTIES
	{
		// First add a top-level category named after the entity class, and populate
		// it with custom keyvals defined in the DEF for that class
		std::string cName = _entity->getEntityClass()->getName();

		wxutil::TreeModel::Row defRoot = _treeStore->AddItem();

		wxDataViewItemAttr blueBold;
		blueBold.SetColour(wxColor(0,0,255));
		blueBold.SetBold(true);

		defRoot[_columns.displayName] = wxVariant(wxDataViewIconText(cName, folderIcon));
		defRoot[_columns.displayName] = blueBold;
		defRoot[_columns.propertyName] = "";
		defRoot[_columns.description] = _(CUSTOM_PROPERTY_TEXT);

		defRoot.SendItemAdded();

		// Use a CustomPropertyAdder class to visit the entityclass and add all
		// custom properties from it
		CustomPropertyAdder adder(_entity, _treeStore, _columns, defRoot.getItem());
		_entity->getEntityClass()->forEachClassAttribute(boost::ref(adder));
	}

	// REGISTRY (GAME FILE) DEFINED PROPERTIES 

	// Ask the XML registry for the list of properties
    game::IGamePtr currentGame = GlobalGameManager().currentGame();
    xml::NodeList propNodes = currentGame->getLocalXPath(PROPERTIES_XPATH);

	// Cache of property categories to GtkTreeIters, to allow properties
	// to be parented to top-level categories
	typedef std::map<std::string, wxDataViewItem> CategoryMap;
	CategoryMap categories;

	// Add each .game-specified property to the tree view
	for (xml::NodeList::const_iterator iter = propNodes.begin();
		 iter != propNodes.end();
		 ++iter)
	{
		// Skip hidden properties
		if (iter->getAttributeValue("hidden") == "1")
		{
			continue;
		}

		wxDataViewItem item;

		// If this property has a category, look up the top-level parent iter
		// or add it if necessary.
		std::string category = iter->getAttributeValue("category");

		if (!category.empty())
		{
			CategoryMap::iterator mIter = categories.find(category);

			if (mIter == categories.end())
			{
				// Not found, add to treestore
				wxutil::TreeModel::Row catRow = _treeStore->AddItem();

				catRow[_columns.displayName] = wxVariant(wxDataViewIconText(category, folderIcon));;
				catRow[_columns.propertyName] = "";
				catRow[_columns.description] = "";

				// Add to map
				mIter = categories.insert(CategoryMap::value_type(category, catRow.getItem())).first;

				catRow.SendItemAdded();
			}

			// Category sorted, add this property below it
			item = _treeStore->AddItem(mIter->second).getItem();

			_treeStore->ItemAdded(mIter->second, item);
		}
		else
		{
			// No category, add at toplevel
			item = _treeStore->AddItem().getItem();

			_treeStore->ItemAdded(_treeStore->GetRoot(), item);
		}

		// Obtain information from the XML node and add it to the treeview
		std::string name = iter->getAttributeValue("match");
		std::string type = iter->getAttributeValue("type");
		std::string description = iter->getContent();

		wxutil::TreeModel::Row row(item, *_treeStore);

		wxIcon icon;
		icon.CopyFromBitmap(PropertyEditorFactory::getBitmapFor(type));

		row[_columns.displayName] = wxVariant(wxDataViewIconText(name, icon));
		row[_columns.propertyName] = name;
		row[_columns.description] = description;

		_treeStore->ItemChanged(item);
	}
}
Esempio n. 3
0
void wxGISGPGxObjectDomain::AddFilter(wxGxObjectFilter* pFilter)
{
	AddValue(wxVariant((void*)pFilter), pFilter->GetName());
}
Esempio n. 4
0
wxVariant wxGISGPValueDomain::GetValue(size_t nIndex) const
{
    wxCHECK_MSG(nIndex < m_asoData.size(), wxVariant(), wxT("The index is out of the domain value scope"));
	return m_asoData[nIndex];
}
Esempio n. 5
0
//------------------------------------------------------------------------------
// void LoadData()
//------------------------------------------------------------------------------
void BurnThrusterPanel::LoadData()
{
   #ifdef DEBUG_BURNPANEL_LOAD
   MessageInterface::ShowMessage(wxT("BurnThrusterPanel::LoadData() entered\n"));
   #endif
   
   // Set object pointer for "Show Script"
   mObject = theObject;
   bool isImpBurn = false;
   if (theObject->GetType() == Gmat::IMPULSIVE_BURN)
      isImpBurn = true;
   
   if (isImpBurn)
   {
      thrustDir1 = wxT("Element1");
      thrustDir2 = wxT("Element2");
      thrustDir3 = wxT("Element3");
   }
   else
   {
      thrustDir1 = wxT("ThrustDirection1");
      thrustDir2 = wxT("ThrustDirection2");
      thrustDir3 = wxT("ThrustDirection3");
   }
   
   Integer paramID;
   
   try
   {
      paramID = theObject->GetParameterID(wxT("CoordinateSystem"));
      coordSysName = theObject->GetStringParameter(paramID);
      coordSysComboBox->SetValue(coordSysName.c_str());
      
      paramID = theObject->GetParameterID(wxT("Origin"));
      wxString objName = theObject->GetStringParameter(paramID);
      originComboBox->SetValue(objName.c_str());
      
      paramID = theObject->GetParameterID(wxT("Axes"));
      objName = theObject->GetStringParameter(paramID);
      axesComboBox->SetValue(objName.c_str());
      
      paramID = theObject->GetParameterID(thrustDir1);
      elem1TextCtrl->SetValue(wxVariant(theObject->GetRealParameter(paramID)));
      
      paramID = theObject->GetParameterID(thrustDir2);
      elem2TextCtrl->SetValue(wxVariant(theObject->GetRealParameter(paramID)));
      
      paramID = theObject->GetParameterID(thrustDir3);
      elem3TextCtrl->SetValue(wxVariant(theObject->GetRealParameter(paramID)));
      
      paramID = theObject->GetParameterID(wxT("DecrementMass"));
      decMassCheckBox->SetValue((wxVariant(theObject->GetBooleanParameter(paramID))));
      
      paramID = theObject->GetParameterID(wxT("GravitationalAccel"));
      gravityAccelTextCtrl->SetValue((wxVariant(theObject->GetRealParameter(paramID))));
      
      paramID = theObject->GetParameterID(wxT("Tank"));
      StringArray tanks = theObject->GetStringArrayParameter(paramID);   
      
      if (tanks.empty())
      {
         if (theGuiManager->GetNumFuelTank() > 0)
         {
            tankComboBox->Insert(wxT("No Fuel Tank Selected"), 0);
            tankComboBox->SetSelection(0);
         }
      }
      else
      {
         tankName = tanks[0];
         tankComboBox->SetValue(tankName.c_str());
         isTankEmpty = false;
      }
      
      // Disable tank combo box if decrement mass is not checked
      if (!decMassCheckBox->IsChecked())
      {
         tankLabel->Disable();
         tankComboBox->Disable();

         if (theObject->GetType() == Gmat::IMPULSIVE_BURN)
         {
            ispLabel->Disable();
            ispTextCtrl->Disable();
            ispUnit->Disable();
         }
      }
      
      // Update Origin and Axes
      UpdateOriginAxes();
   }
   catch (BaseException &e)
   {
      MessageInterface::PopupMessage(Gmat::ERROR_, e.GetFullMessage());
   }
   
   #ifdef DEBUG_BURNPANEL_LOAD
   MessageInterface::ShowMessage(wxT("BurnThrusterPanel::LoadData() exiting\n"));
   #endif
}
Esempio n. 6
0
void NewBuildTab::DoProcessOutput(bool compilationEnded, bool isSummaryLine)
{
    if(!compilationEnded && m_output.Find(wxT("\n")) == wxNOT_FOUND) {
        // still dont have a complete line
        return;
    }

    wxArrayString lines = ::wxStringTokenize(m_output, wxT("\n"), wxTOKEN_RET_DELIMS);
    m_output.Clear();

    // Process only completed lines (i.e. a line that ends with '\n')
    for(size_t i = 0; i < lines.GetCount(); i++) {
        if(!compilationEnded && !lines.Item(i).EndsWith(wxT("\n"))) {
            m_output << lines.Item(i);
            return;
        }

        wxString buildLine = lines.Item(i); //.Trim().Trim(false);
        // If this is a line similar to 'Entering directory `'
        // add the path in the directories array
        DoSearchForDirectory(buildLine);
        BuildLineInfo* buildLineInfo = DoProcessLine(buildLine, isSummaryLine);

        // keep the line info
        if(buildLineInfo->GetFilename().IsEmpty() == false) {
            m_buildInfoPerFile.insert(std::make_pair(buildLineInfo->GetFilename(), buildLineInfo));
        }

        // Append the line content

        if(buildLineInfo->GetSeverity() == SV_ERROR) {
            if(!isSummaryLine) {
                buildLine.Prepend(ERROR_MARKER);
            }

        } else if(buildLineInfo->GetSeverity() == SV_WARNING) {
            if(!isSummaryLine) {
                buildLine.Prepend(WARNING_MARKER);
            }
        }

        if(isSummaryLine) {

            // Add a marker for drawing the bitmap
            if(m_errorCount) {
                buildLine.Prepend(SUMMARY_MARKER_ERROR);

            } else if(m_warnCount) {
                buildLine.Prepend(SUMMARY_MARKER_WARNING);

            } else {
                buildLine.Prepend(SUMMARY_MARKER_SUCCESS);
            }
            buildLine.Prepend(SUMMARY_MARKER);
        }

        wxVector<wxVariant> data;
        data.push_back(wxVariant(buildLine));
#ifdef __WXMSW__
        data.push_back(wxString());
#endif

        // Keep the line number in the build tab
        buildLineInfo->SetLineInBuildTab(m_listctrl->GetItemCount());
        m_listctrl->AppendItem(data, (wxUIntPtr)buildLineInfo);

        if(clConfig::Get().Read(kConfigBuildAutoScroll, true)) {
            unsigned int count = m_listctrl->GetStore()->GetItemCount();
            wxDataViewItem lastItem = m_listctrl->GetStore()->GetItem(count - 1);
            m_listctrl->EnsureVisible(lastItem);
        }
    }
}
//------------------------------------------------------------------------------
// virtual void LoadData()
//------------------------------------------------------------------------------
void ThrusterCoefficientDialog::LoadData()
{
   #ifdef DEBUG_COEFS_LOAD
      MessageInterface::ShowMessage(
            "In ThrusterConfigDialog::LoadData ..., coefsCount = %d\n",
            coefsCount);
   #endif

   std::stringstream c1Strings("");
   std::stringstream c2Strings("");

   coefs1Names.clear();
   coefs2Names.clear();

   std::string coefs1Label;
   std::string coefs2Label;
   StringArray coefs1Units;
   StringArray coefs2Units;

   if (isElectric)
   {
      coefs1Units = theObject->GetStringArrayParameter("T_UNITS");
      coefs2Units = theObject->GetStringArrayParameter("MF_UNITS");
      coefs1Label = "ThrustCoeff";
      coefs2Label = "MassFlowCoeff";
   }
   else
   {
      coefs1Units = theObject->GetStringArrayParameter("C_UNITS");
      coefs2Units = theObject->GetStringArrayParameter("K_UNITS");
      coefs1Label = "C";
      coefs2Label = "K";
   }

   for (Integer ii = 0; ii < coefsCount; ii++)
   {
      c1Strings << coefs1Label << ii + 1;
      coefs1Names.push_back(c1Strings.str());
      c1Strings.str("");

      c2Strings << coefs2Label << ii + 1;
      coefs2Names.push_back(c2Strings.str());
      c2Strings.str("");
      #ifdef DEBUG_COEFS_LOAD
         MessageInterface::ShowMessage(
               "In TCDialog::LoadData, coefs1Names[%d] = %s, units = %s\n",
               ii, coefs1Names.at(ii).c_str(), coefs1Units.at(ii).c_str());
         MessageInterface::ShowMessage(
               "In TCDialog::LoadData, coefs2Names[%d] = %s, units = %s\n",
               ii, coefs2Names.at(ii).c_str(), coefs2Units.at(ii).c_str());
      #endif
   }

   for (Integer jj = 0; jj < coefsCount; jj++)
   {
      #ifdef DEBUG_COEFS_LOAD
         MessageInterface::ShowMessage(
               "In TCDialog::LoadData, %d, setting name = %s,value = %12.10f, units = %s\n",
               jj, coefs1Names[jj].c_str(), coefs1Values[jj], coefs1Units[jj].c_str() );
      #endif
      coefGrid1->SetCellValue(jj, 0, coefs1Names[jj].c_str());
      coefGrid1->SetCellValue(jj, 1, wxVariant(coefs1Values[jj]));
      coefGrid1->SetCellValue(jj, 2, coefs1Units[jj].c_str());

      #ifdef DEBUG_COEFS_LOAD
         MessageInterface::ShowMessage(
               "In TCDialog::LoadData, %d, setting name = %s,value = %12.10f, units = %s\n",
               jj, coefs2Names[jj].c_str(), coefs2Values[jj],coefs2Units[jj].c_str() );
      #endif
      coefGrid2->SetCellValue(jj, 0, coefs2Names[jj].c_str());
      coefGrid2->SetCellValue(jj, 1, wxVariant(coefs2Values[jj]));
      coefGrid2->SetCellValue(jj, 2, coefs2Units[jj].c_str());
   }
}
bool ctConfigToolDoc::DoOpen(wxSimpleHtmlTag* tag, ctConfigItem* parent)
{
    ctConfigItem* newItem = NULL;
    if (tag->NameIs(wxT("setting")))
    {
        wxSimpleHtmlAttribute* attr = tag->FindAttribute(wxT("type"));
        if (attr)
        {
            ctConfigType type = ctTypeUnknown;
            wxString typeStr(attr->GetValue());
            if (typeStr == wxT("group"))
                type = ctTypeGroup;
            else if (typeStr == wxT("option-group") || typeStr == wxT("check-group"))
                type = ctTypeCheckGroup;
            else if (typeStr == wxT("radio-group"))
                type = ctTypeRadioGroup;
            else if (typeStr == wxT("bool-check"))
                type = ctTypeBoolCheck;
            else if (typeStr == wxT("bool-radio"))
                type = ctTypeBoolRadio;
            else if (typeStr == wxT("string"))
                type = ctTypeString;
            else if (typeStr == wxT("integer"))
                type = ctTypeInteger;
            else
            {
                wxLogError(wxT("Unknown type %s"), (const wxChar*) typeStr);
            }
            if (type != ctTypeUnknown)
            {
                newItem = new ctConfigItem(parent, type, wxT(""));
                newItem->InitProperties();
                if (!parent)
                    SetTopItem(newItem);
            }
        }
    }
    wxSimpleHtmlTag* childTag = tag->GetChildren();

    while (childTag)
    {
        if (childTag->GetType() == wxSimpleHtmlTag_Open)
        {
            if (childTag->GetName() == wxT("setting"))
            {
                DoOpen(childTag, newItem);
            }
            else if (childTag->GetName() == wxT("name"))
            {
                if (newItem)
                {
                    wxString name(childTag->GetNext()->GetTagText());
                    newItem->SetName(name);
                }
            }
            else if (childTag->GetName() == wxT("active"))
            {
                if (newItem)
                    newItem->SetActive(GetHtmlBoolValue(childTag->GetNext()->GetTagText()));
            }
            else if (childTag->GetName() == wxT("enabled"))
            {
                if (newItem)
                    newItem->Enable(GetHtmlBoolValue(childTag->GetNext()->GetTagText()));
            }
            else
            {
                if (newItem)
                {
                    ctProperty* prop = newItem->GetProperties().FindProperty(childTag->GetName());
                    if (!prop)
                    {
                        // A custom property, else an obsolete
                        // property that we should ignore.
                        wxString isCustom;
                        if (childTag->GetAttributeValue(isCustom, wxT("custom")) &&
                            isCustom == wxT("true"))
                        {
                            prop = new ctProperty;

                            wxString name(childTag->GetName());
                            wxString type(wxT("string"));
                            wxString choices;
                            wxString editorType(wxT("string"));
                            wxString description(wxT(""));
                            childTag->GetAttributeValue(type, wxT("type"));
                            childTag->GetAttributeValue(type, wxT("editor-type"));
                            childTag->GetAttributeValue(type, wxT("choices"));
                            childTag->GetAttributeValue(description, wxT("description"));

                            if (type == wxT("bool"))
                                prop->GetVariant() = wxVariant(false, name);
                            else if (type == wxT("double"))
                                prop->GetVariant() = wxVariant((double) 0.0, name);
                            else if (type == wxT("long"))
                                prop->GetVariant() = wxVariant((long) 0, name);
                            else
                                prop->GetVariant() = wxVariant(wxT(""), name);
                            prop->SetDescription(description);
                            prop->SetCustom(true);
                            prop->SetEditorType(editorType);
                            if (!choices.IsEmpty())
                            {
                                wxArrayString arr;
                                ctConfigItem::StringToArray(choices, arr);
                                prop->SetChoices(arr);
                            }
                            newItem->GetProperties().AddProperty(prop);
                        }
                    }
                    if (prop)
                    {
                        if (prop->GetVariant().GetType() == wxT("string"))
                            prop->GetVariant() = childTag->GetNext()->GetTagText();
                        else if (prop->GetVariant().GetType() == wxT("long"))
                            prop->GetVariant() = (long) GetHtmlIntegerValue(childTag->GetNext()->GetTagText());
                        else if (prop->GetVariant().GetType() == wxT("bool"))
                            prop->GetVariant() = GetHtmlBoolValue(childTag->GetNext()->GetTagText());
                        else if (prop->GetVariant().GetType() == wxT("double"))
                            prop->GetVariant() = (double) GetHtmlDoubleValue(childTag->GetNext()->GetTagText());
                    }
                }
            }
        }
        childTag = childTag->GetNext();
    }
    return true;
}
Esempio n. 9
0
//------------------------------------------------------------------------------
// virtual void LoadData()
//------------------------------------------------------------------------------
void DragInputsDialog::LoadData()
{
   #ifdef DEBUG_DRAG_LOAD
   MessageInterface::ShowMessage(wxT("DragInputsDialog::LoadData() entered\n"));
   #endif
   
   try
   {
      solarFluxID = theForce->GetParameterID(wxT("F107"));
      solarFluxTextCtrl->
         SetValue(wxVariant(theForce->GetRealParameter(solarFluxID)));
   }
   catch (BaseException &e)
   {
      MessageInterface::ShowMessage(wxT("DragInputsDialog::LoadData()\n") +
                                    e.GetFullMessage()); 
   }
   
   try
   {
      avgSolarFluxID = theForce->GetParameterID(wxT("F107A"));
      avgSolarFluxTextCtrl->
         SetValue(wxVariant(theForce->GetRealParameter(avgSolarFluxID)));
   }
   catch (BaseException &e)
   {
      MessageInterface::ShowMessage(wxT("DragInputsDialog::LoadData()\n") +
                                    e.GetFullMessage()); 
   }
   
   try
   {
      geomagnecticIndexID = theForce->GetParameterID(wxT("MagneticIndex"));
      geomagneticIndexTextCtrl->
         SetValue(wxVariant(theForce->GetRealParameter(geomagnecticIndexID)));
   }
   catch (BaseException &e)
   {
      MessageInterface::ShowMessage(wxT("DragInputsDialog::LoadData()\n") +
                                    e.GetFullMessage()); 
   }
   
   try
   {
      solarFluxFileID = theForce->GetParameterID(wxT("SolarFluxFile"));
      wxString filename = theForce->GetStringParameter(solarFluxFileID).c_str();

      if (!filename.IsNull())
         fileNameTextCtrl->SetValue(filename);
   }
   catch (BaseException &e)
   {
      MessageInterface::ShowMessage(wxT("DragInputsDialog::LoadData()\n") +
                                    e.GetFullMessage()); 
   }
   
   try
   {
      inputSourceID = theForce->GetParameterID(wxT("InputSource"));
      inputSourceString = theForce->GetStringParameter(inputSourceID).c_str();
   }
   catch (BaseException &e)
   {
      MessageInterface::ShowMessage(wxT("DragInputsDialog::LoadData()\n") +
                                    e.GetFullMessage()); 
   }
   
   if (inputSourceString.CmpNoCase(wxT("Constant")) == 0)
   {
      useFile = false;
      userInputRadioButton->SetValue(true);
      fileInputRadioButton->SetValue(false); 
   }
   else if (inputSourceString.CmpNoCase(wxT("File")) == 0)
   {
      useFile = true;
      userInputRadioButton->SetValue(false);
      fileInputRadioButton->SetValue(true);
   }
   
   Update();
   
   #ifdef DEBUG_DRAG_LOAD
   MessageInterface::ShowMessage(wxT("DragInputsDialog::LoadData() leaving\n"));
   #endif
}
Esempio n. 10
0
/// Edit a custom property
void ctConfigToolView::OnEditCustomProperty(wxCommandEvent& WXUNUSED(event))
{
    ctConfigToolDoc* doc = (ctConfigToolDoc*) GetDocument();
    ctConfigItem* sel = GetSelection();
    ctPropertyEditor* editor = wxGetApp().GetMainFrame()->GetPropertyEditor();
    if (doc && sel && editor)
    {
        int row;
        ctProperty* property = editor->FindSelectedProperty(row) ;
        if (property && property->IsCustom())
        {
            wxString oldName = property->GetName();
            wxString oldDescription = property->GetDescription();
            wxString oldType = property->GetVariant().GetType();
            wxString oldEditorType = property->GetEditorType();
            wxArrayString oldChoices = property->GetChoices();

            ctCustomPropertyDialog dialog(wxGetApp().GetMainFrame(),
                wxID_ANY, _("Edit custom property"));
            dialog.SetPropertyName(oldName);
            dialog.SetPropertyType(oldType);
            dialog.SetPropertyDescription(oldDescription);
            if (dialog.ShowModal() == wxID_OK)
            {
                wxString name = dialog.GetPropertyName();
                wxString type = dialog.GetPropertyType();
                wxString editorType = dialog.GetEditorType();
                wxArrayString choices = dialog.GetChoices();
                wxString descr = dialog.GetPropertyDescription();

                if (name != oldName && sel->GetProperties().FindProperty(name))
                {
                    wxMessageBox(_("Sorry, this name already exists."), _T("Add custom property"),
                        wxOK|wxICON_INFORMATION);
                    return;
                }
                if (type != oldType)
                {
                    if (type == wxT("bool"))
                        property->GetVariant() = wxVariant(false, name);
                    else if (type == wxT("double"))
                        property->GetVariant() = wxVariant((double) 0.0, name);
                    else if (type == wxT("long"))
                        property->GetVariant() = wxVariant((long) 0, name);
                    else
                        property->GetVariant() = wxVariant(wxEmptyString, name);
                }
                if (name != oldName)
                    property->GetVariant().SetName(name);

                if (choices != oldChoices)
                    property->SetChoices(choices);

                if (editorType != oldEditorType)
                    property->SetEditorType(editorType);

                if (name != oldName)
                    property->GetVariant().SetName(name);

                property->SetCustom(true);

                if (descr != oldDescription)
                    property->SetDescription(descr);

                editor->ShowItem(sel);
                OnChangeFilename();
            }
        }
    }
}
void WIZARD_FPLIB_TABLE::setupReview()
{
    wxBeginBusyCursor();
    updateLibraries();

    int libTotalCount = m_libraries.size();
    int libCount = 0;
    bool validate = true;
    wxProgressDialog progressDlg( _( "Please wait..." ), _( "Validating libraries" ),
                                  libTotalCount, this,
                                  wxPD_APP_MODAL | wxPD_CAN_ABORT | wxPD_AUTO_HIDE );

    m_dvLibName->SetWidth( 280 );

    // Prepare the review list
    m_listCtrlReview->DeleteAllItems();

    for( std::vector<LIBRARY>::iterator it = m_libraries.begin(); it != m_libraries.end(); ++it )
    {
        wxVector<wxVariant> row;
        LIBRARY::STATUS status = it->GetStatus();

        // Check if the library contents is valid
        if( status == LIBRARY::NOT_CHECKED && validate )
        {
            it->Test();
            status = it->GetStatus();
        }

        row.push_back( wxVariant( it->GetDescription() ) );

        switch( it->GetStatus() )
        {
        case LIBRARY::NOT_CHECKED:
            row.push_back( wxVariant( _( "NOT CHECKED" ) ) );
            break;

        case LIBRARY::OK:
            row.push_back( wxVariant( _( "OK" ) ) );
            break;

        case LIBRARY::INVALID:
            row.push_back( wxVariant( _( "INVALID" ) ) );
            break;
        }

        row.push_back( wxVariant( it->GetPluginName() ) );

        m_listCtrlReview->AppendItem( row );

        ++libCount;
        if( !progressDlg.Update( libCount, wxString::Format( _( "Validating libraries %d/%d" ),
                                 libCount, libTotalCount ) ) )
            validate = false;
    }

    // The list should never be empty, but who knows?
    enableNext( m_listCtrlReview->GetItemCount() > 0 );

    wxEndBusyCursor();
}