summaryrefslogtreecommitdiffstats
path: root/app/widgets/gimpdeviceeditor.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/widgets/gimpdeviceeditor.c')
-rw-r--r--app/widgets/gimpdeviceeditor.c550
1 files changed, 550 insertions, 0 deletions
diff --git a/app/widgets/gimpdeviceeditor.c b/app/widgets/gimpdeviceeditor.c
new file mode 100644
index 0000000..6b9e884
--- /dev/null
+++ b/app/widgets/gimpdeviceeditor.c
@@ -0,0 +1,550 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimpdeviceeditor.c
+ * Copyright (C) 2010 Michael Natterer <mitch@gimp.org>
+ *
+ * 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 3 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 <https://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <gegl.h>
+#include <gtk/gtk.h>
+
+#include "libgimpwidgets/gimpwidgets.h"
+
+#include "widgets-types.h"
+
+#include "core/gimp.h"
+#include "core/gimpcontext.h"
+#include "core/gimplist.h"
+#include "core/gimpmarshal.h"
+
+#include "gimpcontainerview.h"
+#include "gimpcontainertreestore.h"
+#include "gimpcontainertreeview.h"
+#include "gimpdeviceeditor.h"
+#include "gimpdeviceinfo.h"
+#include "gimpdeviceinfoeditor.h"
+#include "gimpdevicemanager.h"
+#include "gimpdevices.h"
+#include "gimpmessagebox.h"
+#include "gimpmessagedialog.h"
+
+#include "gimp-intl.h"
+
+
+enum
+{
+ PROP_0,
+ PROP_GIMP
+};
+
+
+typedef struct _GimpDeviceEditorPrivate GimpDeviceEditorPrivate;
+
+struct _GimpDeviceEditorPrivate
+{
+ Gimp *gimp;
+
+ GQuark name_changed_handler;
+
+ GtkWidget *treeview;
+ GtkWidget *delete_button;
+
+ GtkWidget *label;
+ GtkWidget *image;
+
+ GtkWidget *notebook;
+};
+
+
+#define GIMP_DEVICE_EDITOR_GET_PRIVATE(editor) \
+ ((GimpDeviceEditorPrivate *) gimp_device_editor_get_instance_private ((GimpDeviceEditor *) (editor)))
+
+
+static void gimp_device_editor_constructed (GObject *object);
+static void gimp_device_editor_dispose (GObject *object);
+static void gimp_device_editor_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gimp_device_editor_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+static void gimp_device_editor_add_device (GimpContainer *container,
+ GimpDeviceInfo *info,
+ GimpDeviceEditor *editor);
+static void gimp_device_editor_remove_device (GimpContainer *container,
+ GimpDeviceInfo *info,
+ GimpDeviceEditor *editor);
+static void gimp_device_editor_device_changed (GimpDeviceInfo *info,
+ GimpDeviceEditor *editor);
+
+static void gimp_device_editor_select_device (GimpContainerView *view,
+ GimpViewable *viewable,
+ gpointer insert_data,
+ GimpDeviceEditor *editor);
+
+static void gimp_device_editor_switch_page (GtkNotebook *notebook,
+ gpointer page,
+ guint page_num,
+ GimpDeviceEditor *editor);
+static void gimp_device_editor_delete_clicked (GtkWidget *button,
+ GimpDeviceEditor *editor);
+
+
+G_DEFINE_TYPE_WITH_PRIVATE (GimpDeviceEditor, gimp_device_editor,
+ GTK_TYPE_PANED)
+
+#define parent_class gimp_device_editor_parent_class
+
+
+static void
+gimp_device_editor_class_init (GimpDeviceEditorClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->constructed = gimp_device_editor_constructed;
+ object_class->dispose = gimp_device_editor_dispose;
+ object_class->set_property = gimp_device_editor_set_property;
+ object_class->get_property = gimp_device_editor_get_property;
+
+ g_object_class_install_property (object_class, PROP_GIMP,
+ g_param_spec_object ("gimp",
+ NULL, NULL,
+ GIMP_TYPE_GIMP,
+ GIMP_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+}
+
+static void
+gimp_device_editor_init (GimpDeviceEditor *editor)
+{
+ GimpDeviceEditorPrivate *private = GIMP_DEVICE_EDITOR_GET_PRIVATE (editor);
+ GtkWidget *vbox;
+ GtkWidget *ebox;
+ GtkWidget *hbox;
+ gint icon_width;
+ gint icon_height;
+
+ gtk_orientable_set_orientation (GTK_ORIENTABLE (editor),
+ GTK_ORIENTATION_HORIZONTAL);
+
+ gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (GTK_WIDGET (editor)),
+ GTK_ICON_SIZE_BUTTON,
+ &icon_width, &icon_height);
+
+ private->treeview = gimp_container_tree_view_new (NULL, NULL, icon_height, 0);
+ gtk_widget_set_size_request (private->treeview, 300, -1);
+ gtk_paned_pack1 (GTK_PANED (editor), private->treeview, TRUE, FALSE);
+ gtk_widget_show (private->treeview);
+
+ g_signal_connect_object (private->treeview, "select-item",
+ G_CALLBACK (gimp_device_editor_select_device),
+ G_OBJECT (editor), 0);
+
+ private->delete_button =
+ gimp_editor_add_button (GIMP_EDITOR (private->treeview),
+ "edit-delete",
+ _("Delete the selected device"),
+ NULL,
+ G_CALLBACK (gimp_device_editor_delete_clicked),
+ NULL,
+ G_OBJECT (editor));
+
+ gtk_widget_set_sensitive (private->delete_button, FALSE);
+
+ vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
+ gtk_paned_pack2 (GTK_PANED (editor), vbox, TRUE, FALSE);
+ gtk_widget_show (vbox);
+
+ ebox = gtk_event_box_new ();
+ gtk_widget_set_state (ebox, GTK_STATE_SELECTED);
+ gtk_box_pack_start (GTK_BOX (vbox), ebox, FALSE, FALSE, 0);
+ gtk_widget_show (ebox);
+
+ hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
+ gtk_container_set_border_width (GTK_CONTAINER (hbox), 4);
+ gtk_container_add (GTK_CONTAINER (ebox), hbox);
+ gtk_widget_show (hbox);
+
+ private->label = gtk_label_new (NULL);
+ gtk_label_set_xalign (GTK_LABEL (private->label), 0.0);
+ gtk_label_set_ellipsize (GTK_LABEL (private->label), PANGO_ELLIPSIZE_END);
+ gimp_label_set_attributes (GTK_LABEL (private->label),
+ PANGO_ATTR_WEIGHT, PANGO_WEIGHT_BOLD,
+ -1);
+ gtk_box_pack_start (GTK_BOX (hbox), private->label, TRUE, TRUE, 0);
+ gtk_widget_show (private->label);
+
+ private->image = gtk_image_new ();
+ gtk_widget_set_size_request (private->image, -1, 24);
+ gtk_box_pack_end (GTK_BOX (hbox), private->image, FALSE, FALSE, 0);
+ gtk_widget_show (private->image);
+
+ private->notebook = gtk_notebook_new ();
+ gtk_notebook_set_show_border (GTK_NOTEBOOK (private->notebook), FALSE);
+ gtk_notebook_set_show_tabs (GTK_NOTEBOOK (private->notebook), FALSE);
+ gtk_box_pack_start (GTK_BOX (vbox), private->notebook, TRUE, TRUE, 0);
+ gtk_widget_show (private->notebook);
+
+ g_signal_connect (private->notebook, "switch-page",
+ G_CALLBACK (gimp_device_editor_switch_page),
+ editor);
+}
+
+static void
+gimp_device_editor_constructed (GObject *object)
+{
+ GimpDeviceEditor *editor = GIMP_DEVICE_EDITOR (object);
+ GimpDeviceEditorPrivate *private = GIMP_DEVICE_EDITOR_GET_PRIVATE (editor);
+ GimpContainer *devices;
+ GimpContext *context;
+ GList *list;
+
+ G_OBJECT_CLASS (parent_class)->constructed (object);
+
+ gimp_assert (GIMP_IS_GIMP (private->gimp));
+
+ devices = GIMP_CONTAINER (gimp_devices_get_manager (private->gimp));
+
+ /* connect to "remove" before the container view does so we can get
+ * the notebook child stored in its model
+ */
+ g_signal_connect (devices, "remove",
+ G_CALLBACK (gimp_device_editor_remove_device),
+ editor);
+
+ gimp_container_view_set_container (GIMP_CONTAINER_VIEW (private->treeview),
+ devices);
+
+ context = gimp_context_new (private->gimp, "device-editor-list", NULL);
+ gimp_container_view_set_context (GIMP_CONTAINER_VIEW (private->treeview),
+ context);
+ g_object_unref (context);
+
+ g_signal_connect (devices, "add",
+ G_CALLBACK (gimp_device_editor_add_device),
+ editor);
+
+ private->name_changed_handler =
+ gimp_container_add_handler (devices, "name-changed",
+ G_CALLBACK (gimp_device_editor_device_changed),
+ editor);
+
+ for (list = GIMP_LIST (devices)->queue->head;
+ list;
+ list = g_list_next (list))
+ {
+ gimp_device_editor_add_device (devices, list->data, editor);
+ }
+}
+
+static void
+gimp_device_editor_dispose (GObject *object)
+{
+ GimpDeviceEditorPrivate *private = GIMP_DEVICE_EDITOR_GET_PRIVATE (object);
+ GimpContainer *devices;
+
+ devices = GIMP_CONTAINER (gimp_devices_get_manager (private->gimp));
+
+ g_signal_handlers_disconnect_by_func (devices,
+ gimp_device_editor_add_device,
+ object);
+
+ g_signal_handlers_disconnect_by_func (devices,
+ gimp_device_editor_remove_device,
+ object);
+
+ if (private->name_changed_handler)
+ {
+ gimp_container_remove_handler (devices, private->name_changed_handler);
+ private->name_changed_handler = 0;
+ }
+
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+gimp_device_editor_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GimpDeviceEditorPrivate *private = GIMP_DEVICE_EDITOR_GET_PRIVATE (object);
+
+ switch (property_id)
+ {
+ case PROP_GIMP:
+ private->gimp = g_value_get_object (value); /* don't ref */
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gimp_device_editor_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GimpDeviceEditorPrivate *private = GIMP_DEVICE_EDITOR_GET_PRIVATE (object);
+
+ switch (property_id)
+ {
+ case PROP_GIMP:
+ g_value_set_object (value, private->gimp);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gimp_device_editor_add_device (GimpContainer *container,
+ GimpDeviceInfo *info,
+ GimpDeviceEditor *editor)
+{
+ GimpDeviceEditorPrivate *private = GIMP_DEVICE_EDITOR_GET_PRIVATE (editor);
+ GtkWidget *widget;
+ GtkTreeIter *iter;
+
+ widget = gimp_device_info_editor_new (info);
+ gtk_notebook_append_page (GTK_NOTEBOOK (private->notebook), widget, NULL);
+ gtk_widget_show (widget);
+
+ iter = gimp_container_view_lookup (GIMP_CONTAINER_VIEW (private->treeview),
+ GIMP_VIEWABLE (info));
+
+ if (iter)
+ {
+ GimpContainerTreeView *treeview;
+
+ treeview = GIMP_CONTAINER_TREE_VIEW (private->treeview);
+
+ gtk_tree_store_set (GTK_TREE_STORE (treeview->model), iter,
+ GIMP_CONTAINER_TREE_STORE_COLUMN_USER_DATA, widget,
+ GIMP_CONTAINER_TREE_STORE_COLUMN_NAME_SENSITIVE,
+ gimp_device_info_get_device (info, NULL) != NULL,
+ -1);
+ }
+}
+
+static void
+gimp_device_editor_remove_device (GimpContainer *container,
+ GimpDeviceInfo *info,
+ GimpDeviceEditor *editor)
+{
+ GimpDeviceEditorPrivate *private = GIMP_DEVICE_EDITOR_GET_PRIVATE (editor);
+ GtkTreeIter *iter;
+
+ iter = gimp_container_view_lookup (GIMP_CONTAINER_VIEW (private->treeview),
+ GIMP_VIEWABLE (info));
+
+ if (iter)
+ {
+ GimpContainerTreeView *treeview;
+ GtkWidget *widget;
+
+ treeview = GIMP_CONTAINER_TREE_VIEW (private->treeview);
+
+ gtk_tree_model_get (treeview->model, iter,
+ GIMP_CONTAINER_TREE_STORE_COLUMN_USER_DATA, &widget,
+ -1);
+
+ if (widget)
+ gtk_widget_destroy (widget);
+ }
+}
+
+static void
+gimp_device_editor_device_changed (GimpDeviceInfo *info,
+ GimpDeviceEditor *editor)
+{
+ GimpDeviceEditorPrivate *private = GIMP_DEVICE_EDITOR_GET_PRIVATE (editor);
+ GtkTreeIter *iter;
+
+ iter = gimp_container_view_lookup (GIMP_CONTAINER_VIEW (private->treeview),
+ GIMP_VIEWABLE (info));
+
+ if (iter)
+ {
+ GimpContainerTreeView *treeview;
+
+ treeview = GIMP_CONTAINER_TREE_VIEW (private->treeview);
+
+ gtk_tree_store_set (GTK_TREE_STORE (treeview->model), iter,
+ GIMP_CONTAINER_TREE_STORE_COLUMN_NAME_SENSITIVE,
+ gimp_device_info_get_device (info, NULL) != NULL,
+ -1);
+ }
+}
+
+static void
+gimp_device_editor_select_device (GimpContainerView *view,
+ GimpViewable *viewable,
+ gpointer insert_data,
+ GimpDeviceEditor *editor)
+{
+ GimpDeviceEditorPrivate *private = GIMP_DEVICE_EDITOR_GET_PRIVATE (editor);
+
+ if (viewable && insert_data)
+ {
+ GimpContainerTreeView *treeview;
+ GtkWidget *widget;
+
+ treeview = GIMP_CONTAINER_TREE_VIEW (private->treeview);
+
+ gtk_tree_model_get (treeview->model, insert_data,
+ GIMP_CONTAINER_TREE_STORE_COLUMN_USER_DATA, &widget,
+ -1);
+
+ if (widget)
+ {
+ gint page_num = gtk_notebook_page_num (GTK_NOTEBOOK (private->notebook),
+ widget);
+
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (private->notebook),
+ page_num);
+ }
+ }
+}
+
+static void
+gimp_device_editor_switch_page (GtkNotebook *notebook,
+ gpointer page,
+ guint page_num,
+ GimpDeviceEditor *editor)
+{
+ GimpDeviceEditorPrivate *private = GIMP_DEVICE_EDITOR_GET_PRIVATE (editor);
+ GtkWidget *widget;
+ GimpDeviceInfo *info;
+ gboolean delete_sensitive = FALSE;
+
+ widget = gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), page_num);
+
+ g_object_get (widget ,"info", &info, NULL);
+
+ gtk_label_set_text (GTK_LABEL (private->label),
+ gimp_object_get_name (info));
+ gtk_image_set_from_icon_name (GTK_IMAGE (private->image),
+ gimp_viewable_get_icon_name (GIMP_VIEWABLE (info)),
+ GTK_ICON_SIZE_BUTTON);
+
+ if (! gimp_device_info_get_device (info, NULL))
+ delete_sensitive = TRUE;
+
+ gtk_widget_set_sensitive (private->delete_button, delete_sensitive);
+
+ g_object_unref (info);
+}
+
+static void
+gimp_device_editor_delete_response (GtkWidget *dialog,
+ gint response_id,
+ GimpDeviceEditor *editor)
+{
+ GimpDeviceEditorPrivate *private = GIMP_DEVICE_EDITOR_GET_PRIVATE (editor);
+
+ gtk_widget_destroy (dialog);
+
+ if (response_id == GTK_RESPONSE_OK)
+ {
+ GList *selected;
+
+ if (gimp_container_view_get_selected (GIMP_CONTAINER_VIEW (private->treeview),
+ &selected))
+ {
+ GimpContainer *devices;
+
+ devices = GIMP_CONTAINER (gimp_devices_get_manager (private->gimp));
+
+ gimp_container_remove (devices, selected->data);
+
+ g_list_free (selected);
+ }
+ }
+
+ gtk_widget_set_sensitive (GTK_WIDGET (editor), TRUE);
+}
+
+static void
+gimp_device_editor_delete_clicked (GtkWidget *button,
+ GimpDeviceEditor *editor)
+{
+ GimpDeviceEditorPrivate *private = GIMP_DEVICE_EDITOR_GET_PRIVATE (editor);
+ GtkWidget *dialog;
+ GList *selected;
+
+ if (! gimp_container_view_get_selected (GIMP_CONTAINER_VIEW (private->treeview),
+ &selected))
+ return;
+
+ dialog = gimp_message_dialog_new (_("Delete Device Settings"),
+ GIMP_ICON_DIALOG_QUESTION,
+ gtk_widget_get_toplevel (GTK_WIDGET (editor)),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ gimp_standard_help_func, NULL,
+
+ _("_Cancel"), GTK_RESPONSE_CANCEL,
+ _("_Delete"), GTK_RESPONSE_OK,
+
+ NULL);
+
+ gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
+ GTK_RESPONSE_OK,
+ GTK_RESPONSE_CANCEL,
+ -1);
+
+ g_signal_connect (dialog, "response",
+ G_CALLBACK (gimp_device_editor_delete_response),
+ editor);
+
+ gimp_message_box_set_primary_text (GIMP_MESSAGE_DIALOG (dialog)->box,
+ _("Delete \"%s\"?"),
+ gimp_object_get_name (selected->data));
+ gimp_message_box_set_text (GIMP_MESSAGE_DIALOG (dialog)->box,
+ _("You are about to delete this device's "
+ "stored settings.\n"
+ "The next time this device is plugged, "
+ "default settings will be used."));
+
+ g_list_free (selected);
+
+ gtk_widget_set_sensitive (GTK_WIDGET (editor), FALSE);
+
+ gtk_widget_show (dialog);
+}
+
+
+/* public functions */
+
+GtkWidget *
+gimp_device_editor_new (Gimp *gimp)
+{
+ g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
+
+ return g_object_new (GIMP_TYPE_DEVICE_EDITOR,
+ "gimp", gimp,
+ NULL);
+}