// options.cxx
// This file is part of galvani.
// Copyright (C) 2020-2024 Burkard Lutz <b.lutz@online.de>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

#include <gtkmm.h>
#include <iostream>
#include <fstream>
#include "options.h"
#include <libserial/SerialPortConstants.h>
#include <glibmm/i18n.h>
#include <filesystem>

namespace fs = std::filesystem;

///////////////////////////////// DMM-Functions: Transform to Strings  ///////////////
std::string Multimeter::get_baud()
{
	std::string baudrate;

	switch (dmm_baud)
	{
		case LibSerial::BaudRate::BAUD_600: baudrate = "600"; break;
		case LibSerial::BaudRate::BAUD_1200: baudrate = "1200"; break;
		case LibSerial::BaudRate::BAUD_1800: baudrate = "1800"; break;
		case LibSerial::BaudRate::BAUD_2400: baudrate = "2400"; break;
		case LibSerial::BaudRate::BAUD_4800: baudrate = "4800"; break;
		case LibSerial::BaudRate::BAUD_9600: baudrate = "9600"; break;
		case LibSerial::BaudRate::BAUD_19200: baudrate = "19200"; break;
		case LibSerial::BaudRate::BAUD_38400: baudrate = "38400"; break;
		case LibSerial::BaudRate::BAUD_57600: baudrate = "57600"; break;
		case LibSerial::BaudRate::BAUD_115200: baudrate = "115200"; break;
		default: baudrate = "9600";
	}
	return baudrate;
}

void Multimeter::set_baud(std::string baudrate)
{
	if (baudrate == "600") dmm_baud = LibSerial::BaudRate::BAUD_600;
	else if (baudrate == "1200") dmm_baud = LibSerial::BaudRate::BAUD_1200;
	else if (baudrate == "1800") dmm_baud = LibSerial::BaudRate::BAUD_1800;
	else if (baudrate == "2400") dmm_baud = LibSerial::BaudRate::BAUD_2400;
	else if (baudrate == "4800") dmm_baud = LibSerial::BaudRate::BAUD_4800;
	else if (baudrate == "9600") dmm_baud = LibSerial::BaudRate::BAUD_9600;
	else if (baudrate == "19200") dmm_baud = LibSerial::BaudRate::BAUD_19200;
	else if (baudrate == "38400") dmm_baud = LibSerial::BaudRate::BAUD_38400;
	else if (baudrate == "57600") dmm_baud = LibSerial::BaudRate::BAUD_57600;
	else if (baudrate == "115200") dmm_baud = LibSerial::BaudRate::BAUD_115200;
	else dmm_baud = LibSerial::BaudRate::BAUD_9600;

	return;
}

std::string Multimeter::get_charsize()
{
	std::string charactersize;

	switch (dmm_charsize)
	{
		case LibSerial::CharacterSize::CHAR_SIZE_7: charactersize = "7"; break;
		case LibSerial::CharacterSize::CHAR_SIZE_8: charactersize = "8"; break;
		default: charactersize = "7";
	}
	return charactersize;
}

void Multimeter::set_charsize(std::string charactersize)
{
	if (charactersize == "7") dmm_charsize =LibSerial::CharacterSize::CHAR_SIZE_7;
	else if (charactersize == "8") dmm_charsize =LibSerial::CharacterSize::CHAR_SIZE_8;
	else dmm_charsize =LibSerial::CharacterSize::CHAR_SIZE_7;
	return;
}


std::string Multimeter::get_flowcontrol()
{
	std::string flowcontrol;

	switch (dmm_flowcontrol)
	{
		case LibSerial::FlowControl::FLOW_CONTROL_HARDWARE: flowcontrol = "hardware"; break;
		case LibSerial::FlowControl::FLOW_CONTROL_SOFTWARE: flowcontrol = "software"; break;
		case LibSerial::FlowControl::FLOW_CONTROL_NONE: flowcontrol = "none"; break;
		default: flowcontrol = "none";
	}
	return flowcontrol;
}

void Multimeter::set_flowcontrol(std::string flowcontrol)
{
	if (flowcontrol == "hardware") dmm_flowcontrol = LibSerial::FlowControl::FLOW_CONTROL_HARDWARE;
	else if (flowcontrol == "software") dmm_flowcontrol = LibSerial::FlowControl::FLOW_CONTROL_SOFTWARE;
	else dmm_flowcontrol = LibSerial::FlowControl::FLOW_CONTROL_NONE;
	return;
}

std::string Multimeter::get_stopbits()
{
	std::string stopbits;

	switch (dmm_stopbits)
	{
		case LibSerial::StopBits::STOP_BITS_1: stopbits = "1"; break;
		case LibSerial::StopBits::STOP_BITS_2: stopbits = "2"; break;
		default: stopbits = "2";
	}
	return stopbits;
}

void Multimeter::set_stopbits(std::string stopbits)
{
	if (stopbits == "1") dmm_stopbits = LibSerial::StopBits::STOP_BITS_1;
	else dmm_stopbits = LibSerial::StopBits::STOP_BITS_2;
	return;
}


std::string Multimeter::get_parity()
{
	std::string parity;

	switch (dmm_parity)
	{
		case LibSerial::Parity::PARITY_EVEN: parity = "even"; break;
		case LibSerial::Parity::PARITY_ODD: parity = "odd"; break;
		case LibSerial::Parity::PARITY_NONE: parity = "none"; break;
		default: parity = "none";
	}
	return parity;
}

void Multimeter::set_parity(std::string parity)
{
	if (parity == "even") dmm_parity = LibSerial::Parity::PARITY_EVEN;
	else if (parity == "odd") dmm_parity = LibSerial::Parity::PARITY_ODD;
	else dmm_parity = LibSerial::Parity::PARITY_NONE;
	return;
}


//////////////////////////////// show options //////////////////////////////////

void OptionsDialog::show_options_diag ()
{
	edit_options.set_current_page (0);
	set_options();
	return;
}

void OptionsDialog::show_options_device_x ()
{
	edit_options.set_current_page (1);
	set_options();
	return;
}

void OptionsDialog::show_options_device_y ()
{
	edit_options.set_current_page (2);
	set_options();
	return;
}

void OptionsDialog::show_diag_settings ()
{
	Gdk::RGBA color;

	//Colours
	color.set_rgba(main_win->diag.bkcol_r, main_win->diag.bkcol_g, main_win->diag.bkcol_b);
	diag_bkcolor.set_rgba(color);
	color.set_rgba(main_win->diag.gridcol_r, main_win->diag.gridcol_g, main_win->diag.gridcol_b);
	diag_gridcolor.set_rgba(color);
	color.set_rgba(main_win->diag.axcol_r, main_win->diag.axcol_g, main_win->diag.axcol_b);
	diag_axcolor.set_rgba(color);
	color.set_rgba(main_win->diag.xycol_r, main_win->diag.xycol_g, main_win->diag.xycol_b);
	diag_xycolor.set_rgba(color);
	//Switches
	diag_gridsw.set_active(main_win->diag.grid);
	diag_autoscalesw.set_active(main_win->diag.autoscale);
	diag_zerosw.set_active(main_win->diag.showzero);
	diag_titlesw.set_active(main_win->diag.showtitle);
	//Symbols
	if (main_win->diag.mw_symbol == cross) diag_symbol.set_active_text(_("cross"));
	else if (main_win->diag.mw_symbol == square) diag_symbol.set_active_text(_("square"));
	else if (main_win->diag.mw_symbol == circle) diag_symbol.set_active_text(_("circle"));
	else if (main_win->diag.mw_symbol == diamond) diag_symbol.set_active_text(_("diamond"));
	else diag_symbol.set_active_text(_("no symbol"));
	diag_symw.set_value(main_win->diag.symw);
	//Symbol style
	if (main_win->diag.symbol_filled) diag_symbolstyle.set_active_text(_("filled"));
	else diag_symbolstyle.set_active_text(_("outline"));
	//Line style
	if (main_win->diag.mw_linestyle == dashed) diag_linestyle.set_active_text(_("dashed"));
	else if (main_win->diag.mw_linestyle == pointed) diag_linestyle.set_active_text(_("dotted"));
	else diag_linestyle.set_active_text(_("solid"));
	//Connection between points
	if (main_win->diag.mw_line) diag_graph.set_active_text(_("line"));
	else if (main_win->diag.mw_curve) diag_graph.set_active_text(_("curve"));
	else diag_graph.set_active_text(_("no connection"));
	//manual scaling
	diag_xmin.set_value(main_win->diag.xmin);
	diag_xmax.set_value(main_win->diag.xmax);
	diag_ymin.set_value(main_win->diag.ymin);
	diag_ymax.set_value(main_win->diag.ymax);
	diag_xmin.set_sensitive (!main_win->diag.autoscale);
	diag_xmax.set_sensitive (!main_win->diag.autoscale);
	diag_ymin.set_sensitive (!main_win->diag.autoscale);
	diag_ymax.set_sensitive (!main_win->diag.autoscale);

	return;
}

bool OptionsDialog::show_diag_manual_limits (bool state)
{
	bool auto_scale;

	auto_scale = state;

	diag_xmin.set_sensitive (!auto_scale);
	diag_xmax.set_sensitive (!auto_scale);
	diag_ymin.set_sensitive (!auto_scale);
	diag_ymax.set_sensitive (!auto_scale);

    diag_autoscalesw.set_state (auto_scale);
    if (auto_scale)       //reset limits to auto
    {
        main_win->diag.set_coord_limits ();  //get auto diagram coordinate limits
        diag_xmin.set_value(main_win->diag.xmin);
	    diag_xmax.set_value(main_win->diag.xmax);
	    diag_ymin.set_value(main_win->diag.ymin);
	    diag_ymax.set_value(main_win->diag.ymax);
    }

	return true;
}


