<commit_before>// Plugins.cpp
// Copyright (c) 2009, Dan Heeks
// This program is released under the BSD license. See the file COPYING for details.

#include <sys/stat.h>
#include "stdafx.h"
#include "Plugins.h"
#include "HeeksConfig.h"

enum
{
    ID_BUTTON_ADD,
	ID_BUTTON_EDIT,
	ID_BUTTON_REMOVE,
	ID_BUTTON_PLUGIN_BROWSE,
	ID_LISTBOX_CONTROL
};

BEGIN_EVENT_TABLE( CPluginItemDialog, wxDialog )
EVT_BUTTON( ID_BUTTON_PLUGIN_BROWSE, CPluginItemDialog::OnButtonBrowse )
EVT_BUTTON( wxID_OK, CPluginItemDialog::OnButtonOK )
EVT_BUTTON( wxID_CANCEL, CPluginItemDialog::OnButtonCancel )
END_EVENT_TABLE()

CPluginItemDialog::CPluginItemDialog(wxWindow *parent, const wxString& title, PluginData& pd):wxDialog(parent, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{
	m_pd = &pd;

    m_panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);

    // create buttons
    wxButton *button1 = new wxButton(m_panel, wxID_OK);
    wxButton *button2 = new wxButton(m_panel, wxID_CANCEL);

    wxBoxSizer *mainsizer = new wxBoxSizer( wxVERTICAL );

    wxFlexGridSizer *gridsizer = new wxFlexGridSizer(3, 5, 5);
	gridsizer->Add(new wxStaticText(m_panel, wxID_ANY, _("Name")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL));
	m_name_text_ctrl = new wxTextCtrl(m_panel, wxID_ANY, pd.name);
	gridsizer->Add(m_name_text_ctrl, wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL).Expand());
	gridsizer->Add(new wxStaticText(m_panel, wxID_ANY, _T("")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL));
	gridsizer->Add(new wxStaticText(m_panel, wxID_ANY, _("File Path")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL));
	m_path_text_ctrl = new wxTextCtrl(m_panel, wxID_ANY, pd.path, wxDefaultPosition, wxSize(400, 0));
	gridsizer->Add(m_path_text_ctrl, wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL).Expand());
	wxButton* browse_button = new wxButton(m_panel, ID_BUTTON_PLUGIN_BROWSE, _T("..."));
    gridsizer->Add(browse_button, wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL));

	if(pd.hard_coded)
	{
		// don't allow editing of hard coded plugins
		m_name_text_ctrl->Enable(false);
		m_path_text_ctrl->Enable(false);
		browse_button->Enable(false);
	}

	gridsizer->AddGrowableCol(1, 1);

    wxBoxSizer *bottomsizer = new wxBoxSizer( wxHORIZONTAL );

    bottomsizer->Add( button1, 0, wxALL, 10 );
    bottomsizer->Add( button2, 0, wxALL, 10 );

    mainsizer->Add( gridsizer, wxSizerFlags().Align(wxALIGN_CENTER).Border(wxALL, 10).Expand() );
    mainsizer->Add( bottomsizer, wxSizerFlags().Align(wxALIGN_CENTER) );

    // tell frame to make use of sizer (or constraints, if any)
    m_panel->SetAutoLayout( true );
    m_panel->SetSizer( mainsizer );

#ifndef __WXWINCE__
    // don't allow frame to get smaller than what the sizers tell ye
    mainsizer->SetSizeHints( this );
#endif

    Show(true);
}

void CPluginItemDialog::OnButtonOK(wxCommandEvent& event)
{
	// it must have a name
	if(m_name_text_ctrl->GetValue().Len() == 0)
	{
		wxMessageBox(_("Plugin must have a name!"));
		m_name_text_ctrl->SetFocus();
		return;
	}

	// it must have a file path
	if(m_path_text_ctrl->GetValue().Len() == 0)
	{
		wxMessageBox(_("No file specified!"));
		m_path_text_ctrl->SetFocus();
		return;
	}

	m_pd->name = m_name_text_ctrl->GetValue();
	m_pd->path = m_path_text_ctrl->GetValue();

	EndModal(wxID_OK);
}

void CPluginItemDialog::OnButtonCancel(wxCommandEvent& event)
{
	EndModal(wxID_CANCEL);
}

void CPluginItemDialog::OnButtonBrowse(wxCommandEvent& event)
{
#ifdef WIN32
	wxString ext_str(_T("*.dll"));
#else
	wxString ext_str(_T("*.so*"));
#endif
	wxString wildcard_string = wxString(_("shared library files")) + _T(" |") + ext_str;

    wxFileDialog dialog(this, _("Choose shared library file"), wxEmptyString, wxEmptyString, wildcard_string);
    dialog.CentreOnParent();

    if (dialog.ShowModal() == wxID_OK)
    {
		m_path_text_ctrl->SetValue(dialog.GetPath());
    }
}

BEGIN_EVENT_TABLE( CPluginsDialog, wxDialog )
EVT_BUTTON( ID_BUTTON_ADD, CPluginsDialog::OnButtonAdd )
EVT_BUTTON( ID_BUTTON_EDIT, CPluginsDialog::OnButtonEdit )
EVT_UPDATE_UI(ID_BUTTON_EDIT, CPluginsDialog::OnUpdateEdit)
EVT_BUTTON( ID_BUTTON_REMOVE, CPluginsDialog::OnButtonRemove )
EVT_UPDATE_UI(ID_BUTTON_REMOVE, CPluginsDialog::OnUpdateRemove)
EVT_BUTTON( wxID_OK, CPluginsDialog::OnButtonOK )
EVT_BUTTON( wxID_CANCEL, CPluginsDialog::OnButtonCancel )
EVT_LISTBOX_DCLICK(ID_LISTBOX_CONTROL, CPluginsDialog::OnListboxDblClick)
END_EVENT_TABLE()

CPluginsDialog::CPluginsDialog(wxWindow *parent):wxDialog(parent, wxID_ANY, _("HeeksCAD plugin libraries"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{
   // make a panel with some controls
    m_panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);

	ReadPluginsList(m_plugins);

    CreateCheckListbox();

    // create buttons
    wxButton *button1 = new wxButton(m_panel, ID_BUTTON_ADD, _("New"));
    wxButton *button2 = new wxButton(m_panel, ID_BUTTON_EDIT, _("Edit"));
    wxButton *button3 = new wxButton(m_panel, ID_BUTTON_REMOVE, _("Delete"));
    wxButton *button4 = new wxButton(m_panel, wxID_OK);
    wxButton *button5 = new wxButton(m_panel, wxID_CANCEL);

    wxBoxSizer *mainsizer = new wxBoxSizer( wxVERTICAL );

    mainsizer->Add( m_pListBox, 1, wxGROW|wxALL, 10 );

    wxBoxSizer *bottomsizer = new wxBoxSizer( wxHORIZONTAL );

    bottomsizer->Add( button1, 0, wxALL, 10 );
    bottomsizer->Add( button2, 0, wxALL, 10 );
    bottomsizer->Add( button3, 0, wxALL, 10 );
    bottomsizer->Add( button4, 0, wxALL, 10 );
    bottomsizer->Add( button5, 0, wxALL, 10 );

    mainsizer->Add( bottomsizer, 0, wxCENTER );

    // tell frame to make use of sizer (or constraints, if any)
    m_panel->SetAutoLayout( true );
    m_panel->SetSizer( mainsizer );

#ifndef __WXWINCE__
    // don't allow frame to get smaller than what the sizers tell ye
    mainsizer->SetSizeHints( this );
#endif

    Show(true);
}

void ReadPluginsList(std::list<PluginData> &plugins)
{
	plugins.clear();

	HeeksConfig plugins_config;
	plugins_config.SetPath(_T("/plugins"));

	wxString key;
	long Index;
	wxString str;

	bool entry_found = false;
	bool hCncConfigured = false;  //if true, heekscnc is a plugin already. don't automatically add it in that case

	entry_found = plugins_config.GetFirstEntry(key, Index);

	while(entry_found)
	{
		plugins_config.Read(key, &str);

		PluginData pd;
		if(str[0] == '#')
		{
			str = str.Mid(1);
			pd.enabled = false;
		}
		else
		{
			pd.enabled = true;
		}

		pd.name = key;
		pd.path = str;
		plugins.push_back(pd);
		if( str.Lower().Matches(_T("*heekscnc*")) )
			hCncConfigured = true;

		entry_found = plugins_config.GetNextEntry(key, Index);
	}

	//look for heekscnc in the standard install location and automatically add it, if it isn't already configured
	if( !hCncConfigured ) {
		struct stat cncstat;
		bool foundHcncPlugin = false;
#ifdef WIN32
		//this code should work on windows given the correct path
		const char* cncPlugPath = "standard\windows\path\to\heekscnc.dll";
  #ifndef S_ISREG
  	//if this fails to compile on windows, change it to
  	//#define S_ISREG(mode) true
    #define S_ISREG(mode)  (((mode) & S_IFMT) == S_IFREG)
  #endif
#else
		const char* cncPlugPath = "/usr/lib/libheekscnc.so";  //this is the path that cmake installs the lib to
#endif
		if( stat(cncPlugPath, &cncstat) == 0 ) {
			if( S_ISREG(cncstat.st_mode) )
				foundHcncPlugin = true;
		}

		if( foundHcncPlugin ) {
			PluginData pd;
			pd.enabled = true;
			pd.hard_coded = false; //if this was true, the plugin wouldn't be added to the config - meaning the user couldn't disable it
			pd.name = _T("HeeksCNC (Automatically added)");
			pd.path = _T("/usr/lib/libheekscnc.so");
			plugins.push_back(pd);
		}
	}

	// add plugins from the command line
	std::list<wxString> command_line_plugins;
	wxGetApp().GetPluginsFromCommandLineParams(command_line_plugins);
	for(std::list<wxString>::iterator It = command_line_plugins.begin(); It != command_line_plugins.end(); It++)
	{
		PluginData pd;
		pd.enabled = true;
		pd.hard_coded = true;
		pd.name = _T("CommandLinePlugin");
		pd.path = *It;
		plugins.push_back(pd);
	}

	// add code to always start your dll here.
#ifdef MY_OWN_HARDCODED_PLUGIN
	{
		PluginData pd;
		pd.enabled = true;
		pd.hard_coded = true;
		pd.name = _T("MyPlugin");
		pd.path = _T("$(MYEXEPATH)/mypluing/PluginForHeeksCAD.dll");
		plugins.push_back(pd);
	}
#endif
}

void CPluginsDialog::CreateCheckListbox(long flags)
{
    wxString *astrChoices = new wxString[m_plugins.size()];
    unsigned int ui = 0;
	for ( std::list<PluginData>::iterator It = m_plugins.begin(); It != m_plugins.end(); It++, ui++ )
	{
		PluginData &pd = *It;
		astrChoices[ui] = pd.name;
	}

    m_pListBox = new wxCheckListBox
        (
         m_panel,               // parent
         ID_LISTBOX_CONTROL,       // control id
         wxPoint(10, 10),       // listbox poistion
         wxSize(400, 100),      // listbox size
         m_plugins.size(),		// number of strings
         astrChoices,           // array of strings
         flags
        );

    delete [] astrChoices;

    ui = 0;
	for ( std::list<PluginData>::iterator It = m_plugins.begin(); It != m_plugins.end(); It++, ui++ )
	{
		PluginData &pd = *It;
		if(pd.enabled)m_pListBox->Check(ui);
	}
}

void CPluginsDialog::EditSelected(unsigned int selection)
{
	unsigned int ui = 0;
	for ( std::list<PluginData>::iterator It = m_plugins.begin(); It != m_plugins.end(); It++, ui++ )
	{
		if(ui == selection)
		{
			PluginData &pd = *It;
			bool enabled = m_pListBox->IsChecked(ui);

			CPluginItemDialog dlg(this, _("Add New Plugin"), pd);
			if(dlg.ShowModal() == wxID_OK)
			{
				// updata the check list
				delete m_pListBox;
				CreateCheckListbox();
				m_pListBox->Check(ui, enabled);
			}
		}
	}
}

void CPluginsDialog::OnButtonAdd(wxCommandEvent& event)
{
	PluginData pd;
	CPluginItemDialog dlg(this, _("Add New Plugin"), pd);
	if(dlg.ShowModal() == wxID_OK)
	{
		// add the new item
		m_plugins.push_back(pd);

		// updata the check list
		delete m_pListBox;
		CreateCheckListbox();
	}
}

void CPluginsDialog::OnButtonEdit(wxCommandEvent& event)
{
	unsigned int selection = m_pListBox->GetSelection();

	EditSelected(selection);
}

void CPluginsDialog::OnUpdateEdit( wxUpdateUIEvent& event )
{
	event.Enable(m_pListBox->GetSelection() >= 0);
}

void CPluginsDialog::OnUpdateRemove( wxUpdateUIEvent& event )
{
	event.Enable(m_pListBox->GetSelection() >= 0);
}

void CPluginsDialog::OnButtonRemove(wxCommandEvent& event)
{
	unsigned int selection = m_pListBox->GetSelection();
	unsigned int ui = 0;
	for ( std::list<PluginData>::iterator It = m_plugins.begin(); It != m_plugins.end(); It++, ui++ )
	{
		if(ui == selection)
		{
			m_plugins.erase(It);
			// updata the check list
			delete m_pListBox;
			CreateCheckListbox();
			break;
		}
	}
}

void CPluginsDialog::OnButtonOK(wxCommandEvent& event)
{
	::wxSetWorkingDirectory(wxGetApp().GetExeFolder());

	HeeksConfig plugins_config;

	plugins_config.DeleteGroup(_T("plugins"));
	plugins_config.SetPath(_T("/plugins"));

	unsigned int ui = 0;
	for ( std::list<PluginData>::iterator It = m_plugins.begin(); It != m_plugins.end(); It++, ui++ )
	{
		PluginData &pd = *It;
		if(pd.hard_coded)continue;
		pd.enabled = m_pListBox->IsChecked(ui);
		wxString value = pd.path;
		if(!(pd.enabled))value.Prepend(_T("#"));
		plugins_config.Write(pd.name, value);
	}

	EndModal(wxID_OK);
}

void CPluginsDialog::OnButtonCancel(wxCommandEvent& event)
{
	EndModal(wxID_CANCEL);
}

void CPluginsDialog::OnListboxDblClick(wxCommandEvent& WXUNUSED(event))
{
    int selection = m_pListBox->GetSelection();

	EditSelected(selection);
}
<commit_msg>compile warning with escape characters in Windows build<commit_after>// Plugins.cpp
// Copyright (c) 2009, Dan Heeks
// This program is released under the BSD license. See the file COPYING for details.

#include <sys/stat.h>
#include "stdafx.h"
#include "Plugins.h"
#include "HeeksConfig.h"

enum
{
    ID_BUTTON_ADD,
	ID_BUTTON_EDIT,
	ID_BUTTON_REMOVE,
	ID_BUTTON_PLUGIN_BROWSE,
	ID_LISTBOX_CONTROL
};

BEGIN_EVENT_TABLE( CPluginItemDialog, wxDialog )
EVT_BUTTON( ID_BUTTON_PLUGIN_BROWSE, CPluginItemDialog::OnButtonBrowse )
EVT_BUTTON( wxID_OK, CPluginItemDialog::OnButtonOK )
EVT_BUTTON( wxID_CANCEL, CPluginItemDialog::OnButtonCancel )
END_EVENT_TABLE()

CPluginItemDialog::CPluginItemDialog(wxWindow *parent, const wxString& title, PluginData& pd):wxDialog(parent, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{
	m_pd = &pd;

    m_panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);

    // create buttons
    wxButton *button1 = new wxButton(m_panel, wxID_OK);
    wxButton *button2 = new wxButton(m_panel, wxID_CANCEL);

    wxBoxSizer *mainsizer = new wxBoxSizer( wxVERTICAL );

    wxFlexGridSizer *gridsizer = new wxFlexGridSizer(3, 5, 5);
	gridsizer->Add(new wxStaticText(m_panel, wxID_ANY, _("Name")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL));
	m_name_text_ctrl = new wxTextCtrl(m_panel, wxID_ANY, pd.name);
	gridsizer->Add(m_name_text_ctrl, wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL).Expand());
	gridsizer->Add(new wxStaticText(m_panel, wxID_ANY, _T("")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL));
	gridsizer->Add(new wxStaticText(m_panel, wxID_ANY, _("File Path")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL));
	m_path_text_ctrl = new wxTextCtrl(m_panel, wxID_ANY, pd.path, wxDefaultPosition, wxSize(400, 0));
	gridsizer->Add(m_path_text_ctrl, wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL).Expand());
	wxButton* browse_button = new wxButton(m_panel, ID_BUTTON_PLUGIN_BROWSE, _T("..."));
    gridsizer->Add(browse_button, wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL));

	if(pd.hard_coded)
	{
		// don't allow editing of hard coded plugins
		m_name_text_ctrl->Enable(false);
		m_path_text_ctrl->Enable(false);
		browse_button->Enable(false);
	}

	gridsizer->AddGrowableCol(1, 1);

    wxBoxSizer *bottomsizer = new wxBoxSizer( wxHORIZONTAL );

    bottomsizer->Add( button1, 0, wxALL, 10 );
    bottomsizer->Add( button2, 0, wxALL, 10 );

    mainsizer->Add( gridsizer, wxSizerFlags().Align(wxALIGN_CENTER).Border(wxALL, 10).Expand() );
    mainsizer->Add( bottomsizer, wxSizerFlags().Align(wxALIGN_CENTER) );

    // tell frame to make use of sizer (or constraints, if any)
    m_panel->SetAutoLayout( true );
    m_panel->SetSizer( mainsizer );

