| 115 g_signal_connect(G_OBJECT(entry), "changed", G_CALLBACK(entry_set), |
92 g_signal_connect(G_OBJECT(entry), "changed", G_CALLBACK(entry_set), |
| 116 (char*)key); |
93 (char*)key); |
| 117 } |
94 } |
| 118 |
95 |
| 119 static void |
96 static void |
| 120 dropdown_set(GtkComboBox *combo_box, G_GNUC_UNUSED gpointer data) |
|
| 121 { |
|
| 122 GtkTreeIter iter; |
|
| 123 GtkTreeModel *tree_model; |
|
| 124 PurplePrefType type; |
|
| 125 const char *key; |
|
| 126 |
|
| 127 tree_model = gtk_combo_box_get_model(combo_box); |
|
| 128 if (!gtk_combo_box_get_active_iter(combo_box, &iter)) { |
|
| 129 return; |
|
| 130 } |
|
| 131 |
|
| 132 type = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(combo_box), "type")); |
|
| 133 key = g_object_get_data(G_OBJECT(combo_box), "key"); |
|
| 134 if (type == PURPLE_PREF_INT) { |
|
| 135 gint value; |
|
| 136 gtk_tree_model_get(tree_model, &iter, PIDGIN_PREF_COMBO_VALUE, &value, -1); |
|
| 137 purple_prefs_set_int(key, value); |
|
| 138 } else if (type == PURPLE_PREF_STRING) { |
|
| 139 gchar *value; |
|
| 140 gtk_tree_model_get(tree_model, &iter, PIDGIN_PREF_COMBO_VALUE, &value, -1); |
|
| 141 purple_prefs_set_string(key, value); |
|
| 142 g_free(value); |
|
| 143 } else if (type == PURPLE_PREF_BOOLEAN) { |
|
| 144 gboolean value; |
|
| 145 gtk_tree_model_get(tree_model, &iter, PIDGIN_PREF_COMBO_VALUE, &value, -1); |
|
| 146 purple_prefs_set_bool(key, value); |
|
| 147 } else { |
|
| 148 g_return_if_reached(); |
|
| 149 } |
|
| 150 } |
|
| 151 |
|
| 152 GtkWidget * |
|
| 153 pidgin_prefs_dropdown_from_list(GtkWidget *box, const gchar *title, |
|
| 154 PurplePrefType type, const char *key, GList *menuitems) |
|
| 155 { |
|
| 156 GtkWidget *dropdown = NULL; |
|
| 157 GtkWidget *label = NULL; |
|
| 158 GtkListStore *store = NULL; |
|
| 159 GtkTreeIter active; |
|
| 160 GtkCellRenderer *renderer; |
|
| 161 gint pref_int_value = 0; |
|
| 162 const gchar *pref_str_value = NULL; |
|
| 163 gboolean pref_bool_value = FALSE; |
|
| 164 |
|
| 165 g_return_val_if_fail(menuitems != NULL, NULL); |
|
| 166 |
|
| 167 if (type == PURPLE_PREF_INT) { |
|
| 168 pref_int_value = purple_prefs_get_int(key); |
|
| 169 store = gtk_list_store_new(PIDGIN_PREF_COMBO_N_COLUMNS, G_TYPE_STRING, |
|
| 170 G_TYPE_INT); |
|
| 171 } else if (type == PURPLE_PREF_STRING) { |
|
| 172 pref_str_value = purple_prefs_get_string(key); |
|
| 173 store = gtk_list_store_new(PIDGIN_PREF_COMBO_N_COLUMNS, G_TYPE_STRING, |
|
| 174 G_TYPE_STRING); |
|
| 175 } else if (type == PURPLE_PREF_BOOLEAN) { |
|
| 176 pref_bool_value = purple_prefs_get_bool(key); |
|
| 177 store = gtk_list_store_new(PIDGIN_PREF_COMBO_N_COLUMNS, G_TYPE_STRING, |
|
| 178 G_TYPE_BOOLEAN); |
|
| 179 } else { |
|
| 180 g_return_val_if_reached(NULL); |
|
| 181 } |
|
| 182 |
|
| 183 dropdown = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store)); |
|
| 184 g_object_set_data(G_OBJECT(dropdown), "type", GINT_TO_POINTER(type)); |
|
| 185 |
|
| 186 for (; menuitems != NULL; menuitems = g_list_next(menuitems)) { |
|
| 187 const PurpleKeyValuePair *menu_item = menuitems->data; |
|
| 188 GtkTreeIter iter; |
|
| 189 |
|
| 190 if (menu_item->key == NULL) { |
|
| 191 break; |
|
| 192 } |
|
| 193 |
|
| 194 gtk_list_store_append(store, &iter); |
|
| 195 gtk_list_store_set(store, &iter, |
|
| 196 PIDGIN_PREF_COMBO_TEXT, menu_item->key, |
|
| 197 -1); |
|
| 198 |
|
| 199 if (type == PURPLE_PREF_INT) { |
|
| 200 gint value = GPOINTER_TO_INT(menu_item->value); |
|
| 201 gtk_list_store_set(store, &iter, PIDGIN_PREF_COMBO_VALUE, value, -1); |
|
| 202 if (pref_int_value == value) { |
|
| 203 active = iter; |
|
| 204 } |
|
| 205 |
|
| 206 } else if (type == PURPLE_PREF_STRING) { |
|
| 207 const gchar *value = (const gchar *)menu_item->value; |
|
| 208 gtk_list_store_set(store, &iter, PIDGIN_PREF_COMBO_VALUE, value, -1); |
|
| 209 if (purple_strequal(pref_str_value, value)) { |
|
| 210 active = iter; |
|
| 211 } |
|
| 212 |
|
| 213 } else if (type == PURPLE_PREF_BOOLEAN) { |
|
| 214 gboolean value = (gboolean)GPOINTER_TO_INT(menu_item->value); |
|
| 215 gtk_list_store_set(store, &iter, PIDGIN_PREF_COMBO_VALUE, value, -1); |
|
| 216 if (pref_bool_value == value) { |
|
| 217 active = iter; |
|
| 218 } |
|
| 219 } |
|
| 220 } |
|
| 221 |
|
| 222 renderer = gtk_cell_renderer_text_new(); |
|
| 223 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(dropdown), renderer, TRUE); |
|
| 224 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(dropdown), renderer, |
|
| 225 "text", 0, |
|
| 226 NULL); |
|
| 227 |
|
| 228 gtk_combo_box_set_active_iter(GTK_COMBO_BOX(dropdown), &active); |
|
| 229 |
|
| 230 g_signal_connect(dropdown, "changed", G_CALLBACK(dropdown_set), NULL); |
|
| 231 |
|
| 232 pidgin_add_widget_to_vbox(GTK_BOX(box), title, NULL, dropdown, FALSE, &label); |
|
| 233 |
|
| 234 g_object_set_data(G_OBJECT(dropdown), "key", (gpointer)key); |
|
| 235 |
|
| 236 return label; |
|
| 237 } |
|
| 238 |
|
| 239 GtkWidget * |
|
| 240 pidgin_prefs_dropdown(GtkWidget *box, const gchar *title, PurplePrefType type, |
|
| 241 const char *key, ...) |
|
| 242 { |
|
| 243 va_list ap; |
|
| 244 GList *menuitems = NULL; |
|
| 245 GtkWidget *dropdown = NULL; |
|
| 246 char *name; |
|
| 247 |
|
| 248 g_return_val_if_fail(type == PURPLE_PREF_BOOLEAN || type == PURPLE_PREF_INT || |
|
| 249 type == PURPLE_PREF_STRING, NULL); |
|
| 250 |
|
| 251 va_start(ap, key); |
|
| 252 while ((name = va_arg(ap, char *)) != NULL) { |
|
| 253 PurpleKeyValuePair *kvp; |
|
| 254 |
|
| 255 if (type == PURPLE_PREF_INT || type == PURPLE_PREF_BOOLEAN) { |
|
| 256 kvp = purple_key_value_pair_new(name, GINT_TO_POINTER(va_arg(ap, int))); |
|
| 257 } else { |
|
| 258 kvp = purple_key_value_pair_new(name, va_arg(ap, char *)); |
|
| 259 } |
|
| 260 menuitems = g_list_prepend(menuitems, kvp); |
|
| 261 } |
|
| 262 va_end(ap); |
|
| 263 |
|
| 264 g_return_val_if_fail(menuitems != NULL, NULL); |
|
| 265 |
|
| 266 menuitems = g_list_reverse(menuitems); |
|
| 267 |
|
| 268 dropdown = pidgin_prefs_dropdown_from_list(box, title, type, key, |
|
| 269 menuitems); |
|
| 270 |
|
| 271 g_list_free_full(menuitems, (GDestroyNotify)purple_key_value_pair_free); |
|
| 272 |
|
| 273 return dropdown; |
|
| 274 } |
|
| 275 |
|
| 276 static void |
|
| 277 bind_dropdown_set(GtkComboBox *combo_box, gpointer data) |
|
| 278 { |
|
| 279 PidginPrefCombo *combo = data; |
|
| 280 GtkTreeIter iter; |
|
| 281 GtkTreeModel *tree_model; |
|
| 282 |
|
| 283 tree_model = gtk_combo_box_get_model(combo_box); |
|
| 284 if (!gtk_combo_box_get_active_iter(combo_box, &iter)) |
|
| 285 return; |
|
| 286 |
|
| 287 if (combo->type == PURPLE_PREF_INT) { |
|
| 288 gint value; |
|
| 289 gtk_tree_model_get(tree_model, &iter, PIDGIN_PREF_COMBO_VALUE, &value, -1); |
|
| 290 purple_prefs_set_int(combo->key, value); |
|
| 291 } else if (combo->type == PURPLE_PREF_STRING) { |
|
| 292 gchar *value; |
|
| 293 gtk_tree_model_get(tree_model, &iter, PIDGIN_PREF_COMBO_VALUE, &value, -1); |
|
| 294 purple_prefs_set_string(combo->key, value); |
|
| 295 g_free(value); |
|
| 296 } else if (combo->type == PURPLE_PREF_BOOLEAN) { |
|
| 297 gboolean value; |
|
| 298 gtk_tree_model_get(tree_model, &iter, PIDGIN_PREF_COMBO_VALUE, &value, -1); |
|
| 299 purple_prefs_set_bool(combo->key, value); |
|
| 300 } else { |
|
| 301 g_return_if_reached(); |
|
| 302 } |
|
| 303 } |
|
| 304 |
|
| 305 void |
|
| 306 pidgin_prefs_bind_dropdown(PidginPrefCombo *combo) |
|
| 307 { |
|
| 308 GtkTreeModel *store = NULL; |
|
| 309 GtkTreeIter iter; |
|
| 310 GtkTreeIter active; |
|
| 311 int pref_int_value = 0; |
|
| 312 const char *pref_str_value = NULL; |
|
| 313 gboolean pref_bool_value = FALSE; |
|
| 314 |
|
| 315 if (combo->type == PURPLE_PREF_INT) { |
|
| 316 pref_int_value = purple_prefs_get_int(combo->key); |
|
| 317 } else if (combo->type == PURPLE_PREF_STRING) { |
|
| 318 pref_str_value = purple_prefs_get_string(combo->key); |
|
| 319 } else if (combo->type == PURPLE_PREF_BOOLEAN) { |
|
| 320 pref_bool_value = purple_prefs_get_bool(combo->key); |
|
| 321 } else { |
|
| 322 g_return_if_reached(); |
|
| 323 } |
|
| 324 |
|
| 325 store = gtk_combo_box_get_model(GTK_COMBO_BOX(combo->combo)); |
|
| 326 |
|
| 327 if (!gtk_tree_model_get_iter_first(store, &iter)) { |
|
| 328 g_return_if_reached(); |
|
| 329 } |
|
| 330 |
|
| 331 do { |
|
| 332 if (combo->type == PURPLE_PREF_INT) { |
|
| 333 gint value = 0; |
|
| 334 gtk_tree_model_get(store, &iter, PIDGIN_PREF_COMBO_VALUE, &value, -1); |
|
| 335 if (pref_int_value == value) { |
|
| 336 active = iter; |
|
| 337 break; |
|
| 338 } |
|
| 339 |
|
| 340 } else if (combo->type == PURPLE_PREF_STRING) { |
|
| 341 gchar *value = NULL; |
|
| 342 gtk_tree_model_get(store, &iter, PIDGIN_PREF_COMBO_VALUE, &value, -1); |
|
| 343 if (purple_strequal(pref_str_value, value)) { |
|
| 344 active = iter; |
|
| 345 g_free(value); |
|
| 346 break; |
|
| 347 } |
|
| 348 g_free(value); |
|
| 349 |
|
| 350 } else if (combo->type == PURPLE_PREF_BOOLEAN) { |
|
| 351 gboolean value = FALSE; |
|
| 352 gtk_tree_model_get(store, &iter, PIDGIN_PREF_COMBO_VALUE, &value, -1); |
|
| 353 if (pref_bool_value == value) { |
|
| 354 active = iter; |
|
| 355 break; |
|
| 356 } |
|
| 357 } |
|
| 358 } while (gtk_tree_model_iter_next(store, &iter)); |
|
| 359 |
|
| 360 gtk_combo_box_set_active_iter(GTK_COMBO_BOX(combo->combo), &active); |
|
| 361 |
|
| 362 g_signal_connect(G_OBJECT(combo->combo), "changed", |
|
| 363 G_CALLBACK(bind_dropdown_set), combo); |
|
| 364 } |
|
| 365 |
|
| 366 static void |
|
| 367 bind_combo_row_set(GObject *obj, G_GNUC_UNUSED GParamSpec *pspec, |
97 bind_combo_row_set(GObject *obj, G_GNUC_UNUSED GParamSpec *pspec, |
| 368 gpointer data) |
98 gpointer data) |
| 369 { |
99 { |
| 370 const gchar *key = data; |
100 const gchar *key = data; |
| 371 GtkStringObject *item = NULL; |
101 GtkStringObject *item = NULL; |