void OptionsDialog::show_options_Kanal_XY ()
{
	int i;
	bool dmm_remote;

	preset_mtime ();	// Set minimum values for Measurement intervall
	set_simtyp (); //set simulation type according to dmm function
	for (int k=0; k<=1; k++)
	{
		if (dmm[k].dmm_typ == TIME)
		{
			dmm_typ[k].set_active_text(_("Time"));
			dmm_dmm_options[k].set_visible (false);
			dmm_serial_options[k].set_visible (false);
			dmm_usb_options[k].set_visible (false);
			dmm_simtyp[k].set_visible (false);
			dmm_control_options[k].set_visible (false);
			dmm_function_control[k].set_visible (false);
			sim_linoptions[k].set_visible (false);
			sim_expoptions.set_visible (false);
			sim_chromoptions.set_visible (false);
		}
		else if (dmm[k].dmm_typ == DMM)		//DMM
		{
			dmm_dmm_options[k].set_visible (true);
			sim_linoptions[k].set_visible (false);
			sim_expoptions.set_visible (false);
			sim_chromoptions.set_visible (false);
			if (k == 1) dmm_device_options.set_visible (false);
			dmm_typ[k].set_active_text(_("Digitalmultimeter"));
			dmm_simtyp[k].set_visible (false);
			dmm_interface[k].remove_all();
			ports = dmm[k].dmm_port.GetAvailableSerialPorts();
			for (i=0; i<ports.size(); i++) dmm_interface[k].append (ports.at(i));
			ports = get_usb_ports();
			for (i=0; i<ports.size(); i++) dmm_interface[k].append (ports.at(i));
			dmm_interface[k].set_visible (true);
			//  renew list of all installed dmm
			dmm_name[k].remove_all ();
			for (i=1; i<=mid; i++) dmm_name[k].append (idmm[i].dmm_name);
			dmm[k].m_range = set_std_range (dmm[k].m_funkt);
			dmm_name[k].set_active_text(dmm[k].dmm_name);
			dmm_interface[k].set_active_text(dmm[k].int_face);
			dmm_baud[k].set_active_text(dmm[k].get_baud());
			dmm_bits[k].set_active_text(dmm[k].get_charsize());
			dmm_flowcontrol[k].set_active_text(dmm[1].get_flowcontrol());
			dmm_stopbits[k].set_active_text(dmm[k].get_stopbits());
			dmm_parity[k].set_active_text(dmm[k].get_parity());
			dmm_polling[k].set_active(dmm[k].dmm_polling);
			dmm_scpi[k].set_active(dmm[k].scpi);
			dmm_num_bytes[k].set_value(dmm[k].num_bytes);
			dmm_usb_bytes[k].set_value(dmm[k].usb_bytes);
			dmm_num_val[k].set_value(dmm[k].num_val);
			dmm_timeout[k].set_value(dmm[k].ms_timeout);
			show_dmm_interface_options (k);
			dmm_remote_control[k].set_active(dmm[k].remote_cfg);
			dmm_remote = dmm_remote_control[k].get_active ();
			if (dmm_remote)
			{
				show_dmm_function_control(k);
				dmm_funktion[k].set_active_text(dmm[k].m_funkt);
				dmm_range[k].set_active_text(dmm[k].m_range);
				dmm_DCV[k].set_active_text (dmm[k].get_ctrlstr (DCV));
				dmm_ACV[k].set_active_text (dmm[k].get_ctrlstr (ACV));
				dmm_DCmA[k].set_active_text (dmm[k].get_ctrlstr (DCmA));
				dmm_ACmA[k].set_active_text (dmm[k].get_ctrlstr (ACmA));
				dmm_DCA[k].set_active_text (dmm[k].get_ctrlstr (DCA));
				dmm_ACA[k].set_active_text (dmm[k].get_ctrlstr (ACA));
				dmm_Res[k].set_active_text (dmm[k].get_ctrlstr (Res));
				dmm_Cond[k].set_active_text (dmm[k].get_ctrlstr (Cond));
				dmm_pH[k].set_active_text (dmm[k].get_ctrlstr (pH));
				dmm_Temp[k].set_active_text (dmm[k].get_ctrlstr (Temp));
				dmm_control_options[k].set_visible (true);
			}
			else dmm_control_options[k].set_visible (false);
		}
		else if (dmm[k].dmm_typ == DEVICE)		//Device
		{
			dmm_dmm_options[k].set_visible (false);
			dmm_serial_options[k].set_visible (false);
			dmm_usb_options[k].set_visible (false);
			dmm_control_options[k].set_visible (false);
			dmm_function_control[k].set_visible (false);
			dmm_simtyp[k].set_visible (false);
			sim_linoptions[k].set_visible (false);
			sim_expoptions.set_visible (false);
			sim_chromoptions.set_visible (false);
			if (k == 1) dmm_device_options.set_visible (true);
			dmm_typ[k].set_active_text(_("Device"));
			dev_interface.remove_all();
			ports = dmm[k].dmm_port.GetAvailableSerialPorts();
			for (i=0; i<ports.size(); i++) dev_interface.append (ports.at(i));
			ports = get_usb_ports();
			for (i=0; i<ports.size(); i++) dev_interface.append (ports.at(i));
			dev_interface.set_active_text(dmm[k].int_face);
			dev_interface.set_visible (true);
		}
		else									//Simulation
		{
			dmm_typ[k].set_active_text(_("Simulation"));
			dmm_dmm_options[k].set_visible (false);
			dmm_device_options.set_visible (false);
			dmm_serial_options[k].set_visible (false);
			dmm_usb_options[k].set_visible (false);
			dmm_control_options[k].set_visible (false);
			dmm_function_control[k].set_visible (false);
			switch (dmm[k].dmm_typ)
			{
				case LINEAR: dmm_simtyp[k].set_active_text(_("Linear")); break;
				case EXP: dmm_simtyp[k].set_active_text(_("Exponential")); break;
				case PEAK: dmm_simtyp[k].set_active_text(_("Chromatogram")); break;
				case PH: dmm_simtyp[k].set_active_text("pH"); break;
			}
			dmm_simtyp[k].set_visible (true);
			show_simulation_options (k);
		}
	}
	return;
}

void OptionsDialog::set_simtyp ()   //set simulation type according to dmm function
{
    dmm_simtyp[1].remove_all ();

    if (project->funktion_y == _("DC Voltage"))
    {
        dmm_simtyp[1].append (_("Linear"));
	    dmm_simtyp[1].append (_("Exponential"));
	    dmm_simtyp[1].append (_("Chromatogram"));
    }
    else if ((project->funktion_y == _("AC Voltage"))
            || (project->funktion_y == _("DC Current"))
            || (project->funktion_y == _("AC Current"))
	        || (project->funktion_y == _("Resistance"))
	        || (project->funktion_y == _("Conductivity"))
	        || (project->funktion_y == _("Temperature")))
	{
        dmm_simtyp[1].append (_("Linear"));
	    dmm_simtyp[1].append (_("Exponential"));

    }
    else if (project->funktion_y == _("pH"))
    {
        dmm_simtyp[1].append (_("pH"));
    }

    return;
}


void OptionsDialog::show_simulation_options (int k)	//show options for linear simulation
{
	std::string option;
	typ simtyp;

	option = dmm_simtyp[k].get_active_text();
	if (option == _("Linear")) simtyp = LINEAR;
	else if (option == _("Exponential")) simtyp = EXP;
	else if (option == _("Chromatogram")) simtyp = PEAK;
	else simtyp = PH;
	switch (simtyp)
	{
		case LINEAR:
		{
			dmm_simtyp[k].set_active_text(_("Linear"));
			sim_slope[k].set_value(dmm[k].m);
			sim_shift[k].set_value(100*dmm[k].rf); //shift in percentage
			if (dmm[k].auto_slope) 	//slope
			{
				sim_slope_switch[k].set_active(true);
				sim_slope[k].set_sensitive (false);
			}
			else
			{
				sim_slope_switch[k].set_active(false);
				sim_slope[k].set_sensitive (true);
			}

			if (dmm[k].auto_shift) 	//shift factor
			{
				sim_shift_switch[k].set_active(true);
				sim_shift[k].set_sensitive (false);
			}
			else
			{
				sim_shift_switch[k].set_active(false);
				sim_shift[k].set_sensitive (true);
			}
			sim_linoptions[k].set_visible (true);
			sim_expoptions.set_visible (false);
			sim_chromoptions.hide ();
		} break;
		case EXP:
		{
			dmm_simtyp[k].set_active_text(_("Exponential"));
			sim_init.set_value(dmm[k].a);
			sim_tc.set_value(dmm[k].k);
			sim_expshift.set_value(100*dmm[k].exp_rf); //shift in percentage
			if (dmm[k].auto_init) 	//initial value
			{
				sim_init_sw.set_active(true);
				sim_init.set_sensitive (false);
			}
			else
			{
				sim_init_sw.set_active(false);
				sim_init.set_sensitive (true);
			}
			if (dmm[k].auto_tc) 	//time constant
			{
				sim_tc_sw.set_active(true);
				sim_tc.set_sensitive (false);
			}
			else
			{
				sim_tc_sw.set_active(false);
				sim_tc.set_sensitive (true);
			}
			if (dmm[k].auto_expshift) 	//shift factor
			{
				sim_expshift_sw.set_active(true);
				sim_expshift.set_sensitive (false);
			}
			else
			{
				sim_expshift_sw.set_active(false);
				sim_expshift.set_sensitive (true);
			}
			sim_expoptions.set_visible (true);
			sim_linoptions[k].set_visible (false);
			sim_chromoptions.hide ();
		} break;
		case PEAK:
		{
			dmm_simtyp[k].set_active_text(_("Chromatogram"));
			sim_np.set_value(dmm[k].n);
			sim_max_rt.set_value(dmm[k].max_rt);
			sim_bf.set_value(dmm[k].bf);
			sim_drift.set_value(100*dmm[k].drift); //drift in %
			if (dmm[k].auto_np) 	//number of peaks
			{
				sim_np_sw.set_active(true);
				sim_np.set_sensitive (false);
			}
			else
			{
				sim_np_sw.set_active(false);
				sim_np.set_sensitive (true);
			}
			if (dmm[k].auto_rt) 	//max. retention time
			{
				sim_max_rt_sw.set_active(true);
				sim_max_rt.set_sensitive (false);
			}
			else
			{
				sim_max_rt_sw.set_active(false);
				sim_max_rt.set_sensitive (true);
			}
			if (dmm[k].auto_bf) 	//peak width
			{
				sim_bf_sw.set_active(true);
				sim_bf.set_sensitive (false);
			}
			else
			{
				sim_bf_sw.set_active(false);
				sim_bf.set_sensitive (true);
			}
			if (dmm[k].auto_drift) 	//drift
			{
				sim_drift_sw.set_active(true);
				sim_drift.set_sensitive (false);
			}
			else
			{
				sim_drift_sw.set_active(false);
				sim_drift.set_sensitive (true);
			}
			sim_chromoptions.show ();
			sim_linoptions[k].set_visible (false);
			sim_expoptions.set_visible (false);
		} break;
		case PH:
		{
			dmm_simtyp[k].set_active_text("pH");

			sim_linoptions[k].set_visible (false);
			sim_expoptions.set_visible (false);
			sim_chromoptions.hide ();
		} break;
	}

	return;
}

