Last commit for src/lingot-gui-config-dialog.c: c04af18902322cea1bd05b6f01b7860ca7bfa432

- import version 0.9.1 from upstream

Piotr Pawlow [2014-03-13 19:51:31]
- import version 0.9.1 from upstream
/*
 * lingot, a musical instrument tuner.
 *
 * Copyright (C) 2004-2011  Ibán Cereijo Graña, Jairo Chapela Martínez.
 *
 * This file is part of lingot.
 *
 * lingot 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.
 *
 * lingot 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 lingot; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <stdio.h>
#include <math.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <glade/glade.h>

#include "lingot-defs.h"

#include "lingot-core.h"
#include "lingot-config.h"
#include "lingot-gui-mainframe.h"
#include "lingot-gui-config-dialog.h"
#include "lingot-i18n.h"
#include "lingot-config.h"
#include "lingot-gui-config-dialog-scale.h"
#include "lingot-msg.h"

int lingot_gui_config_dialog_apply(LingotConfigDialog*);
void lingot_gui_config_dialog_close(LingotConfigDialog*);
void lingot_gui_config_dialog_rewrite(LingotConfigDialog*);
void lingot_gui_config_dialog_combo_select_value(GtkWidget* combo, int value);
audio_system_t lingot_gui_config_dialog_get_audio_system(GtkComboBox* combo);

/* button press event attention routine. */

void lingot_gui_config_dialog_callback_button_cancel(GtkButton *button,
		LingotConfigDialog* dialog) {
	lingot_gui_config_dialog_close(dialog);
}

void lingot_gui_config_dialog_callback_button_ok(GtkButton *button,
		LingotConfigDialog* dialog) {
	if (lingot_gui_config_dialog_apply(dialog)) {
		// dumps the current config to the config file
		lingot_config_save(dialog->conf, CONFIG_FILE_NAME);
		// establish the current config as the old config, so the close rollback
		// will do nothing.
		lingot_config_copy(dialog->conf_old, dialog->conf);
		lingot_gui_config_dialog_close(dialog);
	}
}

void lingot_gui_config_dialog_callback_button_apply(GtkButton *button,
		LingotConfigDialog* dialog) {
	if (lingot_gui_config_dialog_apply(dialog)) {
		lingot_gui_config_dialog_rewrite(dialog);
	}
}

void lingot_gui_config_dialog_callback_button_default(GtkButton *button,
		LingotConfigDialog* dialog) {
	lingot_config_restore_default_values(dialog->conf);
	lingot_gui_config_dialog_rewrite(dialog);
}

void lingot_gui_config_dialog_callback_cancel(GtkWidget *widget,
		LingotConfigDialog* dialog) {
	//lingot_mainframe_change_config(dialog->mainframe, dialog->conf_old); // restore old configuration.
	lingot_gui_config_dialog_close(dialog);
}

void lingot_gui_config_dialog_callback_close(GtkWidget *widget,
		LingotConfigDialog *dialog) {
	lingot_gui_mainframe_change_config(dialog->mainframe, dialog->conf_old); // restore old configuration.
	gtk_widget_destroy(dialog->win);
	lingot_gui_config_dialog_destroy(dialog);
}

void lingot_gui_config_dialog_callback_change_sample_rate(GtkWidget *widget,
		LingotConfigDialog *dialog) {

	const gchar* text = gtk_entry_get_text(GTK_ENTRY(
			GTK_BIN(dialog->sample_rate)->child));

	int sr;
	if (text != NULL) {
		sr = atoi(text);
	} else {
		sr = 44100;
		//g_print("WARNING: cannot get sample rate, assuming 44100\n");
	}

	char buff1[20];
	char buff2[20];
	gdouble srf = sr;
	gdouble os = gtk_spin_button_get_value_as_float(GTK_SPIN_BUTTON(
			dialog->oversampling));
	sprintf(buff1, "%d", sr);
	sprintf(buff2, " = %0.1f", srf / os);
	gtk_label_set_text(dialog->label_sample_rate1, buff1);
	//gtk_label_set_text(dialog->jack_label_sample_rate1, buff1);
	gtk_label_set_text(dialog->label_sample_rate2, buff2);
}

