eb05362005-11-05Henrik Grubbström (Grubba) /* -*- C -*- */
1a05542005-07-28Martin Nilsson class GTK2.TreeStore;
bfacff2006-02-06Lance Dillon inherit G.Object;
1a05542005-07-28Martin Nilsson inherit GTK2.TreeModel;
bcc6be2006-02-03Lance Dillon inherit GTK2.TreeSortable;
b5fd0c2006-02-04Lance Dillon inherit GTK2.TreeDragSource;
bfacff2006-02-06Lance Dillon inherit GTK2.TreeDragDest;
1a05542005-07-28Martin Nilsson  //! A tree-like data structure that can be used with W(TreeView). void create(array(mixed) types) //! Create a new tree store with as many columns as there are items in the //! array. A type is either a string representing a type name, such as "int" or //! "float", or an actual widget. If it is a widget, the column in question //! should be a widget of the same type that you would like this column to //! represent. {
ba9e802006-02-27Martin Stjernholm  pgtk2_verify_not_inited(); pgtk2_verify_setup();
1a05542005-07-28Martin Nilsson  { /* GType *types; */ struct array *a; struct store_data *sd; int i;
96f5f42018-08-05Martin Nilsson  get_all_args(NULL,args,"%A",&a);
1a05542005-07-28Martin Nilsson  if (a==NULL) Pike_error("Invalid argument.\n"); if (a->size) { sd=(struct store_data *)g_malloc(sizeof(struct store_data)); if (sd==NULL) SIMPLE_OUT_OF_MEMORY_ERROR("create",sizeof(struct store_data)); sd->types=g_malloc(sizeof(GType)*a->size);
32353e2005-12-30Martin Nilsson  if (sd->types==NULL) { g_free(sd);
1a05542005-07-28Martin Nilsson  SIMPLE_OUT_OF_MEMORY_ERROR("create",sizeof(GType)*a->size);
32353e2005-12-30Martin Nilsson  }
1a05542005-07-28Martin Nilsson  } else Pike_error("Invalid size of array.\n"); for (i=sd->n_cols=0; i<a->size; i++) {
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(ITEM(a)[i]) == PIKE_T_STRING) {
8ae5a42006-01-07Martin Nilsson  const struct pike_string *str = (ITEM(a)+i)->u.string;
6a932b2014-08-18Martin Nilsson  if (str == literal_int_string) {
1a05542005-07-28Martin Nilsson  sd->types[sd->n_cols++]=G_TYPE_INT;
8ae5a42006-01-07Martin Nilsson  } else if (is_same_string(_STR("uint"),str)) {
1a05542005-07-28Martin Nilsson  sd->types[sd->n_cols++]=G_TYPE_UINT;
6a932b2014-08-18Martin Nilsson  } else if (str == literal_float_string) {
1a05542005-07-28Martin Nilsson  sd->types[sd->n_cols++]=G_TYPE_FLOAT;
8ae5a42006-01-07Martin Nilsson  } else if (is_same_string(_STR("double"),str)) {
1a05542005-07-28Martin Nilsson  sd->types[sd->n_cols++]=G_TYPE_DOUBLE;
8ae5a42006-01-07Martin Nilsson  } else if (is_same_string(_STR("boolean"),str)) {
1a05542005-07-28Martin Nilsson  sd->types[sd->n_cols++]=G_TYPE_BOOLEAN;
8ae5a42006-01-07Martin Nilsson  } else if (is_same_string(_STR("long"),str)) {
1a05542005-07-28Martin Nilsson  sd->types[sd->n_cols++]=G_TYPE_LONG;
8ae5a42006-01-07Martin Nilsson  } else if (is_same_string(_STR("ulong"),str)) {
1a05542005-07-28Martin Nilsson  sd->types[sd->n_cols++]=G_TYPE_ULONG;
6a932b2014-08-18Martin Nilsson  } else if (str == literal_string_string) {
1a05542005-07-28Martin Nilsson  sd->types[sd->n_cols++]=G_TYPE_STRING;
8ae5a42006-01-07Martin Nilsson  } else if (is_same_string(_STR("char"),str)) {
1a05542005-07-28Martin Nilsson  sd->types[sd->n_cols++]=G_TYPE_CHAR;
8ae5a42006-01-07Martin Nilsson  } else if (is_same_string(_STR("uchar"),str)) {
1a05542005-07-28Martin Nilsson  sd->types[sd->n_cols++]=G_TYPE_UCHAR;
6a932b2014-08-18Martin Nilsson  } else if (str == literal_object_string) {
1a05542005-07-28Martin Nilsson  sd->types[sd->n_cols++]=G_TYPE_POINTER; } else {
8ae5a42006-01-07Martin Nilsson  sd->types[sd->n_cols]=g_type_from_name(CGSTR0((ITEM(a)+i)->u.string));
1a05542005-07-28Martin Nilsson  if (sd->types[sd->n_cols]==0) break; sd->n_cols++; }
017b572011-10-28Henrik Grubbström (Grubba)  } else if (TYPEOF(ITEM(a)[i]) == PIKE_T_OBJECT) {
1a05542005-07-28Martin Nilsson  struct object *o1=(ITEM(a)+i)->u.object; sd->types[sd->n_cols++]=G_OBJECT_TYPE(get_gobject(o1)); } } if (sd->n_cols) {
3d76632005-11-03Lance Dillon  GtkTreeStore *gt; gt=gtk_tree_store_newv(sd->n_cols,sd->types); THIS->obj=G_OBJECT(gt);
1a05542005-07-28Martin Nilsson  g_object_set_data_full(THIS->obj,"store-data",sd,
ba9e802006-02-27Martin Stjernholm  (GDestroyNotify)pgtk2_destroy_store_data);
1a05542005-07-28Martin Nilsson  } else { Pike_error("No valid types\n"); } }
ba9e802006-02-27Martin Stjernholm  pgtk2_pop_n_elems(args); pgtk2__init_this_object();
1a05542005-07-28Martin Nilsson } void set_row(GTK2.TreeIter iter, array(mixed) values) //! Set the data in an entire row. {
ba9e802006-02-27Martin Stjernholm  pgtk2_verify_inited();
1a05542005-07-28Martin Nilsson  { struct object *o1; struct array *a; struct store_data *sd;
412de22008-01-23Per Hedbor  GValue gv={0};
1a05542005-07-28Martin Nilsson  struct svalue *sv; int i;
96f5f42018-08-05Martin Nilsson  get_all_args(NULL,args,"%o%A",&o1,&a);
1a05542005-07-28Martin Nilsson  if (a==NULL) Pike_error("Invalid array.\n"); sd=g_object_get_data(G_OBJECT(THIS->obj),"store-data"); if (!sd) Pike_error("store-data not found.\n"); for (i=0; i<(a->size>sd->n_cols?sd->n_cols:a->size); i++) { /*
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(ITEM(a)[i]) == PIKE_T_STRING)
1a05542005-07-28Martin Nilsson  fprintf(stderr,"set_row: val==%s\n",STR0((ITEM(a)+i)->u.string)); */
ba9e802006-02-27Martin Stjernholm  pgtk2_set_gvalue(&gv,sd->types[i],(ITEM(a)+i));
1a05542005-07-28Martin Nilsson  gtk_tree_store_set_value(GTK_TREE_STORE(THIS->obj),
ba9e802006-02-27Martin Stjernholm  (GtkTreeIter *)get_pg2object(o1,pgtk2_tree_iter_program),i,&gv);
1a05542005-07-28Martin Nilsson  g_value_unset(&gv); } } RETURN_THIS(); } void set_value(GTK2.TreeIter iter, int column, mixed value) //! Set the data in the cell specified by iter and column. {
ba9e802006-02-27Martin Stjernholm  pgtk2_verify_inited();
1a05542005-07-28Martin Nilsson  { struct object *o1; INT_TYPE col; struct svalue *sv; struct store_data *sd;
412de22008-01-23Per Hedbor  GValue gv={0};
96f5f42018-08-05Martin Nilsson  get_all_args(NULL,args,"%o%i%*",&o1,&col,&sv);
1a05542005-07-28Martin Nilsson  sd=g_object_get_data(G_OBJECT(THIS->obj),"store-data"); if (!sd) Pike_error("store-data not found.\n");
ba9e802006-02-27Martin Stjernholm  pgtk2_set_gvalue(&gv,sd->types[col],sv);
1a05542005-07-28Martin Nilsson  gtk_tree_store_set_value(GTK_TREE_STORE(THIS->obj),
ba9e802006-02-27Martin Stjernholm  (GtkTreeIter *)get_pg2object(o1,pgtk2_tree_iter_program),
1a05542005-07-28Martin Nilsson  col,&gv); g_value_unset(&gv); } RETURN_THIS(); } void remove(GTK2.TreeIter iter) //! Remove iter. //! iter is set to the next valid row at that level, //! or invalidated if it was the last one. {
ba9e802006-02-27Martin Stjernholm  pgtk2_verify_inited();
1a05542005-07-28Martin Nilsson  { struct object *o1;
96f5f42018-08-05Martin Nilsson  get_all_args(NULL,args,"%o",&o1);
1a05542005-07-28Martin Nilsson  gtk_tree_store_remove(GTK_TREE_STORE(THIS->obj),
ba9e802006-02-27Martin Stjernholm  (GtkTreeIter *)get_pg2object(o1,pgtk2_tree_iter_program));
1a05542005-07-28Martin Nilsson  } RETURN_THIS(); }
f284492006-08-03Lance Dillon +GTK2.TreeIter insert(GTK2.TreeIter parent, int position)
1a05542005-07-28Martin Nilsson //! Insert a row at position. If parent is valid, will create as child, //! otherwise at top level. If position is larger than then number //! of rows at that level, it will be added to the end of the list. //! iter will be changed to point to the new row. {
ba9e802006-02-27Martin Stjernholm  pgtk2_verify_inited();
1a05542005-07-28Martin Nilsson  { struct object *o1;
cac4202005-12-17Marcus Comstedt  INT_TYPE pos;
1a05542005-07-28Martin Nilsson  GtkTreeIter *gt;
96f5f42018-08-05Martin Nilsson  get_all_args(NULL,args,"%o%i",&o1,&pos);
1a05542005-07-28Martin Nilsson  gt=(GtkTreeIter *)g_malloc(sizeof(GtkTreeIter)); if (gt==NULL) SIMPLE_OUT_OF_MEMORY_ERROR("insert",sizeof(GtkTreeIter)); gtk_tree_store_insert(GTK_TREE_STORE(THIS->obj),
ba9e802006-02-27Martin Stjernholm  gt,(GtkTreeIter *)get_pg2object(o1,pgtk2_tree_iter_program),pos); pgtk2_pop_n_elems(args);
2fa8a62008-04-11Per Hedbor  push_pgdk2object(gt,pgtk2_tree_iter_program,1);
1a05542005-07-28Martin Nilsson  } }
f284492006-08-03Lance Dillon +GTK2.TreeIter insert_before(?GTK2.TreeIter parent, ?GTK2.TreeIter sibling)
1a05542005-07-28Martin Nilsson //! Insert a row before sibling. If sibling is 0, then the //! row will be appended to parent's children. If parent and //! sibling are 0, then the row will be appended to the toplevel. {
ba9e802006-02-27Martin Stjernholm  pgtk2_verify_inited();
1a05542005-07-28Martin Nilsson  { struct object *o1,*o2; GtkTreeIter *gt; o1=o2=NULL;
96f5f42018-08-05Martin Nilsson  get_all_args(NULL,args,"%o.%o",&o1,&o2);
1a05542005-07-28Martin Nilsson  gt=(GtkTreeIter *)g_malloc(sizeof(GtkTreeIter)); if (gt==NULL) SIMPLE_OUT_OF_MEMORY_ERROR("insert_before",sizeof(GtkTreeIter)); gtk_tree_store_insert_before(GTK_TREE_STORE(THIS->obj), gt,
ba9e802006-02-27Martin Stjernholm  (GtkTreeIter *)get_pg2object(o1,pgtk2_tree_iter_program), (GtkTreeIter *)get_pg2object(o2,pgtk2_tree_iter_program)); pgtk2_pop_n_elems(args);
2fa8a62008-04-11Per Hedbor  push_pgdk2object(gt,pgtk2_tree_iter_program,1);
1a05542005-07-28Martin Nilsson  } }
f284492006-08-03Lance Dillon +GTK2.TreeIter insert_after(?GTK2.TreeIter parent, ?GTK2.TreeIter sibling)
1a05542005-07-28Martin Nilsson //! Insert a new row after sibling. If sibling is 0, then the row //! will be prepended to parent's children. If parent and sibling //! are both 0, then the row will be prepended to the toplevel. {
ba9e802006-02-27Martin Stjernholm  pgtk2_verify_inited();
1a05542005-07-28Martin Nilsson  { struct object *o1,*o2; GtkTreeIter *gt; o1=o2=NULL;
96f5f42018-08-05Martin Nilsson  get_all_args(NULL,args,"%o.%o",&o1,&o2);
1a05542005-07-28Martin Nilsson  gt=(GtkTreeIter *)g_malloc(sizeof(GtkTreeIter)); if (gt==NULL) SIMPLE_OUT_OF_MEMORY_ERROR("insert_after",sizeof(GtkTreeIter)); gtk_tree_store_insert_before(GTK_TREE_STORE(THIS->obj), gt,
ba9e802006-02-27Martin Stjernholm  (GtkTreeIter *)get_pg2object(o1,pgtk2_tree_iter_program), (GtkTreeIter *)get_pg2object(o2,pgtk2_tree_iter_program)); pgtk2_pop_n_elems(args);
2fa8a62008-04-11Per Hedbor  push_pgdk2object(gt,pgtk2_tree_iter_program,1);
1a05542005-07-28Martin Nilsson  } }
f284492006-08-03Lance Dillon +GTK2.TreeIter prepend(?GTK2.TreeIter parent)
1a05542005-07-28Martin Nilsson //! Prepend a new row. If parent is valid, then it will prepend //! the new row before the first child of parent, otherwise it will //! prepend a new row to the toplevel. {
ba9e802006-02-27Martin Stjernholm  pgtk2_verify_inited();
1a05542005-07-28Martin Nilsson  {
4a7cc12005-12-28Martin Nilsson  struct object *o1=NULL;
1a05542005-07-28Martin Nilsson  GtkTreeIter *gt;
96f5f42018-08-05Martin Nilsson  get_all_args(NULL,args,".%o",&o1);
1a05542005-07-28Martin Nilsson  gt=(GtkTreeIter *)g_malloc(sizeof(GtkTreeIter)); if (gt==NULL) SIMPLE_OUT_OF_MEMORY_ERROR("prepend",sizeof(GtkTreeIter)); gtk_tree_store_prepend(GTK_TREE_STORE(THIS->obj),
ba9e802006-02-27Martin Stjernholm  gt, (GtkTreeIter *)get_pg2object(o1,pgtk2_tree_iter_program)); pgtk2_pop_n_elems(args);
2fa8a62008-04-11Per Hedbor  push_pgdk2object(gt,pgtk2_tree_iter_program,1);
1a05542005-07-28Martin Nilsson  } }
f284492006-08-03Lance Dillon +GTK2.TreeIter append(?GTK2.TreeIter parent)
1a05542005-07-28Martin Nilsson //! Append a new row. If parent is valid, then it will append //! the new row after the last child, otherwise it will append //! a row to the toplevel. {
ba9e802006-02-27Martin Stjernholm  pgtk2_verify_inited();
1a05542005-07-28Martin Nilsson  {
4a7cc12005-12-28Martin Nilsson  struct object *o1=NULL;
1a05542005-07-28Martin Nilsson  GtkTreeIter *gt;
96f5f42018-08-05Martin Nilsson  get_all_args(NULL,args,".%o",&o1);
1a05542005-07-28Martin Nilsson  gt=(GtkTreeIter *)g_malloc(sizeof(GtkTreeIter)); if (gt==NULL) SIMPLE_OUT_OF_MEMORY_ERROR("append",sizeof(GtkTreeIter)); gtk_tree_store_append(GTK_TREE_STORE(THIS->obj),
ba9e802006-02-27Martin Stjernholm  gt,(GtkTreeIter *)get_pg2object(o1,pgtk2_tree_iter_program)); pgtk2_pop_n_elems(args);
2fa8a62008-04-11Per Hedbor  push_pgdk2object(gt,pgtk2_tree_iter_program,1);
1a05542005-07-28Martin Nilsson  } } int is_ancestor(GTK2.TreeIter iter, GTK2.TreeIter descendant) //! Returns true if iter is an ancestor of descendant. {
ba9e802006-02-27Martin Stjernholm  pgtk2_verify_inited();
1a05542005-07-28Martin Nilsson  { struct object *o1,*o2; int res;
96f5f42018-08-05Martin Nilsson  get_all_args(NULL,args,"%o%o",&o1,&o2);
1a05542005-07-28Martin Nilsson  res=gtk_tree_store_is_ancestor(GTK_TREE_STORE(THIS->obj),
ba9e802006-02-27Martin Stjernholm  (GtkTreeIter *)get_pg2object(o1,pgtk2_tree_iter_program), (GtkTreeIter *)get_pg2object(o2,pgtk2_tree_iter_program)); pgtk2_pop_n_elems(args);
1a05542005-07-28Martin Nilsson  if (res) push_int(1); else push_int(0); } } int iter_depth(GTK2.TreeIter iter) //! Get the depth of iter. This will be 0 for anything //! on the root level, 1 for anything down a level, and //! so on. {
ba9e802006-02-27Martin Stjernholm  pgtk2_verify_inited();
1a05542005-07-28Martin Nilsson  { struct object *o1; int res;
96f5f42018-08-05Martin Nilsson  get_all_args(NULL,args,"%o",&o1);
1a05542005-07-28Martin Nilsson  res=gtk_tree_store_iter_depth(GTK_TREE_STORE(THIS->obj),
ba9e802006-02-27Martin Stjernholm  (GtkTreeIter *)get_pg2object(o1,pgtk2_tree_iter_program)); pgtk2_pop_n_elems(args);
1a05542005-07-28Martin Nilsson  if (res) push_int(res); else push_int(-1); } } void clear() //! Removes all rows. {
ba9e802006-02-27Martin Stjernholm  pgtk2_verify_inited();
1a05542005-07-28Martin Nilsson  gtk_tree_store_clear(GTK_TREE_STORE(THIS->obj)); RETURN_THIS(); } require gtk22; void swap(GTK2.TreeIter a, GTK2.TreeIter b) //! Swap 2 rows. Only works if this store is unsorted. {
ba9e802006-02-27Martin Stjernholm  pgtk2_verify_inited();
1a05542005-07-28Martin Nilsson  { struct object *o1,*o2;
96f5f42018-08-05Martin Nilsson  get_all_args(NULL,args,"%o%o",&o1,&o2);
1a05542005-07-28Martin Nilsson  gtk_tree_store_swap(GTK_TREE_STORE(THIS->obj),
ba9e802006-02-27Martin Stjernholm  (GtkTreeIter *)get_pg2object(o1,pgtk2_tree_iter_program), (GtkTreeIter *)get_pg2object(o2,pgtk2_tree_iter_program));
1a05542005-07-28Martin Nilsson  } RETURN_THIS(); } void move_before(GTK2.TreeIter iter, ?GTK2.TreeIter position) //! Moves iter to before position. These should be at the //! same level. This only works if the store is unsorted. //! If position is omitted, iter will be moved to the end //! of the level. {
ba9e802006-02-27Martin Stjernholm  pgtk2_verify_inited();
1a05542005-07-28Martin Nilsson  { struct object *o1,*o2; o2=NULL;
96f5f42018-08-05Martin Nilsson  get_all_args(NULL,args,"%o.%o",&o1,&o2);
1a05542005-07-28Martin Nilsson  gtk_tree_store_move_before(GTK_TREE_STORE(THIS->obj),
ba9e802006-02-27Martin Stjernholm  (GtkTreeIter *)get_pg2object(o1,pgtk2_tree_iter_program), (GtkTreeIter *)get_pg2object(o2,pgtk2_tree_iter_program));
1a05542005-07-28Martin Nilsson  } RETURN_THIS(); } void move_after(GTK2.TreeIter iter, ?GTK2.TreeIter position) //! Moves iter to after position. These should be at the //! same level. This only works if the store is unsorted. //! If position is omitted, iter will be moved to the start //! of the level. {
ba9e802006-02-27Martin Stjernholm  pgtk2_verify_inited();
1a05542005-07-28Martin Nilsson  { struct object *o1,*o2; o2=NULL;
96f5f42018-08-05Martin Nilsson  get_all_args(NULL,args,"%o.%o",&o1,&o2);
1a05542005-07-28Martin Nilsson  gtk_tree_store_move_after(GTK_TREE_STORE(THIS->obj),
ba9e802006-02-27Martin Stjernholm  (GtkTreeIter *)get_pg2object(o1,pgtk2_tree_iter_program), (GtkTreeIter *)get_pg2object(o2,pgtk2_tree_iter_program));
1a05542005-07-28Martin Nilsson  } RETURN_THIS(); } endrequire;