bool OptionsDialog::show_simlin_options (bool state, int k) // show options for linear simulation
{
	bool autoslope_x, autoshift_x, autoslope_y, autoshift_y;

	autoslope_x = sim_slope_switch[0].get_active ();
	autoshift_x = sim_shift_switch[0].get_active ();
	autoslope_y = sim_slope_switch[1].get_active ();
	autoshift_y = sim_shift_switch[1].get_active ();
	if (autoslope_x) sim_slope[0].set_sensitive (false);
	else sim_slope[0].set_sensitive (true);
	if (autoshift_x) sim_shift[0].set_sensitive (false);
	else sim_shift[0].set_sensitive (true);
	if (autoslope_y) sim_slope[1].set_sensitive (false);
	else sim_slope[1].set_sensitive (true);
	if (autoshift_y) sim_shift[1].set_sensitive (false);
	else sim_shift[1].set_sensitive (true);

	sim_slope_switch[0].set_state (autoslope_x);
	sim_slope_switch[1].set_state (autoslope_y);
	sim_shift_switch[0].set_state (autoshift_x);
	sim_shift_switch[1].set_state (autoshift_y);

	return true;
}

bool OptionsDialog::show_simexp_options (bool state) // show options for exponential simulation
{
	bool auto_init, auto_tc, auto_shift;

	auto_init = sim_init_sw.get_active ();
	auto_shift = sim_expshift_sw.get_active ();
	auto_tc = sim_tc_sw.get_active ();
	if (auto_init) sim_init.set_sensitive (false);
	else sim_init.set_sensitive (true);
	if (auto_tc) sim_tc.set_sensitive (false);
	else sim_tc.set_sensitive (true);
	if (auto_shift) sim_expshift.set_sensitive (false);
	else sim_expshift.set_sensitive (true);

	sim_init_sw.set_state (auto_init);
	sim_expshift_sw.set_state (auto_shift);
	sim_tc_sw.set_state (auto_tc);

	return true;
}

bool OptionsDialog::show_simchrom_options (bool state) // show options for peak simulation (chromatogram)
{
	bool auto_np, auto_rt, auto_bf, auto_drift;

	auto_np = sim_np_sw.get_active ();
	auto_rt = sim_max_rt_sw.get_active ();
	auto_bf = sim_bf_sw.get_active ();
	auto_drift = sim_drift_sw.get_active ();
	if (auto_np) sim_np.set_sensitive (false);
	else sim_np.set_sensitive (true);
	if (auto_rt) sim_max_rt.set_sensitive (false);
	else sim_max_rt.set_sensitive (true);
	if (auto_bf) sim_bf.set_sensitive (false);
	else sim_bf.set_sensitive (true);
	if (auto_drift) sim_drift.set_sensitive (false);
	else sim_drift.set_sensitive (true);

	sim_np_sw.set_state (auto_np);
	sim_max_rt_sw.set_state (auto_rt);
	sim_bf_sw.set_state (auto_bf);
	sim_drift_sw.set_state (auto_drift);

	return true;
}


bool OptionsDialog::show_dmm_control_options (bool state, int kanal)
{
	bool dmm_remote_ctrl;

	dmm_remote_ctrl = dmm_remote_control[kanal].get_active();

	if ((dmm_remote_ctrl) && (dmm[kanal].dmm_typ == DMM))
	{
		show_dmm_function_control(kanal);
		dmm_control_options[kanal].set_visible (true);
	}
	else
	{
		dmm_function_control[kanal].set_visible (false);
		dmm_control_options[kanal].set_visible (false);
	}
	dmm_remote_control[kanal].set_state (dmm_remote_ctrl);

	return true;
}


void OptionsDialog::show_dmm_function_control(int k)
{
	bool dmm_remote_ctrl;

	dmm_remote_ctrl = dmm_remote_control[k].get_active();
	if ((dmm_remote_ctrl) && (dmm[k].dmm_typ == DMM))
	{
		dmm_funktion[k].remove_all ();
		if (dmm_DCV[k].get_active_text () != "") dmm_funktion[k].append(_("DC Voltage"));
		if (dmm_ACV[k].get_active_text () != "") dmm_funktion[k].append(_("AC Voltage"));
		if ((dmm_DCmA[k].get_active_text () != "") || (dmm_DCA[k].get_active_text () != "")) dmm_funktion[k].append(_("DC Current"));
		if ((dmm_ACmA[k].get_active_text () != "") || (dmm_ACA[k].get_active_text () != "")) dmm_funktion[k].append(_("AC Current"));
		if (dmm_Res[k].get_active_text () != "") dmm_funktion[k].append(_("Resistance"));
		if (dmm_Cond[k].get_active_text () != "") dmm_funktion[k].append(_("Conductivity"));
		if (dmm_pH[k].get_active_text () != "") dmm_funktion[k].append(_("pH"));
		if (dmm_Temp[k].get_active_text () != "") dmm_funktion[k].append(_("Temperature"));
		dmm_funktion[k].set_active_text(dmm[k].m_funkt);
		set_range_options_device (k);
		dmm_range[k].set_active_text(dmm[k].m_range);
		dmm_function_control[k].set_visible (true);
	}
	return;
}

void OptionsDialog::show_dmm_interface_options(int kanal)
{
	std::string interface;
	interface = dmm_interface[kanal].get_active_text();
	if (interface.find ("tty")< interface.size())
	{
		dmm_serial_options[kanal].set_visible (true);
		dmm_usb_options[kanal].set_visible (false);
	}
	else if ((interface.find ("usb")< interface.size()) || (interface.find ("hid")< interface.size()))
	{
		dmm_serial_options[kanal].set_visible (false);
		dmm_usb_options[kanal].set_visible (true);
	}
	else
	{
		dmm_serial_options[kanal].set_visible (false);
		dmm_usb_options[kanal].set_visible (false);
	}
	return;
}

void OptionsDialog::preset_mtime ()	//preset measuring timeout according to device option
{
	double dmm1_timeout,dmm2_timeout;
	std::string dmm1_typ, dmm2_typ;

	dmm1_timeout = dmm_timeout[0].get_value ();
	dmm2_timeout = dmm_timeout[1].get_value ();
	dmm1_typ = dmm_typ[0].get_active_text ();
	dmm2_typ = dmm_typ[1].get_active_text ();
	if (dmm2_typ != _("Simulation")) min_timeout = dmm2_timeout;
	else min_timeout = 1;
	if ((dmm1_typ == _("Digitalmultimeter")) && (dmm1_timeout > min_timeout)) min_timeout = dmm1_timeout;
	dmm_mtime.set_range (0.001 * min_timeout, 3600);
	messintervall = 0.001 * main_win->diag.mtime;		// measurement intervall in seconds
	dmm_mtime.set_value(messintervall);
	dmm_mtime.queue_draw();
	return;
}

void OptionsDialog::restart_options_x ()
{
	std::string option;

	option = dmm_typ[0].get_active_text();
	if (option == _("Time")) dmm[0].dmm_typ = TIME;
	else if (option == _("Digitalmultimeter")) dmm[0].dmm_typ = DMM;
	else
	{
		dmm[0].dmm_typ = LINEAR;
		dmm_simtyp[0].set_active_text(_("Linear"));
	}

	show_options_Kanal_XY ();

	return;
}

void OptionsDialog::restart_options_y ()
{
	std::string option;
	typ dmmtyp;

	dmmtyp = dmm[1].dmm_typ;
	option = dmm_typ[1].get_active_text();
	if (option == _("Digitalmultimeter")) dmm[1].dmm_typ = DMM;
	else if (option == _("Device")) dmm[1].dmm_typ = DEVICE;
	else
	{
		dmm[1].dmm_typ = LINEAR;
		if ((dmmtyp != DMM) && (dmmtyp != DEVICE))  dmm[1].dmm_typ = dmmtyp;
	}

	show_options_Kanal_XY ();
	return;
}


//////////////////////////////// set options //////////////////////////////////

void OptionsDialog::set_options ()
{
    //save variables to cancel changes
    dmm1_typ_saved = dmm[0].dmm_typ;
	dmm2_typ_saved = dmm[1].dmm_typ;
	funkt_x_saved = project->funktion_x;

	// show settings
	show_diag_settings();	//diagram settings
	show_options_Kanal_XY ();	//device settings

	set_visible (true);
	if (!resp_loop->is_running ()) resp_loop-> run();  // start loop to pause program until signal response is received

	return;
}

void OptionsDialog::accept_options (int response_id)
{
	std::string option;
	int i, opt_page;

	switch(response_id)
  	{
    	case(Gtk::ResponseType::ACCEPT):
    	{
			set_options_diag ();	//set new options for diagram
			// device settings
			set_device_options (0);	//set device options for channel X
			set_device_options (1);	//set device options for channel Y
			set_mtime ();
			break;
    	}
    	case(Gtk::ResponseType::CANCEL):
    	{
			// reset dmm_typ
			dmm[0].dmm_typ = dmm1_typ_saved;
			dmm[1].dmm_typ = dmm2_typ_saved;
			project->funktion_x = funkt_x_saved;
			break;
    	}
		case(1):	//Reset
    	{
			if (!main_win->msg_dialog->dialog_ok(_("Reset options of current page?"))) break;
			opt_page = edit_options.get_current_page ();
			switch (opt_page)
			{
				case 0:		// Reset Diagram Settings
					reset_options_diag ();
					break;
				case 1:		// Reset DMM-Settings Channel X
					reset_options_kanal_X();
					break;
				case 2:		// Reset DMM-Settings Channel Y
					reset_options_kanal_Y();
					break;
			}

			break;
    	}
  	}
    if (resp_loop->is_running ()) resp_loop-> quit();     //stop loop
	close();
	return;
}


