2440 lines
79 KiB
C
2440 lines
79 KiB
C
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
|
*
|
|
* Copyright (C) 2010 Red Hat, Inc
|
|
* Copyright (C) 2011 Richard Hughes <richard@hughsie.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 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, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*
|
|
*/
|
|
|
|
#include <config.h>
|
|
|
|
#include <egg-list-box/egg-list-box.h>
|
|
#include <glib/gi18n.h>
|
|
#include <colord.h>
|
|
#include <gtk/gtk.h>
|
|
#include <gdk/gdkx.h>
|
|
|
|
#include "cc-color-calibrate.h"
|
|
#include "cc-color-cell-renderer-text.h"
|
|
#include "cc-color-panel.h"
|
|
#include "cc-color-resources.h"
|
|
#include "cc-color-common.h"
|
|
#include "cc-color-device.h"
|
|
#include "cc-color-profile.h"
|
|
|
|
#define WID(b, w) (GtkWidget *) gtk_builder_get_object (b, w)
|
|
|
|
CC_PANEL_REGISTER (CcColorPanel, cc_color_panel)
|
|
|
|
#define COLOR_PANEL_PRIVATE(o) \
|
|
(G_TYPE_INSTANCE_GET_PRIVATE ((o), CC_TYPE_COLOR_PANEL, CcColorPanelPrivate))
|
|
|
|
struct _CcColorPanelPrivate
|
|
{
|
|
CdClient *client;
|
|
CdDevice *current_device;
|
|
GPtrArray *sensors;
|
|
GCancellable *cancellable;
|
|
GDBusProxy *proxy;
|
|
GSettings *settings;
|
|
GtkBuilder *builder;
|
|
GtkWidget *main_window;
|
|
CcColorCalibrate *calibrate;
|
|
EggListBox *list_box;
|
|
gchar *list_box_filter;
|
|
guint list_box_selected_id;
|
|
GtkSizeGroup *list_box_size;
|
|
gboolean is_live_cd;
|
|
gboolean model_is_changing;
|
|
};
|
|
|
|
enum {
|
|
GCM_PREFS_COMBO_COLUMN_TEXT,
|
|
GCM_PREFS_COMBO_COLUMN_PROFILE,
|
|
GCM_PREFS_COMBO_COLUMN_TYPE,
|
|
GCM_PREFS_COMBO_COLUMN_WARNING_FILENAME,
|
|
GCM_PREFS_COMBO_COLUMN_NUM_COLUMNS
|
|
};
|
|
|
|
/* for the GtkListStores */
|
|
enum {
|
|
COLUMN_CALIB_KIND_DESCRIPTION,
|
|
COLUMN_CALIB_KIND_CAP_VALUE,
|
|
COLUMN_CALIB_KIND_VISIBLE,
|
|
COLUMN_CALIB_KIND_LAST
|
|
};
|
|
enum {
|
|
COLUMN_CALIB_QUALITY_DESCRIPTION,
|
|
COLUMN_CALIB_QUALITY_APPROX_TIME,
|
|
COLUMN_CALIB_QUALITY_VALUE,
|
|
COLUMN_CALIB_QUALITY_LAST
|
|
};
|
|
enum {
|
|
COLUMN_CALIB_SENSOR_OBJECT,
|
|
COLUMN_CALIB_SENSOR_DESCRIPTION,
|
|
COLUMN_CALIB_SENSOR_LAST
|
|
};
|
|
enum {
|
|
COLUMN_CALIB_TEMP_DESCRIPTION,
|
|
COLUMN_CALIB_TEMP_VALUE_K,
|
|
COLUMN_CALIB_TEMP_LAST
|
|
};
|
|
|
|
#define GCM_SETTINGS_SCHEMA "org.gnome.settings-daemon.plugins.color"
|
|
#define GCM_SETTINGS_RECALIBRATE_PRINTER_THRESHOLD "recalibrate-printer-threshold"
|
|
#define GCM_SETTINGS_RECALIBRATE_DISPLAY_THRESHOLD "recalibrate-display-threshold"
|
|
|
|
/* max number of devices and profiles to cause auto-expand at startup */
|
|
#define GCM_PREFS_MAX_DEVICES_PROFILES_EXPANDED 5
|
|
|
|
static void
|
|
gcm_prefs_combobox_add_profile (CcColorPanel *prefs,
|
|
CdProfile *profile,
|
|
GtkTreeIter *iter)
|
|
{
|
|
const gchar *id;
|
|
GtkTreeIter iter_tmp;
|
|
GString *string;
|
|
GtkListStore *list_store;
|
|
gchar *escaped = NULL;
|
|
guint kind = 0;
|
|
const gchar *warning = NULL;
|
|
#if CD_CHECK_VERSION(0,1,25)
|
|
gchar **warnings;
|
|
#endif
|
|
|
|
/* iter is optional */
|
|
if (iter == NULL)
|
|
iter = &iter_tmp;
|
|
|
|
/* use description */
|
|
string = g_string_new (cd_profile_get_title (profile));
|
|
|
|
/* any source prefix? */
|
|
id = cd_profile_get_metadata_item (profile,
|
|
CD_PROFILE_METADATA_DATA_SOURCE);
|
|
if (g_strcmp0 (id, CD_PROFILE_METADATA_DATA_SOURCE_EDID) == 0)
|
|
{
|
|
/* TRANSLATORS: this is a profile prefix to signify the
|
|
* profile has been auto-generated for this hardware */
|
|
g_string_prepend (string, _("Default: "));
|
|
kind = 1;
|
|
}
|
|
#if CD_CHECK_VERSION(0,1,14)
|
|
if (g_strcmp0 (id, CD_PROFILE_METADATA_DATA_SOURCE_STANDARD) == 0)
|
|
{
|
|
/* TRANSLATORS: this is a profile prefix to signify the
|
|
* profile his a standard space like AdobeRGB */
|
|
g_string_prepend (string, _("Colorspace: "));
|
|
kind = 2;
|
|
}
|
|
if (g_strcmp0 (id, CD_PROFILE_METADATA_DATA_SOURCE_TEST) == 0)
|
|
{
|
|
/* TRANSLATORS: this is a profile prefix to signify the
|
|
* profile is a test profile */
|
|
g_string_prepend (string, _("Test profile: "));
|
|
kind = 3;
|
|
}
|
|
#endif
|
|
|
|
/* is the profile faulty */
|
|
#if CD_CHECK_VERSION(0,1,25)
|
|
warnings = cd_profile_get_warnings (profile);
|
|
if (warnings != NULL && warnings[0] != NULL)
|
|
warning = "dialog-warning-symbolic";
|
|
#endif
|
|
|
|
escaped = g_markup_escape_text (string->str, -1);
|
|
list_store = GTK_LIST_STORE(gtk_builder_get_object (prefs->priv->builder,
|
|
"liststore_assign"));
|
|
gtk_list_store_append (list_store, iter);
|
|
gtk_list_store_set (list_store, iter,
|
|
GCM_PREFS_COMBO_COLUMN_TEXT, escaped,
|
|
GCM_PREFS_COMBO_COLUMN_PROFILE, profile,
|
|
GCM_PREFS_COMBO_COLUMN_TYPE, kind,
|
|
GCM_PREFS_COMBO_COLUMN_WARNING_FILENAME, warning,
|
|
-1);
|
|
|
|
g_string_free (string, TRUE);
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_default_cb (GtkWidget *widget, CcColorPanel *prefs)
|
|
{
|
|
CdProfile *profile;
|
|
gboolean ret;
|
|
GError *error = NULL;
|
|
CcColorPanelPrivate *priv = prefs->priv;
|
|
|
|
/* TODO: check if the profile is already systemwide */
|
|
profile = cd_device_get_default_profile (priv->current_device);
|
|
if (profile == NULL)
|
|
goto out;
|
|
|
|
/* install somewhere out of $HOME */
|
|
ret = cd_profile_install_system_wide_sync (profile,
|
|
priv->cancellable,
|
|
&error);
|
|
if (!ret)
|
|
{
|
|
g_warning ("failed to set profile system-wide: %s",
|
|
error->message);
|
|
g_error_free (error);
|
|
goto out;
|
|
}
|
|
out:
|
|
if (profile != NULL)
|
|
g_object_unref (profile);
|
|
}
|
|
|
|
static GFile *
|
|
gcm_prefs_file_chooser_get_icc_profile (CcColorPanel *prefs)
|
|
{
|
|
GtkWindow *window;
|
|
GtkWidget *dialog;
|
|
GFile *file = NULL;
|
|
GtkFileFilter *filter;
|
|
CcColorPanelPrivate *priv = prefs->priv;
|
|
|
|
/* create new dialog */
|
|
window = GTK_WINDOW(gtk_builder_get_object (priv->builder,
|
|
"dialog_assign"));
|
|
/* TRANSLATORS: an ICC profile is a file containing colorspace data */
|
|
dialog = gtk_file_chooser_dialog_new (_("Select ICC Profile File"), window,
|
|
GTK_FILE_CHOOSER_ACTION_OPEN,
|
|
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
|
_("_Import"), GTK_RESPONSE_ACCEPT,
|
|
NULL);
|
|
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(dialog), g_get_home_dir ());
|
|
gtk_file_chooser_set_create_folders (GTK_FILE_CHOOSER(dialog), FALSE);
|
|
gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER(dialog), FALSE);
|
|
|
|
/* setup the filter */
|
|
filter = gtk_file_filter_new ();
|
|
gtk_file_filter_add_mime_type (filter, "application/vnd.iccprofile");
|
|
|
|
/* TRANSLATORS: filter name on the file->open dialog */
|
|
gtk_file_filter_set_name (filter, _("Supported ICC profiles"));
|
|
gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(dialog), filter);
|
|
|
|
/* setup the all files filter */
|
|
filter = gtk_file_filter_new ();
|
|
gtk_file_filter_add_pattern (filter, "*");
|
|
/* TRANSLATORS: filter name on the file->open dialog */
|
|
gtk_file_filter_set_name (filter, _("All files"));
|
|
gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(dialog), filter);
|
|
|
|
/* did user choose file */
|
|
if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
|
|
file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER(dialog));
|
|
|
|
/* we're done */
|
|
gtk_widget_destroy (dialog);
|
|
|
|
/* or NULL for missing */
|
|
return file;
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_calib_cancel_cb (GtkWidget *widget, CcColorPanel *prefs)
|
|
{
|
|
widget = GTK_WIDGET (gtk_builder_get_object (prefs->priv->builder,
|
|
"assistant_calib"));
|
|
gtk_widget_hide (widget);
|
|
}
|
|
|
|
static gboolean
|
|
gcm_prefs_calib_delayed_complete_cb (gpointer user_data)
|
|
{
|
|
CcColorPanel *panel = CC_COLOR_PANEL (user_data);
|
|
GtkAssistant *assistant;
|
|
GtkWidget *widget;
|
|
|
|
assistant = GTK_ASSISTANT (gtk_builder_get_object (panel->priv->builder,
|
|
"assistant_calib"));
|
|
widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder,
|
|
"box_calib_brightness"));
|
|
gtk_assistant_set_page_complete (assistant, widget, TRUE);
|
|
return FALSE;
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_calib_prepare_cb (GtkAssistant *assistant,
|
|
GtkWidget *page,
|
|
CcColorPanel *panel)
|
|
{
|
|
GtkWidget *widget;
|
|
|
|
/* give the user the indication they should actually manually set the
|
|
* desired brightness rather than clicking blindly by delaying the
|
|
* "Next" button deliberately for a second or so */
|
|
widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder,
|
|
"box_calib_brightness"));
|
|
if (widget == page)
|
|
{
|
|
g_timeout_add_seconds (1, gcm_prefs_calib_delayed_complete_cb, panel);
|
|
return;
|
|
}
|
|
|
|
/* disable the brightness page as we don't want to show a 'Finished'
|
|
* button if the user goes back at any point */
|
|
gtk_assistant_set_page_complete (assistant, widget, FALSE);
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_calib_apply_cb (GtkWidget *widget, CcColorPanel *prefs)
|
|
{
|
|
gboolean ret;
|
|
GError *error = NULL;
|
|
GtkWindow *window = NULL;
|
|
|
|
/* setup the calibration object with items that can fail */
|
|
ret = cc_color_calibrate_setup (prefs->priv->calibrate,
|
|
&error);
|
|
if (!ret)
|
|
{
|
|
g_warning ("failed to setup calibrate: %s", error->message);
|
|
g_error_free (error);
|
|
goto out;
|
|
}
|
|
|
|
/* actually start the calibration */
|
|
window = GTK_WINDOW (gtk_builder_get_object (prefs->priv->builder,
|
|
"assistant_calib"));
|
|
ret = cc_color_calibrate_start (prefs->priv->calibrate,
|
|
window,
|
|
&error);
|
|
if (!ret)
|
|
{
|
|
g_warning ("failed to start calibrate: %s", error->message);
|
|
gtk_widget_hide (GTK_WIDGET (window));
|
|
g_error_free (error);
|
|
goto out;
|
|
}
|
|
|
|
/* if we are a LiveCD then don't close the window as there is another
|
|
* summary pane with the export button */
|
|
if (!prefs->priv->is_live_cd)
|
|
gtk_widget_hide (GTK_WIDGET (window));
|
|
out:
|
|
return;
|
|
}
|
|
|
|
static gboolean
|
|
gcm_prefs_calib_delete_event_cb (GtkWidget *widget,
|
|
GdkEvent *event,
|
|
CcColorPanel *prefs)
|
|
{
|
|
/* do not destroy the window */
|
|
gcm_prefs_calib_cancel_cb (widget, prefs);
|
|
return TRUE;
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_calib_temp_treeview_clicked_cb (GtkTreeSelection *selection,
|
|
CcColorPanel *prefs)
|
|
{
|
|
CcColorPanelPrivate *priv = prefs->priv;
|
|
gboolean ret;
|
|
GtkTreeIter iter;
|
|
GtkTreeModel *model;
|
|
GtkWidget *widget;
|
|
guint target_whitepoint;
|
|
GtkAssistant *assistant;
|
|
|
|
/* check to see if anything is selected */
|
|
ret = gtk_tree_selection_get_selected (selection, &model, &iter);
|
|
assistant = GTK_ASSISTANT (gtk_builder_get_object (prefs->priv->builder,
|
|
"assistant_calib"));
|
|
widget = GTK_WIDGET (gtk_builder_get_object (prefs->priv->builder,
|
|
"box_calib_temp"));
|
|
gtk_assistant_set_page_complete (assistant, widget, ret);
|
|
if (!ret)
|
|
return;
|
|
|
|
gtk_tree_model_get (model, &iter,
|
|
COLUMN_CALIB_TEMP_VALUE_K, &target_whitepoint,
|
|
-1);
|
|
cc_color_calibrate_set_temperature (priv->calibrate, target_whitepoint);
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_calib_kind_treeview_clicked_cb (GtkTreeSelection *selection,
|
|
CcColorPanel *prefs)
|
|
{
|
|
CcColorPanelPrivate *priv = prefs->priv;
|
|
CdSensorCap device_kind;
|
|
gboolean ret;
|
|
GtkTreeIter iter;
|
|
GtkTreeModel *model;
|
|
GtkWidget *widget;
|
|
GtkAssistant *assistant;
|
|
|
|
/* check to see if anything is selected */
|
|
ret = gtk_tree_selection_get_selected (selection, &model, &iter);
|
|
assistant = GTK_ASSISTANT (gtk_builder_get_object (prefs->priv->builder,
|
|
"assistant_calib"));
|
|
widget = GTK_WIDGET (gtk_builder_get_object (prefs->priv->builder,
|
|
"box_calib_kind"));
|
|
gtk_assistant_set_page_complete (assistant, widget, ret);
|
|
if (!ret)
|
|
return;
|
|
|
|
/* save the values if we have a selection */
|
|
gtk_tree_model_get (model, &iter,
|
|
COLUMN_CALIB_KIND_CAP_VALUE, &device_kind,
|
|
-1);
|
|
cc_color_calibrate_set_kind (priv->calibrate, device_kind);
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_calib_quality_treeview_clicked_cb (GtkTreeSelection *selection,
|
|
CcColorPanel *prefs)
|
|
{
|
|
CcColorPanelPrivate *priv = prefs->priv;
|
|
CdProfileQuality quality;
|
|
gboolean ret;
|
|
GtkAssistant *assistant;
|
|
GtkTreeIter iter;
|
|
GtkTreeModel *model;
|
|
GtkWidget *widget;
|
|
|
|
/* check to see if anything is selected */
|
|
ret = gtk_tree_selection_get_selected (selection, &model, &iter);
|
|
assistant = GTK_ASSISTANT (gtk_builder_get_object (prefs->priv->builder,
|
|
"assistant_calib"));
|
|
widget = GTK_WIDGET (gtk_builder_get_object (prefs->priv->builder,
|
|
"box_calib_quality"));
|
|
gtk_assistant_set_page_complete (assistant, widget, ret);
|
|
if (!ret)
|
|
return;
|
|
|
|
/* save the values if we have a selection */
|
|
gtk_tree_model_get (model, &iter,
|
|
COLUMN_CALIB_QUALITY_VALUE, &quality,
|
|
-1);
|
|
cc_color_calibrate_set_quality (priv->calibrate, quality);
|
|
}
|
|
|
|
static gboolean
|
|
gcm_prefs_calib_set_sensor_cap_supported_cb (GtkTreeModel *model,
|
|
GtkTreePath *path,
|
|
GtkTreeIter *iter,
|
|
gpointer data)
|
|
{
|
|
CdSensorCap cap;
|
|
CdSensor *sensor = CD_SENSOR (data);
|
|
gboolean supported;
|
|
|
|
gtk_tree_model_get (model, iter,
|
|
COLUMN_CALIB_KIND_CAP_VALUE, &cap,
|
|
-1);
|
|
supported = cd_sensor_has_cap (sensor, cap);
|
|
g_debug ("%s(%s) is %s",
|
|
cd_sensor_get_model (sensor),
|
|
cd_sensor_cap_to_string (cap),
|
|
supported ? "supported" : "not-supported");
|
|
gtk_list_store_set (GTK_LIST_STORE (model), iter,
|
|
COLUMN_CALIB_KIND_VISIBLE, supported,
|
|
-1);
|
|
return FALSE;
|
|
}
|
|
|
|
static guint8
|
|
_cd_bitfield_popcount (guint64 bitfield)
|
|
{
|
|
guint8 i;
|
|
guint8 tmp = 0;
|
|
for (i = 0; i < 64; i++)
|
|
tmp += cd_bitfield_contain (bitfield, i);
|
|
return tmp;
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_calib_set_sensor (CcColorPanel *prefs,
|
|
CdSensor *sensor)
|
|
{
|
|
CcColorPanelPrivate *priv = prefs->priv;
|
|
GtkTreeModel *model;
|
|
GtkWidget *page;
|
|
guint64 caps;
|
|
guint8 i;
|
|
|
|
/* use this sensor for calibration */
|
|
cc_color_calibrate_set_sensor (priv->calibrate, sensor);
|
|
|
|
/* hide display types the sensor does not support */
|
|
model = GTK_TREE_MODEL (gtk_builder_get_object (priv->builder,
|
|
"liststore_calib_kind"));
|
|
gtk_tree_model_foreach (model,
|
|
gcm_prefs_calib_set_sensor_cap_supported_cb,
|
|
sensor);
|
|
|
|
/* if the sensor only supports one kind then do not show the panel at all */
|
|
page = GTK_WIDGET (gtk_builder_get_object (prefs->priv->builder,
|
|
"box_calib_kind"));
|
|
caps = cd_sensor_get_caps (sensor);
|
|
if (_cd_bitfield_popcount (caps) == 1)
|
|
{
|
|
gtk_widget_set_visible (page, FALSE);
|
|
for (i = 0; i < CD_SENSOR_CAP_LAST; i++)
|
|
{
|
|
if (cd_bitfield_contain (caps, i))
|
|
cc_color_calibrate_set_kind (priv->calibrate, i);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
cc_color_calibrate_set_kind (priv->calibrate, CD_SENSOR_CAP_UNKNOWN);
|
|
gtk_widget_set_visible (page, TRUE);
|
|
}
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_calib_sensor_treeview_clicked_cb (GtkTreeSelection *selection,
|
|
CcColorPanel *prefs)
|
|
{
|
|
gboolean ret;
|
|
GtkTreeIter iter;
|
|
GtkTreeModel *model;
|
|
GtkWidget *widget;
|
|
CdSensor *sensor;
|
|
GtkAssistant *assistant;
|
|
|
|
/* check to see if anything is selected */
|
|
ret = gtk_tree_selection_get_selected (selection, &model, &iter);
|
|
assistant = GTK_ASSISTANT (gtk_builder_get_object (prefs->priv->builder,
|
|
"assistant_calib"));
|
|
widget = GTK_WIDGET (gtk_builder_get_object (prefs->priv->builder,
|
|
"box_calib_sensor"));
|
|
gtk_assistant_set_page_complete (assistant, widget, ret);
|
|
if (!ret)
|
|
return;
|
|
|
|
/* save the values if we have a selection */
|
|
gtk_tree_model_get (model, &iter,
|
|
COLUMN_CALIB_SENSOR_OBJECT, &sensor,
|
|
-1);
|
|
gcm_prefs_calib_set_sensor (prefs, sensor);
|
|
g_object_unref (sensor);
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_calibrate_display (CcColorPanel *prefs)
|
|
{
|
|
CcColorPanelPrivate *priv = prefs->priv;
|
|
CdSensor *sensor_tmp;
|
|
const gchar *tmp;
|
|
GtkListStore *liststore;
|
|
GtkTreeIter iter;
|
|
GtkWidget *page;
|
|
GtkWidget *widget;
|
|
guint i;
|
|
|
|
/* set target device */
|
|
cc_color_calibrate_set_device (priv->calibrate, priv->current_device);
|
|
|
|
/* add sensors to list */
|
|
liststore = GTK_LIST_STORE (gtk_builder_get_object (priv->builder,
|
|
"liststore_calib_sensor"));
|
|
gtk_list_store_clear (liststore);
|
|
page = GTK_WIDGET (gtk_builder_get_object (prefs->priv->builder,
|
|
"box_calib_sensor"));
|
|
if (priv->sensors->len > 1)
|
|
{
|
|
for (i = 0; i < priv->sensors->len; i++)
|
|
{
|
|
sensor_tmp = g_ptr_array_index (priv->sensors, i);
|
|
gtk_list_store_append (liststore, &iter);
|
|
gtk_list_store_set (liststore, &iter,
|
|
COLUMN_CALIB_SENSOR_OBJECT, sensor_tmp,
|
|
COLUMN_CALIB_SENSOR_DESCRIPTION, cd_sensor_get_model (sensor_tmp),
|
|
-1);
|
|
}
|
|
gtk_widget_set_visible (page, TRUE);
|
|
}
|
|
else
|
|
{
|
|
sensor_tmp = g_ptr_array_index (priv->sensors, 0);
|
|
gcm_prefs_calib_set_sensor (prefs, sensor_tmp);
|
|
gtk_widget_set_visible (page, FALSE);
|
|
}
|
|
|
|
/* set default profile title */
|
|
tmp = cd_device_get_model (priv->current_device);
|
|
if (tmp == NULL)
|
|
tmp = cd_device_get_vendor (priv->current_device);
|
|
if (tmp == NULL)
|
|
tmp = _("Screen");
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"entry_calib_title"));
|
|
gtk_entry_set_text (GTK_ENTRY (widget), tmp);
|
|
cc_color_calibrate_set_title (priv->calibrate, tmp);
|
|
|
|
/* set the display whitepoint to D65 by default */
|
|
//FIXME?
|
|
|
|
/* show ui */
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"assistant_calib"));
|
|
gtk_window_set_transient_for (GTK_WINDOW (widget),
|
|
GTK_WINDOW (priv->main_window));
|
|
gtk_widget_show (widget);
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_title_entry_changed_cb (GtkWidget *widget,
|
|
GParamSpec *param_spec,
|
|
CcColorPanel *prefs)
|
|
{
|
|
GtkAssistant *assistant;
|
|
GtkWidget *page;
|
|
const gchar *value;
|
|
|
|
assistant = GTK_ASSISTANT (gtk_builder_get_object (prefs->priv->builder,
|
|
"assistant_calib"));
|
|
page = GTK_WIDGET (gtk_builder_get_object (prefs->priv->builder,
|
|
"box_calib_title"));
|
|
value = gtk_entry_get_text (GTK_ENTRY (widget));
|
|
gtk_assistant_set_page_complete (assistant, page, value[0] != '\0');
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_calibrate_cb (GtkWidget *widget, CcColorPanel *prefs)
|
|
{
|
|
gboolean ret;
|
|
GError *error = NULL;
|
|
guint xid;
|
|
GPtrArray *argv;
|
|
CcColorPanelPrivate *priv = prefs->priv;
|
|
|
|
/* use the new-style calibration helper */
|
|
if (cd_device_get_kind (priv->current_device) == CD_DEVICE_KIND_DISPLAY)
|
|
{
|
|
gcm_prefs_calibrate_display (prefs);
|
|
return;
|
|
}
|
|
|
|
/* get xid */
|
|
xid = gdk_x11_window_get_xid (gtk_widget_get_window (GTK_WIDGET (priv->main_window)));
|
|
|
|
/* run with modal set */
|
|
argv = g_ptr_array_new_with_free_func (g_free);
|
|
g_ptr_array_add (argv, g_build_filename (BINDIR, "gcm-calibrate", NULL));
|
|
g_ptr_array_add (argv, g_strdup ("--device"));
|
|
g_ptr_array_add (argv, g_strdup (cd_device_get_id (priv->current_device)));
|
|
g_ptr_array_add (argv, g_strdup ("--parent-window"));
|
|
g_ptr_array_add (argv, g_strdup_printf ("%i", xid));
|
|
g_ptr_array_add (argv, NULL);
|
|
ret = g_spawn_async (NULL, (gchar**) argv->pdata, NULL, 0,
|
|
NULL, NULL, NULL, &error);
|
|
if (!ret)
|
|
{
|
|
g_warning ("failed to run calibrate: %s", error->message);
|
|
g_error_free (error);
|
|
}
|
|
g_ptr_array_unref (argv);
|
|
}
|
|
|
|
static gboolean
|
|
gcm_prefs_is_profile_suitable_for_device (CdProfile *profile,
|
|
CdDevice *device)
|
|
{
|
|
const gchar *data_source;
|
|
CdProfileKind profile_kind_tmp;
|
|
CdProfileKind profile_kind;
|
|
CdColorspace profile_colorspace;
|
|
CdColorspace device_colorspace = 0;
|
|
gboolean ret = FALSE;
|
|
CdDeviceKind device_kind;
|
|
CdStandardSpace standard_space;
|
|
|
|
/* not the right colorspace */
|
|
device_colorspace = cd_device_get_colorspace (device);
|
|
profile_colorspace = cd_profile_get_colorspace (profile);
|
|
if (device_colorspace != profile_colorspace)
|
|
goto out;
|
|
|
|
/* if this is a display matching with one of the standard spaces that displays
|
|
* could emulate, also mark it as suitable */
|
|
if (cd_device_get_kind (device) == CD_DEVICE_KIND_DISPLAY &&
|
|
cd_profile_get_kind (profile) == CD_PROFILE_KIND_DISPLAY_DEVICE)
|
|
{
|
|
data_source = cd_profile_get_metadata_item (profile,
|
|
CD_PROFILE_METADATA_STANDARD_SPACE);
|
|
standard_space = cd_standard_space_from_string (data_source);
|
|
if (standard_space == CD_STANDARD_SPACE_SRGB ||
|
|
standard_space == CD_STANDARD_SPACE_ADOBE_RGB)
|
|
{
|
|
ret = TRUE;
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
/* not the correct kind */
|
|
device_kind = cd_device_get_kind (device);
|
|
profile_kind_tmp = cd_profile_get_kind (profile);
|
|
profile_kind = cd_device_kind_to_profile_kind (device_kind);
|
|
if (profile_kind_tmp != profile_kind)
|
|
goto out;
|
|
|
|
/* ignore the colorspace profiles */
|
|
data_source = cd_profile_get_metadata_item (profile,
|
|
CD_PROFILE_METADATA_DATA_SOURCE);
|
|
if (g_strcmp0 (data_source, CD_PROFILE_METADATA_DATA_SOURCE_STANDARD) == 0)
|
|
goto out;
|
|
|
|
/* success */
|
|
ret = TRUE;
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
static gint
|
|
gcm_prefs_combo_sort_func_cb (GtkTreeModel *model,
|
|
GtkTreeIter *a,
|
|
GtkTreeIter *b,
|
|
gpointer user_data)
|
|
{
|
|
gint type_a, type_b;
|
|
gchar *text_a;
|
|
gchar *text_b;
|
|
gint retval;
|
|
|
|
/* get data from model */
|
|
gtk_tree_model_get (model, a,
|
|
GCM_PREFS_COMBO_COLUMN_TYPE, &type_a,
|
|
GCM_PREFS_COMBO_COLUMN_TEXT, &text_a,
|
|
-1);
|
|
gtk_tree_model_get (model, b,
|
|
GCM_PREFS_COMBO_COLUMN_TYPE, &type_b,
|
|
GCM_PREFS_COMBO_COLUMN_TEXT, &text_b,
|
|
-1);
|
|
|
|
/* prefer normal type profiles over the 'Other Profile...' entry */
|
|
if (type_a < type_b)
|
|
retval = -1;
|
|
else if (type_a > type_b)
|
|
retval = 1;
|
|
else
|
|
retval = g_strcmp0 (text_a, text_b);
|
|
|
|
g_free (text_a);
|
|
g_free (text_b);
|
|
return retval;
|
|
}
|
|
|
|
static gboolean
|
|
gcm_prefs_profile_exists_in_array (GPtrArray *array, CdProfile *profile)
|
|
{
|
|
CdProfile *profile_tmp;
|
|
guint i;
|
|
|
|
for (i = 0; i < array->len; i++)
|
|
{
|
|
profile_tmp = g_ptr_array_index (array, i);
|
|
if (cd_profile_equal (profile, profile_tmp))
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_add_profiles_suitable_for_devices (CcColorPanel *prefs,
|
|
GPtrArray *profiles)
|
|
{
|
|
CdProfile *profile_tmp;
|
|
gboolean ret;
|
|
GError *error = NULL;
|
|
GPtrArray *profile_array = NULL;
|
|
GtkTreeIter iter;
|
|
GtkListStore *list_store;
|
|
GtkWidget *widget;
|
|
guint i;
|
|
CcColorPanelPrivate *priv = prefs->priv;
|
|
|
|
list_store = GTK_LIST_STORE(gtk_builder_get_object (prefs->priv->builder,
|
|
"liststore_assign"));
|
|
gtk_list_store_clear (list_store);
|
|
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (list_store),
|
|
GCM_PREFS_COMBO_COLUMN_TEXT,
|
|
GTK_SORT_ASCENDING);
|
|
gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (list_store),
|
|
GCM_PREFS_COMBO_COLUMN_TEXT,
|
|
gcm_prefs_combo_sort_func_cb,
|
|
list_store, NULL);
|
|
|
|
widget = GTK_WIDGET (gtk_builder_get_object (prefs->priv->builder,
|
|
"label_assign_warning"));
|
|
gtk_widget_hide (widget);
|
|
|
|
/* get profiles */
|
|
profile_array = cd_client_get_profiles_sync (priv->client,
|
|
priv->cancellable,
|
|
&error);
|
|
if (profile_array == NULL)
|
|
{
|
|
g_warning ("failed to get profiles: %s",
|
|
error->message);
|
|
g_error_free (error);
|
|
goto out;
|
|
}
|
|
|
|
/* add profiles of the right kind */
|
|
for (i = 0; i < profile_array->len; i++)
|
|
{
|
|
profile_tmp = g_ptr_array_index (profile_array, i);
|
|
|
|
/* get properties */
|
|
ret = cd_profile_connect_sync (profile_tmp,
|
|
priv->cancellable,
|
|
&error);
|
|
if (!ret)
|
|
{
|
|
g_warning ("failed to get profile: %s", error->message);
|
|
g_error_free (error);
|
|
goto out;
|
|
}
|
|
|
|
/* don't add any of the already added profiles */
|
|
if (profiles != NULL)
|
|
{
|
|
if (gcm_prefs_profile_exists_in_array (profiles, profile_tmp))
|
|
continue;
|
|
}
|
|
|
|
/* only add correct types */
|
|
ret = gcm_prefs_is_profile_suitable_for_device (profile_tmp,
|
|
priv->current_device);
|
|
if (!ret)
|
|
continue;
|
|
|
|
#if CD_CHECK_VERSION(0,1,13)
|
|
/* ignore profiles from other user accounts */
|
|
if (!cd_profile_has_access (profile_tmp))
|
|
continue;
|
|
#endif
|
|
|
|
/* add */
|
|
gcm_prefs_combobox_add_profile (prefs,
|
|
profile_tmp,
|
|
&iter);
|
|
}
|
|
out:
|
|
if (profile_array != NULL)
|
|
g_ptr_array_unref (profile_array);
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_calib_export_cb (GtkWidget *widget, CcColorPanel *prefs)
|
|
{
|
|
CdProfile *profile;
|
|
gboolean ret;
|
|
gchar *default_name = NULL;
|
|
GError *error = NULL;
|
|
GFile *destination = NULL;
|
|
GFile *source = NULL;
|
|
GtkWidget *dialog;
|
|
|
|
/* TRANSLATORS: this is the dialog to save the ICC profile */
|
|
dialog = gtk_file_chooser_dialog_new (_("Save Profile"),
|
|
GTK_WINDOW (prefs->priv->main_window),
|
|
GTK_FILE_CHOOSER_ACTION_SAVE,
|
|
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
|
GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
|
|
NULL);
|
|
gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
|
|
|
|
profile = cc_color_calibrate_get_profile (prefs->priv->calibrate);
|
|
ret = cd_profile_connect_sync (profile, NULL, &error);
|
|
if (!ret)
|
|
{
|
|
g_warning ("Failed to get imported profile: %s", error->message);
|
|
g_error_free (error);
|
|
goto out;
|
|
}
|
|
default_name = g_strdup_printf ("%s.icc", cd_profile_get_title (profile));
|
|
gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), default_name);
|
|
|
|
if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
|
|
{
|
|
source = g_file_new_for_path (cd_profile_get_filename (profile));
|
|
destination = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
|
|
ret = g_file_copy (source,
|
|
destination,
|
|
G_FILE_COPY_OVERWRITE,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&error);
|
|
if (!ret)
|
|
{
|
|
g_warning ("Failed to copy profile: %s", error->message);
|
|
g_error_free (error);
|
|
goto out;
|
|
}
|
|
}
|
|
out:
|
|
gtk_widget_destroy (dialog);
|
|
g_free (default_name);
|
|
if (source != NULL)
|
|
g_object_unref (source);
|
|
if (destination != NULL)
|
|
g_object_unref (destination);
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_calib_export_link_cb (GtkLabel *widget,
|
|
const gchar *url,
|
|
CcColorPanel *prefs)
|
|
{
|
|
gtk_show_uri (gtk_widget_get_screen (GTK_WIDGET (prefs->priv->main_window)),
|
|
"help:gnome-help/color-howtoimport",
|
|
GDK_CURRENT_TIME, NULL);
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_profile_add_cb (GtkWidget *widget, CcColorPanel *prefs)
|
|
{
|
|
GPtrArray *profiles;
|
|
CcColorPanelPrivate *priv = prefs->priv;
|
|
|
|
/* add profiles of the right kind */
|
|
profiles = cd_device_get_profiles (priv->current_device);
|
|
gcm_prefs_add_profiles_suitable_for_devices (prefs, profiles);
|
|
|
|
/* make insensitve until we have a selection */
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"button_assign_ok"));
|
|
gtk_widget_set_sensitive (widget, FALSE);
|
|
|
|
/* show the dialog */
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"dialog_assign"));
|
|
gtk_widget_show (widget);
|
|
gtk_window_set_transient_for (GTK_WINDOW (widget), GTK_WINDOW (priv->main_window));
|
|
if (profiles != NULL)
|
|
g_ptr_array_unref (profiles);
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_profile_remove_cb (GtkWidget *widget, CcColorPanel *prefs)
|
|
{
|
|
CcColorPanelPrivate *priv = prefs->priv;
|
|
CdProfile *profile;
|
|
gboolean ret = FALSE;
|
|
GError *error = NULL;
|
|
|
|
/* get the selected profile */
|
|
widget = egg_list_box_get_selected_child (priv->list_box);
|
|
if (widget == NULL)
|
|
return;
|
|
profile = cc_color_profile_get_profile (CC_COLOR_PROFILE (widget));
|
|
if (profile == NULL)
|
|
{
|
|
g_warning ("failed to get the active profile");
|
|
return;
|
|
}
|
|
|
|
/* just remove it, the list store will get ::changed */
|
|
ret = cd_device_remove_profile_sync (priv->current_device,
|
|
profile,
|
|
priv->cancellable,
|
|
&error);
|
|
if (!ret)
|
|
{
|
|
g_warning ("failed to remove profile: %s", error->message);
|
|
g_error_free (error);
|
|
}
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_make_profile_default_cb (GObject *object,
|
|
GAsyncResult *res,
|
|
gpointer user_data)
|
|
{
|
|
CdDevice *device = CD_DEVICE (object);
|
|
gboolean ret = FALSE;
|
|
GError *error = NULL;
|
|
|
|
ret = cd_device_make_profile_default_finish (device,
|
|
res,
|
|
&error);
|
|
if (!ret)
|
|
{
|
|
g_warning ("failed to set default profile on %s: %s",
|
|
cd_device_get_id (device),
|
|
error->message);
|
|
g_error_free (error);
|
|
}
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_device_profile_enable_cb (GtkWidget *widget, CcColorPanel *prefs)
|
|
{
|
|
CcColorPanelPrivate *priv = prefs->priv;
|
|
CdProfile *profile;
|
|
|
|
/* get the selected profile */
|
|
widget = egg_list_box_get_selected_child (priv->list_box);
|
|
if (widget == NULL)
|
|
return;
|
|
profile = cc_color_profile_get_profile (CC_COLOR_PROFILE (widget));
|
|
if (profile == NULL)
|
|
{
|
|
g_warning ("failed to get the active profile");
|
|
return;
|
|
}
|
|
|
|
/* just set it default */
|
|
g_debug ("setting %s default on %s",
|
|
cd_profile_get_id (profile),
|
|
cd_device_get_id (priv->current_device));
|
|
cd_device_make_profile_default (priv->current_device,
|
|
profile,
|
|
priv->cancellable,
|
|
gcm_prefs_make_profile_default_cb,
|
|
prefs);
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_profile_view (CcColorPanel *prefs, CdProfile *profile)
|
|
{
|
|
GPtrArray *argv = NULL;
|
|
guint xid;
|
|
gboolean ret;
|
|
GError *error = NULL;
|
|
CcColorPanelPrivate *priv = prefs->priv;
|
|
|
|
/* get xid */
|
|
xid = gdk_x11_window_get_xid (gtk_widget_get_window (GTK_WIDGET (priv->main_window)));
|
|
|
|
/* open up gcm-viewer as a info pane */
|
|
argv = g_ptr_array_new_with_free_func (g_free);
|
|
g_ptr_array_add (argv, g_build_filename (BINDIR, "gcm-viewer", NULL));
|
|
g_ptr_array_add (argv, g_strdup ("--profile"));
|
|
g_ptr_array_add (argv, g_strdup (cd_profile_get_id (profile)));
|
|
g_ptr_array_add (argv, g_strdup ("--parent-window"));
|
|
g_ptr_array_add (argv, g_strdup_printf ("%i", xid));
|
|
g_ptr_array_add (argv, NULL);
|
|
ret = g_spawn_async (NULL, (gchar**) argv->pdata, NULL, 0,
|
|
NULL, NULL, NULL, &error);
|
|
if (!ret)
|
|
{
|
|
g_warning ("failed to run calibrate: %s", error->message);
|
|
g_error_free (error);
|
|
}
|
|
|
|
g_ptr_array_unref (argv);
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_profile_assign_link_activate_cb (GtkLabel *label,
|
|
const gchar *uri,
|
|
CcColorPanel *prefs)
|
|
{
|
|
CcColorPanelPrivate *priv = prefs->priv;
|
|
CdProfile *profile;
|
|
GtkWidget *widget;
|
|
|
|
/* get the selected profile */
|
|
widget = egg_list_box_get_selected_child (priv->list_box);
|
|
if (widget == NULL)
|
|
return;
|
|
profile = cc_color_profile_get_profile (CC_COLOR_PROFILE (widget));
|
|
if (profile == NULL)
|
|
{
|
|
g_warning ("failed to get the active profile");
|
|
return;
|
|
}
|
|
|
|
/* show it in the viewer */
|
|
gcm_prefs_profile_view (prefs, profile);
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_profile_view_cb (GtkWidget *widget, CcColorPanel *prefs)
|
|
{
|
|
CdProfile *profile;
|
|
|
|
/* get the selected profile */
|
|
widget = egg_list_box_get_selected_child (prefs->priv->list_box);
|
|
if (widget == NULL)
|
|
return;
|
|
profile = cc_color_profile_get_profile (CC_COLOR_PROFILE (widget));
|
|
if (profile == NULL)
|
|
{
|
|
g_warning ("failed to get the active profile");
|
|
return;
|
|
}
|
|
|
|
/* open up gcm-viewer as a info pane */
|
|
gcm_prefs_profile_view (prefs, profile);
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_button_assign_cancel_cb (GtkWidget *widget, CcColorPanel *prefs)
|
|
{
|
|
CcColorPanelPrivate *priv = prefs->priv;
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"dialog_assign"));
|
|
gtk_widget_hide (widget);
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_button_assign_ok_cb (GtkWidget *widget, CcColorPanel *prefs)
|
|
{
|
|
GtkTreeIter iter;
|
|
GtkTreeModel *model;
|
|
CdProfile *profile = NULL;
|
|
gboolean ret = FALSE;
|
|
GError *error = NULL;
|
|
GtkTreeSelection *selection;
|
|
CcColorPanelPrivate *priv = prefs->priv;
|
|
|
|
/* hide window */
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"dialog_assign"));
|
|
gtk_widget_hide (widget);
|
|
|
|
/* get the selected profile */
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"treeview_assign"));
|
|
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
|
|
if (!gtk_tree_selection_get_selected (selection, &model, &iter))
|
|
goto out;
|
|
gtk_tree_model_get (model, &iter,
|
|
GCM_PREFS_COMBO_COLUMN_PROFILE, &profile,
|
|
-1);
|
|
if (profile == NULL)
|
|
{
|
|
g_warning ("failed to get the active profile");
|
|
goto out;
|
|
}
|
|
|
|
/* if the device is disabled, enable the device so that we can
|
|
* add color profiles to it */
|
|
if (!cd_device_get_enabled (priv->current_device))
|
|
{
|
|
ret = cd_device_set_enabled_sync (priv->current_device,
|
|
TRUE,
|
|
priv->cancellable,
|
|
&error);
|
|
if (!ret)
|
|
{
|
|
g_warning ("failed to enabled device: %s", error->message);
|
|
g_error_free (error);
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
/* just add it, the list store will get ::changed */
|
|
ret = cd_device_add_profile_sync (priv->current_device,
|
|
CD_DEVICE_RELATION_HARD,
|
|
profile,
|
|
priv->cancellable,
|
|
&error);
|
|
if (!ret)
|
|
{
|
|
g_warning ("failed to add: %s", error->message);
|
|
g_error_free (error);
|
|
goto out;
|
|
}
|
|
|
|
/* make it default */
|
|
cd_device_make_profile_default (priv->current_device,
|
|
profile,
|
|
priv->cancellable,
|
|
gcm_prefs_make_profile_default_cb,
|
|
prefs);
|
|
out:
|
|
if (profile != NULL)
|
|
g_object_unref (profile);
|
|
}
|
|
|
|
static gboolean
|
|
gcm_prefs_profile_delete_event_cb (GtkWidget *widget,
|
|
GdkEvent *event,
|
|
CcColorPanel *prefs)
|
|
{
|
|
gcm_prefs_button_assign_cancel_cb (widget, prefs);
|
|
return TRUE;
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_add_profiles_columns (CcColorPanel *prefs,
|
|
GtkTreeView *treeview)
|
|
{
|
|
GtkCellRenderer *renderer;
|
|
GtkTreeViewColumn *column;
|
|
|
|
/* text */
|
|
renderer = gtk_cell_renderer_text_new ();
|
|
column = gtk_tree_view_column_new ();
|
|
gtk_tree_view_column_pack_start (column, renderer, TRUE);
|
|
gtk_tree_view_column_add_attribute (column, renderer,
|
|
"markup", GCM_PREFS_COMBO_COLUMN_TEXT);
|
|
gtk_tree_view_column_set_expand (column, TRUE);
|
|
gtk_tree_view_append_column (treeview, column);
|
|
|
|
/* image */
|
|
column = gtk_tree_view_column_new ();
|
|
renderer = gtk_cell_renderer_pixbuf_new ();
|
|
g_object_set (renderer, "stock-size", GTK_ICON_SIZE_MENU, NULL);
|
|
gtk_tree_view_column_pack_start (column, renderer, FALSE);
|
|
gtk_tree_view_column_add_attribute (column, renderer,
|
|
"icon-name", GCM_PREFS_COMBO_COLUMN_WARNING_FILENAME);
|
|
gtk_tree_view_append_column (treeview, column);
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_set_calibrate_button_sensitivity (CcColorPanel *prefs)
|
|
{
|
|
gboolean ret = FALSE;
|
|
GtkWidget *widget;
|
|
const gchar *tooltip;
|
|
CdDeviceKind kind;
|
|
CdSensor *sensor_tmp;
|
|
CcColorPanelPrivate *priv = prefs->priv;
|
|
|
|
/* TRANSLATORS: this is when the button is sensitive */
|
|
tooltip = _("Create a color profile for the selected device");
|
|
|
|
/* no device selected */
|
|
if (priv->current_device == NULL)
|
|
goto out;
|
|
|
|
/* are we a display */
|
|
kind = cd_device_get_kind (priv->current_device);
|
|
if (kind == CD_DEVICE_KIND_DISPLAY)
|
|
{
|
|
|
|
/* find whether we have hardware installed */
|
|
if (priv->sensors == NULL || priv->sensors->len == 0)
|
|
{
|
|
/* TRANSLATORS: this is when the button is insensitive */
|
|
tooltip = _("The measuring instrument is not detected. Please check it is turned on and correctly connected.");
|
|
goto out;
|
|
}
|
|
|
|
/* success */
|
|
ret = TRUE;
|
|
|
|
}
|
|
else if (kind == CD_DEVICE_KIND_SCANNER ||
|
|
kind == CD_DEVICE_KIND_CAMERA ||
|
|
kind == CD_DEVICE_KIND_WEBCAM)
|
|
{
|
|
|
|
/* TODO: find out if we can scan using gnome-scan */
|
|
ret = TRUE;
|
|
|
|
}
|
|
else if (kind == CD_DEVICE_KIND_PRINTER)
|
|
{
|
|
|
|
/* find whether we have hardware installed */
|
|
if (priv->sensors == NULL || priv->sensors->len == 0)
|
|
{
|
|
/* TRANSLATORS: this is when the button is insensitive */
|
|
tooltip = _("The measuring instrument is not detected. Please check it is turned on and correctly connected.");
|
|
goto out;
|
|
}
|
|
|
|
/* find whether we have hardware installed */
|
|
sensor_tmp = g_ptr_array_index (priv->sensors, 0);
|
|
ret = cd_sensor_has_cap (sensor_tmp, CD_SENSOR_CAP_PRINTER);
|
|
if (!ret)
|
|
{
|
|
/* TRANSLATORS: this is when the button is insensitive */
|
|
tooltip = _("The measuring instrument does not support printer profiling.");
|
|
goto out;
|
|
}
|
|
|
|
/* success */
|
|
ret = TRUE;
|
|
|
|
}
|
|
else
|
|
{
|
|
/* TRANSLATORS: this is when the button is insensitive */
|
|
tooltip = _("The device type is not currently supported.");
|
|
}
|
|
out:
|
|
/* control the tooltip and sensitivity of the button */
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"toolbutton_device_calibrate"));
|
|
gtk_widget_set_tooltip_text (widget, tooltip);
|
|
gtk_widget_set_sensitive (widget, ret);
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_device_clicked (CcColorPanel *prefs, CdDevice *device)
|
|
{
|
|
/* we have a new device */
|
|
g_debug ("selected device is: %s",
|
|
cd_device_get_id (device));
|
|
|
|
/* can this device calibrate */
|
|
gcm_prefs_set_calibrate_button_sensitivity (prefs);
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_profile_clicked (CcColorPanel *prefs, CdProfile *profile, CdDevice *device)
|
|
{
|
|
GtkWidget *widget;
|
|
gchar *s;
|
|
CcColorPanelPrivate *priv = prefs->priv;
|
|
|
|
/* get profile */
|
|
g_debug ("selected profile = %s",
|
|
cd_profile_get_filename (profile));
|
|
|
|
/* allow getting profile info */
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"toolbutton_profile_view"));
|
|
if ((s = g_find_program_in_path ("gcm-viewer")))
|
|
{
|
|
gtk_widget_set_sensitive (widget, TRUE);
|
|
g_free (s);
|
|
}
|
|
else
|
|
gtk_widget_set_sensitive (widget, FALSE);
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_profiles_treeview_clicked_cb (GtkTreeSelection *selection,
|
|
CcColorPanel *prefs)
|
|
{
|
|
GtkWidget *widget;
|
|
GtkTreeModel *model;
|
|
GtkTreeIter iter;
|
|
CdProfile *profile = NULL;
|
|
#if CD_CHECK_VERSION(0,1,25)
|
|
gchar **warnings;
|
|
#endif
|
|
|
|
/* get selection */
|
|
if (!gtk_tree_selection_get_selected (selection, &model, &iter))
|
|
return;
|
|
gtk_tree_model_get (model, &iter,
|
|
GCM_PREFS_COMBO_COLUMN_PROFILE, &profile,
|
|
-1);
|
|
|
|
|
|
/* as soon as anything is selected, make the Add button sensitive */
|
|
widget = GTK_WIDGET (gtk_builder_get_object (prefs->priv->builder,
|
|
"button_assign_ok"));
|
|
gtk_widget_set_sensitive (widget, TRUE);
|
|
|
|
/* is the profile faulty */
|
|
widget = GTK_WIDGET (gtk_builder_get_object (prefs->priv->builder,
|
|
"label_assign_warning"));
|
|
#if CD_CHECK_VERSION(0,1,25)
|
|
warnings = cd_profile_get_warnings (profile);
|
|
gtk_widget_set_visible (widget, warnings != NULL && warnings[0] != NULL);
|
|
#else
|
|
gtk_widget_set_visible (widget, FALSE);
|
|
#endif
|
|
g_object_unref (profile);
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_profiles_row_activated_cb (GtkTreeView *tree_view,
|
|
GtkTreePath *path,
|
|
GtkTreeViewColumn *column,
|
|
CcColorPanel *prefs)
|
|
{
|
|
GtkTreeIter iter;
|
|
gboolean ret;
|
|
|
|
ret = gtk_tree_model_get_iter (gtk_tree_view_get_model (tree_view), &iter, path);
|
|
if (!ret)
|
|
return;
|
|
gcm_prefs_button_assign_ok_cb (NULL, prefs);
|
|
}
|
|
|
|
|
|
static void
|
|
gcm_prefs_button_assign_import_cb (GtkWidget *widget,
|
|
CcColorPanel *prefs)
|
|
{
|
|
GFile *file = NULL;
|
|
GError *error = NULL;
|
|
CdProfile *profile = NULL;
|
|
CcColorPanelPrivate *priv = prefs->priv;
|
|
|
|
file = gcm_prefs_file_chooser_get_icc_profile (prefs);
|
|
if (file == NULL)
|
|
{
|
|
g_warning ("failed to get ICC file");
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"dialog_assign"));
|
|
gtk_widget_hide (widget);
|
|
goto out;
|
|
}
|
|
|
|
#if CD_CHECK_VERSION(0,1,12)
|
|
profile = cd_client_import_profile_sync (priv->client,
|
|
file,
|
|
priv->cancellable,
|
|
&error);
|
|
if (profile == NULL)
|
|
{
|
|
g_warning ("failed to get imported profile: %s", error->message);
|
|
g_error_free (error);
|
|
goto out;
|
|
}
|
|
#endif
|
|
|
|
/* add to list view */
|
|
gcm_prefs_profile_add_cb (NULL, prefs);
|
|
out:
|
|
if (file != NULL)
|
|
g_object_unref (file);
|
|
if (profile != NULL)
|
|
g_object_unref (profile);
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_sensor_coldplug (CcColorPanel *prefs)
|
|
{
|
|
CcColorPanelPrivate *priv = prefs->priv;
|
|
CdSensor *sensor_tmp;
|
|
gboolean ret;
|
|
GError *error = NULL;
|
|
GPtrArray *sensors;
|
|
guint i;
|
|
|
|
/* unref old */
|
|
g_clear_pointer (&priv->sensors, g_ptr_array_unref);
|
|
|
|
/* no present */
|
|
sensors = cd_client_get_sensors_sync (priv->client, NULL, &error);
|
|
if (sensors == NULL)
|
|
{
|
|
g_warning ("%s", error->message);
|
|
g_error_free (error);
|
|
goto out;
|
|
}
|
|
if (sensors->len == 0)
|
|
goto out;
|
|
|
|
/* save a copy of the sensor list */
|
|
priv->sensors = g_ptr_array_ref (sensors);
|
|
|
|
/* connect to each sensor */
|
|
for (i = 0; i < sensors->len; i++)
|
|
{
|
|
sensor_tmp = g_ptr_array_index (sensors, i);
|
|
ret = cd_sensor_connect_sync (sensor_tmp, NULL, &error);
|
|
if (!ret)
|
|
{
|
|
g_warning ("%s", error->message);
|
|
g_error_free (error);
|
|
goto out;
|
|
}
|
|
}
|
|
out:
|
|
if (sensors != NULL)
|
|
g_ptr_array_unref (sensors);
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_client_sensor_changed_cb (CdClient *client,
|
|
CdSensor *sensor,
|
|
CcColorPanel *prefs)
|
|
{
|
|
gcm_prefs_sensor_coldplug (prefs);
|
|
gcm_prefs_set_calibrate_button_sensitivity (prefs);
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_add_device_profile (CcColorPanel *prefs,
|
|
CdDevice *device,
|
|
CdProfile *profile,
|
|
gboolean is_default)
|
|
{
|
|
CcColorPanelPrivate *priv = prefs->priv;
|
|
gboolean ret;
|
|
GError *error = NULL;
|
|
GtkWidget *widget;
|
|
|
|
/* get properties */
|
|
ret = cd_profile_connect_sync (profile,
|
|
priv->cancellable,
|
|
&error);
|
|
if (!ret)
|
|
{
|
|
g_warning ("failed to get profile: %s", error->message);
|
|
g_error_free (error);
|
|
goto out;
|
|
}
|
|
|
|
/* ignore profiles from other user accounts */
|
|
if (!cd_profile_has_access (profile))
|
|
{
|
|
/* only print the filename if it exists */
|
|
if (cd_profile_get_filename (profile) != NULL)
|
|
{
|
|
g_warning ("%s is not usable by this user",
|
|
cd_profile_get_filename (profile));
|
|
}
|
|
else
|
|
{
|
|
g_warning ("%s is not usable by this user",
|
|
cd_profile_get_id (profile));
|
|
}
|
|
goto out;
|
|
}
|
|
|
|
/* add to listbox */
|
|
widget = cc_color_profile_new (device, profile, is_default);
|
|
gtk_widget_show (widget);
|
|
gtk_container_add (GTK_CONTAINER (priv->list_box), widget);
|
|
gtk_size_group_add_widget (priv->list_box_size, widget);
|
|
out:
|
|
return;
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_add_device_profiles (CcColorPanel *prefs, CdDevice *device)
|
|
{
|
|
CdProfile *profile_tmp;
|
|
GPtrArray *profiles = NULL;
|
|
guint i;
|
|
|
|
/* add profiles */
|
|
profiles = cd_device_get_profiles (device);
|
|
if (profiles == NULL)
|
|
goto out;
|
|
for (i = 0; i < profiles->len; i++)
|
|
{
|
|
profile_tmp = g_ptr_array_index (profiles, i);
|
|
gcm_prefs_add_device_profile (prefs, device, profile_tmp, i == 0);
|
|
}
|
|
out:
|
|
if (profiles != NULL)
|
|
g_ptr_array_unref (profiles);
|
|
}
|
|
|
|
/* find the profile in the array -- for flicker-free changes */
|
|
static gboolean
|
|
gcm_prefs_find_profile_by_object_path (GPtrArray *profiles,
|
|
const gchar *object_path)
|
|
{
|
|
CdProfile *profile_tmp;
|
|
guint i;
|
|
|
|
for (i = 0; i < profiles->len; i++)
|
|
{
|
|
profile_tmp = g_ptr_array_index (profiles, i);
|
|
if (g_strcmp0 (cd_profile_get_object_path (profile_tmp), object_path) == 0)
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/* find the profile in the list view -- for flicker-free changes */
|
|
static gboolean
|
|
gcm_prefs_find_widget_by_object_path (GList *list,
|
|
const gchar *object_path_device,
|
|
const gchar *object_path_profile)
|
|
{
|
|
GList *l;
|
|
CdDevice *device_tmp;
|
|
CdProfile *profile_tmp;
|
|
|
|
for (l = list; l != NULL; l = l->next)
|
|
{
|
|
if (!CC_IS_COLOR_PROFILE (l->data))
|
|
continue;
|
|
|
|
/* correct device ? */
|
|
device_tmp = cc_color_profile_get_device (CC_COLOR_PROFILE (l->data));
|
|
if (g_strcmp0 (object_path_device,
|
|
cd_device_get_object_path (device_tmp)) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
/* this profile */
|
|
profile_tmp = cc_color_profile_get_profile (CC_COLOR_PROFILE (l->data));
|
|
if (g_strcmp0 (object_path_profile,
|
|
cd_profile_get_object_path (profile_tmp)) == 0)
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_device_changed_cb (CdDevice *device, CcColorPanel *prefs)
|
|
{
|
|
CcColorPanelPrivate *priv = prefs->priv;
|
|
CdDevice *device_tmp;
|
|
CdProfile *profile_tmp;
|
|
gboolean ret;
|
|
GList *l;
|
|
GList *list;
|
|
GPtrArray *profiles;
|
|
guint i;
|
|
|
|
/* remove anything in the list view that's not in Device.Profiles */
|
|
profiles = cd_device_get_profiles (device);
|
|
list = gtk_container_get_children (GTK_CONTAINER (priv->list_box));
|
|
for (l = list; l != NULL; l = l->next)
|
|
{
|
|
if (!CC_IS_COLOR_PROFILE (l->data))
|
|
continue;
|
|
|
|
/* correct device ? */
|
|
device_tmp = cc_color_profile_get_device (CC_COLOR_PROFILE (l->data));
|
|
if (g_strcmp0 (cd_device_get_id (device),
|
|
cd_device_get_id (device_tmp)) != 0)
|
|
continue;
|
|
|
|
/* if profile is not in Device.Profiles then remove */
|
|
profile_tmp = cc_color_profile_get_profile (CC_COLOR_PROFILE (l->data));
|
|
ret = gcm_prefs_find_profile_by_object_path (profiles,
|
|
cd_profile_get_object_path (profile_tmp));
|
|
if (!ret)
|
|
gtk_widget_destroy (GTK_WIDGET (l->data));
|
|
}
|
|
|
|
/* add anything in Device.Profiles that's not in the list view */
|
|
for (i = 0; i < profiles->len; i++)
|
|
{
|
|
profile_tmp = g_ptr_array_index (profiles, i);
|
|
ret = gcm_prefs_find_widget_by_object_path (list,
|
|
cd_device_get_object_path (device),
|
|
cd_profile_get_object_path (profile_tmp));
|
|
if (!ret)
|
|
gcm_prefs_add_device_profile (prefs, device, profile_tmp, i == 0);
|
|
}
|
|
g_list_free (list);
|
|
|
|
/* resort */
|
|
egg_list_box_resort (priv->list_box);
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_device_expanded_changed_cb (CcColorDevice *widget,
|
|
gboolean is_expanded,
|
|
CcColorPanel *prefs)
|
|
{
|
|
CcColorPanelPrivate *priv = prefs->priv;
|
|
GList *l;
|
|
GList *list;
|
|
|
|
/* ignore internal changes */
|
|
if (prefs->priv->model_is_changing)
|
|
return;
|
|
|
|
g_free (prefs->priv->list_box_filter);
|
|
if (is_expanded)
|
|
{
|
|
priv->list_box_filter = g_strdup (cd_device_get_id (cc_color_device_get_device (widget)));
|
|
|
|
/* unexpand other device widgets */
|
|
list = gtk_container_get_children (GTK_CONTAINER (priv->list_box));
|
|
prefs->priv->model_is_changing = TRUE;
|
|
for (l = list; l != NULL; l = l->next)
|
|
{
|
|
if (!CC_IS_COLOR_DEVICE (l->data))
|
|
continue;
|
|
if (l->data != widget)
|
|
cc_color_device_set_expanded (CC_COLOR_DEVICE (l->data), FALSE);
|
|
}
|
|
prefs->priv->model_is_changing = FALSE;
|
|
g_list_free (list);
|
|
}
|
|
else
|
|
{
|
|
priv->list_box_filter = NULL;
|
|
}
|
|
egg_list_box_refilter (priv->list_box);
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_add_device (CcColorPanel *prefs, CdDevice *device)
|
|
{
|
|
CcColorPanelPrivate *priv = prefs->priv;
|
|
gboolean ret;
|
|
GError *error = NULL;
|
|
GtkWidget *widget;
|
|
|
|
/* get device properties */
|
|
ret = cd_device_connect_sync (device, priv->cancellable, &error);
|
|
if (!ret)
|
|
{
|
|
g_warning ("failed to connect to the device: %s", error->message);
|
|
g_error_free (error);
|
|
goto out;
|
|
}
|
|
|
|
/* add device */
|
|
widget = cc_color_device_new (device);
|
|
g_signal_connect (widget, "expanded-changed",
|
|
G_CALLBACK (gcm_prefs_device_expanded_changed_cb), prefs);
|
|
gtk_widget_show (widget);
|
|
gtk_container_add (GTK_CONTAINER (priv->list_box), widget);
|
|
gtk_size_group_add_widget (priv->list_box_size, widget);
|
|
|
|
/* add profiles */
|
|
gcm_prefs_add_device_profiles (prefs, device);
|
|
|
|
/* watch for changes */
|
|
g_signal_connect (device, "changed",
|
|
G_CALLBACK (gcm_prefs_device_changed_cb), prefs);
|
|
egg_list_box_resort (priv->list_box);
|
|
out:
|
|
return;
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_remove_device (CcColorPanel *prefs, CdDevice *device)
|
|
{
|
|
CcColorPanelPrivate *priv = prefs->priv;
|
|
CdDevice *device_tmp;
|
|
GList *l;
|
|
GList *list;
|
|
|
|
list = gtk_container_get_children (GTK_CONTAINER (priv->list_box));
|
|
for (l = list; l != NULL; l = l->next)
|
|
{
|
|
if (CC_IS_COLOR_DEVICE (l->data))
|
|
device_tmp = cc_color_device_get_device (CC_COLOR_DEVICE (l->data));
|
|
else
|
|
device_tmp = cc_color_profile_get_device (CC_COLOR_PROFILE (l->data));
|
|
if (g_strcmp0 (cd_device_get_object_path (device),
|
|
cd_device_get_object_path (device_tmp)) == 0)
|
|
{
|
|
gtk_widget_destroy (GTK_WIDGET (l->data));
|
|
}
|
|
}
|
|
g_list_free (list);
|
|
g_signal_handlers_disconnect_by_func (device,
|
|
G_CALLBACK (gcm_prefs_device_changed_cb),
|
|
prefs);
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_update_device_list_extra_entry (CcColorPanel *prefs)
|
|
{
|
|
CcColorPanelPrivate *priv = prefs->priv;
|
|
GList *device_widgets;
|
|
GtkWidget *widget;
|
|
guint number_of_devices;
|
|
|
|
/* any devices to show? */
|
|
device_widgets = gtk_container_get_children (GTK_CONTAINER (priv->list_box));
|
|
number_of_devices = g_list_length (device_widgets);
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"label_no_devices"));
|
|
gtk_widget_set_visible (widget, number_of_devices == 0);
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"vbox3"));
|
|
gtk_widget_set_visible (widget, number_of_devices > 0);
|
|
|
|
/* if we have only one device expand it by default */
|
|
if (number_of_devices == 1)
|
|
cc_color_device_set_expanded (CC_COLOR_DEVICE (device_widgets->data), TRUE);
|
|
g_list_free (device_widgets);
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_device_added_cb (CdClient *client,
|
|
CdDevice *device,
|
|
CcColorPanel *prefs)
|
|
{
|
|
/* add the device */
|
|
gcm_prefs_add_device (prefs, device);
|
|
|
|
/* ensure we're not showing the 'No devices detected' entry */
|
|
gcm_prefs_update_device_list_extra_entry (prefs);
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_device_removed_cb (CdClient *client,
|
|
CdDevice *device,
|
|
CcColorPanel *prefs)
|
|
{
|
|
/* remove from the UI */
|
|
gcm_prefs_remove_device (prefs, device);
|
|
|
|
/* ensure we showing the 'No devices detected' entry if required */
|
|
gcm_prefs_update_device_list_extra_entry (prefs);
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_get_devices_cb (GObject *object,
|
|
GAsyncResult *res,
|
|
gpointer user_data)
|
|
{
|
|
CcColorPanel *prefs = (CcColorPanel *) user_data;
|
|
CdClient *client = CD_CLIENT (object);
|
|
CdDevice *device;
|
|
GError *error = NULL;
|
|
GPtrArray *devices;
|
|
guint i;
|
|
|
|
/* get devices and add them */
|
|
devices = cd_client_get_devices_finish (client, res, &error);
|
|
if (devices == NULL)
|
|
{
|
|
g_warning ("failed to add connected devices: %s",
|
|
error->message);
|
|
g_error_free (error);
|
|
goto out;
|
|
}
|
|
for (i = 0; i < devices->len; i++)
|
|
{
|
|
device = g_ptr_array_index (devices, i);
|
|
gcm_prefs_add_device (prefs, device);
|
|
}
|
|
|
|
/* ensure we show the 'No devices detected' entry if empty */
|
|
gcm_prefs_update_device_list_extra_entry (prefs);
|
|
out:
|
|
if (devices != NULL)
|
|
g_ptr_array_unref (devices);
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_list_box_handle_selection_flags (EggListBox *list_box,
|
|
GtkWidget *child)
|
|
{
|
|
GList *l;
|
|
GList *list;
|
|
|
|
list = gtk_container_get_children (GTK_CONTAINER (list_box));
|
|
for (l = list; l != NULL; l = l->next)
|
|
{
|
|
if (child != l->data)
|
|
{
|
|
gtk_widget_unset_state_flags (GTK_WIDGET (l->data),
|
|
GTK_STATE_FLAG_SELECTED);
|
|
continue;
|
|
}
|
|
gtk_widget_set_state_flags (child, GTK_STATE_FLAG_SELECTED, FALSE);
|
|
}
|
|
g_list_free (list);
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_list_box_child_selected_cb (EggListBox *list_box,
|
|
GtkWidget *child,
|
|
CcColorPanel *panel)
|
|
{
|
|
CdProfile *profile = NULL;
|
|
GtkWidget *widget;
|
|
CcColorPanelPrivate *priv = panel->priv;
|
|
gboolean is_device = CC_IS_COLOR_DEVICE (child);
|
|
|
|
/* nothing selected */
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"toolbar_devices"));
|
|
gtk_widget_set_visible (widget, child != NULL);
|
|
if (child == NULL)
|
|
return;
|
|
|
|
/* until Alex works out what to do with forwarding the state onto
|
|
* children in an EggListBox, we have to do this ourselves */
|
|
gcm_prefs_list_box_handle_selection_flags (list_box, child);
|
|
|
|
/* save current device */
|
|
if (priv->current_device != NULL)
|
|
g_object_unref (priv->current_device);
|
|
g_object_get (child, "device", &priv->current_device, NULL);
|
|
|
|
/* device actions */
|
|
g_debug ("%s selected", is_device ? "device" : "profile");
|
|
if (CC_IS_COLOR_DEVICE (child))
|
|
{
|
|
gcm_prefs_device_clicked (panel, priv->current_device);
|
|
cc_color_device_set_expanded (CC_COLOR_DEVICE (child), TRUE);
|
|
}
|
|
else if (CC_IS_COLOR_PROFILE (child))
|
|
{
|
|
profile = cc_color_profile_get_profile (CC_COLOR_PROFILE (child));
|
|
gcm_prefs_profile_clicked (panel, profile, priv->current_device);
|
|
}
|
|
else
|
|
g_assert_not_reached ();
|
|
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"toolbutton_device_default"));
|
|
gtk_widget_set_visible (widget, !is_device && cc_color_profile_get_is_default (CC_COLOR_PROFILE (child)));
|
|
if (profile)
|
|
gtk_widget_set_sensitive (widget, !cd_profile_get_is_system_wide (profile));
|
|
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"toolbutton_device_enable"));
|
|
gtk_widget_set_visible (widget, !is_device && !cc_color_profile_get_is_default (CC_COLOR_PROFILE (child)));
|
|
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"toolbutton_device_calibrate"));
|
|
gtk_widget_set_visible (widget, is_device);
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"toolbutton_profile_add"));
|
|
gtk_widget_set_visible (widget, is_device);
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"toolbutton_profile_view"));
|
|
gtk_widget_set_visible (widget, !is_device);
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"toolbutton_profile_remove"));
|
|
gtk_widget_set_visible (widget, !is_device);
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_connect_cb (GObject *object,
|
|
GAsyncResult *res,
|
|
gpointer user_data)
|
|
{
|
|
gboolean ret;
|
|
GError *error = NULL;
|
|
CcColorPanel *prefs = CC_COLOR_PANEL (user_data);
|
|
CcColorPanelPrivate *priv = prefs->priv;
|
|
|
|
ret = cd_client_connect_finish (priv->client,
|
|
res,
|
|
&error);
|
|
if (!ret)
|
|
{
|
|
g_warning ("failed to connect to colord: %s", error->message);
|
|
g_error_free (error);
|
|
return;
|
|
}
|
|
|
|
/* set calibrate button sensitivity */
|
|
gcm_prefs_sensor_coldplug (prefs);
|
|
|
|
|
|
/* get devices */
|
|
cd_client_get_devices (priv->client,
|
|
priv->cancellable,
|
|
gcm_prefs_get_devices_cb,
|
|
prefs);
|
|
}
|
|
|
|
static gboolean
|
|
gcm_prefs_is_livecd (void)
|
|
{
|
|
gboolean ret = TRUE;
|
|
gchar *data = NULL;
|
|
GError *error = NULL;
|
|
|
|
/* allow testing */
|
|
if (g_getenv ("CC_COLOR_PANEL_IS_LIVECD") != NULL)
|
|
goto out;
|
|
|
|
/* get the kernel commandline */
|
|
ret = g_file_get_contents ("/proc/cmdline", &data, NULL, &error);
|
|
if (!ret)
|
|
{
|
|
g_warning ("failed to get kernel command line: %s",
|
|
error->message);
|
|
g_error_free (error);
|
|
goto out;
|
|
}
|
|
ret = (g_strstr_len (data, -1, "liveimg") != NULL ||
|
|
g_strstr_len (data, -1, "casper") != NULL);
|
|
out:
|
|
g_free (data);
|
|
return ret;
|
|
}
|
|
|
|
static void
|
|
gcm_prefs_window_realize_cb (GtkWidget *widget, CcColorPanel *prefs)
|
|
{
|
|
prefs->priv->main_window = gtk_widget_get_toplevel (widget);
|
|
}
|
|
|
|
static const char *
|
|
cc_color_panel_get_help_uri (CcPanel *panel)
|
|
{
|
|
return "help:gnome-help/color";
|
|
}
|
|
|
|
static void
|
|
cc_color_panel_get_property (GObject *object,
|
|
guint property_id,
|
|
GValue *value,
|
|
GParamSpec *pspec)
|
|
{
|
|
switch (property_id)
|
|
{
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
}
|
|
}
|
|
|
|
static void
|
|
cc_color_panel_set_property (GObject *object,
|
|
guint property_id,
|
|
const GValue *value,
|
|
GParamSpec *pspec)
|
|
{
|
|
switch (property_id)
|
|
{
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
}
|
|
}
|
|
|
|
static void
|
|
cc_color_panel_dispose (GObject *object)
|
|
{
|
|
CcColorPanelPrivate *priv = CC_COLOR_PANEL (object)->priv;
|
|
|
|
/* stop the EggListView from firing when it gets disposed */
|
|
if (priv->list_box_selected_id != 0)
|
|
{
|
|
g_signal_handler_disconnect (priv->list_box,
|
|
priv->list_box_selected_id);
|
|
priv->list_box_selected_id = 0;
|
|
}
|
|
|
|
if (priv->cancellable != NULL)
|
|
g_cancellable_cancel (priv->cancellable);
|
|
g_clear_object (&priv->settings);
|
|
g_clear_object (&priv->cancellable);
|
|
g_clear_object (&priv->builder);
|
|
g_clear_object (&priv->client);
|
|
g_clear_object (&priv->current_device);
|
|
g_clear_object (&priv->calibrate);
|
|
g_clear_object (&priv->list_box_size);
|
|
g_clear_pointer (&priv->sensors, g_ptr_array_unref);
|
|
g_clear_pointer (&priv->list_box_filter, g_free);
|
|
|
|
G_OBJECT_CLASS (cc_color_panel_parent_class)->dispose (object);
|
|
}
|
|
|
|
static void
|
|
cc_color_panel_finalize (GObject *object)
|
|
{
|
|
G_OBJECT_CLASS (cc_color_panel_parent_class)->finalize (object);
|
|
}
|
|
|
|
static void
|
|
cc_color_panel_class_init (CcColorPanelClass *klass)
|
|
{
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
CcPanelClass *panel_class = CC_PANEL_CLASS (klass);
|
|
|
|
g_type_class_add_private (klass, sizeof (CcColorPanelPrivate));
|
|
|
|
panel_class->get_help_uri = cc_color_panel_get_help_uri;
|
|
|
|
object_class->get_property = cc_color_panel_get_property;
|
|
object_class->set_property = cc_color_panel_set_property;
|
|
object_class->dispose = cc_color_panel_dispose;
|
|
object_class->finalize = cc_color_panel_finalize;
|
|
}
|
|
|
|
static gint
|
|
cc_color_panel_sort_func (gconstpointer a,
|
|
gconstpointer b,
|
|
gpointer user_data)
|
|
{
|
|
const gchar *sort_a = NULL;
|
|
const gchar *sort_b = NULL;
|
|
if (CC_IS_COLOR_DEVICE (a))
|
|
sort_a = cc_color_device_get_sortable (CC_COLOR_DEVICE (a));
|
|
else if (CC_IS_COLOR_PROFILE (a))
|
|
sort_a = cc_color_profile_get_sortable (CC_COLOR_PROFILE (a));
|
|
else
|
|
g_assert_not_reached ();
|
|
if (CC_IS_COLOR_DEVICE (b))
|
|
sort_b = cc_color_device_get_sortable (CC_COLOR_DEVICE (b));
|
|
else if (CC_IS_COLOR_PROFILE (b))
|
|
sort_b = cc_color_profile_get_sortable (CC_COLOR_PROFILE (b));
|
|
else
|
|
g_assert_not_reached ();
|
|
return g_strcmp0 (sort_b, sort_a);
|
|
}
|
|
|
|
static gboolean
|
|
cc_color_panel_filter_func (GtkWidget *child, void *user_data)
|
|
{
|
|
CcColorPanel *prefs = CC_COLOR_PANEL (user_data);
|
|
CdDevice *device;
|
|
gboolean ret;
|
|
|
|
/* always show all devices */
|
|
if (CC_IS_COLOR_DEVICE (child))
|
|
return TRUE;
|
|
|
|
g_object_get (child, "device", &device, NULL);
|
|
ret = g_strcmp0 (cd_device_get_id (device), prefs->priv->list_box_filter) == 0;
|
|
g_object_unref (device);
|
|
return ret;
|
|
}
|
|
|
|
static void
|
|
cc_color_panel_separator_func (GtkWidget **separator,
|
|
GtkWidget *child,
|
|
GtkWidget *before,
|
|
gpointer user_data)
|
|
{
|
|
if (before == NULL)
|
|
return;
|
|
|
|
if (*separator == NULL)
|
|
{
|
|
*separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
|
|
g_object_ref_sink (*separator);
|
|
gtk_widget_show (*separator);
|
|
}
|
|
}
|
|
|
|
static gboolean
|
|
cc_color_panel_treeview_quality_default_cb (GtkTreeModel *model,
|
|
GtkTreePath *path,
|
|
GtkTreeIter *iter,
|
|
gpointer data)
|
|
{
|
|
CdProfileQuality quality;
|
|
GtkTreeSelection *selection = GTK_TREE_SELECTION (data);
|
|
|
|
gtk_tree_model_get (model, iter,
|
|
COLUMN_CALIB_QUALITY_VALUE, &quality,
|
|
-1);
|
|
if (quality == CD_PROFILE_QUALITY_MEDIUM)
|
|
gtk_tree_selection_select_iter (selection, iter);
|
|
return FALSE;
|
|
}
|
|
|
|
static void
|
|
cc_color_panel_init (CcColorPanel *prefs)
|
|
{
|
|
CcColorPanelPrivate *priv;
|
|
GError *error = NULL;
|
|
GtkCellRenderer *renderer;
|
|
GtkStyleContext *context;
|
|
GtkTreeModel *model;
|
|
GtkTreeModel *model_filter;
|
|
GtkTreeSelection *selection;
|
|
GtkTreeViewColumn *column;
|
|
GtkWidget *widget;
|
|
|
|
priv = prefs->priv = COLOR_PANEL_PRIVATE (prefs);
|
|
g_resources_register (cc_color_get_resource ());
|
|
|
|
priv->builder = gtk_builder_new ();
|
|
gtk_builder_add_from_resource (priv->builder,
|
|
"/org/gnome/control-center/color/color.ui",
|
|
&error);
|
|
|
|
if (error != NULL)
|
|
{
|
|
g_warning ("Could not load interface file: %s", error->message);
|
|
g_error_free (error);
|
|
return;
|
|
}
|
|
|
|
priv->cancellable = g_cancellable_new ();
|
|
|
|
/* can do native display calibration using colord-session */
|
|
priv->calibrate = cc_color_calibrate_new ();
|
|
|
|
/* setup defaults */
|
|
priv->settings = g_settings_new (GCM_SETTINGS_SCHEMA);
|
|
|
|
/* assign buttons */
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"toolbutton_profile_add"));
|
|
g_signal_connect (widget, "clicked",
|
|
G_CALLBACK (gcm_prefs_profile_add_cb), prefs);
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"toolbutton_profile_remove"));
|
|
g_signal_connect (widget, "clicked",
|
|
G_CALLBACK (gcm_prefs_profile_remove_cb), prefs);
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"toolbutton_profile_view"));
|
|
g_signal_connect (widget, "clicked",
|
|
G_CALLBACK (gcm_prefs_profile_view_cb), prefs);
|
|
|
|
/* href */
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"label_assign_warning"));
|
|
g_signal_connect (widget, "activate-link",
|
|
G_CALLBACK (gcm_prefs_profile_assign_link_activate_cb), prefs);
|
|
|
|
/* add columns to profile tree view */
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"treeview_assign"));
|
|
gcm_prefs_add_profiles_columns (prefs, GTK_TREE_VIEW (widget));
|
|
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
|
|
g_signal_connect (selection, "changed",
|
|
G_CALLBACK (gcm_prefs_profiles_treeview_clicked_cb),
|
|
prefs);
|
|
g_signal_connect (GTK_TREE_VIEW (widget), "row-activated",
|
|
G_CALLBACK (gcm_prefs_profiles_row_activated_cb),
|
|
prefs);
|
|
|
|
/* make larger by default */
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"scrolledwindow_assign"));
|
|
gtk_widget_set_size_request (widget, -1, 250);
|
|
|
|
/* force to be at least ~6 rows high */
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"scrolledwindow_devices"));
|
|
gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (widget),
|
|
300);
|
|
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"toolbutton_device_default"));
|
|
g_signal_connect (widget, "clicked",
|
|
G_CALLBACK (gcm_prefs_default_cb), prefs);
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"toolbutton_device_enable"));
|
|
g_signal_connect (widget, "clicked",
|
|
G_CALLBACK (gcm_prefs_device_profile_enable_cb), prefs);
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"toolbutton_device_calibrate"));
|
|
g_signal_connect (widget, "clicked",
|
|
G_CALLBACK (gcm_prefs_calibrate_cb), prefs);
|
|
|
|
/* make devices toolbar sexy */
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"scrolledwindow_devices"));
|
|
context = gtk_widget_get_style_context (widget);
|
|
gtk_style_context_set_junction_sides (context, GTK_JUNCTION_BOTTOM);
|
|
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"toolbar_devices"));
|
|
context = gtk_widget_get_style_context (widget);
|
|
gtk_style_context_add_class (context, GTK_STYLE_CLASS_INLINE_TOOLBAR);
|
|
gtk_style_context_set_junction_sides (context, GTK_JUNCTION_TOP);
|
|
|
|
/* set up assign dialog */
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"dialog_assign"));
|
|
g_signal_connect (widget, "delete-event",
|
|
G_CALLBACK (gcm_prefs_profile_delete_event_cb), prefs);
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"button_assign_cancel"));
|
|
g_signal_connect (widget, "clicked",
|
|
G_CALLBACK (gcm_prefs_button_assign_cancel_cb), prefs);
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"button_assign_ok"));
|
|
g_signal_connect (widget, "clicked",
|
|
G_CALLBACK (gcm_prefs_button_assign_ok_cb), prefs);
|
|
|
|
/* setup icc profiles list */
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"button_assign_import"));
|
|
g_signal_connect (widget, "clicked",
|
|
G_CALLBACK (gcm_prefs_button_assign_import_cb), prefs);
|
|
|
|
/* setup the calibration helper */
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"assistant_calib"));
|
|
g_signal_connect (widget, "delete-event",
|
|
G_CALLBACK (gcm_prefs_calib_delete_event_cb),
|
|
prefs);
|
|
g_signal_connect (widget, "apply",
|
|
G_CALLBACK (gcm_prefs_calib_apply_cb),
|
|
prefs);
|
|
g_signal_connect (widget, "cancel",
|
|
G_CALLBACK (gcm_prefs_calib_cancel_cb),
|
|
prefs);
|
|
g_signal_connect (widget, "close",
|
|
G_CALLBACK (gcm_prefs_calib_cancel_cb),
|
|
prefs);
|
|
g_signal_connect (widget, "prepare",
|
|
G_CALLBACK (gcm_prefs_calib_prepare_cb),
|
|
prefs);
|
|
|
|
/* setup the calibration helper ::TreeView */
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"treeview_calib_quality"));
|
|
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
|
|
model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));
|
|
gtk_tree_model_foreach (model,
|
|
cc_color_panel_treeview_quality_default_cb,
|
|
selection);
|
|
g_signal_connect (selection, "changed",
|
|
G_CALLBACK (gcm_prefs_calib_quality_treeview_clicked_cb),
|
|
prefs);
|
|
column = gtk_tree_view_column_new ();
|
|
renderer = gtk_cell_renderer_text_new ();
|
|
g_object_set (renderer,
|
|
"xpad", 9,
|
|
"ypad", 9,
|
|
NULL);
|
|
gtk_tree_view_column_pack_start (column, renderer, TRUE);
|
|
gtk_tree_view_column_add_attribute (column, renderer,
|
|
"markup", COLUMN_CALIB_QUALITY_DESCRIPTION);
|
|
gtk_tree_view_column_set_expand (column, TRUE);
|
|
gtk_tree_view_append_column (GTK_TREE_VIEW (widget),
|
|
GTK_TREE_VIEW_COLUMN (column));
|
|
column = gtk_tree_view_column_new ();
|
|
renderer = cc_color_cell_renderer_text_new ();
|
|
g_object_set (renderer,
|
|
"xpad", 9,
|
|
"ypad", 9,
|
|
"is-dim-label", TRUE,
|
|
NULL);
|
|
gtk_tree_view_column_pack_start (column, renderer, TRUE);
|
|
gtk_tree_view_column_add_attribute (column, renderer,
|
|
"markup", COLUMN_CALIB_QUALITY_APPROX_TIME);
|
|
gtk_tree_view_column_set_expand (column, FALSE);
|
|
gtk_tree_view_append_column (GTK_TREE_VIEW (widget),
|
|
GTK_TREE_VIEW_COLUMN (column));
|
|
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"treeview_calib_sensor"));
|
|
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
|
|
g_signal_connect (selection, "changed",
|
|
G_CALLBACK (gcm_prefs_calib_sensor_treeview_clicked_cb),
|
|
prefs);
|
|
column = gtk_tree_view_column_new ();
|
|
renderer = gtk_cell_renderer_text_new ();
|
|
g_object_set (renderer,
|
|
"xpad", 9,
|
|
"ypad", 9,
|
|
NULL);
|
|
gtk_tree_view_column_pack_start (column, renderer, TRUE);
|
|
gtk_tree_view_column_add_attribute (column, renderer,
|
|
"markup", COLUMN_CALIB_SENSOR_DESCRIPTION);
|
|
gtk_tree_view_column_set_expand (column, TRUE);
|
|
gtk_tree_view_append_column (GTK_TREE_VIEW (widget),
|
|
GTK_TREE_VIEW_COLUMN (column));
|
|
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"treeview_calib_kind"));
|
|
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
|
|
g_signal_connect (selection, "changed",
|
|
G_CALLBACK (gcm_prefs_calib_kind_treeview_clicked_cb),
|
|
prefs);
|
|
column = gtk_tree_view_column_new ();
|
|
renderer = gtk_cell_renderer_text_new ();
|
|
g_object_set (renderer,
|
|
"xpad", 9,
|
|
"ypad", 9,
|
|
NULL);
|
|
gtk_tree_view_column_pack_start (column, renderer, TRUE);
|
|
gtk_tree_view_column_add_attribute (column, renderer,
|
|
"markup", COLUMN_CALIB_KIND_DESCRIPTION);
|
|
model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));
|
|
model_filter = gtk_tree_model_filter_new (model, NULL);
|
|
gtk_tree_view_set_model (GTK_TREE_VIEW (widget), model_filter);
|
|
gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (model_filter),
|
|
COLUMN_CALIB_KIND_VISIBLE);
|
|
|
|
gtk_tree_view_column_set_expand (column, TRUE);
|
|
gtk_tree_view_append_column (GTK_TREE_VIEW (widget),
|
|
GTK_TREE_VIEW_COLUMN (column));
|
|
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"treeview_calib_temp"));
|
|
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
|
|
g_signal_connect (selection, "changed",
|
|
G_CALLBACK (gcm_prefs_calib_temp_treeview_clicked_cb),
|
|
prefs);
|
|
column = gtk_tree_view_column_new ();
|
|
renderer = gtk_cell_renderer_text_new ();
|
|
g_object_set (renderer,
|
|
"xpad", 9,
|
|
"ypad", 9,
|
|
NULL);
|
|
gtk_tree_view_column_pack_start (column, renderer, TRUE);
|
|
gtk_tree_view_column_add_attribute (column, renderer,
|
|
"markup", COLUMN_CALIB_TEMP_DESCRIPTION);
|
|
gtk_tree_view_column_set_expand (column, TRUE);
|
|
gtk_tree_view_append_column (GTK_TREE_VIEW (widget),
|
|
GTK_TREE_VIEW_COLUMN (column));
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"entry_calib_title"));
|
|
g_signal_connect (widget, "notify::text",
|
|
G_CALLBACK (gcm_prefs_title_entry_changed_cb), prefs);
|
|
|
|
/* use a device client array */
|
|
priv->client = cd_client_new ();
|
|
g_signal_connect_object (priv->client, "device-added",
|
|
G_CALLBACK (gcm_prefs_device_added_cb), prefs, 0);
|
|
g_signal_connect_object (priv->client, "device-removed",
|
|
G_CALLBACK (gcm_prefs_device_removed_cb), prefs, 0);
|
|
|
|
/* use a listbox for the main UI */
|
|
priv->list_box = egg_list_box_new ();
|
|
egg_list_box_set_filter_func (priv->list_box,
|
|
cc_color_panel_filter_func,
|
|
prefs,
|
|
NULL);
|
|
egg_list_box_set_sort_func (priv->list_box,
|
|
cc_color_panel_sort_func,
|
|
prefs,
|
|
NULL);
|
|
egg_list_box_set_separator_funcs (priv->list_box,
|
|
cc_color_panel_separator_func,
|
|
prefs, NULL);
|
|
egg_list_box_set_selection_mode (priv->list_box,
|
|
GTK_SELECTION_SINGLE);
|
|
priv->list_box_selected_id =
|
|
g_signal_connect (priv->list_box, "child-selected",
|
|
G_CALLBACK (gcm_prefs_list_box_child_selected_cb),
|
|
prefs);
|
|
priv->list_box_size = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL);
|
|
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "scrolledwindow_devices"));
|
|
egg_list_box_add_to_scrolled (priv->list_box,
|
|
GTK_SCROLLED_WINDOW (widget));
|
|
gtk_widget_show (GTK_WIDGET (priv->list_box));
|
|
|
|
/* connect to colord */
|
|
cd_client_connect (priv->client,
|
|
priv->cancellable,
|
|
gcm_prefs_connect_cb,
|
|
prefs);
|
|
|
|
/* use the color sensor */
|
|
g_signal_connect_object (priv->client, "sensor-added",
|
|
G_CALLBACK (gcm_prefs_client_sensor_changed_cb),
|
|
prefs, 0);
|
|
g_signal_connect_object (priv->client, "sensor-removed",
|
|
G_CALLBACK (gcm_prefs_client_sensor_changed_cb),
|
|
prefs, 0);
|
|
|
|
/* set calibrate button sensitivity */
|
|
gcm_prefs_set_calibrate_button_sensitivity (prefs);
|
|
|
|
/* show the confirmation export page if we are running from a LiveCD */
|
|
priv->is_live_cd = gcm_prefs_is_livecd ();
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"box_calib_summary"));
|
|
gtk_widget_set_visible (widget, priv->is_live_cd);
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"button_calib_export"));
|
|
g_signal_connect (widget, "clicked",
|
|
G_CALLBACK (gcm_prefs_calib_export_cb), prefs);
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"label_calib_summary_message"));
|
|
g_signal_connect (widget, "activate-link",
|
|
G_CALLBACK (gcm_prefs_calib_export_link_cb), prefs);
|
|
|
|
|
|
widget = WID (priv->builder, "dialog-vbox1");
|
|
gtk_widget_reparent (widget, (GtkWidget *) prefs);
|
|
g_signal_connect (widget, "realize",
|
|
G_CALLBACK (gcm_prefs_window_realize_cb),
|
|
prefs);
|
|
}
|