00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00041 #include "choice_model.h"
00042
00043 #include <string.h>
00044 #include <gtk/gtk.h>
00045
00046 #include "frontend.h"
00047 #include "question.h"
00048 #include "strutl.h"
00049
00052 struct search_result {
00054 const char * searched_value;
00055
00057 GtkTreePath * path;
00058 };
00059
00068 static gboolean is_searched_value(GtkTreeModel * model, GtkTreePath * path,
00069 GtkTreeIter * iter,
00070 struct search_result * result)
00071 {
00072 char * value;
00073
00074 gtk_tree_model_get(model, iter,
00075 CHOICE_MODEL_VALUE, &value,
00076 -1 );
00077 if (0 == strcmp(value, result->searched_value)) {
00078 result->path = gtk_tree_path_copy(path);
00079 }
00080 g_free(value);
00081 return NULL != result->path;
00082 }
00083
00091 GtkTreePath * fe_gtk_choice_model_find_value(GtkTreeModel * model,
00092 const char * searched_value)
00093 {
00094 struct search_result result;
00095
00096 result.searched_value = searched_value;
00097 result.path = NULL;
00098
00099 gtk_tree_model_foreach(model, (GtkTreeModelForeachFunc) is_searched_value,
00100 &result);
00101 return result.path;
00102 }
00103
00113 GtkTreeModel * fe_gtk_choice_model_create_full(struct frontend * fe,
00114 struct question * question,
00115 parent_predicate is_parent)
00116 {
00117 GtkTreeStore * store;
00118 int count;
00119 int sorted_count;
00120 char * raw_indices;
00121 char * raw_choices;
00122 char * raw_translated_choices;
00123 int * sorted_indices;
00124 char ** choice_values;
00125 char ** choice_translated_values;
00126 char ** default_values;
00127 int default_count;
00128 int i;
00129 GtkTreeIter iter;
00130 GtkTreeIter child;
00131 GtkTreePath * path;
00132
00133 store = gtk_tree_store_new(CHOICE_MODEL_COLUMN_COUNT,
00134 G_TYPE_BOOLEAN ,
00135 G_TYPE_INT ,
00136 G_TYPE_STRING ,
00137 G_TYPE_STRING );
00138 if (NULL == store) {
00139 g_warning("gtk_tree_store_new failed.");
00140 return NULL;
00141 };
00142
00143 raw_indices = q_get_indices(question);
00144 raw_choices = q_get_choices_vals(question);
00145 raw_translated_choices = q_get_choices(question);
00146 count = strgetargc(raw_choices);
00147 g_assert(0 < count);
00148
00149 sorted_indices = g_malloc0(count * sizeof (int));
00150 choice_values = g_malloc0(count * sizeof (char *));
00151 choice_translated_values = g_malloc0(count * sizeof (char *));
00152 default_values = g_malloc0(count * sizeof (char *));
00153
00154
00155
00156
00157 sorted_count = strchoicesplitsort(raw_choices, raw_translated_choices,
00158 raw_indices, choice_values,
00159 choice_translated_values,
00160 sorted_indices, count);
00161 g_assert(sorted_count == count);
00162
00163 default_count = strchoicesplit(question_getvalue(question, ""),
00164 default_values, count);
00165 g_assert(0 <= default_count);
00166
00167
00168 for (i = 0; i < count; i++) {
00169 if (NULL == is_parent ||
00170 is_parent(sorted_indices[i], choice_values[i],
00171 choice_translated_values[i])) {
00172 gtk_tree_store_append(store, &iter, NULL );
00173 gtk_tree_store_set(
00174 store, &iter,
00175 CHOICE_MODEL_SELECTED, FALSE,
00176 CHOICE_MODEL_INDEX, sorted_indices[i],
00177 CHOICE_MODEL_VALUE, choice_values[i],
00178 CHOICE_MODEL_TRANSLATED_VALUE,
00179 choice_translated_values[i],
00180 -1 );
00181 } else {
00182 gtk_tree_store_append(store, &child, &iter);
00183 gtk_tree_store_set(
00184 store, &child,
00185 CHOICE_MODEL_SELECTED, FALSE,
00186 CHOICE_MODEL_INDEX, sorted_indices[i],
00187 CHOICE_MODEL_VALUE, choice_values[i],
00188 CHOICE_MODEL_TRANSLATED_VALUE,
00189 choice_translated_values[i],
00190 -1 );
00191 }
00192 }
00193
00194
00195 for (i = 0; i < default_count; i++) {
00196 if (NULL != (path = fe_gtk_choice_model_find_value(
00197 GTK_TREE_MODEL(store), default_values[i]))) {
00198 if (gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter, path)) {
00199 gtk_tree_store_set(store, &iter,
00200 CHOICE_MODEL_SELECTED, TRUE,
00201 -1 );
00202 }
00203 gtk_tree_path_free(path);
00204 }
00205 }
00206
00207 g_free(sorted_indices);
00208 g_free(choice_values);
00209 g_free(choice_translated_values);
00210 g_free(raw_translated_choices);
00211 g_free(raw_choices);
00212 g_free(raw_indices);
00213 return GTK_TREE_MODEL(store);
00214 }
00215
00222 GtkTreeModel * fe_gtk_choice_model_create(struct frontend * fe,
00223 struct question * question)
00224 {
00225 return fe_gtk_choice_model_create_full(
00226 fe, question, NULL );
00227 }
00228
00237 static gboolean increment_model_length(GtkTreeModel * model,
00238 GtkTreePath * path,
00239 GtkTreeIter * iter, guint * length)
00240 {
00241 *length = *length + 1;
00242 return FALSE;
00243 }
00244
00250 guint fe_gtk_choice_model_get_length(GtkTreeModel * model)
00251 {
00252 guint length = 0;
00253
00254 g_assert(NULL != model);
00255
00256 gtk_tree_model_foreach(
00257 model, (GtkTreeModelForeachFunc) increment_model_length, &length);
00258 return length;
00259 }
00260
00269 static gboolean is_selected(GtkTreeModel * model, GtkTreePath * path,
00270 GtkTreeIter * iter, GtkTreePath ** result)
00271 {
00272 gboolean selected;
00273
00274 gtk_tree_model_get(model, iter,
00275 CHOICE_MODEL_SELECTED, &selected,
00276 -1 );
00277 if (selected) {
00278 *result = gtk_tree_path_copy(path);
00279 return TRUE ;
00280 }
00281 return FALSE;
00282 }
00283
00291 GtkTreePath * fe_gtk_choice_model_get_first_selected(GtkTreeModel * model)
00292 {
00293 GtkTreePath * result = NULL;
00294
00295 gtk_tree_model_foreach(model, (GtkTreeModelForeachFunc) is_selected,
00296 &result);
00297 return result;
00298 }
00299
00309 void fe_gtk_choice_model_set(GtkTreeModel * model, GtkTreeIter * iter, ...)
00310 {
00311 va_list var_args;
00312
00313 va_start(var_args, iter);
00314 gtk_tree_store_set_valist(GTK_TREE_STORE(model), iter, var_args);
00315 va_end(var_args);
00316 }
00317
00318
00319