void OptionsDialog::set_options_diag ()	// Diagram Settings
{
	Gdk::RGBA color;
	std::string option;

	//Colours
	color = diag_bkcolor.get_rgba();
	main_win->diag.bkcol_r = color.get_red();
	main_win->diag.bkcol_g = color.get_green();
	main_win->diag.bkcol_b = color.get_blue();
	color = diag_axcolor.get_rgba();
	main_win->diag.axcol_r = color.get_red();
	main_win->diag.axcol_g = color.get_green();
	main_win->diag.axcol_b = color.get_blue();
	color = diag_gridcolor.get_rgba();
	main_win->diag.gridcol_r = color.get_red();
	main_win->diag.gridcol_g = color.get_green();
	main_win->diag.gridcol_b = color.get_blue();
	color = diag_xycolor.get_rgba();
	main_win->diag.xycol_r = color.get_red();
	main_win->diag.xycol_g = color.get_green();
	main_win->diag.xycol_b = color.get_blue();
	//Switches
	main_win->diag.grid = diag_gridsw.get_active();
	main_win->diag.autoscale = diag_autoscalesw.get_active();
	main_win->diag.showzero = diag_zerosw.get_active();
	main_win->diag.showtitle = diag_titlesw.get_active();
	//Symbols
	option = diag_symbol.get_active_text();
	if (option == _("cross"))
	{
		main_win->diag.mw_symbol = cross;
		diag_symbolstyle.set_active_text(_("outline"));
	}
	else if (option == _("square")) main_win->diag.mw_symbol = square;
	else if (option == _("circle")) main_win->diag.mw_symbol = circle;
	else if (option == _("diamond")) main_win->diag.mw_symbol = diamond;
	else main_win->diag.mw_symbol = none;
	main_win->diag.symw = diag_symw.get_value();
	//Symbol style
	option = diag_symbolstyle.get_active_text();
	if (option == _("filled")) main_win->diag.symbol_filled = true;
	else main_win->diag.symbol_filled = false;
	//Line style
	option = diag_linestyle.get_active_text();
	if (option == _("dashed")) main_win->diag.mw_linestyle = dashed;
	else if (option == _("dotted")) main_win->diag.mw_linestyle = pointed;
	else main_win->diag.mw_linestyle = solid;
	//Connection between points
	option = diag_graph.get_active_text();
	if (option == _("line"))
	{
		main_win->diag.mw_line = true;
		main_win->diag.mw_curve = false;
	}
	else if (option == _("curve"))
	{
		main_win->diag.mw_line = false;
		main_win->diag.mw_curve = true;
	}
	else
	{
		main_win->diag.mw_line = false;
		main_win->diag.mw_curve = false;
	}
	//manual scaling
	main_win->diag.xmin = diag_xmin.get_value();
	if (main_win->diag.xmin < 0) main_win->diag.xmin = 0;
	if (diag_xmax.get_value() > main_win->diag.xmin) main_win->diag.xmax = diag_xmax.get_value();
	main_win->diag.xscale = main_win->diag.xmax - main_win->diag.xmin;
	main_win->diag.ymin = diag_ymin.get_value();
	if ((main_win->diag.showzero) && (main_win->diag.ymin > 0)) main_win->diag.ymin = 0;
	if (diag_ymax.get_value() > main_win->diag.ymin) main_win->diag.ymax = diag_ymax.get_value();
	if ((main_win->diag.showzero) && (main_win->diag.ymax < 0)) main_win->diag.ymax = 0;
	main_win->diag.yscale = main_win->diag.ymax - main_win->diag.ymin;
	main_win->diag.queue_draw ();

	return;
}

void OptionsDialog::set_device_options (int k)	//set options for channel X,Y
{
	std::string option;
	int i;

	option = dmm_typ[k].get_active_text();
	if (option == _("Time"))
	{
		dmm[k].dmm_typ = TIME;
		dmm[k].dmm_name = "";
		project->funktion_x = _("Time");
	}
	else if (option == _("Simulation"))		//simulation
	{
		dmm[k].remote_cfg = false;
		dmm[k].dmm_name = "";
		dmm[k].int_face = "";
		option = dmm_simtyp[k].get_active_text();
		if (option == _("Exponential"))
		{
			dmm[k].dmm_typ = EXP;
			dmm[k].auto_init = sim_init_sw.get_active();
			if (!dmm[k].auto_init) dmm[k].a = sim_init.get_value ();
			dmm[k].auto_tc = sim_tc_sw.get_active();
			if (!dmm[k].auto_tc) dmm[k].k = sim_tc.get_value ();
			dmm[k].auto_expshift = sim_expshift_sw.get_active();
			if (!dmm[k].auto_expshift) dmm[k].exp_rf = 0.01*sim_expshift.get_value (); //shift in percent
		}
		else if (option == _("Chromatogram"))
		{
			dmm[k].dmm_typ = PEAK;
			dmm[k].auto_np = sim_np_sw.get_active();
			if (!dmm[k].auto_np) dmm[k].n = sim_np.get_value ();
			dmm[k].auto_rt = sim_max_rt_sw.get_active();
			if (!dmm[k].auto_rt) dmm[k].max_rt = sim_max_rt.get_value ();
			dmm[k].auto_bf = sim_bf_sw.get_active();
			if (!dmm[k].auto_bf) dmm[k].bf = sim_bf.get_value ();
			dmm[k].auto_drift = sim_drift_sw.get_active();
			if (!dmm[k].auto_drift) dmm[k].drift = 0.01*sim_drift.get_value ();	//drift in %
		}
		else if (option == "pH")
		{
			dmm[k].dmm_typ = PH;
			set_messfunkt (1, "pH");
			eval_titvolumen = true;
		}
		else
		{
			dmm[k].dmm_typ = LINEAR;
			dmm[k].auto_slope = sim_slope_switch[k].get_active();
			if (!dmm[k].auto_slope) dmm[k].m = sim_slope[k].get_value ();
			dmm[k].auto_shift = sim_shift_switch[k].get_active();
			if (!dmm[k].auto_shift) dmm[k].rf = 0.01*sim_shift[k].get_value (); //shift in percent
		}
		if (dmm[k].connected) dmm[k].disconnect_dmm ();  // make changes happen
	}
	else if (option == _("Device"))		//device
	{
		dmm[k].dmm_typ = DEVICE;
		dmm[k].dmm_name = device_name.get_active_text();
		dmm[k].int_face = dev_interface.get_active_text();
		if (dmm[k].dmm_name == "Lutron PH-207") set_device_options_lutron_ph207 ();
		// other devices following

	}
	else 								//DMM
	{
		dmm[k].dmm_typ = DMM;
		dmm[k].dmm_name = dmm_name[k].get_active_text();
		dmm[k].int_face = dmm_interface[k].get_active_text();
		dmm[k].set_baud (dmm_baud[k].get_active_text());
		dmm[k].set_charsize (dmm_bits[k].get_active_text());
		dmm[k].set_flowcontrol (dmm_flowcontrol[k].get_active_text());
		dmm[k].set_stopbits (dmm_stopbits[k].get_active_text());
		dmm[k].set_parity (dmm_parity[k].get_active_text());
		dmm[k].dmm_polling = dmm_polling[k].get_active();
		dmm[k].scpi = dmm_scpi[k].get_active();
		dmm[k].usb_bytes = dmm_usb_bytes[k].get_value();
		dmm[k].num_bytes = dmm_num_bytes[k].get_value();
		dmm[k].num_val = dmm_num_val[k].get_value();
		dmm[k].ms_timeout = dmm_timeout[k].get_value();
		dmm[k].remote_cfg = dmm_remote_control[k].get_active();
		if (dmm_remote_control[k].get_active())
		{
			set_messfunkt (k, dmm_funktion[k].get_active_text());
			dmm[k].m_range = dmm_range[k].get_active_text();
			dmm[k].set_ctrlstr (DCV, dmm_DCV[k].get_active_text ());
			dmm[k].set_ctrlstr (ACV, dmm_ACV[k].get_active_text ());
			dmm[k].set_ctrlstr (DCmA, dmm_DCmA[k].get_active_text ());
			dmm[k].set_ctrlstr (ACmA, dmm_ACmA[k].get_active_text ());
			dmm[k].set_ctrlstr (DCA, dmm_DCA[k].get_active_text ());
			dmm[k].set_ctrlstr (ACA, dmm_ACA[k].get_active_text ());
			dmm[k].set_ctrlstr (Res, dmm_Res[k].get_active_text ());
			dmm[k].set_ctrlstr (Cond, dmm_Cond[k].get_active_text ());
			dmm[k].set_ctrlstr (pH, dmm_pH[k].get_active_text ());
			dmm[k].set_ctrlstr (Temp, dmm_Temp[k].get_active_text ());
		}

		//edit existing dmm or install new one
		if (dmm_exist (dmm_name[k].get_active_text())) i = id; else i = ++mid;
		idmm[i].dmm_name = dmm_name[k].get_active_text();
		idmm[i].set_baud (dmm_baud[k].get_active_text());
		idmm[i].set_charsize (dmm_bits[k].get_active_text());
		idmm[i].set_flowcontrol (dmm_flowcontrol[k].get_active_text());
		idmm[i].set_stopbits (dmm_stopbits[k].get_active_text());
		idmm[i].set_parity (dmm_parity[k].get_active_text());
		idmm[i].dmm_polling = dmm_polling[k].get_active();
		idmm[i].scpi = dmm_scpi[k].get_active();
		idmm[i].usb_bytes = dmm_usb_bytes[k].get_value();
		idmm[i].num_bytes = dmm_num_bytes[k].get_value();
		idmm[i].num_val = dmm_num_val[k].get_value();
		idmm[i].ms_timeout = dmm_timeout[k].get_value();
		idmm[i].remote_cfg = dmm_remote_control[k].get_active();
		if (dmm_remote_control[k].get_active())
		{
			idmm[i].set_ctrlstr (DCV, dmm_DCV[k].get_active_text ());
			idmm[i].set_ctrlstr (ACV, dmm_ACV[k].get_active_text ());
			idmm[i].set_ctrlstr (DCmA, dmm_DCmA[k].get_active_text ());
			idmm[i].set_ctrlstr (ACmA, dmm_ACmA[k].get_active_text ());
			idmm[i].set_ctrlstr (DCA, dmm_DCA[k].get_active_text ());
			idmm[i].set_ctrlstr (ACA, dmm_ACA[k].get_active_text ());
			idmm[i].set_ctrlstr (Res, dmm_Res[k].get_active_text ());
			idmm[i].set_ctrlstr (Cond, dmm_Cond[k].get_active_text ());
			idmm[i].set_ctrlstr (pH, dmm_pH[k].get_active_text ());
			idmm[i].set_ctrlstr (Temp, dmm_Temp[k].get_active_text ());
		}
	}

	return;
}