#ifndef __WXWINCE__
    // don't allow frame to get smaller than what the sizers tell ye
    mainsizer->SetSizeHints( this );
#endif

    Show(true);
}

void CPluginItemDialog::OnButtonOK(wxCommandEvent& event)
{
	// it must have a name
	if(m_name_text_ctrl->GetValue().Len() == 0)
	{
		wxMessageBox(_("Plugin must have a name!"));
		m_name_text_ctrl->SetFocus();
		return;
	}

	// it must have a file path
	if(m_path_text_ctrl->GetValue().Len() == 0)
	{
		wxMessageBox(_("No file specified!"));
		m_path_text_ctrl->SetFocus();
		return;
	}

	m_pd->name = m_name_text_ctrl->GetValue();
	m_pd->path = m_path_text_ctrl->GetValue();

	EndModal(wxID_OK);
}

void CPluginItemDialog::OnButtonCancel(wxCommandEvent& event)
{
	EndModal(wxID_CANCEL);
}

void CPluginItemDialog::OnButtonBrowse(wxCommandEvent& event)
{
#ifdef WIN32
	wxString ext_str(_T("*.dll"));
#else
	wxString ext_str(_T("*.so*"));
#endif
	wxString wildcard_string = wxString(_("shared library files")) + _T(" |") + ext_str;

    wxFileDialog dialog(this, _("Choose shared library file"), wxEmptyString, wxEmptyString, wildcard_string);
    dialog.CentreOnParent();

    if (dialog.ShowModal() == wxID_OK)
    {
		m_path_text_ctrl->SetValue(dialog.GetPath());
    }
}

BEGIN_EVENT_TABLE( CPluginsDialog, wxDialog )
EVT_BUTTON( ID_BUTTON_ADD, CPluginsDialog::OnButtonAdd )
EVT_BUTTON( ID_BUTTON_EDIT, CPluginsDialog::OnButtonEdit )
EVT_UPDATE_UI(ID_BUTTON_EDIT, CPluginsDialog::OnUpdateEdit)
EVT_BUTTON( ID_BUTTON_REMOVE, CPluginsDialog::OnButtonRemove )
EVT_UPDATE_UI(ID_BUTTON_REMOVE, CPluginsDialog::OnUpdateRemove)
EVT_BUTTON( wxID_OK, CPluginsDialog::OnButtonOK )
EVT_BUTTON( wxID_CANCEL, CPluginsDialog::OnButtonCancel )
EVT_LISTBOX_DCLICK(ID_LISTBOX_CONTROL, CPluginsDialog::OnListboxDblClick)
END_EVENT_TABLE()

