pidgin/gtkrequest.c

changeset 42171
9f89ed3c6465
parent 42168
e603d4381fe5
child 42172
7c2d151b410d
equal deleted inserted replaced
42170:c9968cbf01d5 42171:9f89ed3c6465
179 ((PurpleRequestChoiceCb)data->cbs[id])(data->user_data, value); 179 ((PurpleRequestChoiceCb)data->cbs[id])(data->user_data, value);
180 } 180 }
181 } 181 }
182 182
183 purple_request_close(PURPLE_REQUEST_INPUT, data); 183 purple_request_close(PURPLE_REQUEST_INPUT, data);
184 }
185
186 static gboolean
187 field_string_focus_out_cb(GtkEventControllerFocus *controller,
188 PurpleRequestFieldString *field)
189 {
190 GtkWidget *entry = gtk_event_controller_get_widget(GTK_EVENT_CONTROLLER(controller));
191 const char *value;
192
193 if (purple_request_field_string_is_multiline(field))
194 {
195 GtkTextBuffer *buffer;
196 GtkTextIter start_iter, end_iter;
197
198 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(entry));
199
200 gtk_text_buffer_get_start_iter(buffer, &start_iter);
201 gtk_text_buffer_get_end_iter(buffer, &end_iter);
202
203 value = gtk_text_buffer_get_text(buffer, &start_iter, &end_iter, FALSE);
204 }
205 else
206 value = gtk_editable_get_text(GTK_EDITABLE(entry));
207
208 purple_request_field_string_set_value(field,
209 (*value == '\0' ? NULL : value));
210
211 return FALSE;
212 } 184 }
213 185
214 static void 186 static void
215 field_choice_option_cb(GObject *obj, G_GNUC_UNUSED GParamSpec *pspec, 187 field_choice_option_cb(GObject *obj, G_GNUC_UNUSED GParamSpec *pspec,
216 gpointer data) 188 gpointer data)
1001 973
1002 return row; 974 return row;
1003 } 975 }
1004 976
1005 static void 977 static void
1006 req_entry_field_changed_cb(GtkWidget *entry, PurpleRequestField *field) 978 multiline_state_flags_changed_cb(GtkWidget *self, GtkStateFlags flags,
1007 { 979 gpointer data)
1008 if(PURPLE_IS_REQUEST_FIELD_INT(field)) { 980 {
1009 PurpleRequestFieldInt *intfield = PURPLE_REQUEST_FIELD_INT(field); 981 GtkWidget *row = data;
1010 int value = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(entry)); 982 gboolean before = FALSE, after = FALSE;
1011 purple_request_field_int_set_value(intfield, value); 983
1012 984 before = !!(flags & GTK_STATE_FLAG_FOCUS_WITHIN);
1013 } else { 985 after = !!(gtk_widget_get_state_flags(self) & GTK_STATE_FLAG_FOCUS_WITHIN);
1014 PurpleRequestFieldString *strfield = PURPLE_REQUEST_FIELD_STRING(field); 986 if(before != after) {
1015 if(purple_request_field_string_is_multiline(strfield)) { 987 if(after) {
1016 char *text; 988 gtk_widget_add_css_class(row, "focused");
1017 GtkTextIter start_iter, end_iter;
1018
1019 gtk_text_buffer_get_start_iter(GTK_TEXT_BUFFER(entry), &start_iter);
1020 gtk_text_buffer_get_end_iter(GTK_TEXT_BUFFER(entry), &end_iter);
1021
1022 text = gtk_text_buffer_get_text(GTK_TEXT_BUFFER(entry),
1023 &start_iter, &end_iter, FALSE);
1024 purple_request_field_string_set_value(strfield,
1025 purple_strempty(text) ? NULL : text);
1026 g_free(text);
1027
1028 } else { 989 } else {
1029 const char *text = NULL; 990 gtk_widget_remove_css_class(row, "focused");
1030 text = gtk_editable_get_text(GTK_EDITABLE(entry)); 991 }
1031 purple_request_field_string_set_value(strfield,
1032 purple_strempty(text) ? NULL : text);
1033 }
1034 }
1035 }
1036
1037 static void
1038 setup_entry_field(GtkWidget *entry, PurpleRequestField *field,
1039 PurpleKeyValuePair **hinted_widget)
1040 {
1041 const char *type_hint;
1042
1043 g_signal_connect(entry, "changed", G_CALLBACK(req_entry_field_changed_cb),
1044 field);
1045
1046 type_hint = purple_request_field_get_type_hint(field);
1047 if(type_hint != NULL && g_str_has_prefix(type_hint, "screenname")) {
1048 *hinted_widget = purple_key_value_pair_new(type_hint, entry);
1049 } 992 }
1050 } 993 }
1051 994
1052 static GtkWidget * 995 static GtkWidget *
1053 create_string_field(PurpleRequestField *field, 996 create_string_field(PurpleRequestField *field,
1054 PurpleKeyValuePair **hinted_widget) 997 G_GNUC_UNUSED PurpleKeyValuePair **hinted_widget)
1055 { 998 {
1056 PurpleRequestFieldString *strfield = PURPLE_REQUEST_FIELD_STRING(field); 999 PurpleRequestFieldString *strfield = PURPLE_REQUEST_FIELD_STRING(field);
1057 const char *value; 1000 const char *value;
1058 GtkWidget *widget; 1001 GtkWidget *row;
1059 gboolean is_editable;
1060 1002
1061 value = purple_request_field_string_get_default_value(strfield); 1003 value = purple_request_field_string_get_default_value(strfield);
1062 is_editable = purple_request_field_is_sensitive(field);
1063 1004
1064 if(purple_request_field_string_is_multiline(strfield)) { 1005 if(purple_request_field_string_is_multiline(strfield)) {
1065 GtkWidget *textview; 1006 GtkWidget *vbox = NULL;
1066 GtkEventController *controller; 1007 GtkWidget *title = NULL;
1008 GtkWidget *textview = NULL;
1009 GtkWidget *sw = NULL;
1010 GtkTextBuffer *buffer = NULL;
1011
1012 vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6);
1013 gtk_widget_set_margin_top(vbox, 6);
1014
1015 title = gtk_label_new(NULL);
1016 gtk_widget_set_halign(title, GTK_ALIGN_START);
1017 gtk_widget_set_margin_start(title, 12);
1018 gtk_widget_set_margin_end(title, 12);
1019 gtk_widget_add_css_class(title, "subtitle");
1020 gtk_box_append(GTK_BOX(vbox), title);
1067 1021
1068 textview = gtk_text_view_new(); 1022 textview = gtk_text_view_new();
1069 gtk_text_view_set_editable(GTK_TEXT_VIEW(textview), 1023 gtk_widget_set_margin_start(textview, 12);
1070 TRUE); 1024 gtk_widget_set_margin_end(textview, 12);
1025 gtk_widget_remove_css_class(textview, "view");
1071 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(textview), 1026 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(textview),
1072 GTK_WRAP_WORD_CHAR); 1027 GTK_WRAP_WORD_CHAR);
1073 1028
1074 if (value != NULL) 1029 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
1075 { 1030 if(value != NULL) {
1076 GtkTextBuffer *buffer;
1077
1078 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
1079
1080 gtk_text_buffer_set_text(buffer, value, -1); 1031 gtk_text_buffer_set_text(buffer, value, -1);
1081 } 1032 }
1082 1033 g_object_bind_property(field, "value", buffer, "text",
1083 gtk_text_view_set_editable(GTK_TEXT_VIEW(textview), is_editable); 1034 G_BINDING_BIDIRECTIONAL);
1084 1035
1085 controller = gtk_event_controller_focus_new(); 1036 sw = gtk_scrolled_window_new();
1086 gtk_widget_add_controller(textview, controller); 1037 gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(sw), textview);
1087 g_signal_connect(controller, "leave", 1038 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
1088 G_CALLBACK(field_string_focus_out_cb), field);
1089
1090 if (purple_request_field_is_required(field))
1091 {
1092 GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
1093 g_signal_connect(buffer, "changed",
1094 G_CALLBACK(req_entry_field_changed_cb), field);
1095 }
1096
1097 widget = gtk_scrolled_window_new();
1098 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(widget),
1099 GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); 1039 GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
1100 gtk_widget_set_size_request(widget, -1, 75); 1040 gtk_widget_set_size_request(sw, -1, 75);
1101 gtk_widget_set_hexpand(widget, TRUE); 1041 gtk_widget_set_hexpand(sw, TRUE);
1102 gtk_widget_set_vexpand(widget, TRUE); 1042 gtk_widget_set_vexpand(sw, TRUE);
1103 gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(widget), textview); 1043 gtk_box_append(GTK_BOX(vbox), sw);
1104 } 1044
1105 else 1045 row = adw_preferences_row_new();
1106 { 1046 g_object_bind_property(row, "title", title, "label",
1107 GtkEventController *controller = NULL; 1047 G_BINDING_DEFAULT);
1108 1048 g_object_bind_property(row, "use-markup", title, "use-markup",
1049 G_BINDING_DEFAULT);
1050 g_object_bind_property(row, "use-underline", title, "use-underline",
1051 G_BINDING_DEFAULT);
1052 gtk_list_box_row_set_child(GTK_LIST_BOX_ROW(row), vbox);
1053 gtk_widget_set_focusable(row, FALSE);
1054 gtk_widget_add_css_class(row, "entry");
1055 g_signal_connect(textview, "state-flags-changed",
1056 G_CALLBACK(multiline_state_flags_changed_cb), row);
1057
1058 } else {
1109 if(purple_request_field_string_is_masked(strfield)) { 1059 if(purple_request_field_string_is_masked(strfield)) {
1110 widget = gtk_password_entry_new(); 1060 row = adw_password_entry_row_new();
1111 g_object_set(widget, "activates-default", TRUE,
1112 "show-peek-icon", TRUE, NULL);
1113 } else { 1061 } else {
1114 widget = gtk_entry_new(); 1062 row = adw_entry_row_new();
1115 gtk_entry_set_activates_default(GTK_ENTRY(widget), TRUE); 1063 }
1116 }
1117
1118 setup_entry_field(widget, field, hinted_widget);
1119 1064
1120 if(value != NULL) { 1065 if(value != NULL) {
1121 gtk_editable_set_text(GTK_EDITABLE(widget), value); 1066 gtk_editable_set_text(GTK_EDITABLE(row), value);
1122 } 1067 }
1123 1068
1124 gtk_editable_set_editable(GTK_EDITABLE(widget), is_editable); 1069 g_object_bind_property(field, "value", row, "text",
1125 1070 G_BINDING_BIDIRECTIONAL);
1126 controller = gtk_event_controller_focus_new(); 1071 }
1127 gtk_widget_add_controller(widget, controller); 1072
1128 g_signal_connect(controller, "leave", 1073 return row;
1129 G_CALLBACK(field_string_focus_out_cb), field);
1130 }
1131
1132 return widget;
1133 } 1074 }
1134 1075
1135 static GtkWidget * 1076 static GtkWidget *
1136 create_int_field(PurpleRequestField *field, PurpleKeyValuePair **hinted_widget) 1077 create_int_field(PurpleRequestField *field,
1078 G_GNUC_UNUSED PurpleKeyValuePair **hinted_widget)
1137 { 1079 {
1138 PurpleRequestFieldInt *intfield = PURPLE_REQUEST_FIELD_INT(field); 1080 PurpleRequestFieldInt *intfield = PURPLE_REQUEST_FIELD_INT(field);
1081 GtkWidget *widget = NULL;
1082 GtkWidget *spin = NULL;
1139 int value; 1083 int value;
1140 GtkWidget *widget; 1084
1141 1085 spin = gtk_spin_button_new_with_range(
1142 widget = gtk_spin_button_new_with_range(
1143 purple_request_field_int_get_lower_bound(intfield), 1086 purple_request_field_int_get_lower_bound(intfield),
1144 purple_request_field_int_get_upper_bound(intfield), 1); 1087 purple_request_field_int_get_upper_bound(intfield), 1);
1145 1088
1146 setup_entry_field(widget, field, hinted_widget);
1147
1148 value = purple_request_field_int_get_default_value(intfield); 1089 value = purple_request_field_int_get_default_value(intfield);
1149 gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), value); 1090 gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin), value);
1091 g_object_bind_property(field, "value", spin, "value",
1092 G_BINDING_BIDIRECTIONAL);
1093
1094 gtk_widget_set_valign(spin, GTK_ALIGN_CENTER);
1095
1096 widget = adw_action_row_new();
1097 gtk_widget_set_focusable(widget, FALSE);
1098 adw_action_row_add_suffix(ADW_ACTION_ROW(widget), spin);
1099 adw_action_row_set_activatable_widget(ADW_ACTION_ROW(widget), spin);
1150 1100
1151 return widget; 1101 return widget;
1152 } 1102 }
1153 1103
1154 static GtkWidget * 1104 static GtkWidget *
1957 was_handled_by_create = TRUE; 1907 was_handled_by_create = TRUE;
1958 } else if(PURPLE_IS_REQUEST_FIELD_STRING(field)) { 1908 } else if(PURPLE_IS_REQUEST_FIELD_STRING(field)) {
1959 PurpleKeyValuePair *username_hint = NULL; 1909 PurpleKeyValuePair *username_hint = NULL;
1960 1910
1961 widget = create_string_field(field, &username_hint); 1911 widget = create_string_field(field, &username_hint);
1912 was_handled_by_create = TRUE;
1962 1913
1963 if(username_hint != NULL) { 1914 if(username_hint != NULL) {
1964 username_widgets = g_slist_prepend(username_widgets, 1915 username_widgets = g_slist_prepend(username_widgets,
1965 username_hint); 1916 username_hint);
1966 } 1917 }
1967 } else if(PURPLE_IS_REQUEST_FIELD_INT(field)) { 1918 } else if(PURPLE_IS_REQUEST_FIELD_INT(field)) {
1968 PurpleKeyValuePair *username_hint = NULL; 1919 PurpleKeyValuePair *username_hint = NULL;
1969 1920
1970 widget = create_int_field(field, &username_hint); 1921 widget = create_int_field(field, &username_hint);
1922 was_handled_by_create = TRUE;
1971 1923
1972 if(username_hint != NULL) { 1924 if(username_hint != NULL) {
1973 username_widgets = g_slist_prepend(username_widgets, 1925 username_widgets = g_slist_prepend(username_widgets,
1974 username_hint); 1926 username_hint);
1975 } 1927 }
1998 g_object_bind_property(field, "sensitive", widget, "sensitive", 1950 g_object_bind_property(field, "sensitive", widget, "sensitive",
1999 G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE); 1951 G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);
2000 1952
2001 if(!was_handled_by_create) { 1953 if(!was_handled_by_create) {
2002 GtkWidget *row = NULL; 1954 GtkWidget *row = NULL;
2003 if(!PURPLE_IS_REQUEST_FIELD_STRING(field) || 1955
2004 !purple_request_field_string_is_multiline(PURPLE_REQUEST_FIELD_STRING(field))) 1956 gtk_widget_set_valign(widget, GTK_ALIGN_CENTER);
2005 {
2006 gtk_widget_set_valign(widget, GTK_ALIGN_CENTER);
2007 }
2008 1957
2009 row = adw_action_row_new(); 1958 row = adw_action_row_new();
2010 adw_action_row_add_suffix(ADW_ACTION_ROW(row), widget); 1959 adw_action_row_add_suffix(ADW_ACTION_ROW(row), widget);
2011 widget = row; 1960 widget = row;
2012 } 1961 }

mercurial