gtkIOStream  1.7.0
GTK+ << C++ IOStream operators for GTK+. Now with ORBing, numerical computation, audio client and more ...
Selection.H
Go to the documentation of this file.
1 /* Copyright 2000-2018 Matt Flax <flatmax@flatmax.org>
2  This file is part of GTK+ IOStream class set
3 
4  GTK+ IOStream is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or
7  (at your option) any later version.
8 
9  GTK+ IOStream is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You have received a copy of the GNU General Public License
15  along with GTK+ IOStream
16  */
17 
18 #ifndef SELECTION_H_
19 #define SELECTION_H_
20 #if GTK_MAJOR_VERSION>2
21 #error "Support not ready for GTK major version > 2"
22 #endif
23 
24 #include <iomanip>
25 #include <utility>
26 #include <gtk/gtk.h>
27 
28 #include <string.h>
29 #include <string>
30 
31 #include "mffm/LinkList.H"
32 
33 using namespace std;
34 
40 class SelectionColumn : public LinkList<pair<string *, GType> *> {
41  GtkTreeViewColumn *column;
42  int number;
43 public:
48  SelectionColumn(const char*title, int number_) {
49  number=number_;
50  column=gtk_tree_view_column_new();
51  gtk_tree_view_column_set_title (column, title);
52  setTitleAlignment(0.5);
53  }
54 
57  virtual ~SelectionColumn(void) {
58  while (getCount()) { // free up the string pointers in the inherited LinkList<string*>
59  pair<string *, GType> *deleteMe=remove();
60  delete deleteMe->first;
61  delete deleteMe;
62  }
63  }
64 
68  void setTitleAlignment(float align) {
69  gtk_tree_view_column_set_alignment(column, align);
70  }
71 
77  void setAlignment(float xAlign, float yAlign) {
78  GList*renderers=gtk_tree_view_column_get_cell_renderers(column);
79  for (unsigned int i=0;i<g_list_length(renderers);i++)
80  //g_object_set(GTK_CELL_RENDERER(g_list_nth_data(renderers,i)), "align-set", 1, "xalign", xAlign, "yalign", yAlign, NULL);
81  gtk_cell_renderer_set_alignment(GTK_CELL_RENDERER(g_list_nth_data(renderers,i)), xAlign, yAlign);
82  }
83 
84 // /* \brief Set the justification of the text column contents
85 // Justify the text renderer contents with respect to the edges of the column.
86 // param justification The justification 0.0 for left and 1.0 for right, (0.5 center).
87 // */
88 // void setJustification(float justification){
89 // GList*renderers=gtk_tree_view_column_get_cell_renderers(column);
90 // cout<<"flatmax : setJustification : g_list_length(renderers) "<<g_list_length(renderers)<<endl;
91 // for (uint i=0;i<g_list_length(renderers);i++){
92 // cout<<"flatmax "<<i<<endl;
93 // g_object_set(GTK_CELL_RENDERER(g_list_nth_data(renderers,i)), "align-set", 1, "alignment", justification, NULL);
94 // //g_object_set(GTK_CELL_RENDERER(g_list_nth_data(renderers,i)), "xalign", justification, NULL);
95 // }
96 // }
97 
98 // /* \brief Set the justification of the text column contents
99 // Justify the text renderer contents with respect to the edges of the column.
100 // param justification The justification PangoAlignment = {PANGO_ALIGN_LEFT, PANGO_ALIGN_CENTER, PANGO_ALIGN_RIGHT};
101 // */
102 // void setJustification(PangoAlignment justification){
103 // GList*renderers=gtk_tree_view_column_get_cell_renderers(column);
104 // cout<<"flatmax : setJustification : g_list_length(renderers) "<<g_list_length(renderers)<<endl;
105 // for (uint i=0;i<g_list_length(renderers);i++){
106 // cout<<"flatmax "<<i<<endl;
107 // g_object_set(GTK_CELL_RENDERER_TEXT(g_list_nth_data(renderers,i)), "align-set", 1, "alignment", justification, NULL);
108 // ////g_object_set(GTK_CELL_RENDERER(g_list_nth_data(renderers,i)), "alignment", justification, NULL);
109 // }
110 // }
111 //
121  SelectionColumn &add(string *name, GType whichType, GtkCellRenderer *renderer, int source, gboolean expand=true) {
122  gtk_cell_renderer_set_alignment(renderer, 0.5,0.5); // place in the middle
123  LinkList<pair<string*,GType> *>::add(new pair<string*,GType>(name, whichType));
124  gtk_tree_view_column_pack_start (column, renderer, expand);
125  gtk_tree_view_column_add_attribute (column, renderer, name->c_str(), source);
126  return *this;
127  }
128 
129 // /** Add a renderer to the column.
130 // This operator uses this column as the source, and doesn't expand during render
131 // \param detail get<0>(detail) is the name, get<1>(detail) is the renderer, get<2>(detail) is the source, get<3>(detail) is the expansion
132 // */
133 // SelectionColumn &operator<<(tuple<string*, GtkCellRenderer*, int, gboolean> detail){
134 // return add(get<0>(detail),get<1>(detail),get<2>(detail),get<3>(detail));
135 // }
136 //
137 // /** Add a renderer to the column.
138 // This operator uses this column as the source, and doesn't expand during render
139 // \param detail get<0>(detail) is the name, get<1>(detail) is the renderer, get<2>(detail) is the source
140 // */
141 // SelectionColumn &operator<<(tuple<string*, GtkCellRenderer*, int> detail){
142 // return add(get<0>(detail),get<1>(detail),get<2>(detail));
143 // }
144 
149  SelectionColumn &operator<<(pair<string*, GtkCellRendererText*> detail) {
150  return add(detail.first,G_TYPE_STRING,(GtkCellRenderer *)detail.second, number);
151  }
152 
157  SelectionColumn &operator<<(pair<string*, GtkCellRendererPixbuf*> detail) {
158  return add(detail.first,GDK_TYPE_PIXBUF,(GtkCellRenderer *)detail.second, number);
159  }
160 
164  GtkTreeViewColumn *getColumn(void) {
165  return column;
166  }
167 
171  int getNumber(void) {
172  return number;
173  }
174 
185  void setSizing(GtkTreeViewColumnSizing sz){
186  gtk_tree_view_column_set_sizing(column,sz);
187  }
188 
193  GtkTreeViewColumnSizing getSizing(void){
194  return gtk_tree_view_column_get_sizing(column);
195  }
196 
197 };
198 
199 
238 class Selection : public LinkList<SelectionColumn *> {
239 
241 
244  void init(void) {
245  tree = gtk_tree_view_new();
246  changedHandlerID=0;
247  }
248 
249 // GtkTreeIter* getLastIter(void){
250 // GtkTreeIter *iter=new GtkTreeIter;
251 // GtkTreeStore *store = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(tree)));
252 //
253 // GtkTreeIter last;
254 // if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), iter)){
255 // cout<<"n children "<<gtk_tree_model_iter_n_children(GTK_TREE_MODEL(store), iter)<<endl;
256 // while (gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &last))
257 // (*iter)=last;
258 // } else{
259 // delete iter;
260 // return NULL;
261 // }
262 // return iter;
263 // }
264 
269  GtkTreeIter* getLastIter(GtkTreeStore *store=NULL) {
270  if (store==NULL) // get the local tree store
271  store = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(tree)));
272  GtkTreeIter* iter = new GtkTreeIter;
273  if (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), iter, NULL,gtk_tree_model_iter_n_children(GTK_TREE_MODEL(store), NULL)-1))
274  return iter;
275  else
276  return NULL;
277  }
278 
284  GtkTreeIter* appendRow(GtkTreeStore *store=NULL) {
285  if (store==NULL) // get the local tree store
286  store = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(tree)));
287  GtkTreeIter* iter=NULL;
288  if (store) {
289  iter=new GtkTreeIter;
290  if (iter)
291  gtk_tree_store_append(store, iter, NULL);
292  }
293  return iter;
294  }
295 
302  GtkTreeIter* appendNewIter(GtkTreeStore *store, gboolean sameRow, gboolean sameColumn) {
303  GtkTreeIter* iter=NULL;
304  if (!sameColumn)
305  next();
306  if (sameRow) { // find the correct column and add to the same row
307  iter=getLastIter(store);
308  }
309 
310  if (iter==NULL)
311  iter=appendRow(store);
312  return iter;
313  }
314 
315 protected:
316  GtkWidget *tree;
317  GtkTreeSelection *selection;
318 
323  if (!getCount())
324  return -1;
325  int which=0;
326  if (getCount()!=1){
327  SelectionColumn *currentCol=current(); // remember the current column number
328  grab(1);
329  prev(); // get the last column
330  while (next()!=currentCol) // keep getting the next unitl it is the same as the original state
331  which++;
332  }
333  return which; // return the column number, starting from zero, the LinkList's state is as it was upon entry
334  }
335 public:
336 
339  Selection(void) {
340  init();
341  }
342 
349  Selection(const char *listName, GCallback callback=NULL, void *data=NULL) {
350  init(listName, callback, data);
351  }
352 
353  virtual ~Selection(){
354  //cout<<"Selection::~Selection"<<endl;
355  }
356 
363  void init(const char *listName, GCallback callback=NULL, void *data=NULL) {
364  init();
365  selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree));
366 
367  SelectionColumn *sc= new SelectionColumn(listName, getCount()); // create the new column
368  // gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(tree), FALSE); // use this to hide the headers
369 
370  *sc<<pair<string*, GtkCellRendererText*>(new string("text"), GTK_CELL_RENDERER_TEXT(gtk_cell_renderer_text_new()));
371 
372  add(sc);
373 
374  if (callback && data)
375  setSelectionCallback("changed", callback, data);
376  else
377  setSelectionCallback(callback);
378  }
379 
383  void setSelectionCallback(GCallback callback) {
384  setSelectionCallback("changed", callback, this);
385  }
386 
392  void setSelectionCallback(const char *event, GCallback callback, gpointer data) {
393  changedHandlerID=g_signal_connect(selection, event, callback, data);
394  }
395 
407  void setTreeCallback(const char *event, GCallback callback, gpointer data) {
408  g_signal_connect(tree, event, G_CALLBACK(callback), data);
409  }
410 
413  void add(SelectionColumn *newCol) {
414  LinkList<SelectionColumn *>::add(newCol); // add to the list of columns
415 
416  gtk_tree_view_append_column(GTK_TREE_VIEW(tree), current()->getColumn());
417 
418  // find the types and create a new store, then attach to the current treeview
419  // find the total number of renderers.
420 // int rendCnt=0; // in the future support one column with many renderers
421 // for (int i=0;i<getCount();i++)
422 // rendCnt+=next()->getCount();
423 // GType types[rendCnt]; // create the type holder
424 // grab(1); prev(); // get the last column and iterate from there
425 // int index=0;
426 // for (int i=0;i<getCount();i++){
427 // for (int j=0; j<current()->getCount();j++){
428 // types[index++]=current()->next()->second;
429 // }
430 // next();
431 // }
432 
433  GType *types =new GType[getCount()]; // create the type holder
434  grab(1);
435  prev(); // get the last column and iterate from there
436  for (int i=0; i<getCount(); i++) {
437  types[i]=next()->current()->second;
438  }
439 
440  while (next()!=newCol) ; // get the linklist back to its original location
441 
442  GtkTreeStore *store = gtk_tree_store_newv(getCount(), types); // get the column type
443  gtk_tree_view_set_model(GTK_TREE_VIEW(tree), GTK_TREE_MODEL(store));
444  g_object_unref(store);
445  delete [] types;
446  selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree));
447  }
448 
453  void setCallbackAfter(GCallback callback, void *data) {
454  g_signal_connect_after(selection, "changed", G_CALLBACK(callback), data);
455  }
456 
459  GtkWidget *getWidget(void) {
460  return tree;
461  }
462 
465  void show(void) {
466  gtk_widget_show_all(tree);
467  }
468 
471  void hide(void) {
472  gtk_widget_hide(tree);
473  }
474 
478  void getSelection(char *value) {
479  string valueS;
480  getSelection(valueS);
481  strcpy(value,valueS.c_str());
482  }
483 
487  void getSelection(string &value){
488  GtkTreeIter iter;
489  GtkTreeModel *model;
490  char *val;
491 
492  int colNum=currentColumnNumber();
493  if (colNum>=0){
494  if (gtk_tree_selection_get_selected(GTK_TREE_SELECTION(selection), &model, &iter)) {
495  gtk_tree_model_get(model, &iter, colNum, &val, -1);
496  if (val)
497  value=val;
498  else
499  value.resize(0);
500  g_free(val);
501  }
502  }
503  }
504 
513  void add(const char *text, gboolean sameRow=false, gboolean sameColumn=true) {
514  GtkTreeStore *store = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(tree)));
515  GtkTreeIter* iter=appendNewIter(store, sameRow, sameColumn);
516 
517  int whichColumn=currentColumnNumber();
518  if (iter) {
519  gtk_tree_store_set(store, iter, whichColumn, text, -1);
520  delete iter;
521  }
522  }
523 
532  void add(GdkPixbuf *pixbuf, gboolean sameRow=false, gboolean sameColumn=true) {
533  GtkTreeStore *store = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(tree)));
534  GtkTreeIter* iter=appendNewIter(store, sameRow, sameColumn);
535 
536  int whichColumn=currentColumnNumber();
537  if (iter) {
538  gtk_tree_store_set(store, iter, whichColumn, pixbuf, -1);
539  delete iter;
540  }
541  }
542 
545  void clear(void) {
546  if (changedHandlerID)
547  g_signal_handler_block(selection, changedHandlerID);
548  //GtkTreeStore *store = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW (tree)));
549  GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree));
550  GtkTreeIter iter;
551 
552  if (gtk_tree_model_get_iter_first(model, &iter) == FALSE)
553  return;
554  gtk_tree_store_clear(GTK_TREE_STORE(model));
555 
556  if (changedHandlerID)
557  g_signal_handler_unblock(selection, changedHandlerID);
558  }
559 // /* add a pixbuf item to the selection column
560 // if you want to add to a different column, shift the inherited LinkList<SelectionColumn *> to the correct one.
561 // For example use one of these to locate the desired column prior to adding : LinkList<SelectionColumn *>::grab, LinkList<SelectionColumn *>::next, LinkList<SelectionColumn *>::prev
562 // \param firstColumn, which column to start with, 1 for the first column
563 // \return This Selection object
564 // */
565 // void addRow(int firstColumn, ...) {
566 // GtkTreeStore *store = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(tree)));
567 // GtkTreeIter* iter=appendNewIter(store, false, false);
568 // grab(firstColumn);
569 // va_list var_args;
570 // va_start (var_args, firstColumn);
571 // gtk_tree_store_set_valist (store, iter, var_args);
572 // va_end (var_args);
573 // }
574 
575 // /* add a list of items to the same row in each column - starting from the first column
576 // \param ll the LinkList of items to add to the list on the current row
577 // \return This Selection object
578 // */
579 // void add(LinkList<GValue> &ll) {
580 // // int whichColumn=currentColumnNumber(); // restore current column at the end
581 // GtkTreeIter iter;
582 // GtkTreeStore *store = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(tree)));
583 // int cols[ll.getCount()];
584 // GValue values[ll.getCount()];
585 //
586 // ll.grab(1); ll.prev(); // get the last element on the linked list
587 // for (int i=0;i<ll.getCount();i++){
588 // cols[i]=i;
589 // g_value_init (&values[i], next()->current->second); // setup the current type
590 // =ll.next();
591 // }
592 //
593 // gtk_tree_store_append(store, &iter, NULL);
594 // gtk_tree_store_set_valuesv(store, &iter, cols, values, ll.getCount());
596 // }
597 
604  Selection & operator<<(const string text) {
605  add(text.c_str());
606  return *this;
607  }
608 
615  Selection & operator<<(const char *text) {
616  add(text);
617  return *this;
618  }
619 
626  Selection & operator<<(GdkPixbuf *pixbuf) {
627  add(pixbuf);
628  return *this;
629  }
630 
631 // /* add a row with multiple items
632 // starts from row 0
633 // \param ll the LinkList of items to add
634 // \return This Selection object
635 // */
636 // Selection & operator<<(LinkList<void*> &ll) {
637 // add(ll);
638 // return *this;
639 // }
640 
646  add(newCol);
647  return *this;
648  }
649 
659  void selectRow(char *path){
660  GtkTreePath *pathLocal = gtk_tree_path_new_from_string (path);
661  //gtk_tree_view_row_activated(GTK_TREE_VIEW(tree), pathLocal, current()->getColumn());
662  gtk_tree_selection_select_path(selection, pathLocal);
663  }
664 };
665 #endif //SELECTION_H_
void selectRow(char *path)
Definition: Selection.H:659
GtkTreeIter * appendRow(GtkTreeStore *store=NULL)
Definition: Selection.H:284
Selection & operator<<(GdkPixbuf *pixbuf)
Definition: Selection.H:626
Selection & operator<<(SelectionColumn *newCol)
Definition: Selection.H:645
int number
The number of this column.
Definition: Selection.H:42
GtkTreeViewColumn * column
Definition: Selection.H:41
Selection(const char *listName, GCallback callback=NULL, void *data=NULL)
Definition: Selection.H:349
Selection GtkTreeView based widget Inherits from a LinkList of GtkTreeViewColumn* which allows modifi...
Definition: Selection.H:238
void hide(void)
Definition: Selection.H:471
virtual ~SelectionColumn(void)
Definition: Selection.H:57
GtkWidget * getWidget(void)
Definition: Selection.H:459
void setSelectionCallback(const char *event, GCallback callback, gpointer data)
Definition: Selection.H:392
STL namespace.
void init(const char *listName, GCallback callback=NULL, void *data=NULL)
Definition: Selection.H:363
GtkTreeSelection * selection
The tree selection box.
Definition: Selection.H:317
Selection & operator<<(const char *text)
Definition: Selection.H:615
void add(SelectionColumn *newCol)
Definition: Selection.H:413
void setTreeCallback(const char *event, GCallback callback, gpointer data)
Definition: Selection.H:407
gulong changedHandlerID
The callback handler id for when the selection is changed.
Definition: Selection.H:240
void add(GdkPixbuf *pixbuf, gboolean sameRow=false, gboolean sameColumn=true)
Definition: Selection.H:532
void setAlignment(float xAlign, float yAlign)
Set the alignment of the column contents Sets the alignment of the column contents - applies to all r...
Definition: Selection.H:77
void clear(void)
Definition: Selection.H:545
void init(void)
Definition: Selection.H:244
void setTitleAlignment(float align)
Set the alignment of the column title in the header Sets the alignment of the column heading to 0...
Definition: Selection.H:68
int getNumber(void)
Definition: Selection.H:171
void getSelection(char *value)
Definition: Selection.H:478
GtkWidget * tree
The tree of items for the selection widget.
Definition: Selection.H:316
void show(void)
Definition: Selection.H:465
virtual ~Selection()
Definition: Selection.H:353
void add(const char *text, gboolean sameRow=false, gboolean sameColumn=true)
Definition: Selection.H:513
SelectionColumn(const char *title, int number_)
Definition: Selection.H:48
void getSelection(string &value)
Definition: Selection.H:487
Selection & operator<<(const string text)
Definition: Selection.H:604
SelectionColumn & add(string *name, GType whichType, GtkCellRenderer *renderer, int source, gboolean expand=true)
Definition: Selection.H:121
GtkTreeIter * getLastIter(GtkTreeStore *store=NULL)
Definition: Selection.H:269
GtkTreeViewColumn * getColumn(void)
Definition: Selection.H:164
int currentColumnNumber(void)
Definition: Selection.H:322
void setSelectionCallback(GCallback callback)
Definition: Selection.H:383
Selection(void)
Definition: Selection.H:339
void setSizing(GtkTreeViewColumnSizing sz)
Definition: Selection.H:185
GtkTreeViewColumnSizing getSizing(void)
Definition: Selection.H:193
GtkTreeIter * appendNewIter(GtkTreeStore *store, gboolean sameRow, gboolean sameColumn)
Definition: Selection.H:302
void setCallbackAfter(GCallback callback, void *data)
change the callback data to be returned with the callback.
Definition: Selection.H:453
gtkIOStream: /tmp/gtkiostream/include/Selection.H Source File
GTK+ IOStream  Beta