/* * Copyright (C) 2004-2005 Vadim Berezniker * http://www.kryptolus.com * * 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, 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 GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * http://www.gnu.org/copyleft/gpl.html * */ #include "stdafx.h" #include "common.h" #include "sabbu.h" #include "gui_time_entry.h" #include "gui_event_list.h" #include "sound.h" extern struct sabbu app; struct _gui_shift_times *lui_shift_times = NULL; // local ui struct _gui_shift_times_options *lopts_shift_times = &app.gui_shift_times_options; // local options #define lui lui_shift_times #define lopts lopts_shift_times static void gui_shift_times_spin_frame_changed_cb(GtkWidget *widget, gpointer data); void gui_shift_times_destroy() { gui_main_enable(); gui_main_focus(); gtk_widget_destroy(GTK_WIDGET(lui->window)); kry_free(app.gui_shift_times); app.gui_shift_times = NULL; lui = NULL; } void gui_shift_times_shift_event(GtkTreeIter *iter, long offset, gboolean affect_start, gboolean affect_end) { kryEvent *line; gtk_tree_model_get(GTK_TREE_MODEL(gui_event_list_get_store(app.ui.event_list)), iter, PTR_COLUMN, &line, -1); if(line->GetType() == kryEvent::EVENT_BLANK || line->GetType() == kryEvent::EVENT_COMMENT_STRING || line->GetType() == kryEvent::EVENT_COMMENT_BLANK) return; int start = line->GetStart(); int end = line->GetEnd(); if(affect_start) start += offset; if(affect_end) end += offset; if(start < 0) start = 0; if(end < 0) end = 0; line->SetTime(start, end); gui_event_list_update_line(app.ui.event_list, line, iter); app.script->SetModifiedFlag(TRUE); } void gui_shift_times_button_cb(GtkWidget *widget, GtkResponseType response) { GList *iters = NULL; gboolean affect_start = FALSE, affect_end = FALSE; long offset; GtkTreeModel *model; GtkTreeSelection *selection = gui_event_list_get_selection(app.ui.event_list); GList *sel_items = gtk_tree_selection_get_selected_rows(selection, &model); if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lui->radio_row_selected))) lopts->shift_affected_rows = SHIFT_SELECTED; else if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lui->radio_row_before_selection))) lopts->shift_affected_rows = SHIFT_BEFORE_SELECTED; else if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lui->radio_row_notselected))) lopts->shift_affected_rows = SHIFT_NOTSELECTED; else if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lui->radio_row_from_selection))) lopts->shift_affected_rows = SHIFT_FROM_SELECTED; else if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lui->radio_row_all))) lopts->shift_affected_rows = SHIFT_ALL; if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lui->radio_forward))) lopts->shift_direction = SHIFT_FORWARD; else if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lui->radio_backward))) lopts->shift_direction = SHIFT_BACKWARD; if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lui->radio_time_both))) lopts->shift_affected_times = SHIFT_START_END; else if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lui->radio_time_start))) lopts->shift_affected_times = SHIFT_START; else if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lui->radio_time_end))) lopts->shift_affected_times = SHIFT_END; if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lui->radio_by_time))) { lopts->shift_type = SHIFT_BY_TIME; char *offset = gui_time_entry_get_text(lui->entry_time); lopts->offset_mili = time_string_to_mili(offset, 0); kry_free(offset); } else if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lui->radio_by_frame))) { lopts->shift_type = SHIFT_BY_FRAME; lopts->offset_frames = (int) gtk_spin_button_get_value(lui->spin_frame); if(lopts->fps) kry_free(lopts->fps); lopts->fps = KRY_TS(gtk_combo_box_get_active_text(GTK_COMBO_BOX(lui->combo_fps))); } enum shift_affected_rows affected = lopts->shift_affected_rows; if(!sel_items && (affected == SHIFT_SELECTED || affected == SHIFT_BEFORE_SELECTED || affected == SHIFT_NOTSELECTED || affected == SHIFT_FROM_SELECTED)) { gui_error("No rows selected"); gui_shift_times_destroy(); return; } char *offset_str = gui_time_entry_get_text(lui->entry_time); offset = time_string_to_mili(offset_str, 0); kry_free(offset_str); if(lopts->shift_affected_times == SHIFT_START_END || lopts->shift_affected_times == SHIFT_START) affect_start = TRUE; if(lopts->shift_affected_times == SHIFT_START_END || lopts->shift_affected_times == SHIFT_END) affect_end = TRUE; if(lopts->shift_direction == SHIFT_BACKWARD) offset = 0 - offset; if(affected == SHIFT_SELECTED) { if(sel_items == NULL) gui_error("No rows selected"); GtkTreeIter *iter; for(GList *ptr = sel_items; ptr; ptr = ptr->next) { iter = kry_new(GtkTreeIter, 1); GtkTreePath *path = (GtkTreePath *) ptr->data; gtk_tree_model_get_iter(model, iter, path); iters = g_list_append(iters, iter); } } else if(affected == SHIFT_BEFORE_SELECTED) { GtkTreeIter *iter = kry_new(GtkTreeIter, 1); GtkTreeIter *iter_prev = NULL; gtk_tree_model_get_iter_first(model, iter); do { GtkTreePath *path; if(!sel_items) break; path = gtk_tree_model_get_path(model, iter); if(!gtk_tree_path_compare((GtkTreePath *) (sel_items->data), path)) { gtk_tree_path_free(path); break; } iters = g_list_append(iters, iter); gtk_tree_path_free(path); iter_prev = iter; iter = kry_new(GtkTreeIter, 1); *iter = *iter_prev; } while(gtk_tree_model_iter_next(model, iter)); kry_free(iter); } else if(affected == SHIFT_NOTSELECTED) { GtkTreePath *path_cur = (GtkTreePath *) ((sel_items ? sel_items->data : NULL)); GtkTreeIter *iter = kry_new(GtkTreeIter, 1); GtkTreeIter *iter_prev = NULL; GList *sel_ptr = sel_items; gtk_tree_model_get_iter_first(model, iter); do { GtkTreePath *path; path = gtk_tree_model_get_path(model, iter); if(path_cur && !gtk_tree_path_compare(path_cur, path)) { sel_ptr = sel_ptr -> next; path_cur = (GtkTreePath *) ((sel_ptr ? sel_ptr->data : NULL)); gtk_tree_path_free(path); continue; } gtk_tree_path_free(path); iters = g_list_append(iters, iter); iter_prev = iter; iter = kry_new(GtkTreeIter, 1); *iter = *iter_prev; } while(gtk_tree_model_iter_next(model, iter)); kry_free(iter); } else { GtkTreeIter *iter = kry_new(GtkTreeIter, 1); GtkTreeIter *iter_prev = NULL; if(affected == SHIFT_FROM_SELECTED) { if(!sel_items) { gui_shift_times_destroy(); return; } gtk_tree_model_get_iter(model, iter, (GtkTreePath *) sel_items->data); } else { gtk_tree_model_get_iter_first(model, iter); } do { iters = g_list_append(iters, iter); iter_prev = iter; iter = kry_new(GtkTreeIter, 1); *iter = *iter_prev; } while(gtk_tree_model_iter_next(model, iter)); kry_free(iter); } if(offset < 0) { kryEvent *event; for(GList *ptr = iters; ptr; ptr = ptr->next) { GtkTreeIter *iter = (GtkTreeIter*) ptr->data; gtk_tree_model_get(model, iter, PTR_COLUMN, &event, -1); if(event->GetType() != kryEvent::EVENT_BLANK && event->GetType() != kryEvent::EVENT_COMMENT_STRING && event->GetType() != kryEvent::EVENT_COMMENT_BLANK && event->GetStart() < (unsigned long) (0 - offset)) { gboolean rv =gui_warning_yes_no(_("Some of the affected rows' times will be set to 0 because the offset would make them negative. \n\nContinue anyway?")); if(!rv) { g_list_foreach(iters, (GFunc) kry_free_minimal, NULL); g_list_free(iters); iters = NULL; } break; } } } for(GList *ptr = iters; ptr; ptr = ptr->next) { GtkTreeIter *iter = (GtkTreeIter*) ptr->data; gui_shift_times_shift_event(iter, offset, affect_start, affect_end); } gui_shift_times_destroy(); g_list_foreach(iters, (GFunc) kry_free_minimal, NULL); g_list_free(iters); g_list_foreach(sel_items, (GFunc) gtk_tree_path_free, NULL); g_list_free(sel_items); } void gui_shift_times_update_time_from_frame() { char *fpsstr = KRY_TS(gtk_combo_box_get_active_text(GTK_COMBO_BOX(lui->combo_fps))); int frames = (int) gtk_spin_button_get_value(lui->spin_frame); double fps = atof(fpsstr); double milifloat = (int) ((frames / fps) * 1000); int mili = (int) milifloat; if(milifloat - (int) milifloat > 0.5) mili++; if(!GTK_WIDGET_IS_SENSITIVE(lui->entry_time)) { char *strmili = time_mili_to_string(mili); gui_time_entry_set_text(lui->entry_time, strmili); kry_free(strmili); } kry_free(fpsstr); } void gui_shift_times_type_changed_cb(GtkRadioButton *radio, gpointer data) { if(radio == lui->radio_by_frame) { gtk_widget_set_sensitive(lui->entry_time, FALSE); gtk_widget_set_sensitive(GTK_WIDGET(lui->spin_frame), TRUE); gtk_widget_set_sensitive(GTK_WIDGET(lui->label_fps), TRUE); gtk_widget_set_sensitive(GTK_WIDGET(lui->combo_fps), TRUE); gui_shift_times_update_time_from_frame(); } else if(radio == lui->radio_by_time) { gtk_widget_set_sensitive(lui->entry_time, TRUE); gtk_widget_set_sensitive(GTK_WIDGET(lui->spin_frame), FALSE); gtk_widget_set_sensitive(GTK_WIDGET(lui->label_fps), FALSE); gtk_widget_set_sensitive(GTK_WIDGET(lui->combo_fps), FALSE); } } void gui_shift_times_time_changed_cb(char *value, gpointer data) { char *fpsstr = KRY_TS(gtk_combo_box_get_active_text(GTK_COMBO_BOX(lui->combo_fps))); double fps = atof(fpsstr); int time = time_string_to_mili(value, 0); int frames = time_mili_to_frames(time, fps); if(!GTK_WIDGET_IS_SENSITIVE(lui->spin_frame)) gtk_spin_button_set_value(lui->spin_frame, frames); kry_free(fpsstr); } void gui_shift_times_spin_frame_changed_cb(GtkWidget *widget, gpointer data) { gui_shift_times_update_time_from_frame(); } void gui_shift_times_show() { app.gui_shift_times = kry_new0(struct _gui_shift_times); lui = app.gui_shift_times; gui_main_disable(); GtkWindow *window = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL)); gtk_window_set_transient_for(window, app.ui.window); gtk_window_set_position(window, GTK_WIN_POS_CENTER_ON_PARENT); gtk_window_set_modal(window, TRUE); gtk_window_set_title(window, _("Shift Times")); g_signal_connect(window, "delete-event", gui_shift_times_destroy, NULL); GtkVBox *vbox = GTK_VBOX(gtk_vbox_new(FALSE, 0)); // Offset Frame { GtkFrame *frame_offset = GTK_FRAME(gtk_frame_new(_("Offset"))); // by time GtkHBox *hbox_offset_time = GTK_HBOX(gtk_hbox_new(FALSE, 0)); GtkRadioButton *radio_offset = GTK_RADIO_BUTTON(gtk_radio_button_new_with_label(NULL, _("By Time:"))); GtkWidget *entry_time = gui_time_entry_new(G_CALLBACK(gui_shift_times_time_changed_cb), NULL); gtk_box_pack_start(GTK_BOX(hbox_offset_time), GTK_WIDGET(radio_offset), FALSE, TRUE, 0); gtk_box_pack_start(GTK_BOX(hbox_offset_time), GTK_WIDGET(entry_time), FALSE, TRUE, 0); // by frame GtkHBox *hbox_offset_frame = GTK_HBOX(gtk_hbox_new(FALSE, 0)); GtkRadioButton *radio_frame = GTK_RADIO_BUTTON(gtk_radio_button_new_with_label(gtk_radio_button_get_group(radio_offset), _("By Frame:"))); GtkSpinButton *spin_frame = GTK_SPIN_BUTTON(gtk_spin_button_new_with_range(0, 999999, 1)); GtkLabel *label_fps = GTK_LABEL(gtk_label_new(_("FPS:"))); GtkComboBoxEntry *combo_fps = gui_combo_box_fps_new(); lui->radio_by_frame = radio_frame; lui->radio_by_time = radio_offset; lui->spin_frame = spin_frame; lui->label_fps = label_fps; lui->combo_fps = combo_fps; lui->entry_time = entry_time; g_signal_connect(G_OBJECT(radio_offset), "toggled", G_CALLBACK(gui_shift_times_type_changed_cb), NULL); g_signal_connect(G_OBJECT(radio_frame), "toggled", G_CALLBACK(gui_shift_times_type_changed_cb), NULL); g_signal_connect(G_OBJECT(combo_fps), "changed", G_CALLBACK(gui_shift_times_spin_frame_changed_cb), NULL); g_signal_connect(G_OBJECT(spin_frame), "value-changed", G_CALLBACK(gui_shift_times_spin_frame_changed_cb), NULL); if(app.ui.tab_video.video) { char *fps = kry_strdup_printf(KRY_LOC "%f", video_get_fps(app.ui.tab_video.video)); gui_combo_box_add_text(GTK_COMBO_BOX(combo_fps), fps, TRUE); kry_free(fps); } else { gui_combo_box_set_text(GTK_COMBO_BOX(combo_fps), "23.976", TRUE); } gtk_box_pack_start(GTK_BOX(hbox_offset_frame), GTK_WIDGET(radio_frame), FALSE, TRUE, 0); gtk_box_pack_start(GTK_BOX(hbox_offset_frame), GTK_WIDGET(spin_frame), FALSE, TRUE, 0); gtk_box_pack_start(GTK_BOX(hbox_offset_frame), GTK_WIDGET(label_fps), FALSE, TRUE, 5); gtk_box_pack_start(GTK_BOX(hbox_offset_frame), GTK_WIDGET(combo_fps), FALSE, TRUE, 5); gtk_widget_set_sensitive(GTK_WIDGET(spin_frame), FALSE); gtk_widget_set_sensitive(GTK_WIDGET(label_fps), FALSE); gtk_widget_set_sensitive(GTK_WIDGET(combo_fps), FALSE); GtkVBox *vbox_offset = GTK_VBOX(gtk_vbox_new(FALSE, 0)); gtk_box_pack_start(GTK_BOX(vbox_offset), GTK_WIDGET(hbox_offset_time), FALSE, TRUE, 0); gtk_box_pack_start(GTK_BOX(vbox_offset), GTK_WIDGET(hbox_offset_frame), FALSE, TRUE, 4); gtk_container_add(GTK_CONTAINER(frame_offset), GTK_WIDGET(vbox_offset)); gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(frame_offset), FALSE, TRUE, 0); if(lopts->shift_type == SHIFT_BY_TIME) { char *str = time_mili_to_string(lopts->offset_mili); gui_time_entry_set_text(entry_time, str); kry_free(str); } else { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lui->radio_by_frame), TRUE); gtk_spin_button_set_value(lui->spin_frame, lopts->offset_frames); if(lopts->fps) gui_combo_box_add_text(GTK_COMBO_BOX(lui->combo_fps), lopts->fps, TRUE); } } // Direction Frame { GtkVBox *vbox_direction = GTK_VBOX(gtk_vbox_new(FALSE, 0)); GtkFrame *frame_direction = GTK_FRAME(gtk_frame_new(_("Shift Direction"))); GtkRadioButton *radio_forward = GTK_RADIO_BUTTON(gtk_radio_button_new_with_label(NULL, _("Forward"))); GtkRadioButton *radio_backward = GTK_RADIO_BUTTON(gtk_radio_button_new_with_label_from_widget(radio_forward, _("Backward"))); gtk_box_pack_start(GTK_BOX(vbox_direction), GTK_WIDGET(radio_forward), FALSE, TRUE, 0); gtk_box_pack_start(GTK_BOX(vbox_direction), GTK_WIDGET(radio_backward), FALSE, TRUE, 0); gtk_container_add(GTK_CONTAINER(frame_direction), GTK_WIDGET(vbox_direction)); gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(frame_direction), FALSE, TRUE, 0); lui->radio_forward = radio_forward; lui->radio_backward = radio_backward; if(lopts->shift_direction == SHIFT_BACKWARD) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio_backward), TRUE); } // Affected Rows Frame { GtkVBox *vbox_rows = GTK_VBOX(gtk_vbox_new(FALSE, 0)); GtkFrame *frame_rows = GTK_FRAME(gtk_frame_new(_("Affected Rows"))); GtkRadioButton *radio_from_selected = GTK_RADIO_BUTTON(gtk_radio_button_new_with_label(NULL, _("All Starting from First Selected Row"))); GtkRadioButton *radio_until_selected = GTK_RADIO_BUTTON(gtk_radio_button_new_with_label_from_widget(radio_from_selected, _("All Before First Selected Row"))); GtkRadioButton *radio_selected = GTK_RADIO_BUTTON(gtk_radio_button_new_with_label_from_widget(radio_until_selected, _("Selected Rows"))); GtkRadioButton *radio_unselected = GTK_RADIO_BUTTON(gtk_radio_button_new_with_label_from_widget(radio_from_selected, _("Non-Selected Rows"))); GtkRadioButton *radio_all = GTK_RADIO_BUTTON(gtk_radio_button_new_with_label_from_widget(radio_unselected, _("All"))); gtk_box_pack_start(GTK_BOX(vbox_rows), GTK_WIDGET(radio_from_selected), FALSE, TRUE, 0); gtk_box_pack_start(GTK_BOX(vbox_rows), GTK_WIDGET(radio_until_selected), FALSE, TRUE, 0); gtk_box_pack_start(GTK_BOX(vbox_rows), GTK_WIDGET(radio_selected), FALSE, TRUE, 0); gtk_box_pack_start(GTK_BOX(vbox_rows), GTK_WIDGET(radio_unselected), FALSE, TRUE, 0); gtk_box_pack_start(GTK_BOX(vbox_rows), GTK_WIDGET(radio_all), FALSE, TRUE, 0); gtk_container_add(GTK_CONTAINER(frame_rows), GTK_WIDGET(vbox_rows)); gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(frame_rows), FALSE, TRUE, 0); lui->radio_row_all = radio_all; lui->radio_row_from_selection = radio_from_selected; lui->radio_row_before_selection = radio_until_selected; lui->radio_row_selected = radio_selected; lui->radio_row_notselected = radio_unselected; if(lopts->shift_affected_rows == SHIFT_SELECTED || gtk_tree_selection_count_selected_rows(gui_event_list_get_selection(app.ui.event_list)) > 1) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio_selected), TRUE); } else if(lopts->shift_affected_rows == SHIFT_ALL) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio_all), TRUE); } else if(lopts->shift_affected_rows == SHIFT_FROM_SELECTED) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio_from_selected), TRUE); } else if(lopts->shift_affected_rows == SHIFT_BEFORE_SELECTED) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio_until_selected), TRUE); } else if(lopts->shift_affected_rows == SHIFT_NOTSELECTED) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio_unselected), TRUE); } } // Affected Times Frame { GtkVBox *vbox_times = GTK_VBOX(gtk_vbox_new(FALSE, 0)); GtkFrame *frame_times = GTK_FRAME(gtk_frame_new(_("Affected Times"))); GtkRadioButton *radio_both = GTK_RADIO_BUTTON(gtk_radio_button_new_with_label(NULL, _("Both Start Time and End Time"))); GtkRadioButton *radio_start = GTK_RADIO_BUTTON(gtk_radio_button_new_with_label_from_widget(radio_both, _("Only Start Time"))); GtkRadioButton *radio_end = GTK_RADIO_BUTTON(gtk_radio_button_new_with_label_from_widget(radio_start, _("Only End Time"))); gtk_box_pack_start(GTK_BOX(vbox_times), GTK_WIDGET(radio_both), FALSE, TRUE, 0); gtk_box_pack_start(GTK_BOX(vbox_times), GTK_WIDGET(radio_start), FALSE, TRUE, 0); gtk_box_pack_start(GTK_BOX(vbox_times), GTK_WIDGET(radio_end), FALSE, TRUE, 0); gtk_container_add(GTK_CONTAINER(frame_times), GTK_WIDGET(vbox_times)); gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(frame_times), FALSE, TRUE, 0); lui->radio_time_both = radio_both; lui->radio_time_end = radio_end; lui->radio_time_start = radio_start; if(lopts->shift_affected_times == SHIFT_START) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio_start), TRUE); else if(lopts->shift_affected_times == SHIFT_END) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio_end), TRUE); } // Buttons Frame { GtkHBox *hbox_buttons = GTK_HBOX(gtk_hbox_new(TRUE, 5)); GtkButton *button_ok = GTK_BUTTON(gtk_button_new_from_stock(_("gtk-ok"))); GtkButton *button_cancel = GTK_BUTTON(gtk_button_new_from_stock(_("gtk-cancel"))); gtk_box_pack_start(GTK_BOX(hbox_buttons), GTK_WIDGET(button_ok), TRUE, TRUE, 5); gtk_box_pack_start(GTK_BOX(hbox_buttons), GTK_WIDGET(button_cancel), TRUE, TRUE, 5); gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(hbox_buttons), FALSE, TRUE, 5); g_signal_connect(button_ok, "clicked", G_CALLBACK(gui_shift_times_button_cb), NULL); g_signal_connect(button_cancel, "clicked", G_CALLBACK(gui_shift_times_destroy), NULL); } gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(vbox)); gtk_widget_show_all(GTK_WIDGET(window)); lui->window = window; } void gui_shift_times_show_custom(long time, enum shift_direction direction, enum shift_affected_rows rows) { enum shift_type orig_type = lopts->shift_type; enum shift_direction orig_direction = lopts->shift_direction; enum shift_affected_rows orig_rows = lopts->shift_affected_rows; enum shift_affected_times orig_times = lopts->shift_affected_times; int mili_orig = lopts->offset_mili; lopts->shift_type = SHIFT_BY_TIME; lopts->shift_direction = direction; lopts->shift_affected_rows = rows; lopts->shift_affected_times = SHIFT_START_END; lopts->offset_mili = time; gui_shift_times_show(); lopts->shift_type = orig_type; lopts->shift_direction = orig_direction; lopts->shift_affected_rows = orig_rows; lopts->shift_affected_times = orig_times; lopts->offset_mili = mili_orig; } void gui_main_menu_event_shift_times_cb(gpointer callback_data, gint callback_arg, GtkMenuItem *item) { gui_shift_times_show(); }