Added scrolled window
[irreco.git] / irreco / src / core / irreco_cmd_chain_editor.c
blobe6905d8b99a798b6450d217cd6be43148d6eeb59
1 /*
2 * irreco - Ir Remote Control
3 * Copyright (C) 2007 Arto Karppinen (arto.karppinen@iki.fi)
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 #include "irreco_cmd_chain_editor.h"
21 #include "irreco_cmd_chain_setup_dlg.h"
22 #include "irreco_cmd_dlg.h"
24 /**
25 * @addtogroup IrrecoCmdChainEditor
26 * @ingroup Irreco
28 * User interface for editing IrrecoCmdChains.
30 * @{
33 /**
34 * @file
35 * Source file of @ref IrrecoCmdChainEditor.
40 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
41 /* Prototypes. */
42 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
43 static void irreco_cmd_chain_editor_set_sensitivity(IrrecoCmdChainEditor *self);
44 static void irreco_cmd_chain_editor_clear(IrrecoCmdChainEditor *self);
45 void irreco_cmd_chain_editor_add_clicked(GtkButton *button,
46 IrrecoCmdChainEditor *self);
47 void irreco_cmd_chain_editor_remove_clicked(GtkButton *button,
48 IrrecoCmdChainEditor *self);
49 void irreco_cmd_chain_editor_up_clicked(GtkButton *button,
50 IrrecoCmdChainEditor *self);
51 void irreco_cmd_chain_editor_down_clicked(GtkButton *button,
52 IrrecoCmdChainEditor *self);
53 void irreco_cmd_chain_editor_properties_clicked(GtkButton *button,
54 IrrecoCmdChainEditor *self);
55 void irreco_cmd_chain_editor_selection_changed(GtkTreeSelection * selection,
56 IrrecoCmdChainEditor *self);
60 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
61 /* Construction & Destruction */
62 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
64 /**
65 * @name Construction & Destruction
66 * @{
69 G_DEFINE_TYPE(IrrecoCmdChainEditor, irreco_cmd_chain_editor,
70 IRRECO_TYPE_INTERNAL_WIDGET)
72 static void irreco_cmd_chain_editor_finalize(GObject *object)
74 IRRECO_ENTER
75 G_OBJECT_CLASS(irreco_cmd_chain_editor_parent_class)->finalize(object);
76 irreco_cmd_chain_editor_clear(IRRECO_CMD_CHAIN_EDITOR(object));
77 IRRECO_RETURN
80 static void irreco_cmd_chain_editor_class_init(IrrecoCmdChainEditorClass *klass)
82 GObjectClass *object_class;
83 IRRECO_ENTER
85 object_class = G_OBJECT_CLASS (klass);
86 object_class->finalize = irreco_cmd_chain_editor_finalize;
87 IRRECO_RETURN
90 static void irreco_cmd_chain_editor_init(IrrecoCmdChainEditor *self)
92 GdkPixbuf *icon;
93 GtkWidget *image;
94 IRRECO_ENTER
96 gtk_box_set_spacing(GTK_BOX(self), 1);
98 self->edit_mode = IRRECO_INDIRECT_EDITING;
99 self->old_cmd_chain = NULL;
100 self->new_cmd_chain = NULL;
102 self->listbox = irreco_listbox_text_new();
103 self->hbox = gtk_hbox_new(0, 0);
105 gtk_box_pack_start(GTK_BOX(self), self->listbox, 1, 1, 1);
106 gtk_box_pack_start(GTK_BOX(self), self->hbox, 0, 0, 0);
108 self->add = gtk_button_new_from_stock(GTK_STOCK_ADD);
109 self->remove = gtk_button_new_from_stock(GTK_STOCK_REMOVE);
110 self->up = gtk_button_new_from_stock(GTK_STOCK_GO_UP);
111 self->down = gtk_button_new_from_stock(GTK_STOCK_GO_DOWN);
112 self->properties = gtk_button_new();
114 /* Set properties icon. We use just the icon to save space. */
115 icon = gtk_widget_render_icon(self->properties, GTK_STOCK_PROPERTIES,
116 GTK_ICON_SIZE_BUTTON, NULL);
117 image = gtk_image_new_from_pixbuf(icon);
118 gtk_button_set_image(GTK_BUTTON(self->properties), image);
120 gtk_box_pack_start_defaults(GTK_BOX(self->hbox), self->add);
121 gtk_box_pack_start_defaults(GTK_BOX(self->hbox), self->remove);
122 gtk_box_pack_start_defaults(GTK_BOX(self->hbox), self->up);
123 gtk_box_pack_start_defaults(GTK_BOX(self->hbox), self->down);
124 gtk_box_pack_start_defaults(GTK_BOX(self->hbox), self->properties);
126 g_signal_connect(G_OBJECT(self->add), "clicked",
127 G_CALLBACK(irreco_cmd_chain_editor_add_clicked),
128 self);
129 g_signal_connect(G_OBJECT(self->remove), "clicked",
130 G_CALLBACK(irreco_cmd_chain_editor_remove_clicked),
131 self);
132 g_signal_connect(G_OBJECT(self->up), "clicked",
133 G_CALLBACK(irreco_cmd_chain_editor_up_clicked),
134 self);
135 g_signal_connect(G_OBJECT(self->down), "clicked",
136 G_CALLBACK(irreco_cmd_chain_editor_down_clicked),
137 self);
138 g_signal_connect(G_OBJECT(self->properties), "clicked",
139 G_CALLBACK(irreco_cmd_chain_editor_properties_clicked),
140 self);
141 g_signal_connect(G_OBJECT(IRRECO_LISTBOX(
142 self->listbox)->tree_selection),
143 "changed",
144 G_CALLBACK(irreco_cmd_chain_editor_selection_changed),
145 self);
147 irreco_cmd_chain_editor_set_sensitivity(self);
149 IRRECO_RETURN
152 GtkWidget* irreco_cmd_chain_editor_new(IrrecoData *irreco_data,
153 GtkWindow *parent)
155 IrrecoCmdChainEditor *self;
156 IRRECO_ENTER
158 self = g_object_new(IRRECO_TYPE_CMD_CHAIN_EDITOR,
159 "irreco-data", irreco_data,
160 NULL);
161 irreco_cmd_chain_editor_set_parent_window(self, parent);
162 IRRECO_RETURN_PTR(GTK_WIDGET(self));
165 /** @} */
169 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
170 /* Private Functions */
171 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
174 * @name Private Functions
175 * @{
178 static void irreco_cmd_chain_editor_clear(IrrecoCmdChainEditor *self)
180 IRRECO_ENTER
181 irreco_cmd_chain_destroy(self->new_cmd_chain);
182 self->old_cmd_chain = NULL;
183 self->new_cmd_chain = NULL;
184 IRRECO_RETURN
188 * Get the command chain which we should be editing.
190 static IrrecoCmdChain *
191 irreco_cmd_chain_editor_get_edit_chain(IrrecoCmdChainEditor *self)
193 IRRECO_ENTER
194 switch (self->edit_mode) {
195 case IRRECO_INDIRECT_EDITING:
196 g_assert(self->new_cmd_chain);
197 IRRECO_RETURN_PTR(self->new_cmd_chain);
199 case IRRECO_DIRECT_EDITING:
200 g_assert(self->old_cmd_chain);
201 IRRECO_RETURN_PTR(self->old_cmd_chain);
204 /* Invalid enum value. */
205 g_assert_not_reached();
208 static void irreco_cmd_chain_editor_populate_listbox(IrrecoCmdChainEditor *self)
210 IrrecoCmdChain *edit_chain;
211 IRRECO_ENTER
213 edit_chain = irreco_cmd_chain_editor_get_edit_chain(self);
214 irreco_listbox_clear(IRRECO_LISTBOX(self->listbox));
215 IRRECO_CMD_CHAIN_FOREACH(edit_chain, command)
216 irreco_listbox_text_append(IRRECO_LISTBOX_TEXT(self->listbox),
217 irreco_cmd_get_long_name(command),
218 command);
219 IRRECO_CMD_CHAIN_FOREACH_END
220 irreco_listbox_set_selection(IRRECO_LISTBOX(self->listbox), 0);
221 IRRECO_RETURN
224 static void irreco_cmd_chain_editor_set_sensitivity(IrrecoCmdChainEditor *self)
226 gint sel_index;
227 IRRECO_ENTER
229 sel_index = irreco_listbox_get_selection_index(
230 IRRECO_LISTBOX(self->listbox));
232 if (sel_index == -1) {
233 gtk_widget_set_sensitive(self->remove, FALSE);
234 gtk_widget_set_sensitive(self->up, FALSE);
235 gtk_widget_set_sensitive(self->down, FALSE);
236 } else if (IRRECO_LISTBOX(self->listbox)->list_store->length == 1) {
237 gtk_widget_set_sensitive(self->remove, TRUE);
238 gtk_widget_set_sensitive(self->up, FALSE);
239 gtk_widget_set_sensitive(self->down, FALSE);
240 } else if (sel_index == 0) {
241 gtk_widget_set_sensitive(self->remove, TRUE);
242 gtk_widget_set_sensitive(self->up, FALSE);
243 gtk_widget_set_sensitive(self->down, TRUE);
244 } else if (sel_index ==
245 (IRRECO_LISTBOX(self->listbox)->list_store->length - 1)) {
246 gtk_widget_set_sensitive(self->remove, TRUE);
247 gtk_widget_set_sensitive(self->up, TRUE);
248 gtk_widget_set_sensitive(self->down, FALSE);
249 } else {
250 gtk_widget_set_sensitive(self->remove, TRUE);
251 gtk_widget_set_sensitive(self->up, TRUE);
252 gtk_widget_set_sensitive(self->down, TRUE);
254 IRRECO_RETURN
257 /** @} */
261 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
262 /* Public Functions */
263 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
266 * @name Public Functions
267 * @{
271 * Set parent window for popup dialogs.
273 void irreco_cmd_chain_editor_set_parent_window(IrrecoCmdChainEditor *self,
274 GtkWindow *parent)
276 IRRECO_ENTER
277 self->parent_window = parent;
278 IRRECO_RETURN
281 void irreco_cmd_chain_editor_set_edit_mode(IrrecoCmdChainEditor *self,
282 IrrecoEditMode edit_mode)
284 IRRECO_ENTER
285 switch (edit_mode) {
286 case IRRECO_INDIRECT_EDITING:
287 case IRRECO_DIRECT_EDITING:
288 self->edit_mode = edit_mode;
289 break;
291 default:
292 IRRECO_ERROR("Invalid edit mode \"%i\".\n", edit_mode);
293 break;
295 IRRECO_RETURN
298 void irreco_cmd_chain_editor_set_chain(IrrecoCmdChainEditor *self,
299 IrrecoCmdChain *cmd_chain)
301 IRRECO_ENTER
303 g_assert(cmd_chain != NULL);
304 irreco_cmd_chain_editor_clear(self);
306 if (self->edit_mode == IRRECO_INDIRECT_EDITING) {
307 self->old_cmd_chain = cmd_chain;
308 self->new_cmd_chain = irreco_cmd_chain_create();
309 irreco_cmd_chain_copy(cmd_chain, self->new_cmd_chain);
310 } else {
311 self->old_cmd_chain = cmd_chain;
314 irreco_cmd_chain_editor_populate_listbox(self);
315 IRRECO_RETURN
318 IrrecoCmdChain *irreco_cmd_chain_editor_get_chain(IrrecoCmdChainEditor *self)
320 IRRECO_ENTER
321 IRRECO_RETURN_PTR(self->old_cmd_chain);
324 void irreco_cmd_chain_editor_set_autosize(IrrecoCmdChainEditor *self,
325 gint min_width,
326 gint max_width,
327 gint min_height,
328 gint max_height)
330 gint width, height;
331 IRRECO_ENTER
332 gtk_widget_get_size_request(self->hbox, &width, &height);
333 if (max_width < width) max_width = width;
334 irreco_listbox_set_autosize(IRRECO_LISTBOX(self->listbox),
335 min_width, max_width,
336 min_height, max_height - height);
337 IRRECO_RETURN
340 void irreco_cmd_chain_editor_apply_changes(IrrecoCmdChainEditor *self)
342 IRRECO_ENTER
344 g_assert(self->edit_mode == IRRECO_INDIRECT_EDITING);
346 if (self->old_cmd_chain != NULL && self->new_cmd_chain != NULL) {
347 IRRECO_DEBUG("Saving command chain changes.\n");
348 irreco_cmd_chain_print(self->new_cmd_chain);
349 irreco_cmd_chain_copy(self->new_cmd_chain, self->old_cmd_chain);
351 IRRECO_RETURN
354 void irreco_cmd_chain_editor_reset_changes(IrrecoCmdChainEditor *self)
356 IRRECO_ENTER
358 g_assert(self->edit_mode == IRRECO_INDIRECT_EDITING);
360 if (self->old_cmd_chain != NULL && self->new_cmd_chain != NULL) {
361 irreco_cmd_chain_copy(self->old_cmd_chain, self->new_cmd_chain);
363 IRRECO_RETURN
366 void irreco_cmd_chain_editor_clear_chain(IrrecoCmdChainEditor *self)
368 IRRECO_ENTER
369 irreco_cmd_chain_remove_all(self->new_cmd_chain);
370 irreco_cmd_chain_editor_populate_listbox(self);
371 IRRECO_RETURN
374 /** @} */
378 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
379 /* Signals, Events and Callbacks */
380 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
383 * @name Events and Callbacks
384 * @{
387 void irreco_cmd_chain_editor_add_clicked(GtkButton *button,
388 IrrecoCmdChainEditor *self)
390 IrrecoCmdChain *edit_chain;
391 IrrecoCmd *command;
392 IRRECO_ENTER
394 command = irreco_cmd_create();
395 edit_chain = irreco_cmd_chain_editor_get_edit_chain(self);
397 if (irreco_cmd_dlg_run(irreco_internal_widget_get_irreco_data(
398 IRRECO_INTERNAL_WIDGET(self)), command, self->parent_window)) {
400 irreco_cmd_chain_append(edit_chain, command);
401 irreco_listbox_text_append(IRRECO_LISTBOX_TEXT(self->listbox),
402 irreco_cmd_get_long_name(command),
403 command);
404 gtk_widget_grab_focus(IRRECO_LISTBOX(self->listbox)->tree_view);
405 } else {
406 irreco_cmd_destroy(command);
409 irreco_cmd_chain_editor_set_sensitivity(self);
410 IRRECO_RETURN
413 void irreco_cmd_chain_editor_remove_clicked(GtkButton *button,
414 IrrecoCmdChainEditor *self)
416 gint sel_index;
417 IrrecoCmdChain *edit_chain;
418 IRRECO_ENTER
420 sel_index = irreco_listbox_get_selection_index(
421 IRRECO_LISTBOX(self->listbox));
422 edit_chain = irreco_cmd_chain_editor_get_edit_chain(self);
423 irreco_cmd_chain_remove(edit_chain, sel_index);
424 irreco_listbox_remove_selected(IRRECO_LISTBOX(self->listbox));
425 irreco_cmd_chain_editor_set_sensitivity(self);
426 gtk_widget_grab_focus(IRRECO_LISTBOX(self->listbox)->tree_view);
427 IRRECO_RETURN
430 void irreco_cmd_chain_editor_up_clicked(GtkButton *button,
431 IrrecoCmdChainEditor *self)
433 gint sel_index;
434 IrrecoCmdChain *edit_chain;
435 IRRECO_ENTER
437 sel_index = irreco_listbox_get_selection_index(
438 IRRECO_LISTBOX(self->listbox));
439 edit_chain = irreco_cmd_chain_editor_get_edit_chain(self);
440 irreco_cmd_chain_move(edit_chain, sel_index, sel_index - 1);
441 irreco_listbox_move_selected_up(IRRECO_LISTBOX(self->listbox));
442 irreco_cmd_chain_editor_set_sensitivity(self);
443 gtk_widget_grab_focus(IRRECO_LISTBOX(self->listbox)->tree_view);
444 IRRECO_RETURN
447 void irreco_cmd_chain_editor_down_clicked(GtkButton *button,
448 IrrecoCmdChainEditor *self)
450 gint sel_index;
451 IrrecoCmdChain *edit_chain;
452 IRRECO_ENTER
454 sel_index = irreco_listbox_get_selection_index(
455 IRRECO_LISTBOX(self->listbox));
456 edit_chain = irreco_cmd_chain_editor_get_edit_chain(self);
457 irreco_cmd_chain_move(edit_chain, sel_index, sel_index + 1);
458 irreco_listbox_move_selected_down(IRRECO_LISTBOX(self->listbox));
459 irreco_cmd_chain_editor_set_sensitivity(self);
460 gtk_widget_grab_focus(IRRECO_LISTBOX(self->listbox)->tree_view);
461 IRRECO_RETURN
464 void irreco_cmd_chain_editor_properties_clicked(GtkButton *button,
465 IrrecoCmdChainEditor *self)
467 GtkWidget *dlg;
468 IrrecoCmdChain *edit_chain;
469 IRRECO_ENTER
471 edit_chain = irreco_cmd_chain_editor_get_edit_chain(self);
472 dlg = irreco_cmd_chain_setup_dlg_new(self->parent_window, edit_chain);
473 gtk_dialog_run(GTK_DIALOG(dlg));
474 gtk_widget_destroy(dlg);
475 IRRECO_RETURN
478 void irreco_cmd_chain_editor_selection_changed(GtkTreeSelection *selection,
479 IrrecoCmdChainEditor *self)
481 IRRECO_ENTER
482 irreco_cmd_chain_editor_set_sensitivity(self);
483 IRRECO_RETURN
486 /** @} */
488 /** @} */