static void fcitx_config_widget_setup_ui(FcitxConfigWidget *self) { FcitxConfigFileDesc* cfdesc = self->cfdesc; GtkWidget *cvbox = GTK_WIDGET(self); GtkWidget *configNotebook = gtk_notebook_new(); gtk_box_pack_start(GTK_BOX(cvbox), configNotebook, TRUE, TRUE, 0); if (cfdesc) { bindtextdomain(cfdesc->domain, LOCALEDIR); bind_textdomain_codeset(cfdesc->domain, "UTF-8"); FILE *fp; fp = FcitxXDGGetFileWithPrefix(self->prefix, self->name, "r", NULL); self->gconfig.configFile = FcitxConfigParseConfigFileFp(fp, cfdesc); FcitxConfigGroupDesc *cgdesc = NULL; FcitxConfigOptionDesc *codesc = NULL; for (cgdesc = cfdesc->groupsDesc; cgdesc != NULL; cgdesc = (FcitxConfigGroupDesc*)cgdesc->hh.next) { codesc = cgdesc->optionsDesc; if (codesc == NULL) continue; GtkWidget* hbox = gtk_hbox_new(FALSE, 0); GtkWidget *table = gtk_table_new(2, HASH_COUNT(codesc), FALSE); GtkWidget *plabel = gtk_label_new(D_(cfdesc->domain, cgdesc->groupName)); GtkWidget *scrollwnd = gtk_scrolled_window_new(NULL, NULL); gtk_container_set_border_width(GTK_CONTAINER(table), 0); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwnd), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrollwnd), table); gtk_box_pack_start(GTK_BOX(hbox), scrollwnd, TRUE, TRUE, 0); gtk_notebook_append_page(GTK_NOTEBOOK(configNotebook), hbox, plabel); int i = 0; for (; codesc != NULL; codesc = (FcitxConfigOptionDesc*)codesc->hh.next, i++) { const char *s; if (codesc->desc && strlen(codesc->desc) != 0) s = D_(cfdesc->domain, codesc->desc); else s = D_(cfdesc->domain, codesc->optionName); GtkWidget *inputWidget = NULL; void *argument = NULL; switch (codesc->type) { case T_Integer: inputWidget = gtk_spin_button_new_with_range(-1.0, 10000.0, 1.0); argument = inputWidget; break; case T_Color: inputWidget = gtk_color_button_new(); argument = inputWidget; break; case T_Boolean: inputWidget = gtk_check_button_new(); argument = inputWidget; break; case T_Font: { inputWidget = gtk_hbox_new(FALSE, 0); argument = gtk_font_button_new(); GtkWidget *button = gtk_button_new_with_label(_("Clear font setting")); gtk_box_pack_start(GTK_BOX(inputWidget), argument, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(inputWidget), button, FALSE, FALSE, 0); gtk_font_button_set_use_size(GTK_FONT_BUTTON(argument), FALSE); gtk_font_button_set_show_size(GTK_FONT_BUTTON(argument), FALSE); g_signal_connect(G_OBJECT(button), "clicked", (GCallback) set_none_font_clicked, argument); } break; case T_Enum: { int i; FcitxConfigEnum *e = &codesc->configEnum; #if GTK_CHECK_VERSION(2, 24, 0) inputWidget = gtk_combo_box_text_new(); for (i = 0; i < e->enumCount; i ++) { gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(inputWidget), D_(cfdesc->domain, e->enumDesc[i])); } #else inputWidget = gtk_combo_box_new_text(); for (i = 0; i < e->enumCount; i ++) { gtk_combo_box_append_text(GTK_COMBO_BOX(inputWidget), D_(cfdesc->domain, e->enumDesc[i])); } #endif argument = inputWidget; } break; case T_Hotkey: { GtkWidget *button[2]; button[0] = keygrab_button_new(); button[1] = keygrab_button_new(); inputWidget = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(inputWidget), button[0], FALSE, TRUE, 0); gtk_box_pack_start(GTK_BOX(inputWidget), button[1], FALSE, TRUE, 0); argument = g_array_new(FALSE, FALSE, sizeof(void*)); g_array_append_val(argument, button[0]); g_array_append_val(argument, button[1]); } break; case T_File: case T_Char: case T_String: inputWidget = gtk_entry_new(); argument = inputWidget; break; default: break; } if (inputWidget) { GtkWidget* label = gtk_label_new(s); g_object_set(label, "xalign", 0.0f, NULL); gtk_table_attach(GTK_TABLE(table), label, 0, 1, i, i + 1, GTK_FILL, GTK_SHRINK, 5, 5); gtk_table_attach(GTK_TABLE(table), inputWidget, 1, 2, i, i + 1, GTK_EXPAND | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 4); FcitxConfigBindValue(self->gconfig.configFile, cgdesc->groupName, codesc->optionName, NULL, sync_filter, argument); } } } FcitxConfigBindSync(&self->gconfig); } if (self->parser) { GHashTable* subconfigs = self->parser->subconfigs; if (g_hash_table_size(subconfigs) != 0) { GtkWidget *table = gtk_table_new(2, g_hash_table_size(subconfigs), FALSE); GtkWidget *plabel = gtk_label_new(_("Other")); GtkWidget *scrollwnd = gtk_scrolled_window_new(NULL, NULL); GtkWidget *viewport = gtk_viewport_new(NULL, NULL); gtk_container_set_border_width(GTK_CONTAINER(table), 4); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwnd), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_container_add(GTK_CONTAINER(scrollwnd), viewport); gtk_container_add(GTK_CONTAINER(viewport), table); gtk_notebook_append_page(GTK_NOTEBOOK(configNotebook), scrollwnd, plabel); HashForeachContext context; context.i = 0; context.table = table; context.widget = self; g_hash_table_foreach(subconfigs, hash_foreach_cb, &context); } } gtk_widget_set_size_request(configNotebook, 500, -1); gtk_notebook_set_scrollable(GTK_NOTEBOOK(configNotebook), TRUE); }
static void fcitx_config_widget_create_option_widget( FcitxConfigWidget *self, FcitxConfigGroupDesc* cgdesc, FcitxConfigOptionDesc* codesc, char** label, char** tooltip, GtkWidget** inputWidget, void** newarg) { FcitxConfigFileDesc* cfdesc = self->cfdesc; FcitxConfigOptionDesc2* codesc2 = (FcitxConfigOptionDesc2*) codesc; void* oldarg = NULL; void* argument = NULL; char* name = g_strdup_printf("%s/%s", cgdesc->groupName, codesc->optionName); oldarg = g_hash_table_lookup(self->argmap, name); if (codesc->desc && strlen(codesc->desc) != 0) { *label = strdup(D_(cfdesc->domain, codesc->desc)); } else { *label = strdup(D_(cfdesc->domain, codesc->optionName)); } if (codesc2->longDesc && codesc2->longDesc[0]) { *tooltip = strdup(D_(cfdesc->domain, codesc2->longDesc)); } switch (codesc->type) { case T_Integer: *inputWidget = gtk_spin_button_new_with_range( codesc2->constrain.integerConstrain.min, codesc2->constrain.integerConstrain.max, 1.0); g_object_set(*inputWidget, "hexpand", TRUE, NULL); if (oldarg) { g_object_bind_property(*inputWidget, "value", oldarg, "value", G_BINDING_BIDIRECTIONAL); } else { g_signal_connect(*inputWidget, "notify::value", (GCallback) _fcitx_config_widget_changed, self); argument = *inputWidget; } break; case T_Color: *inputWidget = gtk_color_button_new(); g_object_set(*inputWidget, "hexpand", TRUE, NULL); if (oldarg) { g_object_bind_property(*inputWidget, "color", oldarg, "color", G_BINDING_BIDIRECTIONAL); } else { g_signal_connect(*inputWidget, "notify::color", (GCallback) _fcitx_config_widget_changed, self); argument = *inputWidget; } break; case T_Boolean: *inputWidget = gtk_check_button_new(); g_object_set(*inputWidget, "hexpand", TRUE, NULL); if (oldarg) { g_object_bind_property(*inputWidget, "active", oldarg, "active", G_BINDING_BIDIRECTIONAL); } else { g_signal_connect(*inputWidget, "notify::active", (GCallback) _fcitx_config_widget_changed, self); argument = *inputWidget; } break; case T_Font: { *inputWidget = gtk_grid_new(); g_object_set(*inputWidget, "hexpand", TRUE, NULL); GtkWidget* arg = gtk_font_button_new(); GtkWidget *button = gtk_button_new_with_label(_("Clear font setting")); g_object_set(arg, "hexpand", TRUE, NULL); gtk_grid_attach(GTK_GRID(*inputWidget), arg, 0, 0, 1, 1); gtk_grid_attach(GTK_GRID(*inputWidget), button, 1, 0, 2, 1); gtk_font_button_set_use_size(GTK_FONT_BUTTON(arg), FALSE); gtk_font_button_set_show_size(GTK_FONT_BUTTON(arg), FALSE); g_signal_connect(G_OBJECT(button), "clicked", (GCallback) set_none_font_clicked, arg); if (oldarg) { g_object_bind_property(arg, "font-name", oldarg, "font-name", G_BINDING_BIDIRECTIONAL); } else { g_signal_connect(arg, "notify::font-name", (GCallback) _fcitx_config_widget_changed, self); argument = arg; } } break; case T_Enum: { int i; FcitxConfigEnum *e = &codesc->configEnum; *inputWidget = gtk_combo_box_text_new(); for (i = 0; i < e->enumCount; i ++) { gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(*inputWidget), D_(cfdesc->domain, e->enumDesc[i])); } g_object_set(*inputWidget, "hexpand", TRUE, NULL); if (oldarg) { g_object_bind_property(*inputWidget, "active", oldarg, "active", G_BINDING_BIDIRECTIONAL); } else { g_signal_connect(*inputWidget, "notify::active", (GCallback) _fcitx_config_widget_changed, self); argument = *inputWidget; } } break; case T_Hotkey: { GtkWidget *button[2]; button[0] = keygrab_button_new(); button[1] = keygrab_button_new(); *inputWidget = gtk_grid_new(); gtk_grid_attach(GTK_GRID(*inputWidget), button[0], 0, 0, 1, 1); gtk_grid_attach(GTK_GRID(*inputWidget), button[1], 1, 0, 2, 1); g_object_set(G_OBJECT(button[0]), "hexpand", TRUE, NULL); g_object_set(G_OBJECT(button[1]), "hexpand", TRUE, NULL); if (oldarg) { GArray* array = oldarg; int j; for (j = 0; j < 2; j ++) { GtkWidget *oldbutton = g_array_index(array, GtkWidget*, j); g_signal_connect(oldbutton, "changed", (GCallback) sync_hotkey, button[j]); g_signal_connect(button[j], "changed", (GCallback) sync_hotkey, oldbutton); } } else { argument = g_array_new(FALSE, FALSE, sizeof(void*)); int j; for (j = 0; j < 2; j ++) { g_signal_connect(button[j], "changed", (GCallback) _fcitx_config_widget_hotkey_changed, self); g_array_append_val(argument, button[j]); } } } break; case T_File: case T_Char: case T_String: *inputWidget = gtk_entry_new(); g_object_set(*inputWidget, "hexpand", TRUE, NULL); if (oldarg) { g_object_bind_property(*inputWidget, "text", oldarg, "text", G_BINDING_BIDIRECTIONAL); } else { g_signal_connect(*inputWidget, "notify::text", (GCallback) _fcitx_config_widget_changed, self); argument = *inputWidget; } break; default: break; }