void OptionsDialog::set_mtime ()	//set measuring timeout according to selected device
{
	if ((dmm[1].dmm_typ == DMM) || (dmm[1].dmm_typ == DEVICE)) min_timeout = dmm[1].ms_timeout;
	else min_timeout = 1;
	if ((dmm[0].dmm_typ == DMM) && (dmm[0].ms_timeout > dmm[1].ms_timeout)) min_timeout = dmm[0].ms_timeout;
	main_win->diag.mtime = trunc (1000 * dmm_mtime.get_value());
	if (main_win->diag.mtime < min_timeout) main_win->diag.mtime = min_timeout;

	return;
}


void OptionsDialog::set_range_options_device (int k)
{
	std::string funkt;

	funkt = dmm_funktion[k].get_active_text();
	dmm_range[k].remove_all();
	if ((funkt == _("DC Voltage")) || (funkt == _("AC Voltage")))
	{
		dmm_range[k].append("200 mV");
		dmm_range[k].append("2 V");
		dmm_range[k].append("20 V");
		dmm_range[k].append("200 V");
		dmm_range[k].append("1000 V");
		dmm_range[k].set_active_text("200 mV");
	}
	else if ((funkt == _("DC Current")) || (funkt == _("AC Current")))
	{
		dmm_range[k].append("200 uA");
		dmm_range[k].append("200 mA");
		dmm_range[k].append("20 A");
		dmm_range[k].set_active_text("200 mA");
	}
	else if (funkt == _("Resistance"))
	{
		dmm_range[k].append("200 Ohm");
		dmm_range[k].append("2 kOhm");
		dmm_range[k].append("20 kOhm");
		dmm_range[k].append("200 kOhm");
		dmm_range[k].append("2 MOhm");
		dmm_range[k].append("20 MOhm");
		dmm_range[k].set_active_text("200 Ohm");
	}
	else if (funkt == _("Conductivity"))
	{
		dmm_range[k].append("200 mS");
		dmm_range[k].set_active_text("200 mS");
	}
	else if (funkt == _("pH"))
	{
		dmm_range[k].append("pH");
		dmm_range[k].set_active_text("pH");
	}
	else if (funkt == _("Temperature"))
	{
		dmm_range[k].append("°C");
		dmm_range[k].set_active_text("°C");
	}
	dmm_function_control[k].queue_draw ();
	return;
}

bool OptionsDialog::dmm_exist (std::string name) //seek for dmm-name in array of installed dmms and set index
{
	int i;
	bool exist;

	exist = false;
	for (i=0; i<=mid; i++) if (idmm[i].dmm_name == name) //position 0 not used, name is empty
	{
		exist = true;	// dmm is installed
		id = i;			//set index
		break;
	}
	if (!exist) id = 0;
	return exist;
}

void OptionsDialog::select_dmm (int k)
{
	int i;
	std::string name, ctrl_str;
	bool dmm_remote;

	name = dmm_name[k].get_active_text ();
	if (name == "") return;
	for (i=0; i<=mid; i++)
	{
		if (idmm[i].dmm_name == name)
		{
			// copy settings to actual dmm
			dmm_baud[k].set_active_text(idmm[i].get_baud());
			dmm_bits[k].set_active_text(idmm[i].get_charsize());
			dmm_flowcontrol[k].set_active_text(idmm[i].get_flowcontrol());
			dmm_stopbits[k].set_active_text(idmm[i].get_stopbits());
			dmm_parity[k].set_active_text(idmm[i].get_parity());
			dmm_polling[k].set_active(idmm[i].dmm_polling);
			dmm_scpi[k].set_active(idmm[i].scpi);
			dmm_usb_bytes[k].set_value(idmm[i].usb_bytes);
			dmm_num_bytes[k].set_value(idmm[i].num_bytes);
			dmm_num_val[k].set_value(idmm[i].num_val);
			dmm_timeout[k].set_value(idmm[i].ms_timeout);
			dmm_remote_control[k].set_active(idmm[i].remote_cfg);
			dmm_remote = dmm_remote_control[k].get_active ();
			if (dmm_remote)
			{
				ctrl_str = (idmm[i].m_funkt);
				dmm_funktion[k].remove_all();
				dmm_funktion[k].append (ctrl_str);
				dmm_funktion[k].set_active_text (ctrl_str);

				ctrl_str = (idmm[i].m_range);
				dmm_range[k].remove_all();
				dmm_range[k].append (ctrl_str);
				dmm_range[k].set_active_text(ctrl_str);

				ctrl_str = (idmm[i].get_ctrlstr (DCV));
				dmm_DCV[k].remove_all();
				dmm_DCV[k].append (ctrl_str);
				dmm_DCV[k].set_active_text (ctrl_str);

				ctrl_str = (idmm[i].get_ctrlstr (ACV));
				dmm_ACV[k].remove_all();
				dmm_ACV[k].append (ctrl_str);
				dmm_ACV[k].set_active_text (ctrl_str);

				ctrl_str = (idmm[i].get_ctrlstr (DCmA));
				dmm_DCmA[k].remove_all();
				dmm_DCmA[k].append (ctrl_str);
				dmm_DCmA[k].set_active_text (ctrl_str);

				ctrl_str = (idmm[i].get_ctrlstr (ACmA));
				dmm_ACmA[k].remove_all();
				dmm_ACmA[k].append (ctrl_str);
				dmm_ACmA[k].set_active_text (ctrl_str);

				ctrl_str = (idmm[i].get_ctrlstr (DCA));
				dmm_DCA[k].remove_all();
				dmm_DCA[k].append (ctrl_str);
				dmm_DCA[k].set_active_text (ctrl_str);

				ctrl_str = (idmm[i].get_ctrlstr (ACA));
				dmm_ACA[k].remove_all();
				dmm_ACA[k].append (ctrl_str);
				dmm_ACA[k].set_active_text (ctrl_str);

				ctrl_str = (idmm[i].get_ctrlstr (Res));
				dmm_Res[k].remove_all();
				dmm_Res[k].append (ctrl_str);
				dmm_Res[k].set_active_text (ctrl_str);

				ctrl_str = (idmm[i].get_ctrlstr (Cond));
				dmm_Cond[k].remove_all();
				dmm_Cond[k].append (ctrl_str);
				dmm_Cond[k].set_active_text (ctrl_str);

				ctrl_str = (idmm[i].get_ctrlstr (pH));
				dmm_pH[k].remove_all();
				dmm_pH[k].append (ctrl_str);
				dmm_pH[k].set_active_text (ctrl_str);

				ctrl_str = (idmm[i].get_ctrlstr (Temp));
				dmm_Temp[k].remove_all();
				dmm_Temp[k].append (ctrl_str);
				dmm_Temp[k].set_active_text (ctrl_str);

				dmm_control_options[k].set_visible (true);
				show_dmm_function_control (k);
			}
			else dmm_control_options[k].set_visible (false);
		}
	}
	dmm_serial_options[k].queue_draw ();
	dmm_usb_options[k].queue_draw ();
	show_dmm_interface_options (k);

	return;
}

//////////////////// Reset options to standard values /////////////////////

void OptionsDialog::reset_options_diag ()
{
	//set standard values
	std_axcol.set_rgba(0.0,0.0,0.0);
	std_gridcol.set_rgba(0.5,0.5,0.5);
	std_bkcol.set_rgba(0.95,0.95,0.94);
	std_xycol.set_rgba(1.0,0.0,0.0);

	//Colours
	main_win->diag.bkcol_r = std_bkcol.get_red();
	main_win->diag.bkcol_g = std_bkcol.get_green();
	main_win->diag.bkcol_b = std_bkcol.get_blue();
	main_win->diag.axcol_r = std_axcol.get_red();
	main_win->diag.axcol_g = std_axcol.get_green();
	main_win->diag.axcol_b = std_axcol.get_blue();
	main_win->diag.gridcol_r = std_gridcol.get_red();
	main_win->diag.gridcol_g = std_gridcol.get_green();
	main_win->diag.gridcol_b = std_gridcol.get_blue();
	main_win->diag.xycol_r = std_xycol.get_red();
	main_win->diag.xycol_g = std_xycol.get_green();
	main_win->diag.xycol_b = std_xycol.get_blue();
	//Switches
	main_win->diag.grid = true;
	main_win->diag.autoscale = true;
	main_win->diag.showzero = false;
	main_win->diag.showtitle = true;
	//Symbols
	main_win->diag.mw_symbol = none;
	main_win->diag.symbol_filled = false;
	//Line style
	main_win->diag.mw_linestyle = solid;
	//Connection between points
	main_win->diag.mw_line = true;

	return;
}

void OptionsDialog::reset_options_kanal_X ()
{
	project->funktion_x = _("Time");
	dmm[0].dmm_name = "";
	dmm[0].int_face = "";
	dmm[0].dmm_typ = TIME;

	return;
}

void OptionsDialog::reset_options_kanal_Y ()
{
	dmm[1].dmm_name = "";
	dmm[1].int_face = "";
	dmm[1].dmm_typ = DMM;
	dmm[1].dmm_baud = LibSerial::BaudRate::BAUD_9600;
	dmm[1].dmm_charsize = LibSerial::CharacterSize::CHAR_SIZE_7;
	dmm[1].dmm_flowcontrol = LibSerial::FlowControl::FLOW_CONTROL_NONE;
	dmm[1].dmm_stopbits = LibSerial::StopBits::STOP_BITS_2;
	dmm[1].dmm_parity = LibSerial::Parity::PARITY_NONE;
	dmm[1].dmm_polling = true;
	dmm[1].scpi = false;
	dmm[1].usb_bytes = 0;
	dmm[1].num_bytes = 0;
	dmm[1].num_val = 1;
	dmm[1].ms_timeout = 100;
	dmm[1].m_funkt = _("DC Voltage");
	dmm[1].m_range = "2 V";
	main_win->diag.mtime = 1000;

	return;
}



