/* GSequencer - Advanced GTK Sequencer
* Copyright (C) 2005-2021 Joël Krähemann
*
* This file is part of GSequencer.
*
* GSequencer 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 3 of the License, or
* (at your option) any later version.
*
* GSequencer 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 GSequencer. If not, see .
*/
#include
#include
#include
#include
#include
#include
#include
void ags_select_buffer_dialog_class_init(AgsSelectBufferDialogClass *select_buffer_dialog);
void ags_select_buffer_dialog_connectable_interface_init(AgsConnectableInterface *connectable);
void ags_select_buffer_dialog_applicable_interface_init(AgsApplicableInterface *applicable);
void ags_select_buffer_dialog_init(AgsSelectBufferDialog *select_buffer_dialog);
void ags_select_buffer_dialog_set_property(GObject *gobject,
guint prop_id,
const GValue *value,
GParamSpec *param_spec);
void ags_select_buffer_dialog_get_property(GObject *gobject,
guint prop_id,
GValue *value,
GParamSpec *param_spec);
void ags_select_buffer_dialog_finalize(GObject *gobject);
void ags_select_buffer_dialog_connect(AgsConnectable *connectable);
void ags_select_buffer_dialog_disconnect(AgsConnectable *connectable);
void ags_select_buffer_dialog_set_update(AgsApplicable *applicable, gboolean update);
void ags_select_buffer_dialog_apply(AgsApplicable *applicable);
void ags_select_buffer_dialog_reset(AgsApplicable *applicable);
gboolean ags_select_buffer_dialog_delete_event(GtkWidget *widget, GdkEventAny *event);
/**
* SECTION:ags_select_buffer_dialog
* @short_description: select tool
* @title: AgsSelectBufferDialog
* @section_id:
* @include: ags/X/editor/ags_select_buffer_dialog.h
*
* The #AgsSelectBufferDialog lets you select buffers.
*/
enum{
PROP_0,
PROP_MAIN_WINDOW,
};
static gpointer ags_select_buffer_dialog_parent_class = NULL;
GType
ags_select_buffer_dialog_get_type(void)
{
static volatile gsize g_define_type_id__volatile = 0;
if(g_once_init_enter (&g_define_type_id__volatile)){
GType ags_type_select_buffer_dialog = 0;
static const GTypeInfo ags_select_buffer_dialog_info = {
sizeof (AgsSelectBufferDialogClass),
NULL, /* base_init */
NULL, /* base_finalize */
(GClassInitFunc) ags_select_buffer_dialog_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (AgsSelectBufferDialog),
0, /* n_preallocs */
(GInstanceInitFunc) ags_select_buffer_dialog_init,
};
static const GInterfaceInfo ags_connectable_interface_info = {
(GInterfaceInitFunc) ags_select_buffer_dialog_connectable_interface_init,
NULL, /* interface_finalize */
NULL, /* interface_data */
};
static const GInterfaceInfo ags_applicable_interface_info = {
(GInterfaceInitFunc) ags_select_buffer_dialog_applicable_interface_init,
NULL, /* interface_finalize */
NULL, /* interface_data */
};
ags_type_select_buffer_dialog = g_type_register_static(GTK_TYPE_DIALOG,
"AgsSelectBufferDialog", &ags_select_buffer_dialog_info,
0);
g_type_add_interface_static(ags_type_select_buffer_dialog,
AGS_TYPE_CONNECTABLE,
&ags_connectable_interface_info);
g_type_add_interface_static(ags_type_select_buffer_dialog,
AGS_TYPE_APPLICABLE,
&ags_applicable_interface_info);
g_once_init_leave(&g_define_type_id__volatile, ags_type_select_buffer_dialog);
}
return g_define_type_id__volatile;
}
void
ags_select_buffer_dialog_class_init(AgsSelectBufferDialogClass *select_buffer_dialog)
{
GObjectClass *gobject;
GtkWidgetClass *widget;
GParamSpec *param_spec;
ags_select_buffer_dialog_parent_class = g_type_class_peek_parent(select_buffer_dialog);
/* GObjectClass */
gobject = (GObjectClass *) select_buffer_dialog;
gobject->set_property = ags_select_buffer_dialog_set_property;
gobject->get_property = ags_select_buffer_dialog_get_property;
gobject->finalize = ags_select_buffer_dialog_finalize;
/* properties */
/**
* AgsSelectBufferDialog:main-window:
*
* The assigned #AgsWindow.
*
* Since: 3.0.0
*/
param_spec = g_param_spec_object("main-window",
i18n_pspec("assigned main window"),
i18n_pspec("The assigned main window"),
AGS_TYPE_WINDOW,
G_PARAM_READABLE | G_PARAM_WRITABLE);
g_object_class_install_property(gobject,
PROP_MAIN_WINDOW,
param_spec);
/* GtkWidgetClass */
widget = (GtkWidgetClass *) select_buffer_dialog;
widget->delete_event = ags_select_buffer_dialog_delete_event;
}
void
ags_select_buffer_dialog_connectable_interface_init(AgsConnectableInterface *connectable)
{
connectable->is_ready = NULL;
connectable->is_connected = NULL;
connectable->connect = ags_select_buffer_dialog_connect;
connectable->disconnect = ags_select_buffer_dialog_disconnect;
}
void
ags_select_buffer_dialog_applicable_interface_init(AgsApplicableInterface *applicable)
{
applicable->set_update = ags_select_buffer_dialog_set_update;
applicable->apply = ags_select_buffer_dialog_apply;
applicable->reset = ags_select_buffer_dialog_reset;
}
void
ags_select_buffer_dialog_init(AgsSelectBufferDialog *select_buffer_dialog)
{
GtkVBox *vbox;
GtkHBox *hbox;
GtkLabel *label;
select_buffer_dialog->flags = 0;
g_object_set(select_buffer_dialog,
"title", i18n("select buffers"),
NULL);
vbox = (GtkVBox *) gtk_vbox_new(FALSE,
0);
gtk_box_pack_start((GtkBox *) gtk_dialog_get_content_area(select_buffer_dialog),
GTK_WIDGET(vbox),
FALSE, FALSE,
0);
/* copy selection */
select_buffer_dialog->copy_selection = (GtkCheckButton *) gtk_check_button_new_with_label(i18n("copy selection"));
gtk_toggle_button_set_active((GtkToggleButton *) select_buffer_dialog->copy_selection,
TRUE);
gtk_box_pack_start((GtkBox *) vbox,
GTK_WIDGET(select_buffer_dialog->copy_selection),
FALSE, FALSE,
0);
/* select x0 - hbox */
hbox = (GtkHBox *) gtk_hbox_new(FALSE, 0);
gtk_box_pack_start((GtkBox *) vbox,
GTK_WIDGET(hbox),
FALSE, FALSE,
0);
/* select x0 - label */
label = (GtkLabel *) gtk_label_new(i18n("select x0"));
gtk_box_pack_start((GtkBox *) hbox,
GTK_WIDGET(label),
FALSE, FALSE,
0);
/* select x0 - spin button */
select_buffer_dialog->select_x0 = (GtkSpinButton *) gtk_spin_button_new_with_range(0.0,
AGS_SELECT_BUFFER_MAX_BEATS,
0.25);
gtk_spin_button_set_digits(select_buffer_dialog->select_x0,
2);
gtk_spin_button_set_value(select_buffer_dialog->select_x0,
0.0);
gtk_box_pack_start((GtkBox *) hbox,
GTK_WIDGET(select_buffer_dialog->select_x0),
FALSE, FALSE,
0);
/* select x1 - hbox */
hbox = (GtkHBox *) gtk_hbox_new(FALSE, 0);
gtk_box_pack_start((GtkBox *) vbox,
GTK_WIDGET(hbox),
FALSE, FALSE,
0);
/* select x1 - label */
label = (GtkLabel *) gtk_label_new(i18n("select x1"));
gtk_box_pack_start((GtkBox *) hbox,
GTK_WIDGET(label),
FALSE, FALSE,
0);
/* select x1 - spin button */
select_buffer_dialog->select_x1 = (GtkSpinButton *) gtk_spin_button_new_with_range(0.0,
AGS_SELECT_BUFFER_MAX_BEATS,
0.25);
gtk_spin_button_set_digits(select_buffer_dialog->select_x1,
2);
gtk_spin_button_set_value(select_buffer_dialog->select_x1,
0.0);
gtk_box_pack_start((GtkBox *) hbox,
GTK_WIDGET(select_buffer_dialog->select_x1),
FALSE, FALSE,
0);
/* dialog buttons */
gtk_dialog_add_buttons((GtkDialog *) select_buffer_dialog,
i18n("_Apply"), GTK_RESPONSE_APPLY,
i18n("_OK"), GTK_RESPONSE_OK,
i18n("_Cancel"), GTK_RESPONSE_CANCEL,
NULL);
}
void
ags_select_buffer_dialog_set_property(GObject *gobject,
guint prop_id,
const GValue *value,
GParamSpec *param_spec)
{
AgsSelectBufferDialog *select_buffer_dialog;
select_buffer_dialog = AGS_SELECT_BUFFER_DIALOG(gobject);
switch(prop_id){
case PROP_MAIN_WINDOW:
{
AgsWindow *main_window;
main_window = (AgsWindow *) g_value_get_object(value);
if((AgsWindow *) select_buffer_dialog->main_window == main_window){
return;
}
if(select_buffer_dialog->main_window != NULL){
g_object_unref(select_buffer_dialog->main_window);
}
if(main_window != NULL){
g_object_ref(main_window);
}
select_buffer_dialog->main_window = (GtkWidget *) main_window;
}
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
break;
}
}
void
ags_select_buffer_dialog_get_property(GObject *gobject,
guint prop_id,
GValue *value,
GParamSpec *param_spec)
{
AgsSelectBufferDialog *select_buffer_dialog;
select_buffer_dialog = AGS_SELECT_BUFFER_DIALOG(gobject);
switch(prop_id){
case PROP_MAIN_WINDOW:
{
g_value_set_object(value, select_buffer_dialog->main_window);
}
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
break;
}
}
void
ags_select_buffer_dialog_connect(AgsConnectable *connectable)
{
AgsSelectBufferDialog *select_buffer_dialog;
select_buffer_dialog = AGS_SELECT_BUFFER_DIALOG(connectable);
if((AGS_SELECT_BUFFER_DIALOG_CONNECTED & (select_buffer_dialog->flags)) != 0){
return;
}
select_buffer_dialog->flags |= AGS_SELECT_BUFFER_DIALOG_CONNECTED;
g_signal_connect(select_buffer_dialog, "response",
G_CALLBACK(ags_select_buffer_dialog_response_callback), select_buffer_dialog);
}
void
ags_select_buffer_dialog_disconnect(AgsConnectable *connectable)
{
AgsSelectBufferDialog *select_buffer_dialog;
select_buffer_dialog = AGS_SELECT_BUFFER_DIALOG(connectable);
if((AGS_SELECT_BUFFER_DIALOG_CONNECTED & (select_buffer_dialog->flags)) == 0){
return;
}
select_buffer_dialog->flags &= (~AGS_SELECT_BUFFER_DIALOG_CONNECTED);
g_object_disconnect(G_OBJECT(select_buffer_dialog),
"any_signal::response",
G_CALLBACK(ags_select_buffer_dialog_response_callback),
select_buffer_dialog,
NULL);
}
void
ags_select_buffer_dialog_finalize(GObject *gobject)
{
AgsSelectBufferDialog *select_buffer_dialog;
select_buffer_dialog = (AgsSelectBufferDialog *) gobject;
G_OBJECT_CLASS(ags_select_buffer_dialog_parent_class)->finalize(gobject);
}
void
ags_select_buffer_dialog_set_update(AgsApplicable *applicable, gboolean update)
{
/* empty */
}
void
ags_select_buffer_dialog_apply(AgsApplicable *applicable)
{
AgsSelectBufferDialog *select_buffer_dialog;
AgsWindow *window;
AgsWaveEditor *wave_editor;
AgsMachine *machine;
AgsAudio *audio;
AgsTimestamp *timestamp;
GObject *output_soundcard;
xmlDoc *clipboard;
xmlNode *audio_node, *wave_node;
GList *start_list_wave, *list_wave;
xmlChar *buffer;
guint samplerate;
guint buffer_size;
gdouble delay;
guint64 relative_offset;
int size;
guint x0, y0;
guint x1, y1;
gint i;
gboolean copy_selection;
select_buffer_dialog = AGS_SELECT_BUFFER_DIALOG(applicable);
window = (AgsWindow *) select_buffer_dialog->main_window;
wave_editor = window->wave_window->wave_editor;
machine = wave_editor->selected_machine;
if(machine == NULL){
return;
}
audio = machine->audio;
g_object_get(audio,
"output-soundcard", &output_soundcard,
"buffer-size", &buffer_size,
"samplerate", &samplerate,
"wave", &start_list_wave,
NULL);
delay = ags_soundcard_get_delay(AGS_SOUNDCARD(output_soundcard));
/* get some values */
copy_selection = gtk_toggle_button_get_active((GtkToggleButton *) select_buffer_dialog->copy_selection);
x0 = gtk_spin_button_get_value_as_int(select_buffer_dialog->select_x0);
x0 = delay * buffer_size * x0;
x1 = gtk_spin_button_get_value_as_int(select_buffer_dialog->select_x1);
x1 = delay * buffer_size * x1;
timestamp = ags_timestamp_new();
timestamp->flags &= (~AGS_TIMESTAMP_UNIX);
timestamp->flags |= AGS_TIMESTAMP_OFFSET;
relative_offset = samplerate * AGS_WAVE_DEFAULT_BUFFER_LENGTH;
/* select buffer */
if(copy_selection){
/* create document */
clipboard = xmlNewDoc(BAD_CAST XML_DEFAULT_VERSION);
/* create root node */
audio_node = xmlNewNode(NULL, BAD_CAST "audio");
xmlDocSetRootElement(clipboard, audio_node);
}
i = 0;
while((i = ags_notebook_next_active_tab(wave_editor->notebook,
i)) != -1){
list_wave = start_list_wave;
timestamp->timer.ags_offset.offset = 0;
while((list_wave = ags_wave_find_near_timestamp(list_wave, i,
timestamp)) != NULL){
ags_wave_add_region_to_selection(AGS_WAVE(list_wave->data),
x0, x1,
TRUE);
if(copy_selection){
wave_node = ags_wave_copy_selection(AGS_WAVE(list_wave->data));
xmlAddChild(audio_node, wave_node);
}
/* iterate */
timestamp->timer.ags_offset.offset += relative_offset;
list_wave = list_wave->next;
}
i++;
}
g_object_unref(timestamp);
g_list_free_full(start_list_wave,
g_object_unref);
g_object_unref(output_soundcard);
/* write to clipboard */
if(copy_selection){
xmlDocDumpFormatMemoryEnc(clipboard, &buffer, &size, "UTF-8", TRUE);
gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD),
buffer, size);
gtk_clipboard_store(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD));
xmlFreeDoc(clipboard);
}
}
void
ags_select_buffer_dialog_reset(AgsApplicable *applicable)
{
//TODO:JK: implement me
}
gboolean
ags_select_buffer_dialog_delete_event(GtkWidget *widget, GdkEventAny *event)
{
gtk_widget_hide(widget);
// GTK_WIDGET_CLASS(ags_select_buffer_dialog_parent_class)->delete_event(widget, event);
return(TRUE);
}
/**
* ags_select_buffer_dialog_new:
* @main_window: the #AgsWindow
*
* Create a new #AgsSelectBufferDialog.
*
* Returns: a new #AgsSelectBufferDialog
*
* Since: 3.0.0
*/
AgsSelectBufferDialog*
ags_select_buffer_dialog_new(GtkWidget *main_window)
{
AgsSelectBufferDialog *select_buffer_dialog;
select_buffer_dialog = (AgsSelectBufferDialog *) g_object_new(AGS_TYPE_SELECT_BUFFER_DIALOG,
"main-window", main_window,
NULL);
return(select_buffer_dialog);
}