CPluginsDialog::CPluginsDialog(wxWindow *parent):wxDialog(parent, wxID_ANY, _("HeeksCAD plugin libraries"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{
   // make a panel with some controls
    m_panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);

	ReadPluginsList(m_plugins);

    CreateCheckListbox();

    // create buttons
    wxButton *button1 = new wxButton(m_panel, ID_BUTTON_ADD, _("New"));
    wxButton *button2 = new wxButton(m_panel, ID_BUTTON_EDIT, _("Edit"));
    wxButton *button3 = new wxButton(m_panel, ID_BUTTON_REMOVE, _("Delete"));
    wxButton *button4 = new wxButton(m_panel, wxID_OK);
    wxButton *button5 = new wxButton(m_panel, wxID_CANCEL);

    wxBoxSizer *mainsizer = new wxBoxSizer( wxVERTICAL );

    mainsizer->Add( m_pListBox, 1, wxGROW|wxALL, 10 );

    wxBoxSizer *bottomsizer = new wxBoxSizer( wxHORIZONTAL );

    bottomsizer->Add( button1, 0, wxALL, 10 );
    bottomsizer->Add( button2, 0, wxALL, 10 );
    bottomsizer->Add( button3, 0, wxALL, 10 );
    bottomsizer->Add( button4, 0, wxALL, 10 );
    bottomsizer->Add( button5, 0, wxALL, 10 );

    mainsizer->Add( bottomsizer, 0, wxCENTER );

    // tell frame to make use of sizer (or constraints, if any)
    m_panel->SetAutoLayout( true );
    m_panel->SetSizer( mainsizer );

#ifndef __WXWINCE__
    // don't allow frame to get smaller than what the sizers tell ye
    mainsizer->SetSizeHints( this );
#endif

    Show(true);
}

void ReadPluginsList(std::list<PluginData> &plugins)
{
	plugins.clear();

	HeeksConfig plugins_config;
	plugins_config.SetPath(_T("/plugins"));

	wxString key;
	long Index;
	wxString str;

	bool entry_found = false;
	bool hCncConfigured = false;  //if true, heekscnc is a plugin already. don't automatically add it in that case

	entry_found = plugins_config.GetFirstEntry(key, Index);

	while(entry_found)
	{
		plugins_config.Read(key, &str);

		PluginData pd;
		if(str[0] == '#')
		{
			str = str.Mid(1);
			pd.enabled = false;
		}
		else
		{
			pd.enabled = true;
		}

		pd.name = key;
		pd.path = str;
		plugins.push_back(pd);
		if( str.Lower().Matches(_T("*heekscnc*")) )
			hCncConfigured = true;

		entry_found = plugins_config.GetNextEntry(key, Index);
	}

	//look for heekscnc in the standard install location and automatically add it, if it isn't already configured
	if( !hCncConfigured ) {
		struct stat cncstat;
		bool foundHcncPlugin = false;
#ifdef WIN32
		//this code should work on windows given the correct path
		const char* cncPlugPath = "standard\\windows\\path\\to\\heekscnc.dll";
  #ifndef S_ISREG
  	//if this fails to compile on windows, change it to
  	//#define S_ISREG(mode) true
    #define S_ISREG(mode)  (((mode) & S_IFMT) == S_IFREG)
  #endif
#else
		const char* cncPlugPath = "/usr/lib/libheekscnc.so";  //this is the path that cmake installs the lib to
#endif
		if( stat(cncPlugPath, &cncstat) == 0 ) {
			if( S_ISREG(cncstat.st_mode) )
				foundHcncPlugin = true;
		}

		if( foundHcncPlugin ) {
			PluginData pd;
			pd.enabled = true;
			pd.hard_coded = false; //if this was true, the plugin wouldn't be added to the config - meaning the user couldn't disable it
			pd.name = _T("HeeksCNC (Automatically added)");
			pd.path = _T("/usr/lib/libheekscnc.so");
			plugins.push_back(pd);
		}
	}

	// add plugins from the command line
	std::list<wxString> command_line_plugins;
	wxGetApp().GetPluginsFromCommandLineParams(command_line_plugins);
	for(std::list<wxString>::iterator It = command_line_plugins.begin(); It != command_line_plugins.end(); It++)
	{
		PluginData pd;
		pd.enabled = true;
		pd.hard_coded = true;
		pd.name = _T("CommandLinePlugin");
		pd.path = *It;
		plugins.push_back(pd);
	}

	// add code to always start your dll here.
#ifdef MY_OWN_HARDCODED_PLUGIN
	{
		PluginData pd;
		pd.enabled = true;
		pd.hard_coded = true;
		pd.name = _T("MyPlugin");
		pd.path = _T("$(MYEXEPATH)/mypluing/PluginForHeeksCAD.dll");
		plugins.push_back(pd);
	}
#endif
}

void CPluginsDialog::CreateCheckListbox(long flags)
{
    wxString *astrChoices = new wxString[m_plugins.size()];
    unsigned int ui = 0;
	for ( std::list<PluginData>::iterator It = m_plugins.begin(); It != m_plugins.end(); It++, ui++ )
	{
		PluginData &pd = *It;
		astrChoices[ui] = pd.name;
	}

    m_pListBox = new wxCheckListBox
        (
         m_panel,               // parent
         ID_LISTBOX_CONTROL,       // control id
         wxPoint(10, 10),       // listbox poistion
         wxSize(400, 100),      // listbox size
         m_plugins.size(),		// number of strings
         astrChoices,           // array of strings
         flags
        );

    delete [] astrChoices;

    ui = 0;
	for ( std::list<PluginData>::iterator It = m_plugins.begin(); It != m_plugins.end(); It++, ui++ )
	{
		PluginData &pd = *It;
		if(pd.enabled)m_pListBox->Check(ui);
	}
}

void CPluginsDialog::EditSelected(unsigned int selection)
{
	unsigned int ui = 0;
	for ( std::list<PluginData>::iterator It = m_plugins.begin(); It != m_plugins.end(); It++, ui++ )
	{
		if(ui == selection)
		{
			PluginData &pd = *It;
			bool enabled = m_pListBox->IsChecked(ui);

			CPluginItemDialog dlg(this, _("Add New Plugin"), pd);
			if(dlg.ShowModal() == wxID_OK)
			{
				// updata the check list
				delete m_pListBox;
				CreateCheckListbox();
				m_pListBox->Check(ui, enabled);
			}
		}
	}
}

void CPluginsDialog::OnButtonAdd(wxCommandEvent& event)
{
	PluginData pd;
	CPluginItemDialog dlg(this, _("Add New Plugin"), pd);
	if(dlg.ShowModal() == wxID_OK)
	{
		// add the new item
		m_plugins.push_back(pd);

		// updata the check list
		delete m_pListBox;
		CreateCheckListbox();
	}
}

void CPluginsDialog::OnButtonEdit(wxCommandEvent& event)
{
	unsigned int selection = m_pListBox->GetSelection();

	EditSelected(selection);
}

void CPluginsDialog::OnUpdateEdit( wxUpdateUIEvent& event )
{
	event.Enable(m_pListBox->GetSelection() >= 0);
}

void CPluginsDialog::OnUpdateRemove( wxUpdateUIEvent& event )
{
	event.Enable(m_pListBox->GetSelection() >= 0);
}

void CPluginsDialog::OnButtonRemove(wxCommandEvent& event)
{
	unsigned int selection = m_pListBox->GetSelection();
	unsigned int ui = 0;
	for ( std::list<PluginData>::iterator It = m_plugins.begin(); It != m_plugins.end(); It++, ui++ )
	{
		if(ui == selection)
		{
			m_plugins.erase(It);
			// updata the check list
			delete m_pListBox;
			CreateCheckListbox();
			break;
		}
	}
}

void CPluginsDialog::OnButtonOK(wxCommandEvent& event)
{
	::wxSetWorkingDirectory(wxGetApp().GetExeFolder());

	HeeksConfig plugins_config;

	plugins_config.DeleteGroup(_T("plugins"));
	plugins_config.SetPath(_T("/plugins"));

	unsigned int ui = 0;
	for ( std::list<PluginData>::iterator It = m_plugins.begin(); It != m_plugins.end(); It++, ui++ )
	{
		PluginData &pd = *It;
		if(pd.hard_coded)continue;
		pd.enabled = m_pListBox->IsChecked(ui);
		wxString value = pd.path;
		if(!(pd.enabled))value.Prepend(_T("#"));
		plugins_config.Write(pd.name, value);
	}

	EndModal(wxID_OK);
}

void CPluginsDialog::OnButtonCancel(wxCommandEvent& event)
{
	EndModal(wxID_CANCEL);
}

void CPluginsDialog::OnListboxDblClick(wxCommandEvent& WXUNUSED(event))
{
    int selection = m_pListBox->GetSelection();

	EditSelected(selection);
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: marktree.cxx,v $
 *
 *  $Revision: 1.16 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 07:02:01 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_dbaccess.hxx"

#ifndef _DBAUI_MARKTREE_HXX_
#include "marktree.hxx"
#endif
#ifndef _DBAUI_MODULE_DBU_HXX_
#include "moduledbu.hxx"
#endif
#ifndef _DBU_CONTROL_HRC_
#include "dbu_control.hrc"
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif

//.........................................................................
namespace dbaui
{
    using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
//.........................................................................
#define SPACEBETWEENENTRIES     4
//========================================================================
//= OMarkableTreeListBox
//========================================================================
DBG_NAME(OMarkableTreeListBox)
//------------------------------------------------------------------------
OMarkableTreeListBox::OMarkableTreeListBox( Window* pParent, const Reference< XMultiServiceFactory >& _rxORB, WinBits nWinStyle )
    : DBTreeListBox(pParent,_rxORB,nWinStyle)
{
    DBG_CTOR(OMarkableTreeListBox,NULL);

    InitButtonData();
}
//------------------------------------------------------------------------
OMarkableTreeListBox::OMarkableTreeListBox( Window* pParent, const Reference< XMultiServiceFactory >& _rxORB, const ResId& rResId)
    : DBTreeListBox(pParent,_rxORB,rResId)
{
    DBG_CTOR(OMarkableTreeListBox,NULL);

    InitButtonData();
}
//------------------------------------------------------------------------
OMarkableTreeListBox::~OMarkableTreeListBox()
{
    delete m_pCheckButton;

    DBG_DTOR(OMarkableTreeListBox,NULL);
}
//------------------------------------------------------------------------
void OMarkableTreeListBox::Paint(const Rectangle& _rRect)
{
    if (!IsEnabled())
    {
        Font aOldFont = GetFont();
        Font aNewFont(aOldFont);

        StyleSettings aSystemStyle = Application::GetSettings().GetStyleSettings();
        aNewFont.SetColor(aSystemStyle.GetDisableColor());

        SetFont(aNewFont);
        DBTreeListBox::Paint(_rRect);
        SetFont(aOldFont);
    }
    else
        DBTreeListBox::Paint(_rRect);
}
//------------------------------------------------------------------------
void OMarkableTreeListBox::InitButtonData()
{
    m_pCheckButton = new SvLBoxButtonData( this );
    EnableCheckButton( m_pCheckButton );
}
//------------------------------------------------------------------------
void OMarkableTreeListBox::KeyInput( const KeyEvent& rKEvt )
{
    // nur wenn space
    if (rKEvt.GetKeyCode().GetCode() == KEY_SPACE && !rKEvt.GetKeyCode().IsShift() && !rKEvt.GetKeyCode().IsMod1())
    {
        SvLBoxEntry* pCurrentHandlerEntry = GetHdlEntry();
        if(pCurrentHandlerEntry)
        {
            SvButtonState eState = GetCheckButtonState( pCurrentHandlerEntry);
            if(eState == SV_BUTTON_CHECKED)
                SetCheckButtonState( pCurrentHandlerEntry, SV_BUTTON_UNCHECKED);
            else
                SetCheckButtonState( pCurrentHandlerEntry, SV_BUTTON_CHECKED);

            CheckButtonHdl();
        }
        else
            DBTreeListBox::KeyInput(rKEvt);
    }
    else
        DBTreeListBox::KeyInput(rKEvt);

}
//------------------------------------------------------------------------
SvButtonState OMarkableTreeListBox::implDetermineState(SvLBoxEntry* _pEntry)
{
    SvButtonState eState = GetCheckButtonState(_pEntry);
    if (!GetModel()->HasChilds(_pEntry))
        // nothing to do in this bottom-up routine if there are no children ...
        return eState;
#ifdef DBG_UTIL
    String sEntryText  =GetEntryText(_pEntry);
#endif

    // loop through the children and check their states
    sal_uInt16 nCheckedChildren = 0;
    sal_uInt16 nChildrenOverall = 0;

    SvLBoxEntry* pChildLoop = GetModel()->FirstChild(_pEntry);
    while (pChildLoop)
    {
#ifdef DBG_UTIL
        String sChildText  =GetEntryText(pChildLoop);
#endif
        SvButtonState eChildState = implDetermineState(pChildLoop);
        if (SV_BUTTON_TRISTATE == eChildState)
            break;

        if (SV_BUTTON_CHECKED == eChildState)
            ++nCheckedChildren;
        ++nChildrenOverall;

        pChildLoop = GetModel()->NextSibling(pChildLoop);
    }

    if (pChildLoop)
    {
        // we did not finish the loop because at least one of the children is in tristate
        eState = SV_BUTTON_TRISTATE;

        // but this means that we did not finish all the siblings of pChildLoop, so their checking may be
        // incorrect at the moment
        // -> correct this
        // 88485 - 20.06.2001 - frank.schoenheit@sun.com
        while (pChildLoop)
        {
            implDetermineState(pChildLoop);
            pChildLoop = GetModel()->NextSibling(pChildLoop);
        }
    }
    else
        // none if the children is in tristate
        if (nCheckedChildren)
            // we have at least one chil checked
            if (nCheckedChildren != nChildrenOverall)
                // not all children are checked
                eState = SV_BUTTON_TRISTATE;
            else
                // all children are checked
                eState = SV_BUTTON_CHECKED;
        else
            // no children are checked
            eState = SV_BUTTON_UNCHECKED;

    // finally set the entry to the state we just determined
    SetCheckButtonState(_pEntry, eState);

    // outta here
    return eState;
}

//------------------------------------------------------------------------
void OMarkableTreeListBox::CheckButtons()
{
    SvLBoxEntry* pEntry = GetModel()->First();
    while (pEntry)
    {
        implDetermineState(pEntry);
        pEntry = GetModel()->NextSibling(pEntry);
    }

#if 0
    // Plausibilit"atspr"ufung
    SvButtonState eState;
    SvLBoxEntry* pEntry = GetModel()->First();
    while(pEntry)
    {
        if(!GetModel()->HasChilds(pEntry))
        {
            sal_uInt16 nCheck=0;
            sal_uInt16 nCount=0;
            SvLBoxEntry* pChildEntry = pEntry;
            while(pChildEntry)
            {
                if(GetCheckButtonState(pChildEntry) == SV_BUTTON_CHECKED)
                    nCheck++;
                nCount++;
                pChildEntry = GetModel()->NextSibling(pChildEntry);
            }

            if(nCheck && nCount != nCheck)
                eState = SV_BUTTON_TRISTATE;
            else if(nCheck)
                eState = SV_BUTTON_CHECKED;
            else
                eState = SV_BUTTON_UNCHECKED;

            SvLBoxEntry* pSchema = GetModel()->GetParent(pEntry);
            if(pSchema)
            {
                pEntry = GetModel()->NextSibling(pSchema);
                SetCheckButtonState(pSchema, eState);
            }
            else
                pEntry = NULL; // wenn kein Schema dann sind bereits alle pEntry's durchlaufen worden
        }
        else
            pEntry = GetModel()->Next(pEntry);
    }

    SvLBoxEntry* pCatalog = GetModel()->First();
    SvLBoxEntry* pSchema = NULL;
    if(GetModel()->HasChilds(pCatalog) && GetModel()->HasChilds(pSchema = GetModel()->Next(pCatalog)))
    {
        sal_uInt16 nCheck   =0;
        sal_uInt16 nTri     =0;
        sal_uInt16 nCount   =0;
        while(pSchema)
        {
            if((eState = GetCheckButtonState(pSchema)) == SV_BUTTON_TRISTATE)
                break;

            if(eState == SV_BUTTON_CHECKED)
                nCheck++;
            nCount++;
            pSchema = GetModel()->NextSibling(pSchema);
        }

        if(eState != SV_BUTTON_TRISTATE)
        {
            if(nCheck && nCount == nCheck)
                eState = SV_BUTTON_CHECKED;
            else if(nCheck)
                eState = SV_BUTTON_TRISTATE;
            else
                eState = SV_BUTTON_UNCHECKED;
        }
        SetCheckButtonState( pCatalog,eState);
    }
#endif
}
//------------------------------------------------------------------------
void OMarkableTreeListBox::CheckButtonHdl()
{
    checkedButton_noBroadcast(GetHdlEntry());
    if (m_aCheckButtonHandler.IsSet())
        m_aCheckButtonHandler.Call(this);
}

//------------------------------------------------------------------------
void OMarkableTreeListBox::checkedButton_noBroadcast(SvLBoxEntry* _pEntry)
{
    SvButtonState eState = GetCheckButtonState( _pEntry);
    if (GetModel()->HasChilds(_pEntry)) // Falls Kinder, dann diese auch checken
    {
        SvLBoxEntry* pChildEntry = GetModel()->Next(_pEntry);
        SvLBoxEntry* pSiblingEntry = GetModel()->NextSibling(_pEntry);
        while(pChildEntry && pChildEntry != pSiblingEntry)
        {
            SetCheckButtonState(pChildEntry, eState);
            pChildEntry = GetModel()->Next(pChildEntry);
        }
    }

    SvLBoxEntry* pEntry = IsSelected(_pEntry) ? FirstSelected() : NULL;
    while(pEntry)
    {
        SetCheckButtonState(pEntry,eState);
        if(GetModel()->HasChilds(pEntry))   // Falls Kinder, dann diese auch checken
        {
            SvLBoxEntry* pChildEntry = GetModel()->Next(pEntry);
            SvLBoxEntry* pSiblingEntry = GetModel()->NextSibling(pEntry);
            while(pChildEntry && pChildEntry != pSiblingEntry)
            {
                SetCheckButtonState(pChildEntry,eState);
                pChildEntry = GetModel()->Next(pChildEntry);
            }
        }
        pEntry = NextSelected(pEntry);
    }
    CheckButtons();
}

//------------------------------------------------------------------------
//.........................................................................
}   // namespace dbaui
//.........................................................................

<commit_msg>INTEGRATION: CWS hsqlcsvstage1 (1.16.2); FILE MERGED 2006/09/20 11:43:57 fs 1.16.2.1: #i69696#, being stage 1 of issue #i69526#: merging changes from CWS hsqlcsv herein<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: marktree.cxx,v $
 *
 *  $Revision: 1.17 $
 *
 *  last change: $Author: kz $ $Date: 2006-10-05 13:03:15 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_dbaccess.hxx"

#ifndef _DBAUI_MARKTREE_HXX_
#include "marktree.hxx"
#endif
#ifndef _DBAUI_MODULE_DBU_HXX_
#include "moduledbu.hxx"
#endif
#ifndef _DBU_CONTROL_HRC_
#include "dbu_control.hrc"
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif

//.........................................................................
namespace dbaui
{
    using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
//.........................................................................
#define SPACEBETWEENENTRIES     4
//========================================================================
//= OMarkableTreeListBox
//========================================================================
DBG_NAME(OMarkableTreeListBox)
//------------------------------------------------------------------------
OMarkableTreeListBox::OMarkableTreeListBox( Window* pParent, const Reference< XMultiServiceFactory >& _rxORB, WinBits nWinStyle )
    : DBTreeListBox(pParent,_rxORB,nWinStyle)
{
    DBG_CTOR(OMarkableTreeListBox,NULL);

    InitButtonData();
}
//------------------------------------------------------------------------
OMarkableTreeListBox::OMarkableTreeListBox( Window* pParent, const Reference< XMultiServiceFactory >& _rxORB, const ResId& rResId)
    : DBTreeListBox(pParent,_rxORB,rResId)
{
    DBG_CTOR(OMarkableTreeListBox,NULL);

    InitButtonData();
}
//------------------------------------------------------------------------
OMarkableTreeListBox::~OMarkableTreeListBox()
{
    delete m_pCheckButton;

    DBG_DTOR(OMarkableTreeListBox,NULL);
}
//------------------------------------------------------------------------
void OMarkableTreeListBox::Paint(const Rectangle& _rRect)
{
    if (!IsEnabled())
    {
        Font aOldFont = GetFont();
        Font aNewFont(aOldFont);

        StyleSettings aSystemStyle = Application::GetSettings().GetStyleSettings();
        aNewFont.SetColor(aSystemStyle.GetDisableColor());

        SetFont(aNewFont);
        DBTreeListBox::Paint(_rRect);
        SetFont(aOldFont);
    }
    else
        DBTreeListBox::Paint(_rRect);
}
//------------------------------------------------------------------------
void OMarkableTreeListBox::InitButtonData()
{
    m_pCheckButton = new SvLBoxButtonData( this );
    EnableCheckButton( m_pCheckButton );
}
//------------------------------------------------------------------------
void OMarkableTreeListBox::KeyInput( const KeyEvent& rKEvt )
{
    // nur wenn space
    if (rKEvt.GetKeyCode().GetCode() == KEY_SPACE && !rKEvt.GetKeyCode().IsShift() && !rKEvt.GetKeyCode().IsMod1())
    {
        SvLBoxEntry* pCurrentHandlerEntry = GetHdlEntry();
        if(pCurrentHandlerEntry)
        {
            SvButtonState eState = GetCheckButtonState( pCurrentHandlerEntry);
            if(eState == SV_BUTTON_CHECKED)
                SetCheckButtonState( pCurrentHandlerEntry, SV_BUTTON_UNCHECKED);
            else
                SetCheckButtonState( pCurrentHandlerEntry, SV_BUTTON_CHECKED);

            CheckButtonHdl();
        }
        else
            DBTreeListBox::KeyInput(rKEvt);
    }
    else
        DBTreeListBox::KeyInput(rKEvt);

}
//------------------------------------------------------------------------
SvButtonState OMarkableTreeListBox::implDetermineState(SvLBoxEntry* _pEntry)
{
    SvButtonState eState = GetCheckButtonState(_pEntry);
    if (!GetModel()->HasChilds(_pEntry))
        // nothing to do in this bottom-up routine if there are no children ...
        return eState;
#ifdef DBG_UTIL
    String sEntryText  =GetEntryText(_pEntry);
#endif

    // loop through the children and check their states
    sal_uInt16 nCheckedChildren = 0;
    sal_uInt16 nChildrenOverall = 0;

    SvLBoxEntry* pChildLoop = GetModel()->FirstChild(_pEntry);
    while (pChildLoop)
    {
#ifdef DBG_UTIL
        String sChildText  =GetEntryText(pChildLoop);
#endif
        SvButtonState eChildState = implDetermineState(pChildLoop);
        if (SV_BUTTON_TRISTATE == eChildState)
            break;

        if (SV_BUTTON_CHECKED == eChildState)
            ++nCheckedChildren;
        ++nChildrenOverall;

        pChildLoop = GetModel()->NextSibling(pChildLoop);
    }

    if (pChildLoop)
    {
        // we did not finish the loop because at least one of the children is in tristate
        eState = SV_BUTTON_TRISTATE;

        // but this means that we did not finish all the siblings of pChildLoop, so their checking may be
        // incorrect at the moment
        // -> correct this
        // 88485 - 20.06.2001 - frank.schoenheit@sun.com
        while (pChildLoop)
        {
            implDetermineState(pChildLoop);
            pChildLoop = GetModel()->NextSibling(pChildLoop);
        }
    }
    else
        // none if the children is in tristate
        if (nCheckedChildren)
            // we have at least one chil checked
            if (nCheckedChildren != nChildrenOverall)
                // not all children are checked
                eState = SV_BUTTON_TRISTATE;
            else
                // all children are checked
                eState = SV_BUTTON_CHECKED;
        else
            // no children are checked
            eState = SV_BUTTON_UNCHECKED;

    // finally set the entry to the state we just determined
    SetCheckButtonState(_pEntry, eState);

    // outta here
    return eState;
}

//------------------------------------------------------------------------
void OMarkableTreeListBox::CheckButtons()
{
    SvLBoxEntry* pEntry = GetModel()->First();
    while (pEntry)
    {
        implDetermineState(pEntry);
        pEntry = GetModel()->NextSibling(pEntry);
    }
}
//------------------------------------------------------------------------
void OMarkableTreeListBox::CheckButtonHdl()
{
    checkedButton_noBroadcast(GetHdlEntry());
    if (m_aCheckButtonHandler.IsSet())
        m_aCheckButtonHandler.Call(this);
}

//------------------------------------------------------------------------
void OMarkableTreeListBox::checkedButton_noBroadcast(SvLBoxEntry* _pEntry)
{
    SvButtonState eState = GetCheckButtonState( _pEntry);
    if (GetModel()->HasChilds(_pEntry)) // Falls Kinder, dann diese auch checken
    {
        SvLBoxEntry* pChildEntry = GetModel()->Next(_pEntry);
        SvLBoxEntry* pSiblingEntry = GetModel()->NextSibling(_pEntry);
        while(pChildEntry && pChildEntry != pSiblingEntry)
        {
            SetCheckButtonState(pChildEntry, eState);
            pChildEntry = GetModel()->Next(pChildEntry);
        }
    }

    SvLBoxEntry* pEntry = IsSelected(_pEntry) ? FirstSelected() : NULL;
    while(pEntry)
    {
        SetCheckButtonState(pEntry,eState);
        if(GetModel()->HasChilds(pEntry))   // Falls Kinder, dann diese auch checken
        {
            SvLBoxEntry* pChildEntry = GetModel()->Next(pEntry);
            SvLBoxEntry* pSiblingEntry = GetModel()->NextSibling(pEntry);
            while(pChildEntry && pChildEntry != pSiblingEntry)
            {
                SetCheckButtonState(pChildEntry,eState);
                pChildEntry = GetModel()->Next(pChildEntry);
            }
        }
        pEntry = NextSelected(pEntry);
    }
    CheckButtons();
}

//------------------------------------------------------------------------
//.........................................................................
}   // namespace dbaui
//.........................................................................

<|endoftext|>


<commit_before>// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2017 Oslo and Akershus University College of Applied Sciences
// and Alfred Bratterud
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef NET_IP4_CIDR_HPP
#define NET_IP4_CIDR_HPP

#include "addr.hpp"

namespace net {
namespace ip4 {

class Cidr {
public:

  /**
   * @brief      Constructor
   *
   * Create an IPv4 cidr object to represent the cidr <address/mask>,
   * f.ex. 10.0.0.0/24
   *
   * @param[in]  address  IPv4 address
   * @param[in]  mask     A number between 0 and 32, representing the number
   *                        of leading 1 bits in the netmask, f.ex.:
   *                        32 represents the netmask 255.255.255.255
   *                        24 represents the netmask 255.255.255.0
   */
  constexpr Cidr(const Addr address, const uint8_t mask) noexcept
  : from_{calc_from(address, mask)}, to_{calc_to(address, mask)}
  {
    Expects(mask >= 0 and mask <= 32);
  }

  /**
   * @brief      Constructor
   *
   * Create an IPv4 cidr object to represent the cidr <p1.p2.p3.p4/mask>
   *
   * @param[in]  p1    The first part of the IPv4 cidr
   * @param[in]  p2    The second part of the IPv4 cidr
   * @param[in]  p3    The third part of the IPv4 cidr
   * @param[in]  p4    The fourth part of the IPv4 cidr
   * @param[in]  mask  A number between 0 and 32, representing the number
   *                    of leading 1 bits in the netmask, f.ex.:
   *                    32 represents the netmask 255.255.255.255
   *                    24 represents the netmask 255.255.255.0
   */
  constexpr Cidr(const uint8_t p1, const uint8_t p2, const uint8_t p3, const uint8_t p4,
    const uint8_t mask) noexcept
  : Cidr{{p1,p2,p3,p4}, mask}
  {}

  bool contains(Addr ip) const noexcept {
    return ip >= from_ and ip <= to_;
  }

  Addr from() const noexcept {
    return from_;
  }

  Addr to() const noexcept {
    return to_;
  }

private:
  constexpr Addr calc_from(const Addr address, const uint8_t mask) {
    const uint32_t ip_mask = net::ntohl((0xFFFFFFFFUL << (32 - mask)) & 0xFFFFFFFFUL);
    return {address.whole & ip_mask};
  }

  constexpr Addr calc_to(const Addr address, const uint8_t mask) {
    const uint32_t ip_mask = net::ntohl((0xFFFFFFFFUL << (32 - mask)) & 0xFFFFFFFFUL);
    const uint32_t from_ip = address.whole & ip_mask;
    return {from_ip | ~ip_mask};
  }

  const Addr from_; // network address
  const Addr to_;   // broadcast address
}; //< class Cidr

} //< namespace ip4
} //< namespace net

#endif
<commit_msg>IPv4 Cidr: Constructor taking string as parameter created<commit_after>// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2017 Oslo and Akershus University College of Applied Sciences
// and Alfred Bratterud
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef NET_IP4_CIDR_HPP
#define NET_IP4_CIDR_HPP

#include "addr.hpp"

namespace net {
namespace ip4 {

/**
 * This type is thrown when creating an instance of Cidr
 * with a std::string that doesn't represent a valid IPv4
 * cidr
 */
struct Invalid_cidr : public std::runtime_error {
  using runtime_error::runtime_error;
}; //< struct Invalid_cidr

class Cidr {
public:

  /**
   * @brief      Constructor
   *
   * Create an IPv4 cidr object to represent the cidr <address/mask>,
   * f.ex. 10.0.0.0/24
   *
   * @param[in]  address  IPv4 address
   * @param[in]  mask     A number between 0 and 32, representing the number
   *                        of leading 1 bits in the netmask, f.ex.:
   *                        32 represents the netmask 255.255.255.255
   *                        24 represents the netmask 255.255.255.0
   */
  constexpr Cidr(const Addr address, const uint8_t mask) noexcept
  : from_{calc_from(address, mask)}, to_{calc_to(address, mask)}
  {
    Expects(mask >= 0 and mask <= 32);
  }

  /**
   * @brief      Constructor
   *
   * Create an IPv4 cidr object to represent the cidr <p1.p2.p3.p4/mask>
   *
   * @param[in]  p1    The first part of the IPv4 cidr
   * @param[in]  p2    The second part of the IPv4 cidr
   * @param[in]  p3    The third part of the IPv4 cidr
   * @param[in]  p4    The fourth part of the IPv4 cidr
   * @param[in]  mask  A number between 0 and 32, representing the number
   *                    of leading 1 bits in the netmask, f.ex.:
   *                    32 represents the netmask 255.255.255.255
   *                    24 represents the netmask 255.255.255.0
   */
  constexpr Cidr(const uint8_t p1, const uint8_t p2, const uint8_t p3, const uint8_t p4,
    const uint8_t mask) noexcept
  : Cidr{{p1,p2,p3,p4}, mask}
  {}

  /**
   * @brief      Constructor
   *
   * Create an IPv4 cidr object to represent the cidr
   *
   * @param[in]  cidr  The cidr, f.ex. "10.0.0.0/24" ("10.0.0.5/24" is f.ex. also valid)
   */
  Cidr(const std::string& cidr)
  : Cidr{get_addr(cidr), get_mask(cidr)}
  {}

  bool contains(Addr ip) const noexcept {
    return ip >= from_ and ip <= to_;
  }

  Addr from() const noexcept {
    return from_;
  }

  Addr to() const noexcept {
    return to_;
  }

private:
  constexpr Addr calc_from(const Addr address, const uint8_t mask) {
    const uint32_t ip_mask = ntohl((0xFFFFFFFFUL << (32 - mask)) & 0xFFFFFFFFUL);
    return {address.whole & ip_mask};
  }

  constexpr Addr calc_to(const Addr address, const uint8_t mask) {
    const uint32_t ip_mask = ntohl((0xFFFFFFFFUL << (32 - mask)) & 0xFFFFFFFFUL);
    return {(address.whole & ip_mask) | ~ip_mask};
  }

  Addr get_addr(const std::string& cidr) {
    return {cidr.substr(0, cidr.find("/"))};
  }

  uint8_t get_mask(const std::string& cidr) {
    const size_t found = cidr.find('/');

    if (UNLIKELY(found == std::string::npos))
      throw Invalid_cidr("Missing slash in " + cidr);
    if (UNLIKELY(found >= cidr.length() - 1))
      throw Invalid_cidr("Missing mask after slash in " + cidr);

    const char* mask = cidr.substr(found + 1).c_str(); // Getting past the '/'
    int val = 0;
    while (*mask) {
      Expects(std::isdigit((int) *mask));
      val = (val * 10) + (*mask++ - '0');
    }
    Expects(val >= 0 and val <= 32);
    return (uint8_t) val;
  }

  const Addr from_; // network address
  const Addr to_;   // broadcast address
}; //< class Cidr

} //< namespace ip4
} //< namespace net

#endif
<|endoftext|>


<commit_before>// Program.cpp

#include "stdafx.h"
#include "Program.h"
#include "PythonStuff.h"
#include "tinyxml/tinyxml.h"
#include "ProgramCanvas.h"
#include "NCCode.h"
#include "interface/MarkedObject.h"
#include "interface/PropertyString.h"
#include "interface/PropertyChoice.h"
#include "interface/Tool.h"
#include "Profile.h"
#include "Pocket.h"
#include "ZigZag.h"
#include "Adaptive.h"
#include "Op.h"
#include "CNCConfig.h"

bool COperations::CanAdd(HeeksObj* object)
{
	return object->GetType() == ProfileType || object->GetType() == PocketType || object->GetType() == ZigZagType || object->GetType() == AdaptiveType;
}

void COperations::WriteXML(TiXmlNode *root)
{
	TiXmlElement * element;
	element = new TiXmlElement( "Operations" );
	root->LinkEndChild( element );
	WriteBaseXML(element);
}

//static
HeeksObj* COperations::ReadFromXMLElement(TiXmlElement* pElem)
{
	COperations* new_object = new COperations;
	new_object->ReadBaseXML(pElem);
	return new_object;
}

static COperations* object_for_tools = NULL;

class SetAllActive: public Tool{
	// Tool's virtual functions
	const wxChar* GetTitle(){return _("Set All Operations Active");}
	void Run()
	{
		for(HeeksObj* object = object_for_tools->GetFirstChild(); object; object = object_for_tools->GetNextChild())
		{
			if(COp::IsAnOperation(object->GetType()))
			{
				((COp*)object)->m_active = true;
				heeksCAD->WasModified(object);
			}
		}
	}
	wxString BitmapPath(){ return _T("setactive");}
};

static SetAllActive set_all_active;

class SetAllInactive: public Tool{
	// Tool's virtual functions
	const wxChar* GetTitle(){return _("Set All Operations Inactive");}
	void Run()
	{
		for(HeeksObj* object = object_for_tools->GetFirstChild(); object; object = object_for_tools->GetNextChild())
		{
			if(COp::IsAnOperation(object->GetType()))
			{
				((COp*)object)->m_active = false;
				heeksCAD->WasModified(object);
			}
		}
	}
	wxString BitmapPath(){ return _T("setinactive");}
};

static SetAllInactive set_all_inactive;

void COperations::GetTools(std::list<Tool*>* t_list, const wxPoint* p)
{
	object_for_tools = this;
	t_list->push_back(&set_all_active);
	t_list->push_back(&set_all_inactive);

	ObjList::GetTools(t_list, p);
}

CProgram::CProgram():m_nc_code(NULL), m_operations(NULL), m_script_edited(false)
{
	CNCConfig config;
	config.Read(_T("ProgramMachine"), &m_machine, _T("nc.iso"));
#ifdef WIN32
	config.Read(_T("ProgramOutputFile"), &m_output_file, _T("test.tap"));
#else
	config.Read(_T("ProgramOutputFile"), &m_output_file, _T("/tmp/test.tap"));
#endif
	config.Read(_T("ProgramUnits"), &m_units, 1.0);
}

HeeksObj *CProgram::MakeACopy(void)const
{
	return new CProgram(*this);
}

void CProgram::CopyFrom(const HeeksObj* object)
{
	operator=(*((CProgram*)object));
}

static void on_set_machine(const wxChar* value, HeeksObj* object)
{
	((CProgram*)object)->m_machine = value;
	CNCConfig config;
	config.Write(_T("ProgramMachine"), ((CProgram*)object)->m_machine);
}

static void on_set_output_file(const wxChar* value, HeeksObj* object)
{
	((CProgram*)object)->m_output_file = value;
	CNCConfig config;
	config.Write(_T("ProgramOutputFile"), ((CProgram*)object)->m_output_file);
}

static void on_set_units(int value, HeeksObj* object)
{
	((CProgram*)object)->m_units = (value == 0) ? 1.0:25.4;
	CNCConfig config;
	config.Write(_T("ProgramUnits"), ((CProgram*)object)->m_units);

	// also change HeeksCAD's view units automatically
	heeksCAD->SetViewUnits(((CProgram*)object)->m_units, true);
}

void CProgram::GetProperties(std::list<Property *> *list)
{
	list->push_back(new PropertyString(_("machine"), m_machine, this, on_set_machine));
	list->push_back(new PropertyString(_("output file"), m_output_file, this, on_set_output_file));
	{
		std::list< wxString > choices;
		choices.push_back ( wxString ( _("mm") ) );
		choices.push_back ( wxString ( _("inch") ) );
		int choice = 0;
		if(m_units > 25.0)choice = 1;
		list->push_back ( new PropertyChoice ( _("units"),  choices, choice, this, on_set_units ) );
	}
	HeeksObj::GetProperties(list);
}

bool CProgram::CanAdd(HeeksObj* object)
{
	return object->GetType() == NCCodeType || object->GetType() == OperationsType;
}

bool CProgram::CanAddTo(HeeksObj* owner)
{
	return owner->GetType() == DocumentType;
}

void CProgram::SetClickMarkPoint(MarkedObject* marked_object, const double* ray_start, const double* ray_direction)
{
	if(marked_object->m_map.size() > 0)
	{
		MarkedObject* sub_marked_object = marked_object->m_map.begin()->second;
		if(sub_marked_object)
		{
			HeeksObj* object = sub_marked_object->m_map.begin()->first;
			if(object && object->GetType() == NCCodeType)
			{
				((CNCCode*)object)->SetClickMarkPoint(sub_marked_object, ray_start, ray_direction);
			}
		}
	}
}

void CProgram::WriteXML(TiXmlNode *root)
{
	TiXmlElement * element;
	element = new TiXmlElement( "Program" );
	root->LinkEndChild( element );
	element->SetAttribute("machine", Ttc(m_machine.c_str()));
	element->SetAttribute("output_file", Ttc(m_output_file.c_str()));
	element->SetAttribute("program", Ttc(theApp.m_program_canvas->m_textCtrl->GetValue()));
	element->SetDoubleAttribute("units", m_units);

	WriteBaseXML(element);
}

bool CProgram::Add(HeeksObj* object, HeeksObj* prev_object)
{
	if(object->GetType() == NCCodeType)m_nc_code = (CNCCode*)object;
	if(object->GetType() == OperationsType)m_operations = (COperations*)object;
	return ObjList::Add(object, prev_object);
}

void CProgram::Remove(HeeksObj* object)
{
	 // these shouldn't happen, though
	if(object == m_nc_code)m_nc_code = NULL;
	else if(object == m_operations)m_operations = NULL;

	ObjList::Remove(object);
}

// static member function
HeeksObj* CProgram::ReadFromXMLElement(TiXmlElement* pElem)
{
	CProgram* new_object = new CProgram;

	// get the attributes
	for(TiXmlAttribute* a = pElem->FirstAttribute(); a; a = a->Next())
	{
		std::string name(a->Name());
		if(name == "machine"){new_object->m_machine.assign(Ctt(a->Value()));}
		else if(name == "output_file"){new_object->m_output_file.assign(Ctt(a->Value()));}
		else if(name == "program"){theApp.m_program_canvas->m_textCtrl->SetValue(Ctt(a->Value()));}
		else if(name == "units"){new_object->m_units = a->DoubleValue();}
	}

	new_object->ReadBaseXML(pElem);
	theApp.m_program = new_object;

	return new_object;
}

void CProgram::RewritePythonProgram()
{
	theApp.m_program_canvas->m_textCtrl->Clear();
	CZigZag::number_for_stl_file = 1;
	CAdaptive::number_for_stl_file = 1;

	bool profile_op_exists = false;
	bool pocket_op_exists = false;
	bool zigzag_op_exists = false;
	bool adaptive_op_exists = false;
	for(HeeksObj* object = m_operations->GetFirstChild(); object; object = m_operations->GetNextChild())
	{
		if(object->GetType() == ProfileType)
		{
			if(((CProfile*)object)->m_active)profile_op_exists = true;
		}
		else if(object->GetType() == PocketType)
		{
			if(((CPocket*)object)->m_active)pocket_op_exists = true;
		}
		else if(object->GetType() == ZigZagType)
		{
			if(((CZigZag*)object)->m_active)zigzag_op_exists = true;
		}
		else if(object->GetType() == AdaptiveType)
		{
			if(((CAdaptive*)object)->m_active)adaptive_op_exists = true;
		}
	}

	// add standard stuff at the top
	//hackhack, make it work on unix with FHS
#ifndef WIN32
	theApp.m_program_canvas->AppendText(_T("import sys\n"));
	theApp.m_program_canvas->AppendText(_T("sys.path.insert(0,'/usr/lib/heekscnc/')\n"));
#endif
	// kurve related things
	if(profile_op_exists)
	{
		theApp.m_program_canvas->AppendText(_T("import kurve\n"));
		theApp.m_program_canvas->AppendText(_T("import kurve_funcs\n"));
	}

	// area related things
	if(pocket_op_exists)
	{
		theApp.m_program_canvas->AppendText(_T("import area\n"));
		if(fabs(m_units - 1.0) > 0.00000001)
		{
			theApp.m_program_canvas->AppendText(_T("area.set_units("));
			theApp.m_program_canvas->AppendText(m_units);
			theApp.m_program_canvas->AppendText(_T(")\n"));
		}
		theApp.m_program_canvas->AppendText(_T("import area_funcs\n"));
	}

	// pycam stuff
	if(zigzag_op_exists)
	{
#ifdef WIN32
		theApp.m_program_canvas->AppendText(_T("import sys\n"));
#endif
		theApp.m_program_canvas->AppendText(_T("sys.path.insert(0,'PyCam/trunk')\n"));
		theApp.m_program_canvas->AppendText(_T("\n"));
		theApp.m_program_canvas->AppendText(_T("from pycam.Geometry import *\n"));
		theApp.m_program_canvas->AppendText(_T("from pycam.Cutters.SphericalCutter import *\n"));
		theApp.m_program_canvas->AppendText(_T("from pycam.Cutters.CylindricalCutter import *\n"));
		theApp.m_program_canvas->AppendText(_T("from pycam.Cutters.ToroidalCutter import *\n"));
		theApp.m_program_canvas->AppendText(_T("from pycam.Importers.STLImporter import ImportModel\n"));
		theApp.m_program_canvas->AppendText(_T("from pycam.PathGenerators.DropCutter import DropCutter\n"));
		theApp.m_program_canvas->AppendText(_T("from PyCamToHeeks import HeeksCNCExporter\n"));
		theApp.m_program_canvas->AppendText(_T("\n"));
	}

	// actp
	if(adaptive_op_exists)
	{
		theApp.m_program_canvas->AppendText(_T("import actp_funcs\n"));
		theApp.m_program_canvas->AppendText(_T("import actp\n"));
		theApp.m_program_canvas->AppendText(_T("\n"));
	}

	// machine general stuff
	theApp.m_program_canvas->AppendText(_T("from nc.nc import *\n"));

	// specific machine
	theApp.m_program_canvas->AppendText(_T("import ") + m_machine + _T("\n"));
	theApp.m_program_canvas->AppendText(_T("\n"));

	// output file
	theApp.m_program_canvas->AppendText(_T("output('") + m_output_file + _T("')\n"));

	// begin program
	//theApp.m_program_canvas->AppendText(_T("program_begin(123, 'Test program')\n"));
	theApp.m_program_canvas->AppendText(_T("absolute()\n"));
	if(m_units > 25.0)
	{
		theApp.m_program_canvas->AppendText(_T("imperial()\n"));
	}
	else
	{
		theApp.m_program_canvas->AppendText(_T("metric()\n"));
	}
	theApp.m_program_canvas->AppendText(_T("set_plane(0)\n"));
	theApp.m_program_canvas->AppendText(_T("\n"));

	// write the operations
	for(HeeksObj* object = m_operations->GetFirstChild(); object; object = m_operations->GetNextChild())
	{
		switch(object->GetType())
		{
		case ProfileType:
			if(((CProfile*)object)->m_active)((CProfile*)object)->AppendTextToProgram();
			break;
		case PocketType:
			if(((CPocket*)object)->m_active)((CPocket*)object)->AppendTextToProgram();
			break;
		case ZigZagType:
			if(((CZigZag*)object)->m_active)((CZigZag*)object)->AppendTextToProgram();
			break;
		case AdaptiveType:
			if(((CAdaptive*)object)->m_active)((CAdaptive*)object)->AppendTextToProgram();
			break;
		}
	}
}

ProgramUserType CProgram::GetUserType()
{
	if(m_nc_code->m_user_edited)return ProgramUserTypeNC;
	if(m_script_edited)return ProgramUserTypeScript;
	if(m_operations->GetFirstChild())return ProgramUserTypeTree;
	return ProgramUserTypeUnkown;
}

void CProgram::UpdateFromUserType()
{
#if 0
	switch(GetUserType())
	{
	case ProgramUserTypeUnkown:

	case tree:
   Enable "Operations" icon in tree
     editing the tree, recreates the python script
   Read only "Program" window
     pressing "Post-process" creates the NC code ( and backplots it )
   Read only "Output" window
   Disable all buttons on "Output" window

	}
#endif
}
<commit_msg>always write area.set_units<commit_after>// Program.cpp

#include "stdafx.h"
#include "Program.h"
#include "PythonStuff.h"
#include "tinyxml/tinyxml.h"
#include "ProgramCanvas.h"
#include "NCCode.h"
#include "interface/MarkedObject.h"
#include "interface/PropertyString.h"
#include "interface/PropertyChoice.h"
#include "interface/Tool.h"
#include "Profile.h"
#include "Pocket.h"
#include "ZigZag.h"
#include "Adaptive.h"
#include "Op.h"
#include "CNCConfig.h"

bool COperations::CanAdd(HeeksObj* object)
{
	return object->GetType() == ProfileType || object->GetType() == PocketType || object->GetType() == ZigZagType || object->GetType() == AdaptiveType;
}

void COperations::WriteXML(TiXmlNode *root)
{
	TiXmlElement * element;
	element = new TiXmlElement( "Operations" );
	root->LinkEndChild( element );
	WriteBaseXML(element);
}

//static
HeeksObj* COperations::ReadFromXMLElement(TiXmlElement* pElem)
{
	COperations* new_object = new COperations;
	new_object->ReadBaseXML(pElem);
	return new_object;
}

static COperations* object_for_tools = NULL;

class SetAllActive: public Tool{
	// Tool's virtual functions
	const wxChar* GetTitle(){return _("Set All Operations Active");}
	void Run()
	{
		for(HeeksObj* object = object_for_tools->GetFirstChild(); object; object = object_for_tools->GetNextChild())
		{
			if(COp::IsAnOperation(object->GetType()))
			{
				((COp*)object)->m_active = true;
				heeksCAD->WasModified(object);
			}
		}
	}
	wxString BitmapPath(){ return _T("setactive");}
};

static SetAllActive set_all_active;

class SetAllInactive: public Tool{
	// Tool's virtual functions
	const wxChar* GetTitle(){return _("Set All Operations Inactive");}
	void Run()
	{
		for(HeeksObj* object = object_for_tools->GetFirstChild(); object; object = object_for_tools->GetNextChild())
		{
			if(COp::IsAnOperation(object->GetType()))
			{
				((COp*)object)->m_active = false;
				heeksCAD->WasModified(object);
			}
		}
	}
	wxString BitmapPath(){ return _T("setinactive");}
};

static SetAllInactive set_all_inactive;

void COperations::GetTools(std::list<Tool*>* t_list, const wxPoint* p)
{
	object_for_tools = this;
	t_list->push_back(&set_all_active);
	t_list->push_back(&set_all_inactive);

	ObjList::GetTools(t_list, p);
}

CProgram::CProgram():m_nc_code(NULL), m_operations(NULL), m_script_edited(false)
{
	CNCConfig config;
	config.Read(_T("ProgramMachine"), &m_machine, _T("nc.iso"));
#ifdef WIN32
	config.Read(_T("ProgramOutputFile"), &m_output_file, _T("test.tap"));
#else
	config.Read(_T("ProgramOutputFile"), &m_output_file, _T("/tmp/test.tap"));
#endif
	config.Read(_T("ProgramUnits"), &m_units, 1.0);
}

HeeksObj *CProgram::MakeACopy(void)const
{
	return new CProgram(*this);
}

void CProgram::CopyFrom(const HeeksObj* object)
{
	operator=(*((CProgram*)object));
}

static void on_set_machine(const wxChar* value, HeeksObj* object)
{
	((CProgram*)object)->m_machine = value;
	CNCConfig config;
	config.Write(_T("ProgramMachine"), ((CProgram*)object)->m_machine);
}

static void on_set_output_file(const wxChar* value, HeeksObj* object)
{
	((CProgram*)object)->m_output_file = value;
	CNCConfig config;
	config.Write(_T("ProgramOutputFile"), ((CProgram*)object)->m_output_file);
}

static void on_set_units(int value, HeeksObj* object)
{
	((CProgram*)object)->m_units = (value == 0) ? 1.0:25.4;
	CNCConfig config;
	config.Write(_T("ProgramUnits"), ((CProgram*)object)->m_units);

	// also change HeeksCAD's view units automatically
	heeksCAD->SetViewUnits(((CProgram*)object)->m_units, true);
}

void CProgram::GetProperties(std::list<Property *> *list)
{
	list->push_back(new PropertyString(_("machine"), m_machine, this, on_set_machine));
	list->push_back(new PropertyString(_("output file"), m_output_file, this, on_set_output_file));
	{
		std::list< wxString > choices;
		choices.push_back ( wxString ( _("mm") ) );
		choices.push_back ( wxString ( _("inch") ) );
		int choice = 0;
		if(m_units > 25.0)choice = 1;
		list->push_back ( new PropertyChoice ( _("units"),  choices, choice, this, on_set_units ) );
	}
	HeeksObj::GetProperties(list);
}

bool CProgram::CanAdd(HeeksObj* object)
{
	return object->GetType() == NCCodeType || object->GetType() == OperationsType;
}

bool CProgram::CanAddTo(HeeksObj* owner)
{
	return owner->GetType() == DocumentType;
}

void CProgram::SetClickMarkPoint(MarkedObject* marked_object, const double* ray_start, const double* ray_direction)
{
	if(marked_object->m_map.size() > 0)
	{
		MarkedObject* sub_marked_object = marked_object->m_map.begin()->second;
		if(sub_marked_object)
		{
			HeeksObj* object = sub_marked_object->m_map.begin()->first;
			if(object && object->GetType() == NCCodeType)
			{
				((CNCCode*)object)->SetClickMarkPoint(sub_marked_object, ray_start, ray_direction);
			}
		}
	}
}

void CProgram::WriteXML(TiXmlNode *root)
{
	TiXmlElement * element;
	element = new TiXmlElement( "Program" );
	root->LinkEndChild( element );
	element->SetAttribute("machine", Ttc(m_machine.c_str()));
	element->SetAttribute("output_file", Ttc(m_output_file.c_str()));
	element->SetAttribute("program", Ttc(theApp.m_program_canvas->m_textCtrl->GetValue()));
	element->SetDoubleAttribute("units", m_units);

	WriteBaseXML(element);
}

bool CProgram::Add(HeeksObj* object, HeeksObj* prev_object)
{
	if(object->GetType() == NCCodeType)m_nc_code = (CNCCode*)object;
	if(object->GetType() == OperationsType)m_operations = (COperations*)object;
	return ObjList::Add(object, prev_object);
}

void CProgram::Remove(HeeksObj* object)
{
	 // these shouldn't happen, though
	if(object == m_nc_code)m_nc_code = NULL;
	else if(object == m_operations)m_operations = NULL;

	ObjList::Remove(object);
}

// static member function
HeeksObj* CProgram::ReadFromXMLElement(TiXmlElement* pElem)
{
	CProgram* new_object = new CProgram;

	// get the attributes
	for(TiXmlAttribute* a = pElem->FirstAttribute(); a; a = a->Next())
	{
		std::string name(a->Name());
		if(name == "machine"){new_object->m_machine.assign(Ctt(a->Value()));}
		else if(name == "output_file"){new_object->m_output_file.assign(Ctt(a->Value()));}
		else if(name == "program"){theApp.m_program_canvas->m_textCtrl->SetValue(Ctt(a->Value()));}
		else if(name == "units"){new_object->m_units = a->DoubleValue();}
	}

	new_object->ReadBaseXML(pElem);
	theApp.m_program = new_object;

	return new_object;
}

void CProgram::RewritePythonProgram()
{
	theApp.m_program_canvas->m_textCtrl->Clear();
	CZigZag::number_for_stl_file = 1;
	CAdaptive::number_for_stl_file = 1;

	bool profile_op_exists = false;
	bool pocket_op_exists = false;
	bool zigzag_op_exists = false;
	bool adaptive_op_exists = false;
	for(HeeksObj* object = m_operations->GetFirstChild(); object; object = m_operations->GetNextChild())
	{
		if(object->GetType() == ProfileType)
		{
			if(((CProfile*)object)->m_active)profile_op_exists = true;
		}
		else if(object->GetType() == PocketType)
		{
			if(((CPocket*)object)->m_active)pocket_op_exists = true;
		}
		else if(object->GetType() == ZigZagType)
		{
			if(((CZigZag*)object)->m_active)zigzag_op_exists = true;
		}
		else if(object->GetType() == AdaptiveType)
		{
			if(((CAdaptive*)object)->m_active)adaptive_op_exists = true;
		}
	}

	// add standard stuff at the top
	//hackhack, make it work on unix with FHS
#ifndef WIN32
	theApp.m_program_canvas->AppendText(_T("import sys\n"));
	theApp.m_program_canvas->AppendText(_T("sys.path.insert(0,'/usr/lib/heekscnc/')\n"));
#endif
	// kurve related things
	if(profile_op_exists)
	{
		theApp.m_program_canvas->AppendText(_T("import kurve\n"));
		theApp.m_program_canvas->AppendText(_T("import kurve_funcs\n"));
	}

	// area related things
	if(pocket_op_exists)
	{
		theApp.m_program_canvas->AppendText(_T("import area\n"));
		theApp.m_program_canvas->AppendText(_T("area.set_units("));
		theApp.m_program_canvas->AppendText(m_units);
		theApp.m_program_canvas->AppendText(_T(")\n"));
		theApp.m_program_canvas->AppendText(_T("import area_funcs\n"));
	}

	// pycam stuff
	if(zigzag_op_exists)
	{
#ifdef WIN32
		theApp.m_program_canvas->AppendText(_T("import sys\n"));
#endif
		theApp.m_program_canvas->AppendText(_T("sys.path.insert(0,'PyCam/trunk')\n"));
		theApp.m_program_canvas->AppendText(_T("\n"));
		theApp.m_program_canvas->AppendText(_T("from pycam.Geometry import *\n"));
		theApp.m_program_canvas->AppendText(_T("from pycam.Cutters.SphericalCutter import *\n"));
		theApp.m_program_canvas->AppendText(_T("from pycam.Cutters.CylindricalCutter import *\n"));
		theApp.m_program_canvas->AppendText(_T("from pycam.Cutters.ToroidalCutter import *\n"));
		theApp.m_program_canvas->AppendText(_T("from pycam.Importers.STLImporter import ImportModel\n"));
		theApp.m_program_canvas->AppendText(_T("from pycam.PathGenerators.DropCutter import DropCutter\n"));
		theApp.m_program_canvas->AppendText(_T("from PyCamToHeeks import HeeksCNCExporter\n"));
		theApp.m_program_canvas->AppendText(_T("\n"));
	}

	// actp
	if(adaptive_op_exists)
	{
		theApp.m_program_canvas->AppendText(_T("import actp_funcs\n"));
		theApp.m_program_canvas->AppendText(_T("import actp\n"));
		theApp.m_program_canvas->AppendText(_T("\n"));
	}

	// machine general stuff
	theApp.m_program_canvas->AppendText(_T("from nc.nc import *\n"));

	// specific machine
	theApp.m_program_canvas->AppendText(_T("import ") + m_machine + _T("\n"));
	theApp.m_program_canvas->AppendText(_T("\n"));

	// output file
	theApp.m_program_canvas->AppendText(_T("output('") + m_output_file + _T("')\n"));

	// begin program
	//theApp.m_program_canvas->AppendText(_T("program_begin(123, 'Test program')\n"));
	theApp.m_program_canvas->AppendText(_T("absolute()\n"));
	if(m_units > 25.0)
	{
		theApp.m_program_canvas->AppendText(_T("imperial()\n"));
	}
	else
	{
		theApp.m_program_canvas->AppendText(_T("metric()\n"));
	}
	theApp.m_program_canvas->AppendText(_T("set_plane(0)\n"));
	theApp.m_program_canvas->AppendText(_T("\n"));

	// write the operations
	for(HeeksObj* object = m_operations->GetFirstChild(); object; object = m_operations->GetNextChild())
	{
		switch(object->GetType())
		{
		case ProfileType:
			if(((CProfile*)object)->m_active)((CProfile*)object)->AppendTextToProgram();
			break;
		case PocketType:
			if(((CPocket*)object)->m_active)((CPocket*)object)->AppendTextToProgram();
			break;
		case ZigZagType:
			if(((CZigZag*)object)->m_active)((CZigZag*)object)->AppendTextToProgram();
			break;
		case AdaptiveType:
			if(((CAdaptive*)object)->m_active)((CAdaptive*)object)->AppendTextToProgram();
			break;
		}
	}
}

ProgramUserType CProgram::GetUserType()
{
	if(m_nc_code->m_user_edited)return ProgramUserTypeNC;
	if(m_script_edited)return ProgramUserTypeScript;
	if(m_operations->GetFirstChild())return ProgramUserTypeTree;
	return ProgramUserTypeUnkown;
}

void CProgram::UpdateFromUserType()
{
#if 0
	switch(GetUserType())
	{
	case ProgramUserTypeUnkown:

	case tree:
   Enable "Operations" icon in tree
     editing the tree, recreates the python script
   Read only "Program" window
     pressing "Post-process" creates the NC code ( and backplots it )
   Read only "Output" window
   Disable all buttons on "Output" window

	}
#endif
}
<|endoftext|>


<commit_before>///////////////////////////////////////////////////////////////////////////////
//
// File Monodomain.cpp
//
// For more information, please see: http://www.nektar.info
//
// The MIT License
//
// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
// Department of Aeronautics, Imperial College London (UK), and Scientific
// Computing and Imaging Institute, University of Utah (USA).
//
// License for the specific language governing rights and limitations under
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// Description: Monodomain cardiac electrophysiology homogenised model.
//
///////////////////////////////////////////////////////////////////////////////

#include <iostream>

#include <CardiacEPSolver/EquationSystems/Monodomain.h>
#include <CardiacEPSolver/Filters/FilterCheckpointCellModel.h>

namespace Nektar
{
    /**
     * @class Monodomain
     *
     * Base model of cardiac electrophysiology of the form
     * \f{align*}{
     *     \frac{\partial u}{\partial t} = \nabla^2 u + J_{ion},
     * \f}
     * where the reaction term, \f$J_{ion}\f$ is defined by a specific cell
     * model.
     *
     * This implementation, at present, treats the reaction terms explicitly
     * and the diffusive element implicitly.
     */

    /**
     * Registers the class with the Factory.
     */
    string Monodomain::className
            = GetEquationSystemFactory().RegisterCreatorFunction(
                "Monodomain",
                Monodomain::create,
                "Monodomain model of cardiac electrophysiology.");

    /**
     *
     */
    Monodomain::Monodomain(
            const LibUtilities::SessionReaderSharedPtr& pSession)
        : UnsteadySystem(pSession)
    {
    }

    /**
     *
     */
    void Monodomain::v_InitObject()
    {
        UnsteadySystem::v_InitObject();

        m_session->LoadParameter("Chi",        m_chi);
        m_session->LoadParameter("Cm",         m_capMembrane);

        std::string vCellModel;
        m_session->LoadSolverInfo("CELLMODEL", vCellModel, "");

        ASSERTL0(vCellModel != "", "Cell Model not specified.");

        m_cell = GetCellModelFactory().CreateInstance(
                                        vCellModel, m_session, m_fields[0]);

        m_intVariables.push_back(0);

        // Load variable coefficients
        StdRegions::VarCoeffType varCoeffEnum[3] = {
                StdRegions::eVarCoeffD00,
                StdRegions::eVarCoeffD11,
                StdRegions::eVarCoeffD22
        };
        std::string varName = "intensity";
        std::string aniso_var[3] = {
                "fx", "fy", "fz"
        };
        int nq = m_fields[0]->GetNpoints();
        Array<OneD, NekDouble> vTemp;

        // Allocate storage for variable coeffs and initialize to 1.
        for (int i = 0; i < m_spacedim; ++i)
        {
            m_vardiff[varCoeffEnum[i]] = Array<OneD, NekDouble>(nq, 1.0);
        }

        // Apply fibre map f \in [0,1], scale to conductivity range
        // [o_min,o_max], specified by the session parameters o_min and o_max
        if (m_session->DefinesFunction("AnisotropicConductivity"))
        {
            if (m_session->DefinesCmdLineArgument("verbose"))
            {
                cout << "Loading Anisotropic Fibre map." << endl;
            }

            NekDouble o_min = m_session->GetParameter("o_min");
            NekDouble o_max = m_session->GetParameter("o_max");

            for (int i = 0; i < m_spacedim; ++i)
            {
                ASSERTL0(m_session->DefinesFunction("AnisotropicConductivity",
                                                    aniso_var[i]),
                         "Function 'AnisotropicConductivity' not correctly "
                         "defined.");
                EvaluateFunction(aniso_var[i], vTemp,
                                 "AnisotropicConductivity");
                Vmath::Smul(nq, o_max-o_min, vTemp, 1,
                                m_vardiff[varCoeffEnum[i]], 1);
                Vmath::Sadd(nq, o_min, m_vardiff[varCoeffEnum[i]], 1,
                                       m_vardiff[varCoeffEnum[i]], 1);
            }
        }

        // Scale by scar map (range 0->1) derived from intensity map
        // (range d_min -> d_max)
        if (m_session->DefinesFunction("IsotropicConductivity"))
        {
            if (m_session->DefinesCmdLineArgument("verbose"))
            {
                cout << "Loading Isotropic Conductivity map." << endl;
            }

            NekDouble f_min = m_session->GetParameter("d_min");
            NekDouble f_max = m_session->GetParameter("d_max");

            EvaluateFunction(varName, vTemp, "IsotropicConductivity");

            // Threshold based on d_min, d_max
            for (int j = 0; j < nq; ++j)
            {
                vTemp[j] = (vTemp[j] < f_min ? f_min : vTemp[j]);
                vTemp[j] = (vTemp[j] > f_max ? f_max : vTemp[j]);
            }

            // Rescale to s \in [0,1] (0 maps to d_max, 1 maps to d_min)
            Vmath::Sadd(nq, -f_min, vTemp, 1, vTemp, 1);
            Vmath::Smul(nq, -1.0/(f_max-f_min), vTemp, 1, vTemp, 1);
            Vmath::Sadd(nq, 1.0, vTemp, 1, vTemp, 1);

            // Scale anisotropic conductivity values
            for (int i = 0; i < m_spacedim; ++i)
            {
                Vmath::Vmul(nq, vTemp, 1,
                                m_vardiff[varCoeffEnum[i]], 1,
                                m_vardiff[varCoeffEnum[i]], 1);
            }
        }

        // Write out conductivity values
        for (int i = 0; i < m_spacedim; ++i)
        {
            // Transform variable coefficient and write out to file.
            m_fields[0]->FwdTrans_IterPerExp(m_vardiff[varCoeffEnum[i]],
                                             m_fields[0]->UpdateCoeffs());
            std::stringstream filename;
            filename << "Conductivity_" << aniso_var[i];
            if (m_comm->GetSize() > 1)
            {
                filename << "_P" << m_comm->GetRank();
            }
            filename << ".fld";
            WriteFld(filename.str());
        }

        // Search through the loaded filters and pass the cell model to any
        // CheckpointCellModel filters loaded.
        int k = 0;
        const LibUtilities::FilterMap& f = m_session->GetFilters();
        LibUtilities::FilterMap::const_iterator x;
        for (x = f.begin(); x != f.end(); ++x, ++k)
        {
            if (x->first == "CheckpointCellModel")
            {
                boost::shared_ptr<FilterCheckpointCellModel> c
                    = boost::dynamic_pointer_cast<FilterCheckpointCellModel>(
                                                                m_filters[k]);
                c->SetCellModel(m_cell);
            }
        }

        // Load stimuli
        m_stimulus = Stimulus::LoadStimuli(m_session, m_fields[0]);

        if (!m_explicitDiffusion)
        {
            m_ode.DefineImplicitSolve (&Monodomain::DoImplicitSolve, this);
        }
        m_ode.DefineOdeRhs(&Monodomain::DoOdeRhs, this);
    }

    /**
     *
     */
    Monodomain::~Monodomain()
    {

    }

    /**
     * @param   inarray         Input array.
     * @param   outarray        Output array.
     * @param   time            Current simulation time.
     * @param   lambda          Timestep.
     */
    void Monodomain::DoImplicitSolve(
            const Array<OneD, const Array<OneD, NekDouble> >&inarray,
                  Array<OneD, Array<OneD, NekDouble> >&outarray,
            const NekDouble time,
            const NekDouble lambda)
    {
        int nvariables  = inarray.num_elements();
        int nq          = m_fields[0]->GetNpoints();
        StdRegions::ConstFactorMap factors;
        // lambda = \Delta t
        factors[StdRegions::eFactorLambda] = 1.0/lambda*m_chi*m_capMembrane;

        // We solve ( \nabla^2 - HHlambda ) Y[i] = rhs [i]
        // inarray = input: \hat{rhs} -> output: \hat{Y}
        // outarray = output: nabla^2 \hat{Y}
        // where \hat = modal coeffs
        for (int i = 0; i < nvariables; ++i)
        {
            // Multiply 1.0/timestep
            Vmath::Smul(nq, -factors[StdRegions::eFactorLambda], inarray[i], 1,
                                            m_fields[i]->UpdatePhys(), 1);

            // Solve a system of equations with Helmholtz solver and transform
            // back into physical space.
            m_fields[i]->HelmSolve(m_fields[i]->GetPhys(),
                                   m_fields[i]->UpdateCoeffs(), NullFlagList,
                                   factors, m_vardiff);

            m_fields[i]->BwdTrans( m_fields[i]->GetCoeffs(),
                                   m_fields[i]->UpdatePhys());
            m_fields[i]->SetPhysState(true);

            // Copy the solution vector (required as m_fields must be set).
            outarray[i] = m_fields[i]->GetPhys();
        }
    }

    /**
     *
     */
    void Monodomain::DoOdeRhs(
            const Array<OneD, const  Array<OneD, NekDouble> >&inarray,
                  Array<OneD,        Array<OneD, NekDouble> >&outarray,
            const NekDouble time)
    {
        // Compute I_ion
        m_cell->TimeIntegrate(inarray, outarray, time);

        // Compute I_stim
        for (unsigned int i = 0; i < m_stimulus.size(); ++i)
        {
            m_stimulus[i]->Update(outarray, time);
        }
    }

    /**
     *
     */
    void Monodomain::v_SetInitialConditions(NekDouble initialtime,
                        bool dumpInitialConditions)
    {
        EquationSystem::v_SetInitialConditions(initialtime,
                                               dumpInitialConditions);
        m_cell->Initialise();
    }

    /**
     *
     */
    void Monodomain::v_PrintSummary(std::ostream &out)
    {
        UnsteadySystem::v_PrintSummary(out);
        if (m_session->DefinesFunction("d00") &&
            m_session->GetFunctionType("d00", "intensity")
                    == LibUtilities::eFunctionTypeExpression)
        {
            out << "\tDiffusivity-x   : "
                << m_session->GetFunction("d00", "intensity")->GetExpression()
                << endl;
        }
        if (m_session->DefinesFunction("d11") &&
            m_session->GetFunctionType("d11", "intensity")
                    == LibUtilities::eFunctionTypeExpression)
        {
            out << "\tDiffusivity-x   : "
                << m_session->GetFunction("d11", "intensity")->GetExpression()
                << endl;
        }
        if (m_session->DefinesFunction("d22") &&
            m_session->GetFunctionType("d22", "intensity")
                    == LibUtilities::eFunctionTypeExpression)
        {
            out << "\tDiffusivity-x   : "
                << m_session->GetFunction("d22", "intensity")->GetExpression()
                << endl;
        }
        m_cell->PrintSummary(out);
    }
}
<commit_msg>Added off-diagonal terms in diffusion tensor.<commit_after>///////////////////////////////////////////////////////////////////////////////
//
// File Monodomain.cpp
//
// For more information, please see: http://www.nektar.info
//
// The MIT License
//
// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
// Department of Aeronautics, Imperial College London (UK), and Scientific
// Computing and Imaging Institute, University of Utah (USA).
//
// License for the specific language governing rights and limitations under
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// Description: Monodomain cardiac electrophysiology homogenised model.
//
///////////////////////////////////////////////////////////////////////////////

#include <iostream>

#include <CardiacEPSolver/EquationSystems/Monodomain.h>
#include <CardiacEPSolver/Filters/FilterCheckpointCellModel.h>

namespace Nektar
{
    /**
     * @class Monodomain
     *
     * Base model of cardiac electrophysiology of the form
     * \f{align*}{
     *     \frac{\partial u}{\partial t} = \nabla^2 u + J_{ion},
     * \f}
     * where the reaction term, \f$J_{ion}\f$ is defined by a specific cell
     * model.
     *
     * This implementation, at present, treats the reaction terms explicitly
     * and the diffusive element implicitly.
     */

    /**
     * Registers the class with the Factory.
     */
    string Monodomain::className
            = GetEquationSystemFactory().RegisterCreatorFunction(
                "Monodomain",
                Monodomain::create,
                "Monodomain model of cardiac electrophysiology.");

    /**
     *
     */
    Monodomain::Monodomain(
            const LibUtilities::SessionReaderSharedPtr& pSession)
        : UnsteadySystem(pSession)
    {
    }

    /**
     *
     */
    void Monodomain::v_InitObject()
    {
        UnsteadySystem::v_InitObject();

        m_session->LoadParameter("Chi",        m_chi);
        m_session->LoadParameter("Cm",         m_capMembrane);

        std::string vCellModel;
        m_session->LoadSolverInfo("CELLMODEL", vCellModel, "");

        ASSERTL0(vCellModel != "", "Cell Model not specified.");

        m_cell = GetCellModelFactory().CreateInstance(
                                        vCellModel, m_session, m_fields[0]);

        m_intVariables.push_back(0);

        // Load variable coefficients
        StdRegions::VarCoeffType varCoeffEnum[6] = {
                StdRegions::eVarCoeffD00,
                StdRegions::eVarCoeffD01,
                StdRegions::eVarCoeffD11,
                StdRegions::eVarCoeffD02,
                StdRegions::eVarCoeffD12,
                StdRegions::eVarCoeffD22
        };
        std::string varName = "intensity";
        std::string aniso_var[3] = {
                "fx", "fy", "fz"
        };
        int nq = m_fields[0]->GetNpoints();
        Array<OneD, NekDouble> vTemp;
        Array<OneD, NekDouble> vTemp_i;
        Array<OneD, NekDouble> vTemp_j;

        // Allocate storage for variable coeffs and initialize to 1.
        for (int i = 0; i < m_spacedim*(m_spacedim+1)/2; ++i)
        {
            m_vardiff[varCoeffEnum[i]] = Array<OneD, NekDouble>(nq, 1.0);
        }

        // Apply fibre map f \in [0,1], scale to conductivity range
        // [o_min,o_max], specified by the session parameters o_min and o_max
        if (m_session->DefinesFunction("AnisotropicConductivity"))
        {
            if (m_session->DefinesCmdLineArgument("verbose"))
            {
                cout << "Loading Anisotropic Fibre map." << endl;
            }

            NekDouble o_min = m_session->GetParameter("o_min");
            NekDouble o_max = m_session->GetParameter("o_max");

            int k = 0;

            /*
             * Diffusivity matrix is upper triangular and defined as
             *    d_00   d_01  d_02
             *           d_11  d_12
             *                 d_22
             *
             * Given a principle fibre direction _f_ the diffusivity is given
             * by
             *    d_ij = { D_2 + (D_1 - D_2) f_i f_j   if i==j
             *           {       (D_1 - D_2) f_i f_j   if i!=j
             *
             * The vector _f_ is given in terms of the variables fx,fy,fz in the
             * function AnisotropicConductivity. The values of D_1 and D_2 are
             * the parameters o_max and o_min, respectively.
             */

            // Loop through columns of D
            for (int j = 0; j < m_spacedim; ++j)
            {
                ASSERTL0(m_session->DefinesFunction("AnisotropicConductivity",
                                                    aniso_var[j]),
                         "Function 'AnisotropicConductivity' not correctly "
                         "defined.");
                EvaluateFunction(aniso_var[j], vTemp_j,
                                 "AnisotropicConductivity");

                // Loop through rows of D
                for (int i = 0; i < j + 1; ++i)
                {
                    ASSERTL0(m_session->DefinesFunction("AnisotropicConductivity",
                                                        aniso_var[i]),
                             "Function 'AnisotropicConductivity' not correctly "
                             "defined.");
                    EvaluateFunction(aniso_var[i], vTemp_i,
                                     "AnisotropicConductivity");

                    Vmath::Vmul(nq, vTemp_i, 1, vTemp_j, 1,
                                           m_vardiff[varCoeffEnum[k]], 1);

                    Vmath::Smul(nq, o_max-o_min,
                                           m_vardiff[varCoeffEnum[k]], 1,
                                           m_vardiff[varCoeffEnum[k]], 1);

                    if (i == j)
                    {
                        Vmath::Sadd(nq, o_min, m_vardiff[varCoeffEnum[k]], 1,
                                               m_vardiff[varCoeffEnum[k]], 1);
                    }

                    ++k;
                }
            }
        }

        // Scale by scar map (range 0->1) derived from intensity map
        // (range d_min -> d_max)
        if (m_session->DefinesFunction("IsotropicConductivity"))
        {
            if (m_session->DefinesCmdLineArgument("verbose"))
            {
                cout << "Loading Isotropic Conductivity map." << endl;
            }

            NekDouble f_min = m_session->GetParameter("d_min");
            NekDouble f_max = m_session->GetParameter("d_max");

            EvaluateFunction(varName, vTemp, "IsotropicConductivity");

            // Threshold based on d_min, d_max
            for (int j = 0; j < nq; ++j)
            {
                vTemp[j] = (vTemp[j] < f_min ? f_min : vTemp[j]);
                vTemp[j] = (vTemp[j] > f_max ? f_max : vTemp[j]);
            }

            // Rescale to s \in [0,1] (0 maps to d_max, 1 maps to d_min)
            Vmath::Sadd(nq, -f_min, vTemp, 1, vTemp, 1);
            Vmath::Smul(nq, -1.0/(f_max-f_min), vTemp, 1, vTemp, 1);
            Vmath::Sadd(nq, 1.0, vTemp, 1, vTemp, 1);

            // Scale anisotropic conductivity values
            for (int i = 0; i < m_spacedim; ++i)
            {
                Vmath::Vmul(nq, vTemp, 1,
                                m_vardiff[varCoeffEnum[i]], 1,
                                m_vardiff[varCoeffEnum[i]], 1);
            }
        }

        // Write out conductivity values
        for (int i = 0; i < m_spacedim; ++i)
        {
            // Transform variable coefficient and write out to file.
            m_fields[0]->FwdTrans_IterPerExp(m_vardiff[varCoeffEnum[i]],
                                             m_fields[0]->UpdateCoeffs());
            std::stringstream filename;
            filename << "Conductivity_" << aniso_var[i];
            if (m_comm->GetSize() > 1)
            {
                filename << "_P" << m_comm->GetRank();
            }
            filename << ".fld";
            WriteFld(filename.str());
        }

        // Search through the loaded filters and pass the cell model to any
        // CheckpointCellModel filters loaded.
        int k = 0;
        const LibUtilities::FilterMap& f = m_session->GetFilters();
        LibUtilities::FilterMap::const_iterator x;
        for (x = f.begin(); x != f.end(); ++x, ++k)
        {
            if (x->first == "CheckpointCellModel")
            {
                boost::shared_ptr<FilterCheckpointCellModel> c
                    = boost::dynamic_pointer_cast<FilterCheckpointCellModel>(
                                                                m_filters[k]);
                c->SetCellModel(m_cell);
            }
        }

        // Load stimuli
        m_stimulus = Stimulus::LoadStimuli(m_session, m_fields[0]);

        if (!m_explicitDiffusion)
        {
            m_ode.DefineImplicitSolve (&Monodomain::DoImplicitSolve, this);
        }
        m_ode.DefineOdeRhs(&Monodomain::DoOdeRhs, this);
    }

    /**
     *
     */
    Monodomain::~Monodomain()
    {

    }

    /**
     * @param   inarray         Input array.
     * @param   outarray        Output array.
     * @param   time            Current simulation time.
     * @param   lambda          Timestep.
     */
    void Monodomain::DoImplicitSolve(
            const Array<OneD, const Array<OneD, NekDouble> >&inarray,
                  Array<OneD, Array<OneD, NekDouble> >&outarray,
            const NekDouble time,
            const NekDouble lambda)
    {
        int nvariables  = inarray.num_elements();
        int nq          = m_fields[0]->GetNpoints();
        StdRegions::ConstFactorMap factors;
        // lambda = \Delta t
        factors[StdRegions::eFactorLambda] = 1.0/lambda*m_chi*m_capMembrane;

        // We solve ( \nabla^2 - HHlambda ) Y[i] = rhs [i]
        // inarray = input: \hat{rhs} -> output: \hat{Y}
        // outarray = output: nabla^2 \hat{Y}
        // where \hat = modal coeffs
        for (int i = 0; i < nvariables; ++i)
        {
            // Multiply 1.0/timestep
            Vmath::Smul(nq, -factors[StdRegions::eFactorLambda], inarray[i], 1,
                                            m_fields[i]->UpdatePhys(), 1);

            // Solve a system of equations with Helmholtz solver and transform
            // back into physical space.
            m_fields[i]->HelmSolve(m_fields[i]->GetPhys(),
                                   m_fields[i]->UpdateCoeffs(), NullFlagList,
                                   factors, m_vardiff);

            m_fields[i]->BwdTrans( m_fields[i]->GetCoeffs(),
                                   m_fields[i]->UpdatePhys());
            m_fields[i]->SetPhysState(true);

            // Copy the solution vector (required as m_fields must be set).
            outarray[i] = m_fields[i]->GetPhys();
        }
    }

    /**
     *
     */
    void Monodomain::DoOdeRhs(
            const Array<OneD, const  Array<OneD, NekDouble> >&inarray,
                  Array<OneD,        Array<OneD, NekDouble> >&outarray,
            const NekDouble time)
    {
        // Compute I_ion
        m_cell->TimeIntegrate(inarray, outarray, time);

        // Compute I_stim
        for (unsigned int i = 0; i < m_stimulus.size(); ++i)
        {
            m_stimulus[i]->Update(outarray, time);
        }
    }

    /**
     *
     */
    void Monodomain::v_SetInitialConditions(NekDouble initialtime,
                        bool dumpInitialConditions)
    {
        EquationSystem::v_SetInitialConditions(initialtime,
                                               dumpInitialConditions);
        m_cell->Initialise();
    }

    /**
     *
     */
    void Monodomain::v_PrintSummary(std::ostream &out)
    {
        UnsteadySystem::v_PrintSummary(out);
        if (m_session->DefinesFunction("d00") &&
            m_session->GetFunctionType("d00", "intensity")
                    == LibUtilities::eFunctionTypeExpression)
        {
            out << "\tDiffusivity-x   : "
                << m_session->GetFunction("d00", "intensity")->GetExpression()
                << endl;
        }
        if (m_session->DefinesFunction("d11") &&
            m_session->GetFunctionType("d11", "intensity")
                    == LibUtilities::eFunctionTypeExpression)
        {
            out << "\tDiffusivity-x   : "
                << m_session->GetFunction("d11", "intensity")->GetExpression()
                << endl;
        }
        if (m_session->DefinesFunction("d22") &&
            m_session->GetFunctionType("d22", "intensity")
                    == LibUtilities::eFunctionTypeExpression)
        {
            out << "\tDiffusivity-x   : "
                << m_session->GetFunction("d22", "intensity")->GetExpression()
                << endl;
        }
        m_cell->PrintSummary(out);
    }
}
<|endoftext|>