void lingot_gui_config_dialog_callback_change_input_system(GtkWidget *widget,
		LingotConfigDialog *dialog) {

	char buff[10];
	char* text = gtk_combo_box_get_active_text(dialog->input_system);
	audio_system_t audio_system = str_to_audio_system_t(text);
	free(text);

	LingotAudioSystemProperties* properties =
			lingot_audio_get_audio_system_properties(audio_system);

	if (properties != NULL) {
		if ((properties->forced_sample_rate)
				&& (properties->n_sample_rates > 0)) {
			sprintf(buff, "%d", properties->sample_rates[0]);
			gtk_entry_set_text(GTK_ENTRY(GTK_BIN(dialog->sample_rate)->child),
					buff);
		}

		gtk_widget_set_sensitive(GTK_WIDGET(dialog->sample_rate),
				(gboolean) !properties->forced_sample_rate);

		GtkListStore* model = GTK_LIST_STORE(gtk_combo_box_get_model(
						GTK_COMBO_BOX(dialog->sample_rate)));
		gtk_list_store_clear(model);

		int i;
		for (i = 0; i < properties->n_sample_rates; i++) {
			sprintf(buff, "%d", properties->sample_rates[i]);
			gtk_combo_box_append_text(GTK_COMBO_BOX(dialog->sample_rate), buff);
		}

		// TODO: devices

		gtk_entry_set_text(GTK_ENTRY(GTK_BIN(dialog->input_dev)->child),
				dialog->conf->audio_dev[audio_system]);
		gtk_widget_set_sensitive(GTK_WIDGET(dialog->input_dev),
				(gboolean) (audio_system != AUDIO_SYSTEM_JACK));

		lingot_audio_audio_system_properties_destroy(properties);
	} else {
		gtk_entry_set_text(GTK_ENTRY(GTK_BIN(dialog->input_dev)->child), "");
		gtk_widget_set_sensitive(GTK_WIDGET(dialog->input_dev), FALSE);
		gtk_widget_set_sensitive(GTK_WIDGET(dialog->sample_rate), FALSE);
	}
}

void lingot_gui_config_dialog_callback_change_deviation(GtkWidget *widget,
		LingotConfigDialog *dialog) {
	gtk_widget_queue_draw(GTK_WIDGET(dialog->scale_treeview));
}

void lingot_gui_config_dialog_set_audio_system(GtkComboBox* combo,
		audio_system_t audio_system) {
	const char* token = audio_system_t_to_str(audio_system);
	GtkTreeModel* model = gtk_combo_box_get_model(combo);
	GtkTreeIter iter;

	gboolean valid = gtk_tree_model_get_iter_first(model, &iter);

	while (valid) {
		gchar *str_data;
		gtk_tree_model_get(model, &iter, 0, &str_data, -1);
		if (!strcmp(str_data, token))
			gtk_combo_box_set_active_iter(combo, &iter);
		g_free(str_data);
		valid = gtk_tree_model_iter_next(model, &iter);
	}
}

audio_system_t lingot_gui_config_dialog_get_audio_system(GtkComboBox* combo) {
	char* text = gtk_combo_box_get_active_text(combo);
	int result = str_to_audio_system_t(text);
	free(text);
	return result;
}

void lingot_gui_config_dialog_combo_select_value(GtkWidget* combo, int value) {

	GtkTreeModel* model = gtk_combo_box_get_model(GTK_COMBO_BOX(combo));
	GtkTreeIter iter;

	gboolean valid = gtk_tree_model_get_iter_first(model, &iter);

	while (valid) {
		gchar *str_data;
		gtk_tree_model_get(model, &iter, 0, &str_data, -1);
		if (atoi(str_data) == value)
			gtk_combo_box_set_active_iter(GTK_COMBO_BOX(combo), &iter);
		g_free(str_data);
		valid = gtk_tree_model_iter_next(model, &iter);
	}
}

