Added first cut wxWindows Configuration Tool
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@21083 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
992
utils/configtool/src/configtooldoc.cpp
Normal file
992
utils/configtool/src/configtooldoc.cpp
Normal file
@@ -0,0 +1,992 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: configtooldoc.h
|
||||
// Purpose: Document class
|
||||
// Author: Julian Smart
|
||||
// Modified by:
|
||||
// Created: 2003-06-04
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) Julian Smart
|
||||
// Licence:
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma implementation "configtooldoc.h"
|
||||
#endif
|
||||
|
||||
#include "wx/wx.h"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#include "wx/config.h"
|
||||
#include "wx/textfile.h"
|
||||
#include "wx/process.h"
|
||||
#include "wx/mimetype.h"
|
||||
#include "wx/process.h"
|
||||
#include "wx/wfstream.h"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#include "configtooldoc.h"
|
||||
#include "configtoolview.h"
|
||||
#include "configtree.h"
|
||||
#include "mainframe.h"
|
||||
#include "utils.h"
|
||||
#include "wxconfigtool.h"
|
||||
#include "htmlparser.h"
|
||||
|
||||
IMPLEMENT_DYNAMIC_CLASS(ctConfigToolDoc, wxDocument)
|
||||
|
||||
// Ctor
|
||||
ctConfigToolDoc::ctConfigToolDoc()
|
||||
{
|
||||
m_topItem = NULL;
|
||||
m_clipboardItem = NULL;
|
||||
}
|
||||
|
||||
// Dtor
|
||||
ctConfigToolDoc::~ctConfigToolDoc()
|
||||
{
|
||||
DeleteItems();
|
||||
ClearClipboard();
|
||||
if (GetCommandProcessor())
|
||||
GetCommandProcessor()->SetEditMenu(NULL);
|
||||
}
|
||||
|
||||
// Delete all the items not already deleted
|
||||
void ctConfigToolDoc::DeleteItems()
|
||||
{
|
||||
if (m_topItem)
|
||||
delete m_topItem;
|
||||
m_topItem = NULL;
|
||||
}
|
||||
|
||||
/// Clears the clipboard item.
|
||||
void ctConfigToolDoc::ClearClipboard()
|
||||
{
|
||||
if (m_clipboardItem)
|
||||
delete m_clipboardItem;
|
||||
m_clipboardItem = NULL;
|
||||
}
|
||||
|
||||
/// Sets the clipboard item.
|
||||
void ctConfigToolDoc::SetClipboardItem(ctConfigItem* item)
|
||||
{
|
||||
if (m_clipboardItem)
|
||||
delete m_clipboardItem;
|
||||
m_clipboardItem = item;
|
||||
}
|
||||
|
||||
|
||||
// Closes and clears the document
|
||||
bool ctConfigToolDoc::OnCloseDocument()
|
||||
{
|
||||
if (wxDocument::OnCloseDocument())
|
||||
{
|
||||
ctConfigToolHint hint(NULL, ctClear);
|
||||
UpdateAllViews (NULL, & hint);
|
||||
|
||||
DeleteItems();
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// Saves the doc
|
||||
bool ctConfigToolDoc::Save()
|
||||
{
|
||||
bool ret = FALSE;
|
||||
|
||||
if (!IsModified() && m_savedYet) return TRUE;
|
||||
if (m_documentFile == wxT("") || !m_savedYet)
|
||||
ret = SaveAs();
|
||||
else
|
||||
ret = OnSaveDocument(m_documentFile);
|
||||
if ( ret )
|
||||
SetDocumentSaved(TRUE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Create the document
|
||||
bool ctConfigToolDoc::OnCreate(const wxString& path, long flags)
|
||||
{
|
||||
GetCommandProcessor()->SetEditMenu(wxGetApp().GetMainFrame()->GetEditMenu());
|
||||
GetCommandProcessor()->Initialize();
|
||||
GetCommandProcessor()->ClearCommands();
|
||||
|
||||
// wxGetApp().m_currentDoc = this;
|
||||
|
||||
if (flags & wxDOC_NEW)
|
||||
{
|
||||
ctConfigItem* rootItem = new ctConfigItem(NULL, ctTypeGroup, _T("Configuration"));
|
||||
//rootItem->InitProperties();
|
||||
rootItem->GetProperties().AddProperty(
|
||||
new ctProperty(
|
||||
wxT("The item description."),
|
||||
wxVariant(wxT(""), wxT("description")),
|
||||
wxT("multiline")));
|
||||
|
||||
rootItem->SetPropertyString(_T("description"),
|
||||
_T("<B>This is the top-level configuration item.</B>"));
|
||||
|
||||
|
||||
SetTopItem(rootItem);
|
||||
|
||||
Modify(FALSE);
|
||||
SetDocumentSaved(FALSE);
|
||||
|
||||
wxString rootName(wxT("untitled"));
|
||||
wxStripExtension(rootName);
|
||||
SetFilename(wxGetApp().GetSettings().GenerateFilename(rootName));
|
||||
}
|
||||
|
||||
// Creates the view, so do any view updating after this
|
||||
bool success = wxDocument::OnCreate(path, flags);
|
||||
|
||||
if (success)
|
||||
{
|
||||
if (flags & wxDOC_NEW)
|
||||
{
|
||||
wxBusyCursor wait;
|
||||
|
||||
ctConfigToolHint hint(NULL, ctInitialUpdate);
|
||||
UpdateAllViews (NULL, & hint);
|
||||
|
||||
SetFilename(GetFilename(), TRUE);
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
// Save the document
|
||||
bool ctConfigToolDoc::OnSaveDocument(const wxString& filename)
|
||||
{
|
||||
wxBusyCursor cursor;
|
||||
|
||||
const wxString strOldPath(GetFilename());
|
||||
|
||||
// Do some backing up first
|
||||
|
||||
// This is the backup filename
|
||||
wxString backupFilename(filename);
|
||||
backupFilename += wxT(".bak");
|
||||
|
||||
// This is the temporary copy of the backup
|
||||
wxString tempFilename(filename);
|
||||
tempFilename += wxT(".tmp");
|
||||
if (wxFileExists(tempFilename))
|
||||
wxRemoveFile(tempFilename);
|
||||
|
||||
bool leaveBackup = TRUE;
|
||||
|
||||
bool saved = DoSave(tempFilename);
|
||||
|
||||
if (saved)
|
||||
{
|
||||
// Remove the old .bak file
|
||||
if (wxFileExists(backupFilename))
|
||||
{
|
||||
wxRemoveFile(backupFilename);
|
||||
}
|
||||
|
||||
// Copy the old file to the .bak
|
||||
|
||||
if (leaveBackup)
|
||||
{
|
||||
if (wxFileExists(filename))
|
||||
{
|
||||
if (!wxRenameFile(filename, backupFilename))
|
||||
{
|
||||
wxCopyFile(filename, backupFilename);
|
||||
wxRemoveFile(filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (wxFileExists(filename))
|
||||
wxRemoveFile(filename);
|
||||
}
|
||||
|
||||
// Finally, copy the temporary file to the proper filename
|
||||
if (!wxRenameFile(tempFilename, filename))
|
||||
{
|
||||
wxCopyFile(tempFilename, filename);
|
||||
wxRemoveFile(tempFilename);
|
||||
}
|
||||
|
||||
Modify(FALSE);
|
||||
((ctConfigToolView*)GetFirstView())->OnChangeFilename();
|
||||
SetDocumentSaved(TRUE);
|
||||
SetFilename(filename);
|
||||
wxGetApp().GetSettings().m_lastFilename = filename;
|
||||
} else
|
||||
{
|
||||
SetFilename(strOldPath);
|
||||
}
|
||||
wxGetApp().GetMainFrame()->UpdateFrameTitle();
|
||||
return saved;
|
||||
}
|
||||
|
||||
// Open the document
|
||||
bool ctConfigToolDoc::OnOpenDocument(const wxString& filename)
|
||||
{
|
||||
wxBusyCursor cursor;
|
||||
|
||||
bool opened = DoOpen(filename);
|
||||
|
||||
if (opened)
|
||||
{
|
||||
SetFilename(filename);
|
||||
wxGetApp().GetSettings().m_lastFilename = filename;
|
||||
|
||||
((ctConfigToolView*)GetFirstView())->OnChangeFilename();
|
||||
|
||||
RefreshDependencies();
|
||||
|
||||
// ctConfigToolHint hint(NULL, ctFilenameChanged);
|
||||
ctConfigToolHint hint(NULL, ctInitialUpdate);
|
||||
UpdateAllViews (NULL, & hint);
|
||||
}
|
||||
|
||||
SetDocumentSaved(TRUE); // Necessary or it will pop up the Save As dialog
|
||||
|
||||
return opened;
|
||||
}
|
||||
|
||||
/// Save the settings file
|
||||
bool ctConfigToolDoc::DoSave(const wxString& filename)
|
||||
{
|
||||
wxFileOutputStream stream(filename);
|
||||
if (!stream.Ok())
|
||||
return FALSE;
|
||||
|
||||
stream << wxT("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
|
||||
stream << wxT("<settings xmlns=\"http://www.wxwindows.org/wxs\" version=\"2.5.0.1\">");
|
||||
|
||||
DoSave(m_topItem, stream, 1);
|
||||
|
||||
stream << wxT("\n</settings>\n");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
inline static void OutputIndentation(wxOutputStream& stream, int indent)
|
||||
{
|
||||
wxString str = wxT("\n");
|
||||
for (int i = 0; i < indent; i++)
|
||||
str << wxT(' ') << wxT(' ');
|
||||
stream << str ;
|
||||
}
|
||||
|
||||
/// Recursive helper function for file saving
|
||||
bool ctConfigToolDoc::DoSave(ctConfigItem* item, wxOutputStream& stream, int indent)
|
||||
{
|
||||
OutputIndentation(stream, indent*2);
|
||||
|
||||
wxString name(item->GetName());
|
||||
wxString s;
|
||||
wxString typeStr;
|
||||
if (item->GetType() == ctTypeGroup)
|
||||
typeStr = wxT("group");
|
||||
else if (item->GetType() == ctTypeCheckGroup)
|
||||
typeStr = wxT("check-group");
|
||||
else if (item->GetType() == ctTypeRadioGroup)
|
||||
typeStr = wxT("radio-group");
|
||||
else if (item->GetType() == ctTypeString)
|
||||
typeStr = wxT("string");
|
||||
else if (item->GetType() == ctTypeBoolCheck)
|
||||
typeStr = wxT("bool-check");
|
||||
else if (item->GetType() == ctTypeBoolRadio)
|
||||
typeStr = wxT("bool-radio");
|
||||
else if (item->GetType() == ctTypeInteger)
|
||||
typeStr = wxT("integer");
|
||||
else
|
||||
typeStr = wxT("unknown");
|
||||
|
||||
stream << wxT("<setting type=\"") << typeStr << wxT("\">");
|
||||
|
||||
indent ++;
|
||||
|
||||
OutputIndentation(stream, indent*2);
|
||||
if (item->IsActive())
|
||||
stream << wxT("<active>1</active>");
|
||||
else
|
||||
stream << wxT("<active>0</active>");
|
||||
OutputIndentation(stream, indent*2);
|
||||
if (item->IsEnabled())
|
||||
stream << wxT("<enabled>1</enabled>");
|
||||
else
|
||||
stream << wxT("<enabled>0</enabled>");
|
||||
|
||||
// Output properties
|
||||
wxNode* node = item->GetProperties().GetList().GetFirst();
|
||||
while (node)
|
||||
{
|
||||
ctProperty* prop = (ctProperty*) node->GetData();
|
||||
OutputIndentation(stream, indent*2);
|
||||
stream << wxT("<") << prop->GetName() ;
|
||||
|
||||
if (prop->IsCustom())
|
||||
{
|
||||
stream << wxT(" custom=\"true\"");
|
||||
stream << wxT(" type=\"") << prop->GetVariant().GetType() << wxT("\"");
|
||||
stream << wxT(" editor-type=\"") << prop->GetEditorType() << wxT("\"");
|
||||
stream << wxT(" description=\"") << prop->GetDescription() << wxT("\"");
|
||||
if (prop->GetChoices().GetCount() > 0)
|
||||
{
|
||||
wxString choices;
|
||||
ctConfigItem::ArrayToString(prop->GetChoices(), choices);
|
||||
stream << wxT(" choices=\"") << choices << wxT("\"");
|
||||
}
|
||||
}
|
||||
|
||||
stream << wxT(">");
|
||||
|
||||
stream << ctEscapeHTMLCharacters(prop->GetVariant().GetString()) ;
|
||||
stream << wxT("</") << prop->GetName() << wxT(">");
|
||||
|
||||
node = node->Next();
|
||||
}
|
||||
|
||||
// Output children
|
||||
node = item->GetChildren().GetFirst();
|
||||
while (node)
|
||||
{
|
||||
ctConfigItem* child = (ctConfigItem*) node->GetData();
|
||||
DoSave(child, stream, indent);
|
||||
|
||||
node = node->Next();
|
||||
}
|
||||
|
||||
indent --;
|
||||
|
||||
OutputIndentation(stream, indent*2);
|
||||
stream << wxT("</setting>");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/// Open the settings file
|
||||
bool ctConfigToolDoc::DoOpen(const wxString& filename)
|
||||
{
|
||||
wxSimpleHtmlParser parser;
|
||||
if (parser.ParseFile(filename))
|
||||
{
|
||||
ctConfigToolHint hint(NULL, ctClear);
|
||||
UpdateAllViews (NULL, & hint);
|
||||
m_topItem = NULL;
|
||||
|
||||
if (parser.GetTopLevelTag()->GetChildren())
|
||||
{
|
||||
wxSimpleHtmlTag* settingsTag = parser.GetTopLevelTag()->GetChildren()->FindTag(wxT("settings"));
|
||||
if (settingsTag && settingsTag->GetChildren())
|
||||
{
|
||||
wxSimpleHtmlTag* firstSettingTag = settingsTag->GetChildren();
|
||||
if (firstSettingTag)
|
||||
DoOpen(firstSettingTag, NULL);
|
||||
return TRUE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static bool GetHtmlBoolValue(const wxString& value)
|
||||
{
|
||||
if (value == wxT("true") || value == wxT("TRUE") || value == wxT("1"))
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static int GetHtmlIntegerValue(const wxString& value)
|
||||
{
|
||||
return wxAtoi(value);
|
||||
}
|
||||
|
||||
static double GetHtmlDoubleValue(const wxString& value)
|
||||
{
|
||||
return wxAtof(value);
|
||||
}
|
||||
|
||||
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((bool) 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() = (bool) GetHtmlBoolValue(childTag->GetNext()->GetTagText());
|
||||
else if (prop->GetVariant().GetType() == wxT("double"))
|
||||
prop->GetVariant() = (double) GetHtmlDoubleValue(childTag->GetNext()->GetTagText());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
childTag = childTag->GetNext();
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/// Clear dependencies
|
||||
void ctConfigToolDoc::ClearDependencies(ctConfigItem* item)
|
||||
{
|
||||
if (!item)
|
||||
item = GetTopItem();
|
||||
|
||||
item->GetDependents().Clear();
|
||||
for ( wxNode* node = item->GetChildren().GetFirst(); node; node = node->GetNext() )
|
||||
{
|
||||
ctConfigItem* child = (ctConfigItem*) node->GetData();
|
||||
ClearDependencies(child);
|
||||
}
|
||||
}
|
||||
|
||||
/// Refresh dependencies
|
||||
void ctConfigToolDoc::RefreshDependencies()
|
||||
{
|
||||
ClearDependencies(GetTopItem());
|
||||
RefreshDependencies(GetTopItem());
|
||||
}
|
||||
|
||||
/// Refresh dependencies
|
||||
void ctConfigToolDoc::RefreshDependencies(ctConfigItem* item)
|
||||
{
|
||||
wxArrayString requiresArr;
|
||||
wxString requires = item->GetPropertyString(wxT("requires"));
|
||||
wxString precludes = item->GetPropertyString(wxT("precludes"));
|
||||
wxString enabledIf = item->GetPropertyString(wxT("enabled-if"));
|
||||
wxString enabledIfNot = item->GetPropertyString(wxT("enabled-if-not"));
|
||||
wxString context = item->GetPropertyString(wxT("context"));
|
||||
|
||||
if (!requires.IsEmpty())
|
||||
item->StringToArray(requires, requiresArr);
|
||||
|
||||
if (!precludes.IsEmpty())
|
||||
item->StringToArray(precludes, requiresArr);
|
||||
|
||||
if (!enabledIfNot.IsEmpty())
|
||||
item->StringToArray(enabledIfNot, requiresArr);
|
||||
|
||||
if (!enabledIf.IsEmpty())
|
||||
item->StringToArray(enabledIf, requiresArr);
|
||||
|
||||
// Add the parent to the list of dependencies, if the
|
||||
// parent is a check or radio group.
|
||||
ctConfigItem* parent = item->GetParent();
|
||||
if (parent &&
|
||||
(parent->GetType() == ctTypeCheckGroup ||
|
||||
parent->GetType() == ctTypeRadioGroup))
|
||||
requiresArr.Add(parent->GetName());
|
||||
|
||||
// Also look in 'context' since these items
|
||||
// are another kind of dependency (switching to
|
||||
// a different platform may cause the dependencies
|
||||
// to be evaluated differently).
|
||||
if (!context.IsEmpty())
|
||||
item->StringToArray(context, requiresArr);
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < requiresArr.GetCount(); i++)
|
||||
{
|
||||
wxString itemName(requiresArr[i]);
|
||||
ctConfigItem* otherItem = GetTopItem()->FindItem(itemName);
|
||||
if (otherItem && !otherItem->GetDependents().Member(item))
|
||||
{
|
||||
otherItem->GetDependents().Append(item);
|
||||
}
|
||||
}
|
||||
for ( wxNode* node = item->GetChildren().GetFirst(); node; node = node->GetNext() )
|
||||
{
|
||||
ctConfigItem* child = (ctConfigItem*) node->GetData();
|
||||
RefreshDependencies(child);
|
||||
}
|
||||
}
|
||||
|
||||
/// Generate the text of a setup.h
|
||||
wxString ctConfigToolDoc::GenerateSetup()
|
||||
{
|
||||
wxString str;
|
||||
str << wxT("/*\n * setup.h\n * Generated by wxConfigTool\n *\n */\n\n");
|
||||
|
||||
GenerateSetup(GetTopItem(), str);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/// Helper function
|
||||
void ctConfigToolDoc::GenerateSetup(ctConfigItem* item, wxString& str)
|
||||
{
|
||||
// Generate the setup.h entries for this item
|
||||
wxString name = item->GetName();
|
||||
|
||||
// We don't process the platform choice
|
||||
if (item->GetName() == wxT("Platform"))
|
||||
return;
|
||||
|
||||
if (item->IsInActiveContext() &&
|
||||
(item->GetType() == ctTypeCheckGroup ||
|
||||
item->GetType() == ctTypeRadioGroup ||
|
||||
item->GetType() == ctTypeBoolCheck ||
|
||||
item->GetType() == ctTypeBoolRadio))
|
||||
{
|
||||
// TODO: write description
|
||||
wxString name = item->GetName();
|
||||
if (name.Left(6) == wxT("wxUSE_") ||
|
||||
name == wxT("REMOVE_UNUSED_ARG") || // Hack alert: change to wxUSE_UNUSED_ARG_REMOVAL
|
||||
name.Find(wxT("COMPATIBILITY")) != wxNOT_FOUND)
|
||||
{
|
||||
str << wxT("#define ") << name ;
|
||||
if (item->IsEnabled())
|
||||
str << wxT(" 1");
|
||||
else
|
||||
str << wxT(" 0");
|
||||
str << wxT("\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
for ( wxNode* node = item->GetChildren().GetFirst(); node; node = node->GetNext() )
|
||||
{
|
||||
ctConfigItem* child = (ctConfigItem*) node->GetData();
|
||||
GenerateSetup(child, str);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Generate a configure command
|
||||
wxString ctConfigToolDoc::GenerateConfigureCommand()
|
||||
{
|
||||
wxString str;
|
||||
str << wxT("# configurewx\n# Generated by wxConfigTool\n\n");
|
||||
|
||||
wxString path = GetFrameworkDir(TRUE);
|
||||
bool makeUnix = TRUE;
|
||||
if (!path.IsEmpty())
|
||||
{
|
||||
if (makeUnix)
|
||||
path += wxT("/");
|
||||
else
|
||||
path += wxFILE_SEP_PATH ;
|
||||
}
|
||||
|
||||
str << path << wxT("configure");
|
||||
|
||||
// Find the platform option to use
|
||||
ctConfigItem* platformsFolder = GetTopItem()->FindItem(wxT("Platform"));
|
||||
if (platformsFolder)
|
||||
{
|
||||
for ( wxNode* node = platformsFolder->GetChildren().GetFirst(); node; node = node->GetNext() )
|
||||
{
|
||||
ctConfigItem* child = (ctConfigItem*) node->GetData();
|
||||
if (child->GetType() == ctTypeBoolRadio && child->IsEnabled())
|
||||
{
|
||||
wxString configureCommand = child->GetPropertyString(wxT("configure-command"));
|
||||
if (!configureCommand.IsEmpty())
|
||||
str << wxT(" ") << configureCommand;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GenerateConfigureCommand(GetTopItem(), str);
|
||||
return str;
|
||||
}
|
||||
|
||||
/// Helper function
|
||||
void ctConfigToolDoc::GenerateConfigureCommand(ctConfigItem* item, wxString& str)
|
||||
{
|
||||
// We don't process the platform group, since we've
|
||||
// already done so.
|
||||
if (item->GetName() == wxT("Platform"))
|
||||
return;
|
||||
|
||||
if (item->IsInActiveContext() &&
|
||||
(item->GetType() == ctTypeCheckGroup ||
|
||||
item->GetType() == ctTypeRadioGroup ||
|
||||
item->GetType() == ctTypeBoolCheck ||
|
||||
item->GetType() == ctTypeBoolRadio))
|
||||
{
|
||||
wxString name = item->GetName();
|
||||
wxString configureCommand = item->GetPropertyString(wxT("configure-command"));
|
||||
if (!configureCommand.IsEmpty())
|
||||
{
|
||||
if (!item->IsEnabled())
|
||||
{
|
||||
// Replace 'enable' with 'disable' if this
|
||||
// option is off.
|
||||
configureCommand.Replace(wxT("--enable-"), wxT("--disable-"));
|
||||
configureCommand.Replace(wxT("--with-"), wxT("--without-"));
|
||||
}
|
||||
ctProperty* prop = item->GetProperties().FindProperty(wxT("builtin"));
|
||||
if (prop && prop->GetVariant().GetType() == wxT("bool"))
|
||||
{
|
||||
bool builtin = prop->GetVariant().GetBool();
|
||||
str << wxT(" ") << configureCommand;
|
||||
if (builtin)
|
||||
str << wxT("=builtin");
|
||||
else
|
||||
str << wxT("=sys");
|
||||
}
|
||||
else
|
||||
{
|
||||
ctProperty* prop = item->GetProperties().FindProperty(wxT("value"));
|
||||
if (prop && prop->GetVariant().GetType() == wxT("string"))
|
||||
{
|
||||
wxString val = prop->GetVariant().GetString();
|
||||
if (item->IsEnabled() && !val.IsEmpty())
|
||||
{
|
||||
str << wxT(" ") << configureCommand;
|
||||
str << wxT("=\"") << val << wxT("\"");
|
||||
}
|
||||
// If the string is empty, ignore this parameter,
|
||||
// since it's obviously intended to be supplied
|
||||
// only if there's a string to use and it's enabled.
|
||||
}
|
||||
else
|
||||
{
|
||||
str << wxT(" ") << configureCommand;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( wxNode* node = item->GetChildren().GetFirst(); node; node = node->GetNext() )
|
||||
{
|
||||
ctConfigItem* child = (ctConfigItem*) node->GetData();
|
||||
GenerateConfigureCommand(child, str);
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets the current framework directory
|
||||
wxString ctConfigToolDoc::GetFrameworkDir(bool makeUnix)
|
||||
{
|
||||
wxString path = wxGetApp().GetSettings().m_frameworkDir;
|
||||
if (wxGetApp().GetSettings().m_useEnvironmentVariable)
|
||||
{
|
||||
// Should probably allow other variables
|
||||
// to be used, and maybe expand variables within m_frameworkDir
|
||||
path = wxGetenv(wxT("WXWIN"));
|
||||
#ifdef __WXMSW__
|
||||
if (makeUnix)
|
||||
path.Replace(wxT("\\"), wxT("/"));
|
||||
#endif
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Implements a document editing command.
|
||||
*/
|
||||
|
||||
ctConfigCommand::ctConfigCommand(const wxString& name, int cmdId,
|
||||
ctConfigItem* activeState, ctConfigItem* savedState,
|
||||
ctConfigItem* parent, ctConfigItem* insertBefore,
|
||||
bool ignoreFirstTime): wxCommand(TRUE, name)
|
||||
{
|
||||
m_activeState = activeState;
|
||||
m_savedState = savedState;
|
||||
m_ignoreThis = ignoreFirstTime;
|
||||
m_cmdId = cmdId;
|
||||
m_properties = NULL;
|
||||
m_parent = parent;
|
||||
m_insertBefore = insertBefore;
|
||||
}
|
||||
|
||||
ctConfigCommand::ctConfigCommand(const wxString& name, int cmdId,
|
||||
ctConfigItem* activeState, ctProperties* properties,
|
||||
bool ignoreFirstTime): wxCommand(TRUE, name)
|
||||
{
|
||||
m_activeState = activeState;
|
||||
m_savedState = NULL;
|
||||
m_properties = properties;
|
||||
m_ignoreThis = ignoreFirstTime;
|
||||
m_cmdId = cmdId;
|
||||
m_properties = properties;
|
||||
m_parent = NULL;
|
||||
m_insertBefore = NULL;
|
||||
}
|
||||
|
||||
ctConfigCommand::~ctConfigCommand()
|
||||
{
|
||||
if (m_savedState)
|
||||
delete m_savedState;
|
||||
if (m_properties)
|
||||
delete m_properties;
|
||||
}
|
||||
|
||||
bool ctConfigCommand::Do()
|
||||
{
|
||||
return DoAndUndo(TRUE);
|
||||
}
|
||||
|
||||
bool ctConfigCommand::Undo()
|
||||
{
|
||||
return DoAndUndo(FALSE);
|
||||
}
|
||||
|
||||
// Combine Do and Undo into one
|
||||
bool ctConfigCommand::DoAndUndo(bool doCmd)
|
||||
{
|
||||
switch (m_cmdId)
|
||||
{
|
||||
case ctCMD_CUT:
|
||||
{
|
||||
if (doCmd)
|
||||
{
|
||||
wxASSERT(m_savedState == NULL);
|
||||
wxASSERT(m_activeState != NULL);
|
||||
|
||||
ctConfigItem* newItem = m_activeState->DeepClone();
|
||||
ctConfigToolDoc* doc = m_activeState->GetDocument();
|
||||
|
||||
// This will delete the old clipboard contents, if any.
|
||||
doc->SetClipboardItem(newItem);
|
||||
|
||||
m_parent = m_activeState->GetParent();
|
||||
m_insertBefore = m_activeState->FindNextSibling();
|
||||
|
||||
m_activeState->Detach();
|
||||
m_savedState = m_activeState;
|
||||
m_activeState = NULL;
|
||||
|
||||
m_savedState->GetDocument()->Modify(TRUE);
|
||||
ctConfigToolView* view = (ctConfigToolView*) m_savedState->GetDocument()->GetFirstView();
|
||||
view->OnChangeFilename();
|
||||
}
|
||||
else
|
||||
{
|
||||
wxASSERT(m_savedState != NULL);
|
||||
wxASSERT(m_activeState == NULL);
|
||||
|
||||
m_savedState->GetDocument()->Modify(TRUE);
|
||||
m_savedState->Attach(m_parent, m_insertBefore);
|
||||
ctConfigToolView* view = (ctConfigToolView*) m_savedState->GetDocument()->GetFirstView();
|
||||
view->AddItems(wxGetApp().GetMainFrame()->GetConfigTreeCtrl(), m_savedState);
|
||||
m_activeState = m_savedState;
|
||||
m_savedState = NULL;
|
||||
m_parent = NULL;
|
||||
m_insertBefore = NULL;
|
||||
view->OnChangeFilename();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ctCMD_PASTE:
|
||||
{
|
||||
if (doCmd)
|
||||
{
|
||||
wxASSERT(m_savedState != NULL);
|
||||
wxASSERT(m_activeState == NULL);
|
||||
|
||||
m_savedState->GetDocument()->Modify(TRUE);
|
||||
m_savedState->Attach(m_parent, m_insertBefore);
|
||||
ctConfigToolView* view = (ctConfigToolView*) m_savedState->GetDocument()->GetFirstView();
|
||||
view->AddItems(wxGetApp().GetMainFrame()->GetConfigTreeCtrl(), m_savedState);
|
||||
wxGetApp().GetMainFrame()->GetConfigTreeCtrl()->SelectItem(m_savedState->GetTreeItemId());
|
||||
m_activeState = m_savedState;
|
||||
m_savedState = NULL;
|
||||
view->OnChangeFilename();
|
||||
}
|
||||
else
|
||||
{
|
||||
wxASSERT(m_savedState == NULL);
|
||||
wxASSERT(m_activeState != NULL);
|
||||
|
||||
m_activeState->GetDocument()->Modify(TRUE);
|
||||
ctConfigToolView* view = (ctConfigToolView*) m_activeState->GetDocument()->GetFirstView();
|
||||
m_activeState->Detach();
|
||||
m_savedState = m_activeState;
|
||||
m_activeState = NULL;
|
||||
view->OnChangeFilename();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ctCMD_NEW_ELEMENT:
|
||||
{
|
||||
if (doCmd)
|
||||
{
|
||||
wxASSERT(m_savedState != NULL);
|
||||
wxASSERT(m_activeState == NULL);
|
||||
|
||||
m_savedState->GetDocument()->Modify(TRUE);
|
||||
m_savedState->Attach(m_parent, m_insertBefore);
|
||||
ctConfigToolView* view = (ctConfigToolView*) m_savedState->GetDocument()->GetFirstView();
|
||||
view->AddItems(wxGetApp().GetMainFrame()->GetConfigTreeCtrl(), m_savedState);
|
||||
wxGetApp().GetMainFrame()->GetConfigTreeCtrl()->SelectItem(m_savedState->GetTreeItemId());
|
||||
|
||||
m_activeState = m_savedState;
|
||||
m_savedState = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
wxASSERT(m_savedState == NULL);
|
||||
wxASSERT(m_activeState != NULL);
|
||||
|
||||
m_activeState->GetDocument()->Modify(TRUE);
|
||||
m_activeState->Detach();
|
||||
m_savedState = m_activeState;
|
||||
m_activeState = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ctCMD_APPLY_PROPERTY:
|
||||
{
|
||||
wxASSERT(m_properties != NULL);
|
||||
wxASSERT(m_activeState != NULL);
|
||||
|
||||
// Don't update the properties editor first time
|
||||
// around since it will be done one property at a time
|
||||
// initially (and no property editor update required)
|
||||
if (!m_ignoreThis)
|
||||
{
|
||||
// Just swap the saved and current properties.
|
||||
ctProperties propsTemp = m_activeState->GetProperties() ;
|
||||
m_activeState->GetProperties() = (* m_properties);
|
||||
(* m_properties) = propsTemp;
|
||||
|
||||
// Apply only those that need applying
|
||||
// (those properties in activeState that are not in propsTemp)
|
||||
wxNode* node = m_activeState->GetProperties().GetList().GetFirst();
|
||||
while (node)
|
||||
{
|
||||
ctProperty* prop = (ctProperty*) node->GetData();
|
||||
ctProperty* otherProp = propsTemp.FindProperty(prop->GetName());
|
||||
if (otherProp && ((*prop) != (*otherProp)))
|
||||
{
|
||||
m_activeState->ApplyProperty(prop, otherProp->GetVariant());
|
||||
}
|
||||
node = node->GetNext();
|
||||
}
|
||||
m_activeState->GetDocument()->Modify(TRUE);
|
||||
ctConfigToolView* view = (ctConfigToolView*) m_activeState->GetDocument()->GetFirstView();
|
||||
if (view)
|
||||
{
|
||||
ctConfigToolHint hint(NULL, ctValueChanged);
|
||||
m_activeState->GetDocument()->UpdateAllViews (NULL, & hint);
|
||||
}
|
||||
}
|
||||
m_ignoreThis = FALSE;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user