gwenhywfar
4.3.1
|
00001 /*************************************************************************** 00002 begin : Fri Jul 09 2010 00003 copyright : (C) 2010 by Martin Preuss 00004 email : martin@libchipcard.de 00005 00006 *************************************************************************** 00007 * Please see toplevel file COPYING for license details * 00008 ***************************************************************************/ 00009 00010 00011 #define W_LISTBOX_MAX_TYPES 256 00012 00013 00014 00015 static GWENHYWFAR_CB 00016 int Gtk2Gui_WListBox_SetIntProperty(GWEN_WIDGET *w, 00017 GWEN_DIALOG_PROPERTY prop, 00018 int index, 00019 int value, 00020 int doSignal) { 00021 GtkWidget *g; 00022 00023 g=GTK_WIDGET(GWEN_Widget_GetImplData(w, GTK2_DIALOG_WIDGET_CONTENT)); 00024 assert(g); 00025 00026 switch(prop) { 00027 case GWEN_DialogProperty_Enabled: 00028 gtk_widget_set_sensitive(GTK_WIDGET(g), (value==0)?FALSE:TRUE); 00029 return 0; 00030 00031 case GWEN_DialogProperty_Focus: 00032 gtk_widget_grab_focus(GTK_WIDGET(g)); 00033 return 0; 00034 00035 case GWEN_DialogProperty_Value: { 00036 GtkTreePath *path; 00037 00038 path=gtk_tree_path_new_from_indices(value, -1); 00039 gtk_tree_view_set_cursor(GTK_TREE_VIEW(g), path, NULL, FALSE); 00040 gtk_tree_path_free(path); 00041 return 0; 00042 } 00043 00044 case GWEN_DialogProperty_SelectionMode: { 00045 GtkTreeSelection *sel; 00046 00047 sel=gtk_tree_view_get_selection(GTK_TREE_VIEW(g)); 00048 if (sel) { 00049 switch(value) { 00050 case GWEN_Dialog_SelectionMode_None: 00051 gtk_tree_selection_set_mode(sel, GTK_SELECTION_NONE); 00052 return 0; 00053 case GWEN_Dialog_SelectionMode_Single: 00054 gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE); 00055 return 0; 00056 case GWEN_Dialog_SelectionMode_Multi: 00057 gtk_tree_selection_set_mode(sel, GTK_SELECTION_MULTIPLE); 00058 return 0; 00059 } 00060 DBG_ERROR(GWEN_LOGDOMAIN, "Unknown SelectionMode %d", value); 00061 return GWEN_ERROR_INVALID; 00062 } 00063 break; 00064 } 00065 00066 case GWEN_DialogProperty_ColumnWidth: { 00067 GtkTreeViewColumn *col; 00068 00069 col=gtk_tree_view_get_column(GTK_TREE_VIEW(g), index); 00070 if (col) { 00071 gtk_tree_view_column_set_fixed_width(col, value); 00072 return 0; 00073 } 00074 00075 /* no width */ 00076 return GWEN_ERROR_INVALID; 00077 } 00078 00079 case GWEN_DialogProperty_SortDirection: { 00080 GtkTreeViewColumn *col; 00081 int i; 00082 int cols; 00083 00084 /* remove sort indicator from all columns */ 00085 cols=GWEN_Widget_GetColumns(w); 00086 for (i=0; i<cols; i++) { 00087 col=gtk_tree_view_get_column(GTK_TREE_VIEW(g), index); 00088 if (col) { 00089 if (gtk_tree_view_column_get_sort_indicator(col)==TRUE) 00090 gtk_tree_view_column_set_sort_indicator(col, FALSE); 00091 } 00092 } 00093 00094 if (value!=GWEN_DialogSortDirection_None) { 00095 /* set sort indicator on given column */ 00096 col=gtk_tree_view_get_column(GTK_TREE_VIEW(g), index); 00097 if (col) { 00098 switch(value) { 00099 case GWEN_DialogSortDirection_Up: 00100 gtk_tree_view_column_set_sort_order(col, GTK_SORT_ASCENDING); 00101 break; 00102 case GWEN_DialogSortDirection_Down: 00103 gtk_tree_view_column_set_sort_order(col, GTK_SORT_DESCENDING); 00104 break; 00105 default: 00106 break; 00107 } 00108 } 00109 } 00110 00111 return 0; 00112 } 00113 00114 case GWEN_DialogProperty_ClearValues: { 00115 GtkListStore *sto; 00116 00117 sto=GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(g))); 00118 if (sto) 00119 gtk_list_store_clear(sto); 00120 return 0; 00121 } 00122 00123 case GWEN_DialogProperty_Sort: 00124 /* NOOP, we use auto-sorting for now (TODO: figure out how to manually sort) */ 00125 return 0; 00126 00127 default: 00128 break; 00129 } 00130 00131 DBG_WARN(GWEN_LOGDOMAIN, 00132 "Function is not appropriate for this type of widget (%s)", 00133 GWEN_Widget_Type_toString(GWEN_Widget_GetType(w))); 00134 return GWEN_ERROR_INVALID; 00135 } 00136 00137 00138 00139 00140 static GWENHYWFAR_CB 00141 int Gtk2Gui_WListBox_GetIntProperty(GWEN_WIDGET *w, 00142 GWEN_DIALOG_PROPERTY prop, 00143 int index, 00144 int defaultValue) { 00145 GtkWidget *g; 00146 00147 g=GTK_WIDGET(GWEN_Widget_GetImplData(w, GTK2_DIALOG_WIDGET_CONTENT)); 00148 assert(g); 00149 00150 switch(prop) { 00151 case GWEN_DialogProperty_Enabled: 00152 return (gtk_widget_get_sensitive(GTK_WIDGET(g))==TRUE)?1:0; 00153 00154 case GWEN_DialogProperty_Focus: 00155 return (gtk_widget_has_focus(GTK_WIDGET(g))==TRUE)?1:0; 00156 return 0; 00157 00158 case GWEN_DialogProperty_Value: { 00159 GtkTreePath *path=NULL; 00160 00161 gtk_tree_view_get_cursor(GTK_TREE_VIEW(g), &path, NULL); 00162 if (path!=NULL) { 00163 gint *idxlist; 00164 00165 idxlist=gtk_tree_path_get_indices(path); 00166 if (idxlist!=NULL) { 00167 int res; 00168 00169 res=idxlist[0]; 00170 gtk_tree_path_free(path); 00171 return res; 00172 } 00173 gtk_tree_path_free(path); 00174 } 00175 00176 /* no cursor */ 00177 return -1; 00178 } 00179 00180 case GWEN_DialogProperty_ColumnWidth: { 00181 GtkTreeViewColumn *col; 00182 00183 col=gtk_tree_view_get_column(GTK_TREE_VIEW(g), index); 00184 if (col) 00185 return gtk_tree_view_column_get_width(col); 00186 00187 /* no width */ 00188 return -1; 00189 } 00190 00191 case GWEN_DialogProperty_SortDirection: { 00192 GtkTreeViewColumn *col; 00193 00194 col=gtk_tree_view_get_column(GTK_TREE_VIEW(g), index); 00195 if (col) { 00196 if (gtk_tree_view_column_get_sort_indicator(col)==TRUE) { 00197 switch(gtk_tree_view_column_get_sort_order(col)) { 00198 case GTK_SORT_ASCENDING: 00199 return GWEN_DialogSortDirection_Up; 00200 case GTK_SORT_DESCENDING: 00201 return GWEN_DialogSortDirection_Down; 00202 default: 00203 break; 00204 } 00205 } 00206 /*break; <- this is wrong here, isn't it? */ 00207 } 00208 00209 return GWEN_DialogSortDirection_None; 00210 } 00211 00212 default: 00213 break; 00214 } 00215 00216 DBG_WARN(GWEN_LOGDOMAIN, 00217 "Function %d is not appropriate for this type of widget (%s)", 00218 prop, 00219 GWEN_Widget_Type_toString(GWEN_Widget_GetType(w))); 00220 return defaultValue; 00221 } 00222 00223 00224 00225 static GWENHYWFAR_CB 00226 int Gtk2Gui_WListBox_SetCharProperty(GWEN_WIDGET *w, 00227 GWEN_DIALOG_PROPERTY prop, 00228 int index, 00229 const char *value, 00230 int doSignal) { 00231 GtkWidget *g; 00232 00233 g=GTK_WIDGET(GWEN_Widget_GetImplData(w, GTK2_DIALOG_WIDGET_CONTENT)); 00234 assert(g); 00235 00236 switch(prop) { 00237 case GWEN_DialogProperty_Title: { 00238 int cols=0; 00239 if (value && *value) { 00240 int i; 00241 int l; 00242 00243 l=strlen(value); 00244 cols=1; 00245 for (i=0; i<l; i++) { 00246 if (value[i]=='\t') 00247 cols++; 00248 } 00249 } 00250 00251 if (cols) { 00252 GType types[W_LISTBOX_MAX_TYPES]; 00253 GtkListStore *sto; 00254 int i; 00255 const char *s; 00256 GtkTreeViewColumn *col; 00257 char *vcopy; 00258 char *p; 00259 00260 if (cols>W_LISTBOX_MAX_TYPES) 00261 cols=W_LISTBOX_MAX_TYPES; 00262 for (i=0; i<cols; i++) 00263 types[i]=G_TYPE_STRING; 00264 sto=gtk_list_store_newv(cols, types); 00265 s=value; 00266 00267 /* clear current headers in tree view */ 00268 while( (col=gtk_tree_view_get_column(GTK_TREE_VIEW(g), 0)) ) 00269 gtk_tree_view_remove_column(GTK_TREE_VIEW(g), col); 00270 00271 /* set new model */ 00272 gtk_tree_view_set_model(GTK_TREE_VIEW(g), GTK_TREE_MODEL(sto)); 00273 00274 /* insert new headers */ 00275 i=0; 00276 vcopy=strdup(value); 00277 p=vcopy; 00278 while(*p && i<cols) { 00279 char *pT; 00280 GtkCellRenderer *renderer; 00281 00282 pT=strchr(p, '\t'); 00283 if (pT) 00284 *pT=0; 00285 00286 renderer=gtk_cell_renderer_text_new(); 00287 col=gtk_tree_view_column_new(); 00288 gtk_tree_view_column_set_title(col, p); 00289 gtk_tree_view_column_pack_start(col, renderer, TRUE); 00290 gtk_tree_view_column_set_sort_column_id(col, i); 00291 gtk_tree_view_column_set_resizable(col, TRUE); 00292 gtk_tree_view_column_set_sizing(col, GTK_TREE_VIEW_COLUMN_FIXED); 00293 gtk_tree_view_column_set_attributes(col, renderer, "text", i, NULL); 00294 00295 gtk_tree_view_append_column(GTK_TREE_VIEW(g), col); 00296 00297 if (pT) 00298 p=pT+1; 00299 else 00300 /* no more tab, all columns done */ 00301 break; 00302 i++; 00303 } 00304 free(vcopy); 00305 GWEN_Widget_SetColumns(w, cols); 00306 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(g), TRUE); 00307 } 00308 else { 00309 DBG_ERROR(GWEN_LOGDOMAIN, "No columns (empty title)"); 00310 return GWEN_ERROR_INVALID; 00311 } 00312 00313 return 0; 00314 } 00315 00316 case GWEN_DialogProperty_ClearValues: { 00317 GtkListStore *sto; 00318 00319 sto=GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(g))); 00320 if (sto) 00321 gtk_list_store_clear(sto); 00322 return 0; 00323 } 00324 00325 case GWEN_DialogProperty_AddValue: { 00326 GtkListStore *sto; 00327 00328 sto=GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(g))); 00329 if (sto) { 00330 GtkTreeIter iter; 00331 int cols; 00332 int i; 00333 char *vcopy; 00334 char *p; 00335 00336 cols=GWEN_Widget_GetColumns(w); 00337 00338 vcopy=strdup(value); 00339 p=vcopy; 00340 i=0; 00341 gtk_list_store_append(sto, &iter); 00342 while(*p && i<cols) { 00343 char *pT; 00344 GValue val={0}; 00345 00346 g_value_init(&val, G_TYPE_STRING); 00347 00348 pT=strchr(p, '\t'); 00349 if (pT) 00350 *pT=0; 00351 g_value_set_string(&val, p); 00352 gtk_list_store_set_value(sto, &iter, i, &val); 00353 g_value_unset(&val); 00354 00355 if (pT) 00356 p=pT+1; 00357 else 00358 /* no more tabs, all columns done */ 00359 break; 00360 i++; 00361 } 00362 free(vcopy); 00363 } 00364 00365 return 0; 00366 } 00367 00368 default: 00369 break; 00370 } 00371 00372 DBG_WARN(GWEN_LOGDOMAIN, 00373 "Function is not appropriate for this type of widget (%s)", 00374 GWEN_Widget_Type_toString(GWEN_Widget_GetType(w))); 00375 return GWEN_ERROR_INVALID; 00376 } 00377 00378 00379 00380 static GWENHYWFAR_CB 00381 const char* Gtk2Gui_WListBox_GetCharProperty(GWEN_WIDGET *w, 00382 GWEN_DIALOG_PROPERTY prop, 00383 int index, 00384 const char *defaultValue) { 00385 GtkWidget *g; 00386 00387 g=GTK_WIDGET(GWEN_Widget_GetImplData(w, GTK2_DIALOG_WIDGET_CONTENT)); 00388 assert(g); 00389 00390 switch(prop) { 00391 case GWEN_DialogProperty_Title: { 00392 GList *cols; 00393 00394 cols=gtk_tree_view_get_columns(GTK_TREE_VIEW(g)); 00395 if (cols) { 00396 GList *le; 00397 GWEN_BUFFER *tbuf; 00398 int cnt=0; 00399 00400 tbuf=GWEN_Buffer_new(0, 256, 0, 1); 00401 le=g_list_first(cols); 00402 while(le) { 00403 const gchar *s; 00404 00405 if (cnt) 00406 GWEN_Buffer_AppendByte(tbuf, '\t'); 00407 s=gtk_tree_view_column_get_title(GTK_TREE_VIEW_COLUMN(le->data)); 00408 if (s && *s) 00409 GWEN_Buffer_AppendString(tbuf, s); 00410 cnt++; 00411 le=g_list_next(le); 00412 } /* while */ 00413 GWEN_Widget_SetText(w, GTK2_DIALOG_STRING_TITLE, GWEN_Buffer_GetStart(tbuf)); 00414 GWEN_Buffer_free(tbuf); 00415 00416 g_list_free(cols); 00417 return GWEN_Widget_GetText(w, GTK2_DIALOG_STRING_TITLE); 00418 } 00419 return defaultValue; 00420 } 00421 00422 case GWEN_DialogProperty_Value: { 00423 GtkTreePath *path; 00424 00425 path=gtk_tree_path_new_from_indices(index, -1); 00426 if (path!=NULL) { 00427 GtkListStore *sto; 00428 GtkTreeIter iter; 00429 00430 sto=GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(g))); 00431 if (gtk_tree_model_get_iter(GTK_TREE_MODEL(sto), &iter, path)) { 00432 GList *cols; 00433 00434 cols=gtk_tree_view_get_columns(GTK_TREE_VIEW(g)); 00435 if (cols) { 00436 GList *le; 00437 GWEN_BUFFER *tbuf; 00438 int cnt=0; 00439 00440 tbuf=GWEN_Buffer_new(0, 256, 0, 1); 00441 le=g_list_first(cols); 00442 while(le) { 00443 gchar *s; 00444 00445 if (cnt) 00446 GWEN_Buffer_AppendByte(tbuf, '\t'); 00447 gtk_tree_model_get(GTK_TREE_MODEL(sto), &iter, cnt, &s, -1, NULL); 00448 if (s) { 00449 GWEN_Buffer_AppendString(tbuf, s); 00450 g_free(s); 00451 } 00452 cnt++; 00453 le=g_list_next(le); 00454 } /* while */ 00455 GWEN_Widget_SetText(w, GTK2_DIALOG_STRING_VALUE, GWEN_Buffer_GetStart(tbuf)); 00456 GWEN_Buffer_free(tbuf); 00457 00458 g_list_free(cols); 00459 return GWEN_Widget_GetText(w, GTK2_DIALOG_STRING_VALUE); 00460 } 00461 } 00462 00463 gtk_tree_path_free(path); 00464 } 00465 return defaultValue; 00466 } 00467 00468 default: 00469 break; 00470 } 00471 00472 DBG_WARN(GWEN_LOGDOMAIN, 00473 "Function is not appropriate for this type of widget (%s)", 00474 GWEN_Widget_Type_toString(GWEN_Widget_GetType(w))); 00475 return defaultValue; 00476 } 00477 00478 00479 00480 static void Gtk2Gui_WListBox_CursorChanged_handler(GtkTreeView *g, gpointer data) { 00481 GWEN_WIDGET *w; 00482 int rv; 00483 00484 w=data; 00485 assert(w); 00486 rv=GWEN_Dialog_EmitSignal(GWEN_Widget_GetDialog(w), 00487 GWEN_DialogEvent_TypeActivated, 00488 GWEN_Widget_GetName(w)); 00489 if (rv==GWEN_DialogEvent_ResultAccept) 00490 Gtk2Gui_Dialog_Leave(GWEN_Widget_GetTopDialog(w), 1); 00491 else if (rv==GWEN_DialogEvent_ResultReject) 00492 Gtk2Gui_Dialog_Leave(GWEN_Widget_GetTopDialog(w), 0); 00493 } 00494 00495 00496 00497 int Gtk2Gui_WListBox_Setup(GWEN_WIDGET *w) { 00498 GtkWidget *g; 00499 GtkWidget *gScroll; 00500 uint32_t flags; 00501 GWEN_WIDGET *wParent; 00502 gulong changed_handler_id; 00503 00504 flags=GWEN_Widget_GetFlags(w); 00505 wParent=GWEN_Widget_Tree_GetParent(w); 00506 00507 gScroll=gtk_scrolled_window_new(NULL, NULL); 00508 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(gScroll), 00509 GTK_POLICY_AUTOMATIC, 00510 GTK_POLICY_AUTOMATIC); 00511 g=gtk_tree_view_new(); 00512 gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(g), TRUE); 00513 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(g), TRUE); 00514 gtk_container_add(GTK_CONTAINER(gScroll), GTK_WIDGET(g)); 00515 00516 GWEN_Widget_SetImplData(w, GTK2_DIALOG_WIDGET_REAL, (void*) gScroll); 00517 GWEN_Widget_SetImplData(w, GTK2_DIALOG_WIDGET_CONTENT, (void*) g); 00518 00519 GWEN_Widget_SetSetIntPropertyFn(w, Gtk2Gui_WListBox_SetIntProperty); 00520 GWEN_Widget_SetGetIntPropertyFn(w, Gtk2Gui_WListBox_GetIntProperty); 00521 GWEN_Widget_SetSetCharPropertyFn(w, Gtk2Gui_WListBox_SetCharProperty); 00522 GWEN_Widget_SetGetCharPropertyFn(w, Gtk2Gui_WListBox_GetCharProperty); 00523 00524 changed_handler_id=g_signal_connect(g, 00525 "cursor-changed", 00526 G_CALLBACK (Gtk2Gui_WListBox_CursorChanged_handler), 00527 w); 00528 00529 if (wParent) 00530 GWEN_Widget_AddChildGuiWidget(wParent, w); 00531 00532 return 0; 00533 } 00534 00535