gwenhywfar 4.0.3
|
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; 00207 } 00208 00209 return GWEN_DialogSortDirection_None; 00210 } 00211 00212 default: 00213 break; 00214 } 00215 00216 DBG_WARN(GWEN_LOGDOMAIN, 00217 "Function is not appropriate for this type of widget (%s)", 00218 GWEN_Widget_Type_toString(GWEN_Widget_GetType(w))); 00219 return defaultValue; 00220 } 00221 00222 00223 00224 static GWENHYWFAR_CB 00225 int Gtk2Gui_WListBox_SetCharProperty(GWEN_WIDGET *w, 00226 GWEN_DIALOG_PROPERTY prop, 00227 int index, 00228 const char *value, 00229 int doSignal) { 00230 GtkWidget *g; 00231 00232 g=GTK_WIDGET(GWEN_Widget_GetImplData(w, GTK2_DIALOG_WIDGET_CONTENT)); 00233 assert(g); 00234 00235 switch(prop) { 00236 case GWEN_DialogProperty_Title: { 00237 int cols=0; 00238 if (value && *value) { 00239 int i; 00240 int l; 00241 00242 l=strlen(value); 00243 cols=1; 00244 for (i=0; i<l; i++) { 00245 if (value[i]=='\t') 00246 cols++; 00247 } 00248 } 00249 00250 if (cols) { 00251 GType types[W_LISTBOX_MAX_TYPES]; 00252 GtkListStore *sto; 00253 int i; 00254 const char *s; 00255 GtkTreeViewColumn *col; 00256 char *vcopy; 00257 char *p; 00258 00259 if (cols>W_LISTBOX_MAX_TYPES) 00260 cols=W_LISTBOX_MAX_TYPES; 00261 for (i=0; i<cols; i++) 00262 types[i]=G_TYPE_STRING; 00263 sto=gtk_list_store_newv(cols, types); 00264 s=value; 00265 00266 /* clear current headers in tree view */ 00267 while( (col=gtk_tree_view_get_column(GTK_TREE_VIEW(g), 0)) ) 00268 gtk_tree_view_remove_column(GTK_TREE_VIEW(g), col); 00269 00270 /* set new model */ 00271 gtk_tree_view_set_model(GTK_TREE_VIEW(g), GTK_TREE_MODEL(sto)); 00272 00273 /* insert new headers */ 00274 i=0; 00275 vcopy=strdup(value); 00276 p=vcopy; 00277 while(*p && i<cols) { 00278 char *pT; 00279 GtkCellRenderer *renderer; 00280 00281 pT=strchr(p, '\t'); 00282 if (pT) 00283 *pT=0; 00284 00285 renderer=gtk_cell_renderer_text_new(); 00286 col=gtk_tree_view_column_new(); 00287 gtk_tree_view_column_set_title(col, p); 00288 gtk_tree_view_column_pack_start(col, renderer, TRUE); 00289 gtk_tree_view_column_set_sort_column_id(col, i); 00290 gtk_tree_view_column_set_resizable(col, TRUE); 00291 gtk_tree_view_column_set_sizing(col, GTK_TREE_VIEW_COLUMN_FIXED); 00292 gtk_tree_view_column_set_attributes(col, renderer, "text", i, NULL); 00293 00294 gtk_tree_view_append_column(GTK_TREE_VIEW(g), col); 00295 00296 if (pT) 00297 p=pT+1; 00298 else 00299 /* no more tab, all columns done */ 00300 break; 00301 i++; 00302 } 00303 free(vcopy); 00304 GWEN_Widget_SetColumns(w, cols); 00305 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(g), TRUE); 00306 } 00307 else { 00308 DBG_ERROR(GWEN_LOGDOMAIN, "No columns (empty title)"); 00309 return GWEN_ERROR_INVALID; 00310 } 00311 00312 return 0; 00313 } 00314 00315 case GWEN_DialogProperty_ClearValues: { 00316 GtkListStore *sto; 00317 00318 sto=GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(g))); 00319 if (sto) 00320 gtk_list_store_clear(sto); 00321 return 0; 00322 } 00323 00324 case GWEN_DialogProperty_AddValue: { 00325 GtkListStore *sto; 00326 00327 sto=GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(g))); 00328 if (sto) { 00329 GtkTreeIter iter; 00330 int cols; 00331 int i; 00332 char *vcopy; 00333 char *p; 00334 00335 cols=GWEN_Widget_GetColumns(w); 00336 00337 vcopy=strdup(value); 00338 p=vcopy; 00339 i=0; 00340 gtk_list_store_append(sto, &iter); 00341 while(*p && i<cols) { 00342 char *pT; 00343 GValue val={0}; 00344 00345 g_value_init(&val, G_TYPE_STRING); 00346 00347 pT=strchr(p, '\t'); 00348 if (pT) 00349 *pT=0; 00350 g_value_set_string(&val, p); 00351 gtk_list_store_set_value(sto, &iter, i, &val); 00352 g_value_unset(&val); 00353 00354 if (pT) 00355 p=pT+1; 00356 else 00357 /* no more tabs, all columns done */ 00358 break; 00359 i++; 00360 } 00361 free(vcopy); 00362 } 00363 00364 return 0; 00365 } 00366 00367 default: 00368 break; 00369 } 00370 00371 DBG_WARN(GWEN_LOGDOMAIN, 00372 "Function is not appropriate for this type of widget (%s)", 00373 GWEN_Widget_Type_toString(GWEN_Widget_GetType(w))); 00374 return GWEN_ERROR_INVALID; 00375 } 00376 00377 00378 00379 static GWENHYWFAR_CB 00380 const char* Gtk2Gui_WListBox_GetCharProperty(GWEN_WIDGET *w, 00381 GWEN_DIALOG_PROPERTY prop, 00382 int index, 00383 const char *defaultValue) { 00384 GtkWidget *g; 00385 00386 g=GTK_WIDGET(GWEN_Widget_GetImplData(w, GTK2_DIALOG_WIDGET_CONTENT)); 00387 assert(g); 00388 00389 switch(prop) { 00390 case GWEN_DialogProperty_Title: { 00391 GList *cols; 00392 00393 cols=gtk_tree_view_get_columns(GTK_TREE_VIEW(g)); 00394 if (cols) { 00395 GList *le; 00396 GWEN_BUFFER *tbuf; 00397 int cnt=0; 00398 00399 tbuf=GWEN_Buffer_new(0, 256, 0, 1); 00400 le=g_list_first(cols); 00401 while(le) { 00402 const gchar *s; 00403 00404 if (cnt) 00405 GWEN_Buffer_AppendByte(tbuf, '\t'); 00406 s=gtk_tree_view_column_get_title(GTK_TREE_VIEW_COLUMN(le->data)); 00407 if (s && *s) 00408 GWEN_Buffer_AppendString(tbuf, s); 00409 cnt++; 00410 le=g_list_next(le); 00411 } /* while */ 00412 GWEN_Widget_SetText(w, GTK2_DIALOG_STRING_TITLE, GWEN_Buffer_GetStart(tbuf)); 00413 GWEN_Buffer_free(tbuf); 00414 00415 g_list_free(cols); 00416 return GWEN_Widget_GetText(w, GTK2_DIALOG_STRING_TITLE); 00417 } 00418 return defaultValue; 00419 } 00420 00421 case GWEN_DialogProperty_Value: { 00422 GtkTreePath *path; 00423 00424 path=gtk_tree_path_new_from_indices(index, -1); 00425 if (path!=NULL) { 00426 GtkListStore *sto; 00427 GtkTreeIter iter; 00428 00429 sto=GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(g))); 00430 if (gtk_tree_model_get_iter(GTK_TREE_MODEL(sto), &iter, path)) { 00431 GList *cols; 00432 00433 cols=gtk_tree_view_get_columns(GTK_TREE_VIEW(g)); 00434 if (cols) { 00435 GList *le; 00436 GWEN_BUFFER *tbuf; 00437 int cnt=0; 00438 00439 tbuf=GWEN_Buffer_new(0, 256, 0, 1); 00440 le=g_list_first(cols); 00441 while(le) { 00442 gchar *s; 00443 00444 if (cnt) 00445 GWEN_Buffer_AppendByte(tbuf, '\t'); 00446 gtk_tree_model_get(GTK_TREE_MODEL(sto), &iter, cnt, &s, -1, NULL); 00447 if (s) { 00448 GWEN_Buffer_AppendString(tbuf, s); 00449 g_free(s); 00450 } 00451 cnt++; 00452 le=g_list_next(le); 00453 } /* while */ 00454 GWEN_Widget_SetText(w, GTK2_DIALOG_STRING_VALUE, GWEN_Buffer_GetStart(tbuf)); 00455 GWEN_Buffer_free(tbuf); 00456 00457 g_list_free(cols); 00458 return GWEN_Widget_GetText(w, GTK2_DIALOG_STRING_VALUE); 00459 } 00460 } 00461 00462 gtk_tree_path_free(path); 00463 } 00464 return defaultValue; 00465 } 00466 00467 default: 00468 break; 00469 } 00470 00471 DBG_WARN(GWEN_LOGDOMAIN, 00472 "Function is not appropriate for this type of widget (%s)", 00473 GWEN_Widget_Type_toString(GWEN_Widget_GetType(w))); 00474 return defaultValue; 00475 } 00476 00477 00478 00479 static void Gtk2Gui_WListBox_CursorChanged_handler(GtkTreeView *g, gpointer data) { 00480 GWEN_WIDGET *w; 00481 int rv; 00482 00483 w=data; 00484 assert(w); 00485 rv=GWEN_Dialog_EmitSignal(GWEN_Widget_GetDialog(w), 00486 GWEN_DialogEvent_TypeActivated, 00487 GWEN_Widget_GetName(w)); 00488 if (rv==GWEN_DialogEvent_ResultAccept) 00489 Gtk2Gui_Dialog_Leave(GWEN_Widget_GetTopDialog(w), 1); 00490 else if (rv==GWEN_DialogEvent_ResultReject) 00491 Gtk2Gui_Dialog_Leave(GWEN_Widget_GetTopDialog(w), 0); 00492 } 00493 00494 00495 00496 int Gtk2Gui_WListBox_Setup(GWEN_WIDGET *w) { 00497 GtkWidget *g; 00498 GtkWidget *gScroll; 00499 uint32_t flags; 00500 GWEN_WIDGET *wParent; 00501 gulong changed_handler_id; 00502 00503 flags=GWEN_Widget_GetFlags(w); 00504 wParent=GWEN_Widget_Tree_GetParent(w); 00505 00506 gScroll=gtk_scrolled_window_new(NULL, NULL); 00507 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(gScroll), 00508 GTK_POLICY_AUTOMATIC, 00509 GTK_POLICY_AUTOMATIC); 00510 g=gtk_tree_view_new(); 00511 gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(g), TRUE); 00512 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(g), TRUE); 00513 gtk_container_add(GTK_CONTAINER(gScroll), GTK_WIDGET(g)); 00514 00515 GWEN_Widget_SetImplData(w, GTK2_DIALOG_WIDGET_REAL, (void*) gScroll); 00516 GWEN_Widget_SetImplData(w, GTK2_DIALOG_WIDGET_CONTENT, (void*) g); 00517 00518 GWEN_Widget_SetSetIntPropertyFn(w, Gtk2Gui_WListBox_SetIntProperty); 00519 GWEN_Widget_SetGetIntPropertyFn(w, Gtk2Gui_WListBox_GetIntProperty); 00520 GWEN_Widget_SetSetCharPropertyFn(w, Gtk2Gui_WListBox_SetCharProperty); 00521 GWEN_Widget_SetGetCharPropertyFn(w, Gtk2Gui_WListBox_GetCharProperty); 00522 00523 changed_handler_id=g_signal_connect(g, 00524 "cursor-changed", 00525 G_CALLBACK (Gtk2Gui_WListBox_CursorChanged_handler), 00526 w); 00527 00528 if (wParent) 00529 GWEN_Widget_AddChildGuiWidget(wParent, w); 00530 00531 return 0; 00532 } 00533 00534