///////////////// Save DMM Settings ////////////////////////////
void OptionsDialog::save_dmm_options(int k)
{
	std::string filename;

	kanal = k;
	dmm_folder = Gio::File::create_for_path(dmmdir);
	dmm_file_dialog->set_filters(dmm_filters);
	dmm_file_dialog->set_initial_folder (dmm_folder);
	dmm_file_dialog->save(sigc::bind(sigc::mem_fun(*this, &OptionsDialog::save_dmmdata_to_file), dmm_file_dialog));
	filename = dmm_name[k].get_active_text () + ".dmm";
	filename = dmmdir + filename;
	dmm_file_dialog->set_initial_name(filename);

	return;
}

void OptionsDialog::save_dmmdata_to_file(const Glib::RefPtr<Gio::AsyncResult>& result, const Glib::RefPtr<Gtk::FileDialog>& dmm_file_dialog)
{
	std::ofstream dmm_save_file;
	std::string filename;
	int k;

	k = kanal;
	try
	{
	    auto file = dmm_file_dialog->save_finish(result);
        filename = file->get_path();
    }
    catch (const Gtk::DialogError& err)
    {
        return;
    }

	dmm_save_file.open (filename);
	if (!dmm_save_file.is_open())
	{
		error_msg (_("Error writing File"));

		return;
	}

	//Write data
	dmm_save_file <<dmm_file_id<<"\n"; //ID
	try
	{
		dmm_save_file <<"dmm_name: " << dmm_name[k].get_active_text() <<"\n";
		dmm_save_file <<"dmm_baud: " << dmm_baud[k].get_active_text() <<"\n";
		dmm_save_file <<"dmm_charsize: " << dmm_bits[k].get_active_text() <<"\n";
		dmm_save_file <<"dmm_flowcontrol: " << dmm_flowcontrol[k].get_active_text() <<"\n";
		dmm_save_file <<"dmm_stopbits: " << dmm_stopbits[k].get_active_text() <<"\n";
		dmm_save_file <<"dmm_parity: " << dmm_parity[k].get_active_text() <<"\n";
		dmm_save_file <<"dmm_polling: " << dmm_polling[k].get_active() <<"\n";
		dmm_save_file <<"dmm_num_bytes: " << dmm_num_bytes[k].get_value_as_int () <<"\n";
		dmm_save_file <<"dmm_num_val: " << dmm_num_val[k].get_value_as_int () <<"\n";
		dmm_save_file <<"dmm_timeout: " << dmm_timeout[k].get_value () <<"\n";
		dmm_save_file <<"dmm_remote_control: " << dmm_remote_control[k].get_active() <<"\n";
		dmm_save_file <<"dmm_scpi: " << dmm_scpi[k].get_active() <<"\n";
		dmm_save_file <<"dmm_usb_bytes: " << dmm_usb_bytes[k].get_value_as_int () <<"\n";
		if (dmm_remote_control[k].get_active())
		{
			dmm_save_file << "DCV: " << dmm_DCV[k].get_active_text () <<"\n";
			dmm_save_file << "ACV: " << dmm_ACV[k].get_active_text () <<"\n";
			dmm_save_file << "DCmA: " << dmm_DCmA[k].get_active_text () <<"\n";
			dmm_save_file << "ACmA: " << dmm_ACmA[k].get_active_text () <<"\n";
			dmm_save_file << "DCA: " << dmm_DCA[k].get_active_text () <<"\n";
			dmm_save_file << "ACA: " << dmm_ACA[k].get_active_text () <<"\n";
			dmm_save_file << "Res: " << dmm_Res[k].get_active_text () <<"\n";
			dmm_save_file << "Cond: " << dmm_Cond[k].get_active_text () <<"\n";
			dmm_save_file << "pH: " << dmm_pH[k].get_active_text () <<"\n";
			dmm_save_file << "Temp: " << dmm_Temp[k].get_active_text () <<"\n";
		}

	}
	catch (const Glib::FileError & ex)
	{
		error_str = ex.what();
		error_msg (error_str);

		return;
	}

	dmm_save_file.close();

	return;
}

///////////////// Load DMM Settings ////////////////////////////

void OptionsDialog::load_dmm_options(int k)
{
	kanal = k;
	dmm_folder = Gio::File::create_for_path(dmmdir);
	dmm_file_dialog->set_filters(dmm_filters);
	dmm_file_dialog->set_initial_folder (dmm_folder);
	dmm_file_dialog->open(sigc::bind(sigc::mem_fun(*this, &OptionsDialog::read_dmmdata_from_file), dmm_file_dialog));

	return;
}

void OptionsDialog::read_dmmdata_from_file(const Glib::RefPtr<Gio::AsyncResult>& result,
    const Glib::RefPtr<Gtk::FileDialog>& dmm_file_dialog)
{
	std::string filename, line, dmm_nm, ctrl_str;
	size_t pos,dotpos;
	int i,k;

	k = kanal;
	try
	{
	    auto file = dmm_file_dialog->open_finish(result);
        filename = file->get_path();
    }
    catch (const Gtk::DialogError& err)
    {
        error_str = err.what();
		error_msg (error_str);

        return;
    }

	dmm_open_file.open (filename);

	//Import data
	if (dmm_open_file.is_open())
	{
		getline(dmm_open_file,line);
		if (line != dmm_file_id)
		{
			error_msg (_("No Galvani DMM configuration file"));
			dmm_open_file.close();

			return;
		}
		dmm_nm = read_dmmoption("dmm_name: ");

		// append new dmm to list
		dmm_name[0].append (dmm_nm);
		dmm_name[1].append (dmm_nm);

		// select new dmm
		dmm_name[k].set_active_text (dmm_nm);
		dmm_baud[k].set_active_text (read_dmmoption("dmm_baud: "));
		dmm_bits[k].set_active_text (read_dmmoption("dmm_charsize: "));
		dmm_flowcontrol[k].set_active_text (read_dmmoption("dmm_flowcontrol: "));
		dmm_stopbits[k].set_active_text (read_dmmoption("dmm_stopbits: "));
		dmm_parity[k].set_active_text (read_dmmoption("dmm_parity: "));
		dmm_polling[k].set_active(get_boolstr(read_dmmoption("dmm_polling: ")));
		dmm_num_bytes[k].set_value(get_intstr(read_dmmoption("dmm_num_bytes: ")));
		dmm_num_val[k].set_value(get_intstr(read_dmmoption("dmm_num_val: ")));
		dmm_timeout[k].set_value(get_intstr(read_dmmoption("dmm_timeout: ")));
		dmm_remote_control[k].set_active(get_boolstr(read_dmmoption("dmm_remote_control: ")));
		dmm_scpi[k].set_active(get_boolstr(read_dmmoption("dmm_scpi: ")));
		dmm_usb_bytes[k].set_value(get_intstr(read_dmmoption("dmm_usb_bytes: ")));
		if (dmm_remote_control[k].get_active())
		{
			ctrl_str = read_dmmoption("DCV: ");
			dmm_DCV[k].append (ctrl_str);
			dmm_DCV[k].set_active_text (ctrl_str);
			ctrl_str = read_dmmoption("ACV: ");
			dmm_ACV[k].append (ctrl_str);
			dmm_ACV[k].set_active_text (ctrl_str);
			ctrl_str = read_dmmoption("DCmA: ");
			dmm_DCmA[k].append (ctrl_str);
			dmm_DCmA[k].set_active_text (ctrl_str);
			ctrl_str = read_dmmoption("ACmA: ");
			dmm_ACmA[k].append (ctrl_str);
			dmm_ACmA[k].set_active_text (ctrl_str);
			ctrl_str = read_dmmoption("DCA: ");
			dmm_DCA[k].append (ctrl_str);
			dmm_DCA[k].set_active_text (ctrl_str);
			ctrl_str = read_dmmoption("ACA: ");
			dmm_ACA[k].append (ctrl_str);
			dmm_ACA[k].set_active_text (ctrl_str);
			ctrl_str = read_dmmoption("Res: ");
			dmm_Res[k].append (ctrl_str);
			dmm_Res[k].set_active_text (ctrl_str);
			ctrl_str = read_dmmoption("Cond: ");
			dmm_Cond[k].append (ctrl_str);
			dmm_Cond[k].set_active_text (ctrl_str);
			ctrl_str = read_dmmoption("pH: ");
			dmm_pH[k].append (ctrl_str);
			dmm_pH[k].set_active_text (ctrl_str);
			ctrl_str = read_dmmoption("Temp: ");
			dmm_Temp[k].append (ctrl_str);
			dmm_Temp[k].set_active_text (ctrl_str);
		}
		dmm_serial_options[k].queue_draw ();
		dmm_usb_options[k].queue_draw ();

		dmm_open_file.close();
	}
	else error_msg (_("Error reading File"));

	return;
}


std::string OptionsDialog::read_dmmoption(std::string opt_item)
{
	std::string opt = "", line;
	int pos;

	dmm_open_file.seekg(0,std::ios::beg);
	while (!dmm_open_file.eof())
	{
		getline(dmm_open_file,line);
		pos = line.find (opt_item);
		if (pos <= line.length())
		{
			opt = line.substr (pos + opt_item.length ());
			break;
		}
	}
	return opt;
}