void lingot_gui_config_dialog_rewrite(LingotConfigDialog* dialog) {
	LingotConfig* conf = dialog->conf;

	lingot_gui_config_dialog_set_audio_system(dialog->input_system,
			conf->audio_system);
	//		gtk_entry_set_text(dialog->oss_input_dev, conf->audio_dev);
	//		gtk_entry_set_text(dialog->alsa_input_dev, conf->audio_dev_alsa);
	gtk_entry_set_text(GTK_ENTRY(GTK_BIN(dialog->input_dev)->child),
			conf->audio_dev[conf->audio_system]);

	gtk_range_set_value(GTK_RANGE(dialog->calculation_rate),
			conf->calculation_rate);
	gtk_range_set_value(GTK_RANGE(dialog->visualization_rate),
			conf->visualization_rate);
	gtk_range_set_value(GTK_RANGE(dialog->noise_threshold),
			conf->noise_threshold_db);
	gtk_range_set_value(GTK_RANGE(dialog->gain), conf->gain);
	gtk_spin_button_set_value(dialog->oversampling, conf->oversampling);
	//	lingot_config_dialog_set_root_reference_note(
	//			dialog->combo_root_frequency_reference_note,
	//			conf->root_frequency_referente_note);
	gtk_spin_button_set_value(dialog->root_frequency_error,
			conf->root_frequency_error);
	gtk_spin_button_set_value(dialog->temporal_window, conf->temporal_window);
	gtk_spin_button_set_value(dialog->dft_number, conf->dft_number);
	gtk_spin_button_set_value(dialog->dft_size, conf->dft_size);
	gtk_spin_button_set_value(dialog->peak_number, conf->peak_number);
	gtk_spin_button_set_value(dialog->peak_halfwidth, conf->peak_half_width);
	gtk_spin_button_set_value(dialog->minimum_frequency, conf->min_frequency);
	gtk_range_set_value(GTK_RANGE(dialog->rejection_peak_relation),
			conf->peak_rejection_relation_db);
	lingot_gui_config_dialog_combo_select_value(GTK_WIDGET(dialog->fft_size),
			(int) conf->fft_size);

	char buff[10];
	sprintf(buff, "%d", conf->sample_rate);
	gtk_entry_set_text(GTK_ENTRY(GTK_BIN(dialog->sample_rate)->child), buff);

	lingot_gui_config_dialog_scale_rewrite(dialog, conf->scale);
}

void lingot_gui_config_dialog_destroy(LingotConfigDialog* dialog) {
	dialog->mainframe->config_dialog = NULL;
	lingot_config_destroy(dialog->conf);
	lingot_config_destroy(dialog->conf_old);
	free(dialog);
}

int lingot_gui_config_dialog_apply(LingotConfigDialog* dialog) {

	gchar* text1;
	const gchar* text2;
	LingotConfig* conf = dialog->conf;

	if (!lingot_gui_config_dialog_scale_validate(dialog, conf->scale)) {
		return 0;
	}

	conf->audio_system = lingot_gui_config_dialog_get_audio_system(
			dialog->input_system);
	sprintf(conf->audio_dev[conf->audio_system], "%s", gtk_entry_get_text(
			GTK_ENTRY(GTK_BIN(dialog->input_dev)->child)));
	conf->root_frequency_error = gtk_spin_button_get_value_as_float(
			dialog->root_frequency_error);
	conf->calculation_rate = gtk_range_get_value(GTK_RANGE(
			dialog->calculation_rate));
	conf->visualization_rate = gtk_range_get_value(GTK_RANGE(
			dialog->visualization_rate));
	conf->temporal_window = gtk_spin_button_get_value_as_float(
			dialog->temporal_window);
	conf->noise_threshold_db = gtk_range_get_value(GTK_RANGE(
			dialog->noise_threshold));
	conf->gain = gtk_range_get_value(GTK_RANGE(dialog->gain));
	conf->oversampling = gtk_spin_button_get_value_as_int(dialog->oversampling);
	conf->dft_number = gtk_spin_button_get_value_as_int(dialog->dft_number);
	conf->dft_size = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(
			dialog->dft_size));
	conf->peak_number = gtk_spin_button_get_value_as_int(dialog->peak_number);
	conf->peak_half_width = gtk_spin_button_get_value_as_int(
			dialog->peak_halfwidth);
	conf->peak_rejection_relation_db = gtk_range_get_value(GTK_RANGE(
			dialog->rejection_peak_relation));
	conf->min_frequency = gtk_spin_button_get_value_as_int(
			dialog->minimum_frequency);
	text1 = gtk_combo_box_get_active_text(dialog->fft_size);
	conf->fft_size = atoi(text1);
	g_free(text1);
	text2 = gtk_entry_get_text(GTK_ENTRY(GTK_BIN(dialog->sample_rate)->child));
	conf->sample_rate = atoi(text2);

	LingotScale* scale = conf->scale;
	lingot_config_scale_destroy(scale);

	lingot_gui_config_dialog_scale_apply(dialog, scale);

	lingot_config_update_internal_params(conf);
	lingot_gui_mainframe_change_config(dialog->mainframe, conf);

	if (scale->max_offset_rounded > 200) {
		lingot_msg_add_warning(
				_("The provided scale contains wide gaps in frequency that increase the gauge range and produce a loss of visual accuracy. Consider providing scales with at least 12 tones, or with a maximum distance between adjacent notes below 200 cents."));
	}

	return 1;
}

