From a898b096a5439d30375c43486a2e7eb1917b375f Mon Sep 17 00:00:00 2001 From: Jean Sirmai Date: Thu, 4 Jul 2024 22:29:34 +0200 Subject: [PATCH] WIP: creating a text_window: click the menu button & check get_STOCK_text in stock.c --- data/text/théorie.txt | 51 ++++++++++++++++++++++++++++++++++++++ include/callbacks.h | 2 ++ include/widgets.h | 6 +++++ src/callbacks.c | 16 +++++++++++- src/main.c | 1 + src/widget.c/heads.c | 57 +++++++++++++++++++++++++++++-------------- src/widget.c/stock.c | 21 ++++++++-------- 7 files changed, 125 insertions(+), 29 deletions(-) create mode 100644 data/text/théorie.txt diff --git a/data/text/théorie.txt b/data/text/théorie.txt new file mode 100644 index 0000000..755335b --- /dev/null +++ b/data/text/théorie.txt @@ -0,0 +1,51 @@ +Représentations des phénomènes par des réécritures de multigraphes géométriques. Propriétés, applications (déc 2017). + +Espace, objets. + +Gem-graph (une abréviation pour "graphes géométriques") permet de représenter par des dessins divers objets en interaction. Ces dessins peuvent ensuite être animés par un automate. Il est ainsi possible de modéliser des phénomènes complexes qu'il serait difficile de saisir par des équations. L'espace où ces dessins sont réalisés est dérivé d'un espace euclidien orthonormé. Il est homogène et isotrope mais doit être discrétisé pour pouvoir être traité automatiquement. Il est régulièrement pavé, c'est-à-dire composé d'unités juxtaposées toutes semblables appelées "cellules". +Les dessins sont effectués au moyen au moyen de symboles appelés "flèches". Une flèche va d'une cellule à une autre. Les flèches sont représentées dans la cellule d'où elles partent (la cellule origine). Pour ce faire, chaque cellule possède des sites. Chaque site est dirigé vers une cellule cible voisine et une seule. Le nombre et l'attribution des sites définit le voisinage. La cellule origine peut également être sa propre cible. Toutes les cellules ont le même nombre et la même disposition de leurs sites. Chaque cellule peut avoir au plus autant de sites qu'il y a d'autres cellules dans l'espace. Chaque site peut contenir zéro, une ou plusieurs flèches. Qu'elle soit désignée (ciblée) ou non par une ou éventuellement plusieurs flèches provenant de cellules voisines, une cellule peut elle-même contenir zéro, une ou plusieurs flèches réparties dans ses propres sites. Le nombre et la disposition des flèches qu'une cellule émet vers ses voisines et vers elle-même est donc indépendant du nombre et de la disposition de celles qu'elle reçoit. + +Toute distribution de flèches dans l'ensemble des sites de toutes les cellules de l'espace réalise un graphe et définit un état de l'espace. Aucun autre symbole que les flèches n'intervient dans cette définition. + +Un objet est une partie connexe isolée de ce graphe. Chaque état de l'espace, sauf si cet espace est complètement vide ou saturé, décrit au moins un objet. Le nombre et la forme des objets qui peuvent être représentés ne sont limités que par les dimensions de l'espace. Il peut s'agir de monomères, polymères, cordes, nœuds, surfaces, volumes, cavités, etc. et ils peuvent être associés dans le même espace pour décrire des structures de plus en plus complexes (solides, fluides, membranes, compartiments, machines élémentaires, etc.). Leurs combinaisons permettent donc de représenter simultanément et dans le même espace un grand nombre de situations diverses. Toutes ces représentations n'utilisent qu'un seul et même symbole: la flèche. + +Règles de transition. + +Les règles de transition font évoluer ces situations. Chaque règle de transition associe plusieurs règles élémentaires dans un ordre quelconque. Chaque règle élémentaire associe une condition et une assignation. Les deux concernent le même site dans la même cellule. Une condition associe les coordonnées d'un site dans une cellule à un nombre (c). Si le nombre de flèches de ce site est égal à (c), alors la condition est satisfaite. Sinon, elle ne l'est pas. Une assignation associe les coordonnées d'un site dans une cellule à un nombre (a). Si l'assignation est réalisée, alors le nombre de flèches qui contient ce site devient égal à (a). Une règle élémentaire peut modifier ou non l'état de l'espace. Une règle de transition doit comporter au moins une règle élémentaire et ne doit pas en comporter plus d'une concernant un même site. + +Chaque règle de transition définit deux états de l'espace : un initial et un final. Elle les définit complètement si elle combine autant de règles élémentaires qu'il y a de sites dans l'espace. Sinon, elle les définit partiellement ou localement. Inversement, pour toute paire formée de deux états quelconques de l'espace, il existe toujours une règle et une seule qui décrit la transition du premier à l'autre. + +La réécriture du graphe permet d'associer à chaque objet ou groupe d'objets un mouvement, une déformation, un transport ou une transformation qui lui confère des propriétés variées : force, flexibilité, élasticité, perméabilité, fluidité, viscosité, etc... Des flèches dirigées vers des cellules vides peuvent être utilisées pour générer des connexions aléatoires qui peuvent mimer des défauts structurels ou des mutations. Grâce à ces approximations, de multiples interactions entre une grande variété d'objets peuvent être décrites simultanément dans un même modèle. + +Propriétés des règles de transition. + +Pour tout état, il existe une seule règle de transition neutre qui ne modifie pas cet état. Toute règle de transition a une seule règle inverse qui produit son état initial à partir de son état final. Étant donné deux états (1) et (2) il existe toujours au moins une règle de transition produisant l'état (2) à partir de l'état (1) L'une de ces règles est la plus simple possible. Étant donné deux règles (a) et (b) dont l'état final de (a) est égal à l'état initial de (b), il existe une seule règle (c) (dite "composée") qui va de l'état initial de (a) à l'état final de (b). Si cette règle (c) fait partie de l'automate, le passage par l'état entre (a) et (b) est facultatif. Sinon, il est nécessaire. Dans ce cas, la règle (a) sera toujours exécutée avant la règle (b). Par conséquent, la propriété modélisée par la règle (a) peut être interprétée comme une cause de la propriété modélisée par la règle (b). Étant donné trois règles (a), (b) et (c) avec l'état final de (a) égal à l'état initial de (b) et l'état final de (b) égal à l'état initial de (c), il existe une seule règle de transition de l'état initial de (a) à l'état final (c). Cette règle peut être produite par les compositions successives de (a * b) * c ainsi que de a * (b * c). (associativité) L'aire d'une règle est constituée par l'ensemble des cellules contenant un site sur lequel il existe une condition à condition qu'aucune cellule ne soit modifiée par une assignation sans avoir été préalablement testée par au moins une condition. + +Automate. + +Un automate spatial est un ensemble de règles de transition associées à un état initial de l'espace. Toute l'information statique est dans l'espace. Toute l'information dynamique est dans les règles. L'automate n'utilise aucune autre information. Il doit contenir au moins une règle de transition et ne doit pas en associer deux identiques. Les transitions sont locales et asynchrones. Elles peuvent être réalisées en parallèle si leurs espaces d'application ne se chevauchent pas. Elles sont des processus de Markov. Lors d'une transition, toutes les règles de transition sont évaluées. Si plusieurs peuvent s'appliquer, l'une d'entre elles est choisie au hasard ou selon tout autre algorithme. + +Arbre des conditions. + +Toutes les règles de transition d'un même automate peuvent être regroupées en un seul arbre : l'arbre des conditions. Cet arbre peut être créé automatiquement à partir d'une liste de règles. Chaque règle est inscrite dans l'arbre sous la forme d'un chemin allant de la racine à une feuille. Ce chemin liste toutes les conditions qui doivent être remplies pour que cette règle de transition soit appliquée. Dans chaque chemin, l'ordre des conditions est le même. Il fait référence à un ordre défini précédemment sur l'ensemble des sites de toutes les cellules où une règle élémentaire peut s'appliquer. Cet ordre est le même pour toutes les règles. A chaque noeud, chaque règle de transition suit la branche dont le numéro est égal au nombre de flèches qui ont satisfait à sa condition pour ce site. Deux règles suivent le même chemin à partir de la racine tant qu'elles partagent les mêmes conditions. Lorsqu'elles diffèrent sur une condition, elles suivent alors deux branches différentes. A chaque site sur lequel une règle a une condition correspond au moins un noeud. Chaque nœud peut avoir autant de branches qu'il peut y avoir de flèches dans un site (y compris zéro) plus une. Cette branche, dite neutre, est suivie par les règles qui n'ont pas de condition sur ce site mais qui ont tout de même des conditions qui n'ont pas été évaluées jusqu'ici lors du parcours de l'arbre. + +Performances. + +La vitesse d'exécution de l'automate dépend de la profondeur moyenne de l'arbre des transitions et du nombre de branches neutres. Si toutes les situations possibles sont chacune décrites par une règle, il n'y a pas de branches neutres et la performance est proportionnelle à la profondeur moyenne de l'arbre des transitions. La profondeur maximale de l'arbre ne peut pas dépasser le nombre de sites que contient l'espace d'application de la règle (ou espace de travail). Si certaines situations possibles ne sont pas décrites par une règle, il y a des branches neutres. Dans ce cas, l'exploration de l'espace de travail peut ne conduire à aucun changement. Plus il y a de branches neutres, plus l'exploration de l'arbre est longue. En effet, les nœuds qui ont une branche neutre doivent éventuellement être explorés plusieurs fois. Cela se produit si l'exploration de leurs branches non neutres échoue ou si plusieurs transitions sont possibles à partir de ce nœud avec chacune une probabilité inférieure à 1 (leur somme étant égale à 1). La vitesse dépend aussi de la taille de la zone couverte par l'ensemble des règles de transition (l'espace de travail). Cette taille limite principalement le nombre de processus parallèles possibles dans l'espace. + +La granularité n'est pas fixée une fois pour toutes. Il est possible de gérer simultanément des objets ou parties d'objets proches et lointains en combinant des flèches de courte et longue portée. Celles-ci permettent de détailler des zones d'intérêt locales au sein d'une situation décrite de manière globale et d'associer différents niveaux de granularité jusqu'à une approximation d'un espace continu. En utilisant les flèches, il est également possible d'inscrire dans l'espace des étiquettes spécifiques qui peuvent être associées à n'importe quel objet ou situation. Cette technique permet de maintenir une séparation claire entre les informations statiques et dynamiques en utilisant des méthodes de reconnaissance de formes automatiques. Cette séparation est la condition d'une conception unique des règles qui permet, à son tour, leur réécriture automatique. + +Opérations sur les automates. + +Plusieurs automates peuvent être ajoutés (additionnés) les uns aux autres à condition que leurs espaces partagent la même dimension et le même pavage. Lors d'une opération d'addition, des objets provenant de modèles différents doivent être dessinés dans un nouvel espace (sans y être superposés) pour construire un nouvel état initial. Toutes les règles provenant des modèles à additionner peuvent être regroupées dans un même arbre puisqu'elles utilisent le même formalisme. Au cours du processus d'addition, des redondances ou des conflits peuvent apparaître. Il y a redondance lorsque deux règles provenant de modèles différents effectuent des opérations identiques sur des situations identiques. Dans ce cas, une seule instance de ces règles doit être conservée. Il y a conflit lorsque deux règles provenant de modèles différents effectuent des opérations différentes sur certains objets ou situations. Les règles peuvent être incomplètes ou inadéquates. Deux types de solutions sont alors possibles et non exclusives : modifier les formes des objets et/ou ajouter de nouvelles conditions à certaines règles afin de restreindre leur domaine d'application. Si les représentations des modèles sont correctes, alors les conflits révèlent une contradiction entre les modèles eux-mêmes : une opération effectuée par un modèle n'est pas compatible avec l'autre. Des conflits peuvent également apparaître lorsqu'un objet unique est associé à plusieurs tags différents (les tags peuvent être utilisés comme des clés). + +Un modèle gem-graph peut être associé à une description continue (par équations différentielles) d'une répartition de fermions (gradient, champ) et à des phénomènes décrits par des bosons. Dans ces deux cas, une condition et une action spécifique sont nécéssaires. + +Perspectives. + + Production automatique (par IA) d'ensembles de règles de transition à partir de la définition graphique des états initiaux et finaux. + Aide graphique pour l'édition de règles individuelles à partir de dessins schématiques de situations. + Ajout d'objets et de règles à partir de plusieurs modèles indépendants. Cette propriété pourrait permettre d'intégrer des modèles conçus ou développés par différentes équipes travaillant en parallèle sur des mécanismes distincts impliquant les mêmes objets. Les méta-règles pourraient aider à détecter les règles incomplètes ou incompatibles. + La production aléatoire de règles peut être utilisée pour simuler l'apprentissage de modèles ou des phénomènes évolutifs. Des méta-règles peuvent être utilisées pour éliminer les règles mal construites avant leur exécution. + + diff --git a/include/callbacks.h b/include/callbacks.h index 4733618..0b933ce 100644 --- a/include/callbacks.h +++ b/include/callbacks.h @@ -35,6 +35,7 @@ void on_main_window_activation (GtkApplication *app, gpointer user_data); void on_dialog_window_activation (GtkApplication *app, gpointer user_data); +void on_text_window_activation (GtkApplication *app, gpointer user_data); void on_toggle_EXEC_EDIT (GtkWidget *btt_XOR_EXEC_EDIT, gpointer user_data); void on_toggle_STATE_RULES_DATA (GtkWidget *btt, gpointer user_data); @@ -62,6 +63,7 @@ void on_axis_value_change (GtkAdjustment *adjustment, gpointer data); void on_reset_image (GtkWidget *btt_reset, gpointer data); void on_clicked_HOME (GtkWidget *btt_reset, gpointer data); +void on_clicked_X (GtkWidget *btt_reset, gpointer data); diff --git a/include/widgets.h b/include/widgets.h index b076131..827dd49 100644 --- a/include/widgets.h +++ b/include/widgets.h @@ -33,13 +33,17 @@ void set_main_window (GtkApplication *app); void set_dialog_window (GtkApplication *app); +void set_text_window (GtkApplication *app); void widget_MAIN_WINDOW_design (GtkWindow *main_window); void widget_DIALOG_WINDOW_design (GtkWindow *main_window, GtkWindow *dialog_window); +void widget_TEXT_WINDOW_design (GtkWindow *main_window, + GtkWindow *text_window); GtkWindow *get_main_window(); GtkWindow *get_dialog_window(); +GtkWindow *get_text_window(); GtkButton *get_GtkButton (char *btt_name); @@ -47,6 +51,8 @@ GtkWidget *widget_get_STATE_page(); GtkWidget *widget_get_RULES_page(); GtkWidget *widget_get_STOCK_page(); +GtkWidget *widget_get_STOCK_text (gchar *text_name, GtkTextView* text_view); + struct TreeNode_t {gchar *text; struct TreeNode_t *child, *next;}; void add_child_node (struct TreeNode_t *parent, struct TreeNode_t *child); struct TreeNode_t *create_user_tree_node (const gchar* text); diff --git a/src/callbacks.c b/src/callbacks.c index f369e4a..dad813d 100644 --- a/src/callbacks.c +++ b/src/callbacks.c @@ -52,6 +52,15 @@ void on_dialog_window_activation (GtkApplication *app, } +void on_text_window_activation (GtkApplication *app, + gpointer no_user_data) +{ + set_text_window (app); + widget_TEXT_WINDOW_design (get_main_window(), + get_text_window()); +} + + static void on_auto_notification (const char *message) { /* Ignored (2024-06-06) because I don't know how to get "main_window" easily @@ -307,10 +316,15 @@ void on_WRITE_CURRENT_MODEL (GtkWidget *btt_WRITE_CURRENT_MODEL, } void on_clicked_HOME (GtkWidget *btt_reset, gpointer data) { - printf ("on_clicked_HOME button presents the dialog_window ( :- ) but it works only once.\n"); + printf ("callback.on_clicked_HOME() button presents the dialog_window ( :- ) but it works only once.\n"); gtk_window_present (GTK_WINDOW (get_dialog_window())); // works once only ! } +void on_clicked_X (GtkWidget *btt_reset, gpointer data) { + printf ("ocallback.n_clicked_X button() presents the text_window ( :- ) but... it works only once.\n"); + gtk_window_present (GTK_WINDOW (get_text_window())); // works once only ! +} + void on_reset_image (GtkWidget *btt_reset, gpointer data) { printf ("callback.on_reset_image() <> Comment remettre tous les curseurs à zéro ?\n"); } diff --git a/src/main.c b/src/main.c index 78f4cee..8dd9cff 100644 --- a/src/main.c +++ b/src/main.c @@ -41,6 +41,7 @@ int main (int argc, char **argv) g_signal_connect (app, "activate", G_CALLBACK (on_main_window_activation), NULL); g_signal_connect (app, "activate", G_CALLBACK (on_dialog_window_activation), NULL); + g_signal_connect (app, "activate", G_CALLBACK (on_text_window_activation), NULL); status = g_application_run (G_APPLICATION (app), argc, argv); g_object_unref (app); diff --git a/src/widget.c/heads.c b/src/widget.c/heads.c index 199dee7..c4abab2 100644 --- a/src/widget.c/heads.c +++ b/src/widget.c/heads.c @@ -32,11 +32,12 @@ #include "../../include/callbacks.h" #include "../../include/widgets.h" -static GtkWindow *main_window, *dialog_window; -static GtkButton *btt_open_STATE, *btt_open_RULES, *btt_open_DATA; +static GtkWindow *main_window, *dialog_window, *text_window; +static GtkButton *btt_STATE, *btt_RULES, *btt_DATA; GtkWindow *get_main_window() {return main_window;} GtkWindow *get_dialog_window() {return dialog_window;} +GtkWindow *get_text_window() {return text_window;} void set_main_window (GtkApplication *app) { main_window = GTK_WINDOW (gtk_application_window_new (app)); @@ -46,15 +47,34 @@ void set_dialog_window (GtkApplication *app) { dialog_window = GTK_WINDOW (gtk_application_window_new (app)); } +void set_text_window (GtkApplication *app) { + text_window = GTK_WINDOW (gtk_application_window_new (app)); +} + GtkButton *get_GtkButton (char *btt_name) { - if (strcmp (btt_name, "state")) return btt_open_STATE; - if (strcmp (btt_name, "rules")) return btt_open_RULES; - if (strcmp (btt_name, "data analysis")) return btt_open_DATA; + if (strcmp (btt_name, "state")) return btt_STATE; + if (strcmp (btt_name, "rules")) return btt_RULES; + if (strcmp (btt_name, "data analysis")) return btt_DATA; return NULL; } //------------------------------------------------------------------------------ +void widget_TEXT_WINDOW_design (GtkWindow *main_window, GtkWindow *text_window){ + char *title = " Learn more about Gem Graph. "; + GtkWidget *header_bar = GTK_WIDGET (gtk_header_bar_new ()); + gtk_header_bar_set_title_widget (GTK_HEADER_BAR (header_bar), gtk_label_new (title)); + gtk_window_set_titlebar (text_window, header_bar); + + gchar *text_address = "/home/jean/Gem-Graph/gem-graph-client/data/text/théorie.txt"; + gtk_window_set_child (GTK_WINDOW (text_window), + GTK_WIDGET (widget_get_STOCK_text (text_address, + GTK_TEXT_VIEW (text_window)))); + + gtk_window_set_transient_for (GTK_WINDOW (text_window), GTK_WINDOW (main_window)); + gtk_window_set_destroy_with_parent (GTK_WINDOW (text_window), TRUE); +} + void widget_DIALOG_WINDOW_design (GtkWindow *main_window, GtkWindow *dialog_window){ char *title = " Save the current model before modifying it? "; GtkWidget *header_bar = GTK_WIDGET (gtk_header_bar_new ()); @@ -106,23 +126,23 @@ static void window_header_bar (GtkWindow *window, char *title){ GtkCheckButton *group_STATE_RULES_DATA = GTK_CHECK_BUTTON (gtk_check_button_new ()); - btt_open_STATE = GTK_BUTTON (gtk_check_button_new_with_label ("state")); - g_signal_connect (btt_open_STATE, "toggled", G_CALLBACK (on_toggle_STATE_RULES_DATA), no_local_data); - gtk_check_button_set_group (GTK_CHECK_BUTTON (btt_open_STATE), group_STATE_RULES_DATA); + btt_STATE = GTK_BUTTON (gtk_check_button_new_with_label ("state")); + g_signal_connect (btt_STATE, "toggled", G_CALLBACK (on_toggle_STATE_RULES_DATA), no_local_data); + gtk_check_button_set_group (GTK_CHECK_BUTTON (btt_STATE), group_STATE_RULES_DATA); - btt_open_RULES = GTK_BUTTON (gtk_check_button_new_with_label ("rules")); - g_signal_connect (btt_open_RULES, "toggled", G_CALLBACK (on_toggle_STATE_RULES_DATA), no_local_data); - gtk_check_button_set_group (GTK_CHECK_BUTTON (btt_open_RULES), group_STATE_RULES_DATA); + btt_RULES = GTK_BUTTON (gtk_check_button_new_with_label ("rules")); + g_signal_connect (btt_RULES, "toggled", G_CALLBACK (on_toggle_STATE_RULES_DATA), no_local_data); + gtk_check_button_set_group (GTK_CHECK_BUTTON (btt_RULES), group_STATE_RULES_DATA); - btt_open_DATA = GTK_BUTTON (gtk_check_button_new_with_label ("data analysis")); - g_signal_connect (btt_open_DATA, "toggled", G_CALLBACK (on_toggle_STATE_RULES_DATA), no_local_data); - gtk_check_button_set_group (GTK_CHECK_BUTTON (btt_open_DATA), group_STATE_RULES_DATA); + btt_DATA = GTK_BUTTON (gtk_check_button_new_with_label ("data analysis")); + g_signal_connect (btt_DATA, "toggled", G_CALLBACK (on_toggle_STATE_RULES_DATA), no_local_data); + gtk_check_button_set_group (GTK_CHECK_BUTTON (btt_DATA), group_STATE_RULES_DATA); gtk_header_bar_pack_start (GTK_HEADER_BAR (header_bar), GTK_WIDGET (btt_XOR_EXEC_EDIT)); gtk_header_bar_pack_start (GTK_HEADER_BAR (header_bar), GTK_WIDGET (any_Label)); - gtk_header_bar_pack_start (GTK_HEADER_BAR (header_bar), GTK_WIDGET (btt_open_STATE)); - gtk_header_bar_pack_start (GTK_HEADER_BAR (header_bar), GTK_WIDGET (btt_open_RULES)); - gtk_header_bar_pack_start (GTK_HEADER_BAR (header_bar), GTK_WIDGET (btt_open_DATA)); + gtk_header_bar_pack_start (GTK_HEADER_BAR (header_bar), GTK_WIDGET (btt_STATE)); + gtk_header_bar_pack_start (GTK_HEADER_BAR (header_bar), GTK_WIDGET (btt_RULES)); + gtk_header_bar_pack_start (GTK_HEADER_BAR (header_bar), GTK_WIDGET (btt_DATA)); // https://iconduck.com/sets/adwaita-icon-theme https://iconduck.com/sets/carbon-icons @@ -141,13 +161,14 @@ static void window_header_bar (GtkWindow *window, char *title){ GtkButton *open_menu = GTK_BUTTON (gtk_button_new ()); gtk_button_set_icon_name (open_menu, "open-menu-symbolic"); + g_signal_connect (open_menu, "clicked", G_CALLBACK (on_clicked_X), no_local_data); gtk_header_bar_pack_end (GTK_HEADER_BAR (header_bar), GTK_WIDGET (open_menu)); } void widget_MAIN_WINDOW_design (GtkWindow *main_window){ window_header_bar (main_window, "E coli (with permission from David S. Goodsell, 2009)"); - gtk_check_button_set_active (GTK_CHECK_BUTTON (btt_open_STATE), TRUE); + gtk_check_button_set_active (GTK_CHECK_BUTTON (btt_STATE), TRUE); gtk_window_present (GTK_WINDOW (main_window)); } diff --git a/src/widget.c/stock.c b/src/widget.c/stock.c index 0e97e29..a6fd675 100644 --- a/src/widget.c/stock.c +++ b/src/widget.c/stock.c @@ -64,16 +64,17 @@ GtkWidget *widget_get_STOCK_page () { return GTK_WIDGET (data_box); } - - - - - - - - - - +GtkWidget *widget_get_STOCK_text (gchar *text_address, GtkTextView* text_view) { + printf("widget_get_STOCK_text ():\ + building a child widget using the text address : [ %s ]\n", text_address); +// GtkWidget* child = gtk_text_view_new (); + GtkTextBuffer* buffer = gtk_text_buffer_new (NULL); + gtk_text_buffer_set_text (buffer, "a text", 6); +// gtk_text_view_set_buffer (GTK_TEXT_VIEW (text_view), buffer); // GTK_TEXT_BUFFER + gtk_text_buffer_set_modified (buffer, FALSE); +// return child; + return gtk_button_new_with_label (text_address); +}