1/*
2 * Copyright (C) 2011 Igalia S.L.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "BrowserSettingsDialog.h"
27#include "BrowserCellRendererVariant.h"
28
29enum {
30 PROP_0,
31
32 PROP_SETTINGS
33};
34
35enum {
36 SETTINGS_LIST_COLUMN_NAME,
37 SETTINGS_LIST_COLUMN_NICK,
38 SETTINGS_LIST_COLUMN_BLURB,
39 SETTINGS_LIST_COLUMN_VALUE,
40 SETTINGS_LIST_COLUMN_ADJUSTMENT,
41
42 SETTINGS_LIST_N_COLUMNS
43};
44
45struct _BrowserSettingsDialog {
46 GtkDialog parent;
47
48 GtkWidget *settingsList;
49 WebKitSettings *settings;
50};
51
52struct _BrowserSettingsDialogClass {
53 GtkDialogClass parent;
54};
55
56G_DEFINE_TYPE(BrowserSettingsDialog, browser_settings_dialog, GTK_TYPE_DIALOG)
57
58static const char *hardwareAccelerationPolicyToString(WebKitHardwareAccelerationPolicy policy)
59{
60 switch (policy) {
61 case WEBKIT_HARDWARE_ACCELERATION_POLICY_ALWAYS:
62 return "always";
63 case WEBKIT_HARDWARE_ACCELERATION_POLICY_NEVER:
64 return "never";
65 case WEBKIT_HARDWARE_ACCELERATION_POLICY_ON_DEMAND:
66 return "ondemand";
67 }
68
69 g_assert_not_reached();
70 return "ondemand";
71}
72
73static int stringToHardwareAccelerationPolicy(const char *policy)
74{
75 if (!g_ascii_strcasecmp(policy, "always"))
76 return WEBKIT_HARDWARE_ACCELERATION_POLICY_ALWAYS;
77 if (!g_ascii_strcasecmp(policy, "never"))
78 return WEBKIT_HARDWARE_ACCELERATION_POLICY_NEVER;
79 if (!g_ascii_strcasecmp(policy, "ondemand"))
80 return WEBKIT_HARDWARE_ACCELERATION_POLICY_ON_DEMAND;
81
82 g_warning("Invalid value %s for hardware-acceleration-policy setting valid values are always, never and ondemand", policy);
83 return -1;
84}
85
86static void cellRendererChanged(GtkCellRenderer *renderer, const char *path, const GValue *value, BrowserSettingsDialog *dialog)
87{
88 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(dialog->settingsList));
89 GtkTreePath *treePath = gtk_tree_path_new_from_string(path);
90 GtkTreeIter iter;
91 gtk_tree_model_get_iter(model, &iter, treePath);
92
93 gboolean updateTreeStore = TRUE;
94 char *name;
95 gtk_tree_model_get(model, &iter, SETTINGS_LIST_COLUMN_NAME, &name, -1);
96 if (!g_strcmp0(name, "hardware-acceleration-policy")) {
97 int policy = stringToHardwareAccelerationPolicy(g_value_get_string(value));
98 if (policy != -1)
99 webkit_settings_set_hardware_acceleration_policy(dialog->settings, policy);
100 else
101 updateTreeStore = FALSE;
102 } else
103 g_object_set_property(G_OBJECT(dialog->settings), name, value);
104 g_free(name);
105
106 if (updateTreeStore)
107 gtk_list_store_set(GTK_LIST_STORE(model), &iter, SETTINGS_LIST_COLUMN_VALUE, value, -1);
108 gtk_tree_path_free(treePath);
109}
110
111static void browserSettingsDialogSetProperty(GObject *object, guint propId, const GValue *value, GParamSpec *pspec)
112{
113 BrowserSettingsDialog *dialog = BROWSER_SETTINGS_DIALOG(object);
114
115 switch (propId) {
116 case PROP_SETTINGS:
117 dialog->settings = g_value_get_object(value);
118 break;
119 default:
120 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, pspec);
121 }
122}
123
124static void browser_settings_dialog_init(BrowserSettingsDialog *dialog)
125{
126 GtkBox *contentArea = GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog)));
127 gtk_box_set_spacing(contentArea, 2);
128
129 gtk_window_set_default_size(GTK_WINDOW(dialog), 600, 400);
130 gtk_window_set_type_hint(GTK_WINDOW(dialog), GDK_WINDOW_TYPE_HINT_DIALOG);
131 gtk_window_set_title(GTK_WINDOW(dialog), "WebKit View Settings");
132 gtk_window_set_destroy_with_parent(GTK_WINDOW(dialog), TRUE);
133 gtk_container_set_border_width(GTK_CONTAINER(dialog), 5);
134 gtk_dialog_add_button(GTK_DIALOG(dialog), GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE);
135 gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_CLOSE);
136
137 GtkWidget *scrolledWindow = gtk_scrolled_window_new(NULL, NULL);
138 dialog->settingsList = gtk_tree_view_new();
139 GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
140 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(dialog->settingsList),
141 0, "Name", renderer,
142 "text", SETTINGS_LIST_COLUMN_NICK,
143 NULL);
144 renderer = browser_cell_renderer_variant_new();
145 g_signal_connect(renderer, "changed", G_CALLBACK(cellRendererChanged), dialog);
146 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(dialog->settingsList),
147 1, "Value", renderer,
148 "value", SETTINGS_LIST_COLUMN_VALUE,
149 "adjustment", SETTINGS_LIST_COLUMN_ADJUSTMENT,
150 NULL);
151 gtk_tree_view_set_tooltip_column(GTK_TREE_VIEW(dialog->settingsList), SETTINGS_LIST_COLUMN_BLURB);
152
153 gtk_container_add(GTK_CONTAINER(scrolledWindow), dialog->settingsList);
154 gtk_widget_show(dialog->settingsList);
155
156 gtk_box_pack_start(contentArea, scrolledWindow, TRUE, TRUE, 0);
157 gtk_widget_show(scrolledWindow);
158
159 g_signal_connect(dialog, "response", G_CALLBACK(gtk_widget_destroy), NULL);
160}
161
162static void browserSettingsDialogConstructed(GObject *object)
163{
164 G_OBJECT_CLASS(browser_settings_dialog_parent_class)->constructed(object);
165
166 BrowserSettingsDialog *dialog = BROWSER_SETTINGS_DIALOG(object);
167 WebKitSettings *settings = dialog->settings;
168 GtkListStore *model = gtk_list_store_new(SETTINGS_LIST_N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
169 G_TYPE_VALUE, G_TYPE_OBJECT);
170 guint propertiesCount;
171 GParamSpec **properties = g_object_class_list_properties(G_OBJECT_GET_CLASS(settings), &propertiesCount);
172 guint i;
173 for (i = 0; i < propertiesCount; i++) {
174 GParamSpec *property = properties[i];
175 const char *name = g_param_spec_get_name(property);
176 const char *nick = g_param_spec_get_nick(property);
177 char *blurb = g_markup_escape_text(g_param_spec_get_blurb(property), -1);
178
179 GValue value = { 0, { { 0 } } };
180 if (!g_strcmp0(name, "hardware-acceleration-policy")) {
181 g_value_init(&value, G_TYPE_STRING);
182 g_value_set_string(&value, hardwareAccelerationPolicyToString(webkit_settings_get_hardware_acceleration_policy(settings)));
183 char *extendedBlutb = g_strdup_printf("%s (always, never or ondemand)", blurb);
184 g_free(blurb);
185 blurb = extendedBlutb;
186 } else {
187 g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(property));
188 g_object_get_property(G_OBJECT(settings), name, &value);
189 }
190
191 GtkAdjustment *adjustment = NULL;
192 if (G_PARAM_SPEC_VALUE_TYPE(property) == G_TYPE_UINT) {
193 GParamSpecUInt *uIntProperty = G_PARAM_SPEC_UINT(property);
194 adjustment = gtk_adjustment_new(uIntProperty->default_value, uIntProperty->minimum,
195 uIntProperty->maximum, 1, 1, 1);
196 }
197
198 GtkTreeIter iter;
199 gtk_list_store_append(model, &iter);
200 gtk_list_store_set(model, &iter,
201 SETTINGS_LIST_COLUMN_NAME, name,
202 SETTINGS_LIST_COLUMN_NICK, nick,
203 SETTINGS_LIST_COLUMN_BLURB, blurb,
204 SETTINGS_LIST_COLUMN_VALUE, &value,
205 SETTINGS_LIST_COLUMN_ADJUSTMENT, adjustment,
206 -1);
207 g_free(blurb);
208 g_value_unset(&value);
209 }
210 g_free(properties);
211
212 gtk_tree_view_set_model(GTK_TREE_VIEW(dialog->settingsList), GTK_TREE_MODEL(model));
213 g_object_unref(model);
214}
215
216static void browser_settings_dialog_class_init(BrowserSettingsDialogClass *klass)
217{
218 GObjectClass *gobjectClass = G_OBJECT_CLASS(klass);
219
220 gobjectClass->constructed = browserSettingsDialogConstructed;
221 gobjectClass->set_property = browserSettingsDialogSetProperty;
222
223 g_object_class_install_property(gobjectClass,
224 PROP_SETTINGS,
225 g_param_spec_object("settings",
226 "Settings",
227 "The WebKitSettings",
228 WEBKIT_TYPE_SETTINGS,
229 G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
230}
231
232GtkWidget *browser_settings_dialog_new(WebKitSettings *settings)
233{
234 g_return_val_if_fail(WEBKIT_IS_SETTINGS(settings), NULL);
235
236 return GTK_WIDGET(g_object_new(BROWSER_TYPE_SETTINGS_DIALOG, "settings", settings, NULL));
237}
238
239