void OptionsDialog::save_all_options ()
{
	std::ofstream conf_save_file;
	std::string filename;

	filename = confdir + "/galvani.conf";
	conf_save_file.open (filename);
	if (!conf_save_file.is_open())
	{
		error_msg (_("Error writing File"));
		return;
	}
	conf_save_file <<conf_file_id<<"\n"; //ID

	//////// Graphics Settings //////////
	try
	{
		// Colours
		conf_save_file <<"axcol_r: " << main_win->diag.axcol_r<<"\n";
		conf_save_file <<"axcol_g: " << main_win->diag.axcol_g<<"\n";
		conf_save_file <<"axcol_b: " << main_win->diag.axcol_b<<"\n";
		conf_save_file <<"bkcol_r: " << main_win->diag.bkcol_r<<"\n";
		conf_save_file <<"bkcol_g: " << main_win->diag.bkcol_g<<"\n";
		conf_save_file <<"bkcol_b: " << main_win->diag.bkcol_b<<"\n";
		conf_save_file <<"gridcol_r: " << main_win->diag.gridcol_r<<"\n";
		conf_save_file <<"gridcol_g: " << main_win->diag.gridcol_g<<"\n";
		conf_save_file <<"gridcol_b: " << main_win->diag.gridcol_b<<"\n";
		conf_save_file <<"xycol_r: " << main_win->diag.xycol_r<<"\n";
		conf_save_file <<"xycol_g: " << main_win->diag.xycol_g<<"\n";
		conf_save_file <<"xycol_b: " << main_win->diag.xycol_b<<"\n";
		//Switches
		conf_save_file <<"grid: " << main_win->diag.grid<<"\n";
		conf_save_file <<"autoscale: " << main_win->diag.autoscale<<"\n";
		conf_save_file <<"showzero: " << main_win->diag.showzero<<"\n";
		conf_save_file <<"showtitle: " << main_win->diag.showtitle<<"\n";
		//Symbols
		conf_save_file <<"mw_symbol: " << main_win->diag.mw_symbol<<"\n";
		conf_save_file <<"symbol_filled: " << main_win->diag.symbol_filled<<"\n";
		conf_save_file <<"symw: " << main_win->diag.symw<<"\n";
		//Line style
		conf_save_file <<"mw_linestyle: " << main_win->diag.mw_linestyle<<"\n";
		//Connection between points
		conf_save_file <<"mw_line: " << main_win->diag.mw_line<<"\n";
		conf_save_file <<"mw_curve: " << main_win->diag.mw_curve<<"\n";

	}
	catch (const Glib::FileError & ex)
	{
		error_str = ex.what();
		error_msg (error_str);
		return;
	}

	//////// DMM Settings ////////////
	try
	{
		///////////// Kanal X /////////////////////
		conf_save_file <<"Kanal X: " << project->funktion_x<<"\n";
		conf_save_file <<"dmm1_typ: " << dmm[0].dmm_typ <<"\n";
		conf_save_file <<"dmm1_name: " << dmm[0].dmm_name <<"\n";
		conf_save_file <<"dmm1_interface: " << dmm[0].int_face <<"\n";
		conf_save_file <<"dmm1_baud: " << dmm[0].get_baud() <<"\n";
		conf_save_file <<"dmm1_charsize: " << dmm[0].get_charsize() <<"\n";
		conf_save_file <<"dmm1_flowcontrol: " << dmm[0].get_flowcontrol () <<"\n";
		conf_save_file <<"dmm1_stopbits: " << dmm[0].get_stopbits () <<"\n";
		conf_save_file <<"dmm1_parity: " << dmm[0].get_parity() <<"\n";
		conf_save_file <<"dmm1_polling: " << dmm[0].dmm_polling <<"\n";
		conf_save_file <<"dmm1_num_bytes: " << dmm[0].num_bytes <<"\n";
		conf_save_file <<"dmm1_num_val: " << dmm[0].num_val <<"\n";
		conf_save_file <<"dmm1_timeout: " << dmm[0].ms_timeout <<"\n";
		conf_save_file <<"dmm1_mfunkt: " << dmm[0].m_funkt <<"\n";
		conf_save_file <<"dmm1_mrange: " << dmm[0].m_range <<"\n";
		conf_save_file <<"dmm1_remote_control: " << dmm[0].remote_cfg <<"\n";
		conf_save_file <<"dmm1_scpi: " << dmm[0].scpi <<"\n";
		conf_save_file <<"dmm1_usb_bytes: " << dmm[0].usb_bytes <<"\n";
		conf_save_file << "dmm1_DCV: " << dmm[0].get_ctrlstr (DCV) <<"\n";
		conf_save_file << "dmm1_ACV: " << dmm[0].get_ctrlstr (ACV) <<"\n";
		conf_save_file << "dmm1_DCmA: " << dmm[0].get_ctrlstr (DCmA) <<"\n";
		conf_save_file << "dmm1_ACmA: " << dmm[0].get_ctrlstr (ACmA) <<"\n";
		conf_save_file << "dmm1_DCA: " << dmm[0].get_ctrlstr (DCA) <<"\n";
		conf_save_file << "dmm1_ACA: " << dmm[0].get_ctrlstr (ACA) <<"\n";
		conf_save_file << "dmm1_Res: " << dmm[0].get_ctrlstr (Res) <<"\n";
		conf_save_file << "dmm1_Cond: " << dmm[0].get_ctrlstr (Cond) <<"\n";
		conf_save_file << "dmm1_pH: " << dmm[0].get_ctrlstr (pH) <<"\n";
		conf_save_file << "dmm1_Temp: " << dmm[0].get_ctrlstr (Temp) <<"\n";

		///////////// Kanal Y /////////////////////
		conf_save_file <<"Kanal Y: " << project->funktion_y<<"\n";
		conf_save_file <<"dmm2_typ: " << dmm[1].dmm_typ <<"\n";
		conf_save_file <<"dmm2_name: " << dmm[1].dmm_name <<"\n";
		conf_save_file <<"dmm2_interface: " << dmm[1].int_face <<"\n";
		conf_save_file <<"dmm2_baud: " << dmm[1].get_baud() <<"\n";
		conf_save_file <<"dmm2_charsize: " << dmm[1].get_charsize() <<"\n";
		conf_save_file <<"dmm2_flowcontrol: " << dmm[1].get_flowcontrol () <<"\n";
		conf_save_file <<"dmm2_stopbits: " << dmm[1].get_stopbits () <<"\n";
		conf_save_file <<"dmm2_parity: " << dmm[1].get_parity() <<"\n";
		conf_save_file <<"dmm2_polling: " << dmm[1].dmm_polling <<"\n";
		conf_save_file <<"dmm2_num_bytes: " << dmm[1].num_bytes <<"\n";
		conf_save_file <<"dmm2_num_val: " << dmm[1].num_val <<"\n";
		conf_save_file <<"dmm2_timeout: " << dmm[1].ms_timeout <<"\n";
		conf_save_file <<"dmm2_mfunkt: " << dmm[1].m_funkt <<"\n";
		conf_save_file <<"dmm2_mrange: " << dmm[1].m_range <<"\n";
		conf_save_file <<"dmm2_remote_control: " << dmm[1].remote_cfg <<"\n";
		conf_save_file <<"dmm2_scpi: " << dmm[1].scpi <<"\n";
		conf_save_file <<"dmm2_usb_bytes: " << dmm[1].usb_bytes <<"\n";
		conf_save_file << "dmm2_DCV: " << dmm[1].get_ctrlstr (DCV) <<"\n";
		conf_save_file << "dmm2_ACV: " << dmm[1].get_ctrlstr (ACV) <<"\n";
		conf_save_file << "dmm2_DCmA: " << dmm[1].get_ctrlstr (DCmA) <<"\n";
		conf_save_file << "dmm2_ACmA: " << dmm[1].get_ctrlstr (ACmA) <<"\n";
		conf_save_file << "dmm2_DCA: " << dmm[1].get_ctrlstr (DCA) <<"\n";
		conf_save_file << "dmm2_ACA: " << dmm[1].get_ctrlstr (ACA) <<"\n";
		conf_save_file << "dmm2_Res: " << dmm[1].get_ctrlstr (Res) <<"\n";
		conf_save_file << "dmm2_Cond: " << dmm[1].get_ctrlstr (Cond) <<"\n";
		conf_save_file << "dmm2_pH: " << dmm[1].get_ctrlstr (pH) <<"\n";
		conf_save_file << "dmm2_Temp: " << dmm[1].get_ctrlstr (Temp) <<"\n";

		conf_save_file <<"Messintervall: " << main_win->diag.mtime <<"\n";
	}
	catch (const Glib::FileError & ex)
	{
		error_str = ex.what();
		error_msg (error_str);
		return;
	}
	conf_save_file.close();
	return;
}