void lingot_gui_config_dialog_close(LingotConfigDialog* dialog) {
	dialog->mainframe->config_dialog = NULL;
	gtk_widget_destroy(dialog->win);
}

void lingot_gui_config_dialog_show(LingotMainFrame* frame, LingotConfig* config) {
	GladeXML* _gladeXML = NULL;

	if (frame->config_dialog == NULL) {

		LingotConfigDialog* dialog = malloc(sizeof(LingotConfigDialog));

		dialog->mainframe = frame;
		dialog->conf = lingot_config_new();
		dialog->conf_old = lingot_config_new();

		// config copy
		lingot_config_copy(dialog->conf, (config == NULL) ? frame->conf
				: config);
		lingot_config_copy(dialog->conf_old, frame->conf);

		// TODO: obtain glade files installation dir by other way
#	    define FILE_NAME "lingot-config-dialog.glade"
		FILE* fd = fopen("src/glade/" FILE_NAME, "r");
		if (fd != NULL) {
			fclose(fd);
			_gladeXML = glade_xml_new("src/glade/" FILE_NAME, "dialog1", NULL);
		} else {
			_gladeXML = glade_xml_new(LINGOT_GLADEDIR FILE_NAME, "dialog1",
					NULL);
		}
#		undef FILE_NAME

		dialog->win = glade_xml_get_widget(_gladeXML, "dialog1");

		gtk_window_set_icon(GTK_WINDOW(dialog->win), gtk_window_get_icon(
				GTK_WINDOW(frame->win)));
		//gtk_window_set_position(GTK_WINDOW(dialog->win), GTK_WIN_POS_CENTER_ALWAYS);
		dialog->mainframe->config_dialog = dialog;

		dialog->input_system
				= GTK_COMBO_BOX(glade_xml_get_widget(_gladeXML, "input_system"));
		dialog->input_dev
				= GTK_COMBO_BOX_ENTRY(glade_xml_get_widget(_gladeXML, "input_dev"));
		dialog->sample_rate
				= GTK_COMBO_BOX_ENTRY(glade_xml_get_widget(_gladeXML, "sample_rate"));
		dialog->calculation_rate
				= GTK_HSCALE(glade_xml_get_widget(_gladeXML, "calculation_rate"));
		dialog->visualization_rate
				= GTK_HSCALE(glade_xml_get_widget(_gladeXML, "visualization_rate"));
		dialog->noise_threshold
				= GTK_HSCALE(glade_xml_get_widget(_gladeXML, "noise_threshold"));
		dialog->gain = GTK_HSCALE(glade_xml_get_widget(_gladeXML, "gain"));
		dialog->oversampling
				= GTK_SPIN_BUTTON(glade_xml_get_widget(_gladeXML, "oversampling"));
		dialog->fft_size
				= GTK_COMBO_BOX(glade_xml_get_widget(_gladeXML, "fft_size"));
		dialog->temporal_window
				= GTK_SPIN_BUTTON(glade_xml_get_widget(_gladeXML, "temporal_window"));
		dialog->root_frequency_error
				= GTK_SPIN_BUTTON(glade_xml_get_widget(_gladeXML,
								"root_frequency_error"));
		dialog->dft_number
				= GTK_SPIN_BUTTON(glade_xml_get_widget(_gladeXML, "dft_number"));
		dialog->dft_size
				= GTK_SPIN_BUTTON(glade_xml_get_widget(_gladeXML, "dft_size"));
		dialog->peak_number
				= GTK_SPIN_BUTTON(glade_xml_get_widget(_gladeXML, "peak_number"));
		dialog->peak_halfwidth
				= GTK_SPIN_BUTTON(glade_xml_get_widget(_gladeXML, "peak_halfwidth"));
		dialog->rejection_peak_relation
				= GTK_HSCALE(glade_xml_get_widget(_gladeXML,
								"rejection_peak_relation"));
		dialog->label_sample_rate1 = GTK_LABEL(glade_xml_get_widget(_gladeXML,
						"label_sample_rate1"));
		dialog->label_sample_rate2 = GTK_LABEL(glade_xml_get_widget(_gladeXML,
						"label_sample_rate2"));
		dialog->minimum_frequency
				= GTK_SPIN_BUTTON(glade_xml_get_widget(_gladeXML,
								"minimum_frequency"));

		lingot_gui_config_dialog_scale_show(dialog, _gladeXML);

		gtk_signal_connect(GTK_OBJECT(dialog->input_system), "changed",
				GTK_SIGNAL_FUNC (lingot_gui_config_dialog_callback_change_input_system), dialog);
		gtk_signal_connect(GTK_OBJECT(GTK_BIN(dialog->sample_rate)->child), "changed",
				GTK_SIGNAL_FUNC (lingot_gui_config_dialog_callback_change_sample_rate), dialog);

		gtk_signal_connect (GTK_OBJECT (dialog->oversampling), "value_changed",
				GTK_SIGNAL_FUNC (lingot_gui_config_dialog_callback_change_sample_rate), dialog);
		gtk_signal_connect (GTK_OBJECT (dialog->root_frequency_error), "value_changed",
				GTK_SIGNAL_FUNC (lingot_gui_config_dialog_callback_change_deviation), dialog);

		g_signal_connect(GTK_OBJECT(glade_xml_get_widget(_gladeXML, "button_default")), "clicked", GTK_SIGNAL_FUNC(lingot_gui_config_dialog_callback_button_default), dialog);
		g_signal_connect(GTK_OBJECT(glade_xml_get_widget(_gladeXML, "button_apply")), "clicked", GTK_SIGNAL_FUNC(lingot_gui_config_dialog_callback_button_apply), dialog);
		g_signal_connect(GTK_OBJECT(glade_xml_get_widget(_gladeXML, "button_accept")), "clicked", GTK_SIGNAL_FUNC(lingot_gui_config_dialog_callback_button_ok), dialog);
		g_signal_connect(GTK_OBJECT(glade_xml_get_widget(_gladeXML, "button_cancel")), "clicked", GTK_SIGNAL_FUNC(lingot_gui_config_dialog_callback_button_cancel), dialog);
		g_signal_connect(GTK_OBJECT(dialog->win), "destroy", GTK_SIGNAL_FUNC(lingot_gui_config_dialog_callback_close), dialog);

		lingot_gui_config_dialog_rewrite(dialog);

		gtk_widget_show(dialog->win);
		GtkWidget* scroll = glade_xml_get_widget(_gladeXML, "scrolledwindow1");
		gtk_widget_show_all(scroll);
		g_object_unref(_gladeXML);
	} else {
		if (config != NULL) {
			lingot_config_copy(frame->config_dialog->conf, config);
			lingot_gui_config_dialog_rewrite(frame->config_dialog);
		}

		gtk_window_present(GTK_WINDOW(frame->config_dialog->win));
	}

	if (config != NULL) {
		lingot_config_destroy(config);
	}
}
ViewGit