void OptionsDialog::load_all_options ()
{
	std::string filename, line;
	std::string mw_symbol, mw_linestyle, dmm_nm;
	size_t pos,dotpos;

	filename = confdir + "/galvani.conf";
	conf_open_file.open (filename);

	//Read settings
	if (conf_open_file.is_open())
	{
		getline(conf_open_file,line);
		if (line != conf_file_id)
		{
			error_msg (_("No Galvani Configuration File"));
			conf_open_file.close();
			return;
		}
		//////// Graphics Settings //////////
		main_win->diag.axcol_r = get_dbstr (read_option("axcol_r: "));
		main_win->diag.axcol_g = get_dbstr (read_option("axcol_g: "));
		main_win->diag.axcol_b = get_dbstr (read_option("axcol_b: "));
		main_win->diag.bkcol_r = get_dbstr (read_option("bkcol_r: "));
		main_win->diag.bkcol_g = get_dbstr (read_option("bkcol_g: "));
		main_win->diag.bkcol_b = get_dbstr (read_option("bkcol_b: "));
		main_win->diag.gridcol_r = get_dbstr (read_option("gridcol_r: "));
		main_win->diag.gridcol_g = get_dbstr (read_option("gridcol_g: "));
		main_win->diag.gridcol_b = get_dbstr (read_option("gridcol_b: "));
		main_win->diag.xycol_r = get_dbstr (read_option("xycol_r: "));
		main_win->diag.xycol_g = get_dbstr (read_option("xycol_g: "));
		main_win->diag.xycol_b = get_dbstr (read_option("xycol_b: "));
		if (read_option("grid: ") == "1") main_win->diag.grid = true; else main_win->diag.grid = false;
		if (read_option("autoscale: ") == "1") main_win->diag.autoscale = true; else main_win->diag.autoscale = false;
		if (read_option("showzero: ") == "1") main_win->diag.showzero = true; else main_win->diag.showzero = false;
		if (read_option("showtitle: ") == "1") main_win->diag.showtitle = true; else main_win->diag.showtitle = false;
		mw_symbol = read_option("mw_symbol: ");
		if (mw_symbol == "1") main_win->diag.mw_symbol = cross;
		else if (mw_symbol == "2") main_win->diag.mw_symbol = square;
		else if (mw_symbol == "3") main_win->diag.mw_symbol = diamond;
		else if (mw_symbol == "4") main_win->diag.mw_symbol = circle;
		else main_win->diag.mw_symbol = none;
		if (read_option("symbol_filled: ") == "1") main_win->diag.symbol_filled = true; else main_win->diag.symbol_filled = false;
		main_win->diag.symw = get_intstr (read_option("symw: "));
		mw_linestyle = read_option ("mw_linestyle: ");
		if (mw_linestyle == "1") main_win->diag.mw_linestyle = pointed;
		else if (mw_linestyle == "2") main_win->diag.mw_linestyle = dashed;
		else main_win->diag.mw_linestyle = solid;
		if (read_option("mw_line: ") == "1") main_win->diag.mw_line = true; else main_win->diag.mw_line = false;
		if (read_option("mw_curve: ") == "1") main_win->diag.mw_curve = true; else main_win->diag.mw_curve = false;


		//////// DMM Settings ////////////
		project->funktion_x = read_option("Kanal X: ");
		dmm[0].dmm_typ = get_dmmtyp (read_option("dmm1_typ: "));
		dmm_nm = read_option("dmm1_name: ");
		dmm[0].dmm_name = dmm_nm;
		dmm_name[0].prepend (dmm_nm);
		dmm_name[0].set_active_text (dmm_nm);
		dmm[0].int_face = read_option("dmm1_interface: ");
		dmm[0].set_baud(read_option("dmm1_baud: "));
		dmm[0].set_charsize(read_option("dmm1_charsize: "));
		dmm[0].set_flowcontrol (read_option("dmm1_flowcontrol: "));
		dmm[0].set_stopbits (read_option("dmm1_stopbits: "));
		dmm[0].set_parity (read_option("dmm1_parity: "));
		dmm[0].dmm_polling = get_boolstr (read_option ("dmm1_polling: " ));
		dmm[0].num_bytes = get_intstr(read_option("dmm1_num_bytes: "));
		dmm[0].num_val = get_intstr(read_option("dmm1_num_val: "));
		dmm[0].ms_timeout = get_intstr(read_option("dmm1_timeout: "));
		dmm[0].m_funkt = read_option("dmm1_mfunkt: ");
		dmm[0].m_range = read_option("dmm1_mrange: ");
		dmm[0].remote_cfg = get_boolstr (read_option ("dmm1_remote_control: " ));
		dmm[0].scpi = get_boolstr (read_option ("dmm1_scpi: " ));
		dmm[0].usb_bytes = get_intstr(read_option("dmm1_usb_bytes: "));
		dmm[0].set_ctrlstr (DCV, read_option("dmm1_DCV: "));
		dmm_DCV[0].append (read_option("dmm1_DCV: "));
		dmm[0].set_ctrlstr (ACV, read_option("dmm1_ACV: "));
		dmm_ACV[0].append (read_option("dmm1_ACV: "));
		dmm[0].set_ctrlstr (DCmA, read_option("dmm1_DCmA: "));
		dmm_DCmA[0].append (read_option("dmm1_DCmA: "));
		dmm[0].set_ctrlstr (ACmA, read_option("dmm1_ACmA: "));
		dmm_ACmA[0].append (read_option("dmm1_ACmA: "));
		dmm[0].set_ctrlstr (DCA, read_option("dmm1_DCA: "));
		dmm_DCA[0].append (read_option("dmm1_DCA: "));
		dmm[0].set_ctrlstr (ACA, read_option("dmm1_ACA: "));
		dmm_ACA[0].append (read_option("dmm1_ACA: "));
		dmm[0].set_ctrlstr (Res, read_option("dmm1_Res: "));
		dmm_Res[0].append (read_option("dmm1_Res: "));
		dmm[0].set_ctrlstr (Cond, read_option("dmm1_Cond: "));
		dmm_Cond[0].append (read_option("dmm1_Cond: "));
		dmm[0].set_ctrlstr (pH, read_option("dmm1_pH: "));
		dmm_pH[0].append (read_option("dmm1_pH: "));
		dmm[0].set_ctrlstr (Temp, read_option("dmm1_Temp: "));
		dmm_Temp[0].append (read_option("dmm1_Temp: "));
		project->funktion_y = read_option("Kanal Y: ");
		dmm[1].dmm_typ = get_dmmtyp (read_option("dmm2_typ: "));
		dmm_nm= read_option("dmm2_name: ");
		dmm[1].dmm_name = dmm_nm;
		dmm_name[1].prepend (dmm_nm);
		dmm_name[1].set_active_text (dmm_nm);
		dmm[1].int_face = read_option("dmm2_interface: ");
		dmm[1].set_baud(read_option("dmm2_baud: "));
		dmm[1].set_charsize(read_option("dmm2_charsize: "));
		dmm[1].set_flowcontrol (read_option("dmm2_flowcontrol: "));
		dmm[1].set_stopbits (read_option("dmm2_stopbits: "));
		dmm[1].set_parity (read_option("dmm2_parity: "));
		dmm[1].dmm_polling = get_boolstr (read_option ("dmm2_polling: " ));
		dmm[1].num_bytes = get_intstr(read_option("dmm2_num_bytes: "));
		dmm[1].num_val = get_intstr(read_option("dmm2_num_val: "));
		dmm[1].ms_timeout = get_intstr(read_option("dmm2_timeout: "));
		dmm[1].m_funkt = read_option("dmm2_mfunkt: ");
		dmm[1].m_range = read_option("dmm2_mrange: ");
		dmm[1].remote_cfg = get_boolstr (read_option ("dmm2_remote_control: " ));
		dmm[1].scpi = get_boolstr (read_option ("dmm2_scpi: " ));
		dmm[1].usb_bytes = get_intstr(read_option("dmm2_usb_bytes: "));
		dmm[1].set_ctrlstr (DCV, read_option("dmm2_DCV: "));
		dmm_DCV[1].append (read_option("dmm2_DCV: "));
		dmm[1].set_ctrlstr (ACV, read_option("dmm2_ACV: "));
		dmm_ACV[1].append (read_option("dmm2_ACV: "));
		dmm[1].set_ctrlstr (DCmA, read_option("dmm2_DCmA: "));
		dmm_DCmA[1].append (read_option("dmm2_DCmA: "));
		dmm[1].set_ctrlstr (ACmA, read_option("dmm2_ACmA: "));
		dmm_ACmA[1].append (read_option("dmm2_ACmA: "));
		dmm[1].set_ctrlstr (DCA, read_option("dmm2_DCA: "));
		dmm_DCA[1].append (read_option("dmm2_DCA: "));
		dmm[1].set_ctrlstr (ACA, read_option("dmm2_ACA: "));
		dmm_ACA[1].append (read_option("dmm2_ACA: "));
		dmm[1].set_ctrlstr (Res, read_option("dmm2_Res: "));
		dmm_Res[1].append (read_option("dmm2_Res: "));
		dmm[1].set_ctrlstr (Cond, read_option("dmm2_Cond: "));
		dmm_Cond[1].append (read_option("dmm2_Cond: "));
		dmm[1].set_ctrlstr (pH, read_option("dmm2_pH: "));
		dmm_pH[1].append (read_option("dmm2_pH: "));
		dmm[1].set_ctrlstr (Temp, read_option("dmm2_Temp: "));
		dmm_Temp[1].append (read_option("dmm2_Temp: "));

		main_win->diag.mtime = get_intstr (read_option("Messintervall: "));

		conf_open_file.close();
	}
	else error_msg (_("Error Reading Configuration File"));
	if ((!is_known_function (project->funktion_x)) || (!is_known_function (project->funktion_y))) main_win->map_func->translate_functions ();
	if (project->funktion_x != _("Time")) dmm[0].m_funkt = project->funktion_x;
	dmm[1].m_funkt = project->funktion_y;
	return;
}

std::string OptionsDialog::read_option(std::string opt_item)
{
	std::string opt = "", line;
	int pos;

	conf_open_file.seekg(0,std::ios::beg);
	while (conf_open_file.peek() != EOF)
	{
		getline(conf_open_file,line);
		pos = line.find (opt_item);
		if (pos <= line.length())
		{
			opt = line.substr (pos + opt_item.length ());
			break;
		}
	}
	return opt;
}

double get_dbstr(std::string num_str)
{
	double result;
	std::string dezimal, error_str;
	size_t dotpos;
	struct lconv *lc  = localeconv();

	lc=localeconv();
	dezimal = lc->decimal_point;
	if (dezimal == ",")
	{
		dotpos = num_str.find (".");
		if (dotpos <= num_str.length()) num_str.replace (dotpos,1,",");
	}
	try
	{
		result = stod(num_str);
	}
	catch (const std::invalid_argument& ia)
	{
		error_str = _("Conversion to double: ");
		error_str += num_str;
		error_msg(error_str);
    	result = 0.0;
	}
	catch (const std::out_of_range& oor)
	{
		error_str = _("Conversion to double: ");
		error_str += num_str;
		error_msg(error_str);
    	result = 0.0;
	}
	return result;
}

int get_intstr(std::string num_str)
{
	int result;
	std::string error_str;

	try
	{
		result = stoi(num_str);
	}
	catch (const std::invalid_argument& ia)
	{
		error_str = _("Conversion to integer: ");
		error_str += num_str;
		error_msg(error_str);
    	result = 0;
	}
	catch (const std::out_of_range& oor)
	{
		error_str = _("Conversion to integer: ");
		error_str += num_str;
		error_msg(error_str);
    	result = 0;
	}
	return result;
}

bool get_boolstr(std::string num_str)
{
	bool result;
	std::string error_str;


	if (num_str == "1") result = true;
	else if (num_str == "0") result = false;
	else
	{
		error_str = _("Conversion to bool: ");
		error_str += num_str;
		error_msg(error_str);
    	result = false;
	}
	return result;
}

std::vector<std::string> OptionsDialog::get_usb_ports ()
{
	std::vector<std::string> ports;
	std::string found;
	const fs::path usbdev{"/dev"};
	const fs::path usb{"/dev/usb"};
	int usb_pos;

	for (auto const& dir_entry : fs::directory_iterator{usbdev})
    {
		try
		{
			found = dir_entry.path();
		}
		catch (const std::exception & ex)
		{

		}
		usb_pos = found.find ("usb");

		if ((usb_pos < found.size()) && (!fs::is_directory(dir_entry)))
		    ports.push_back (dir_entry.path());
    }

	try
	{
		if (fs::exists(usb))
		{
			for (auto const& dir_entry : fs::directory_iterator{usb})
    		{
       			ports.push_back (dir_entry.path());
    		}
		}

	}
	catch (fs::filesystem_error const& ex) { }

	return ports;
}


////////////// Set Device Options //////////////////
void OptionsDialog::set_device_options_lutron_ph207 ()
{
	dmm[1].set_baud ("9600");
	dmm[1].set_charsize ("7");
	dmm[1].set_stopbits ("2");
	dmm[1].dmm_polling = false;
	dmm[1].num_bytes = 16;
	// min m_time: 2 Sec
	dmm[1].ms_timeout = 2000;
	project->funktion_y = "pH";
	return;
}


