/* Pertenece a la ficha _factorizar */ #include #include "cabecera.h" #define G_ASCII_DTOSTR_BUF_SIZE (29 + 10) #include #define _(String) gettext (String) GtkWidget *ventana1; GtkWidget *vbox1, *hbox1, *hbox3; GtkWidget *label1, *label3, *label4, *label6, *labelb1; GtkWidget *hseparator1, *hseparator2, *hseparator3; GtkWidget *entry1; GtkWidget *boton1, *boton2, *boton3; GtkWidget *scrolled_window, *scrolled_window2; GtkWidget *canvas; GnomeCanvasGroup *root; GnomeCanvasPoints *points; GtkTextBuffer *bufer, *bufer2; GtkTextTag *negrita, *cursiva, *subrayado; GtkTextTag *color_rojo, *color_verde, *color_azul; GtkTextTag *fondo_1, *fondo_2; GtkTextTag *fuente_10, *fuente_11, *fuente_12, *fuente_13, *fuente_14; GtkTextTag *superindice; GtkTextTagTable *tags, *tags2; GtkTextView *view, *view2; GtkTextIter start, end, inicio, final; gchar *numero; gint num_int; extern GArray *primos; extern gint num_primos; GString *etiqueta, *linea; gint dividendo; gint primo_actual, k; gdouble Cx, Cy; gboolean terminado=FALSE; gboolean primeravez=TRUE; extern GArray *factores; extern GArray *bases; extern GArray *exponentes; extern gint num_factores, num_bases; void crea_ventana_principal () { ventana1 = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_widget_set_size_request (GTK_WIDGET (ventana1), 700, 540); gtk_window_set_title (GTK_WINDOW (ventana1), _("gMatESO - Factorización")); gtk_window_set_resizable (GTK_WINDOW (ventana1), FALSE); g_signal_connect (G_OBJECT (ventana1), "delete_event", G_CALLBACK (exit), NULL); vbox1 = gtk_vbox_new (FALSE, 0); gtk_widget_show (vbox1); gtk_container_add (GTK_CONTAINER (ventana1), vbox1); gtk_container_set_border_width(GTK_CONTAINER (vbox1), 5); label1 = gtk_label_new (_("Factorización")); gtk_widget_show (label1); gtk_box_pack_start (GTK_BOX (vbox1), label1, FALSE, FALSE, 1); gtk_widget_set_size_request(GTK_WIDGET (label1), 780, 30); gtk_label_set_markup (GTK_LABEL(label1), _(" Factorización de un número natural ")); hseparator1 = gtk_hseparator_new (); gtk_widget_show (hseparator1); gtk_box_pack_start (GTK_BOX (vbox1), hseparator1, FALSE, FALSE, 1); scrolled_window2 = gtk_scrolled_window_new (NULL, NULL); gtk_widget_show (scrolled_window2); gtk_box_pack_start (GTK_BOX (vbox1), scrolled_window2, TRUE, TRUE, 1); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window2), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); tags = gtk_text_tag_table_new(); bufer = gtk_text_buffer_new(tags); view = GTK_TEXT_VIEW(gtk_text_view_new_with_buffer(bufer)); gtk_text_view_set_left_margin (view, 5); gtk_container_add (GTK_CONTAINER (scrolled_window2), GTK_WIDGET(view)); g_object_set(view, "wrap-mode", GTK_WRAP_WORD, NULL); gtk_widget_show (GTK_WIDGET(view)); gtk_text_buffer_set_text(bufer, _("\ Texto que aparece en el TextView\n"), -1); negrita = gtk_text_buffer_create_tag(bufer, "negrita", "weight", 500, NULL); cursiva = gtk_text_buffer_create_tag(bufer, "cursiva", "style", PANGO_STYLE_ITALIC, NULL); subrayado = gtk_text_buffer_create_tag(bufer, "subrayado", "underline", PANGO_UNDERLINE_SINGLE, NULL); color_rojo = gtk_text_buffer_create_tag(bufer, "color_rojo", "foreground", "#ff0000", NULL); color_verde = gtk_text_buffer_create_tag(bufer, "color_verde", "foreground", "#00aa00", NULL); color_azul = gtk_text_buffer_create_tag(bufer, "color_azul", "foreground", "#0000bb", NULL); fondo_1 = gtk_text_buffer_create_tag(bufer, "fondo_1", /* amarillo */ "background", "#fcfcc0", NULL); fondo_2 = gtk_text_buffer_create_tag(bufer, "fondo_2", /* grisecillo */ "background", "#fcfcf0", NULL); fuente_10 = gtk_text_buffer_create_tag(bufer, "fuente_10", "size", 10 * PANGO_SCALE, NULL); fuente_11 = gtk_text_buffer_create_tag(bufer, "fuente_11", "size", 11 * PANGO_SCALE, NULL); fuente_12 = gtk_text_buffer_create_tag(bufer, "fuente_12", "size", 12 * PANGO_SCALE, NULL); fuente_13 = gtk_text_buffer_create_tag(bufer, "fuente_13", "size", 13 * PANGO_SCALE, NULL); superindice = gtk_text_buffer_create_tag(bufer,"superindice", "rise", 4*PANGO_SCALE, NULL); gtk_text_buffer_set_text(bufer, "", -1); gtk_text_buffer_get_selection_bounds (bufer, &start, &end); gtk_text_buffer_insert_with_tags_by_name (bufer, &start, _(" Factorizar "), -1, "negrita","color_rojo", "fuente_11", NULL); gtk_text_buffer_insert_with_tags_by_name(bufer, &start, _("un número es descomponerlo en un producto de "), -1, "fuente_11", NULL); gtk_text_buffer_insert_with_tags_by_name(bufer, &start, _("factores primos\n"), -1, "negrita","fuente_11", NULL); gtk_text_buffer_insert_with_tags_by_name(bufer, &start, _(" Ejemplo: el número 6 factorizado sería: "), -1, "fuente_11", NULL); gtk_text_buffer_insert_with_tags_by_name(bufer, &start, _(" 6 = 2 · 3 "), -1, "negrita","fuente_11", "fondo_1", NULL); gtk_text_buffer_insert_with_tags_by_name(bufer, &start, _("(el 2 y el 3 son primos)\n El número 8 = 2 · 4 no está bien factorizado (pues el 4 no es primo). \n La forma correcta sería: "), -1 ,"fuente_11", NULL); gtk_text_buffer_insert_with_tags_by_name(bufer, &start, "8 = 2 · 2 · 2", -1, "negrita","fuente_11","fondo_1" , NULL); gtk_text_buffer_insert_with_tags_by_name(bufer, &start, _(" o también "), -1 ,"fuente_11", NULL); gtk_text_buffer_insert_with_tags_by_name(bufer, &start, "8 = 2", -1, "negrita","fuente_11", NULL); gtk_text_buffer_insert_with_tags_by_name(bufer, &start, "3", -1, "negrita","fuente_10","superindice",NULL); gtk_text_buffer_insert_with_tags_by_name(bufer, &start, _("\n\n Para factorizar un número lo dividimos entre el primer primo (empezamos por el 2, si no es divisible probamos con el 3, 5, 7, 11, ...) de forma que la división sea exacta.\nProcedemos igual con el cociente obtenido y cuando ya no sea divisible, pasamos al siguiente primo.\nTerminamos cuando el último cociente sea 1. Todos los divisores obtenidos son los factores"), -1, "fuente_10","fondo_2" ,NULL); gtk_text_view_set_editable (view, FALSE); hseparator2 = gtk_hseparator_new (); gtk_widget_show (hseparator2); gtk_box_pack_start (GTK_BOX (vbox1), hseparator2, FALSE, FALSE, 1); hbox1 = gtk_hbox_new (FALSE, 0); gtk_widget_show (hbox1); gtk_box_pack_start (GTK_BOX (vbox1), hbox1, FALSE, FALSE, 1); label3 = gtk_label_new ("Ejemplo: "); gtk_label_set_markup (GTK_LABEL(label3),_(" Ejemplo: ") ); gtk_widget_show (label3); gtk_box_pack_start (GTK_BOX (hbox1), label3, FALSE, FALSE, 1); label4 = gtk_label_new (""); gtk_label_set_markup (GTK_LABEL(label4),_("Factorizamos el número:")); gtk_widget_show (label4); gtk_box_pack_start (GTK_BOX (hbox1), label4, FALSE, FALSE, 1); entry1 = gtk_entry_new_with_max_length (5); gtk_entry_set_width_chars(GTK_ENTRY(entry1), 5); gtk_box_pack_start (GTK_BOX (hbox1), entry1, FALSE, FALSE, 1); gtk_widget_show (entry1); gtk_widget_grab_focus (entry1); boton1 = gtk_button_new (); gtk_widget_show (boton1); gtk_box_pack_start (GTK_BOX (hbox1), boton1, FALSE, FALSE, 15); labelb1=gtk_label_new(""); gtk_container_add (GTK_CONTAINER (boton1), labelb1); gtk_label_set_markup (GTK_LABEL(labelb1),_(" Factorizar ")); gtk_widget_show (labelb1); boton2=gtk_button_new_from_stock("gtk-go-forward"); gtk_box_pack_start (GTK_BOX (hbox1), boton2, FALSE, FALSE, 10); boton3=gtk_button_new_from_stock("gtk-goto-last"); gtk_box_pack_start (GTK_BOX (hbox1), boton3, FALSE, FALSE, 10); scrolled_window = gtk_scrolled_window_new (NULL, NULL); gtk_widget_show (scrolled_window); gtk_box_pack_start (GTK_BOX (vbox1), scrolled_window, TRUE, TRUE, 1); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); canvas = gnome_canvas_new_aa(); gtk_container_add(GTK_CONTAINER(scrolled_window), canvas); root = gnome_canvas_root(GNOME_CANVAS(canvas)); gnome_canvas_set_center_scroll_region (GNOME_CANVAS(canvas), FALSE); gnome_canvas_set_scroll_region (GNOME_CANVAS(canvas),0.0,0.0,660.0,500.0); gtk_widget_set_size_request(GTK_WIDGET (scrolled_window), -1, 195); tags2 = gtk_text_tag_table_new(); bufer2 = gtk_text_buffer_new(tags2); view2 = GTK_TEXT_VIEW(gtk_text_view_new_with_buffer(bufer2)); gtk_text_view_set_justification (view2, GTK_JUSTIFY_CENTER); gtk_text_view_set_editable (view2, FALSE); g_object_set(view2, "wrap-mode", GTK_WRAP_WORD, NULL); gnome_canvas_item_new(root, gnome_canvas_widget_get_type(), "widget", view2, "x", 300.0, "y",120.0, "width", 300.0, "height",60.0, NULL); fuente_13 = gtk_text_buffer_create_tag(bufer2, "fuente_13", "size", 13 * PANGO_SCALE, NULL); fuente_14 = gtk_text_buffer_create_tag(bufer2, "fuente_14", "size", 14 * PANGO_SCALE, NULL); superindice = gtk_text_buffer_create_tag(bufer2, "superindice", "rise", 6*PANGO_SCALE, NULL); hseparator3 = gtk_hseparator_new (); gtk_widget_show (hseparator3); gtk_box_pack_start (GTK_BOX (vbox1), hseparator3, FALSE, FALSE, 1); hbox3 = gtk_hbox_new (FALSE, 0); gtk_widget_show (hbox3); gtk_box_pack_start (GTK_BOX (vbox1), hbox3, FALSE, FALSE, 1); label6 = gtk_label_new (_("AYUDA: Teclea un número y pulsa 'FACTORIZAR'")); gtk_widget_show (label6); gtk_box_pack_start (GTK_BOX (hbox3), label6, FALSE, FALSE, 1); gchar *cadena_markup=_(" "); PangoAttrList *attrList; pango_parse_markup(cadena_markup, -1, 0, &attrList, NULL, NULL, NULL); gtk_label_set_attributes(GTK_LABEL(label6), attrList); GString *carpeta; gchar *texto; carpeta=g_string_new(NULL); g_string_append (carpeta, g_get_home_dir ()); g_string_append (carpeta, "/gmateso/estilos.rc"); texto = g_string_free (carpeta, FALSE); gtk_rc_parse(texto); gtk_widget_show (ventana1); return; } void conecta_senales () { gtk_signal_connect (GTK_OBJECT (boton1), "clicked", GTK_SIGNAL_FUNC (callback), NULL); gtk_signal_connect (GTK_OBJECT (boton2), "clicked", GTK_SIGNAL_FUNC (callback2), NULL); gtk_signal_connect (GTK_OBJECT (boton3), "clicked", GTK_SIGNAL_FUNC (callback3), NULL); g_signal_connect ((gpointer) entry1, "key_press_event", G_CALLBACK (on_entry1_key_press_event), NULL); gtk_signal_connect (GTK_OBJECT (entry1), "insert_text", GTK_SIGNAL_FUNC (insert_text_handler1), NULL); } gboolean on_entry1_key_press_event (GtkWidget *widget, GdkEventKey *event, gpointer user_data) { if ((event->keyval == 0xFF0D)||(event->keyval == 0xFF8D)) Aceptar(); return FALSE; } void insert_text_handler1 (GtkEditable *editable, const gchar *text, gint length, gint *position, gpointer data) { int i; GString *result; gboolean SI; result = g_string_new(""); for (i = 0; i < length; i++) { SI = FALSE; if (g_ascii_isdigit (text[i])) SI=TRUE; if (SI) g_string_append_c(result, text[i]); } g_signal_handlers_block_by_func (editable, (gpointer) insert_text_handler1, data); if (SI) gtk_editable_insert_text (editable, result->str, length, position); g_signal_handlers_unblock_by_func (editable, (gpointer) insert_text_handler1, data); g_signal_stop_emission_by_name (editable, "insert_text"); g_string_free (result, TRUE); } int captura_numero (gchar *numero) { gboolean semaforo = TRUE; GtkWidget *dialog; gint i; numero = gtk_editable_get_chars(GTK_EDITABLE(entry1),0,-1); /*capturamos numero */ for (i=0; icoords[0] = Cx+60; points->coords[1] = Cy-20; points->coords[2] = Cx+60; points->coords[3] = Cy+20; gnome_canvas_item_new(root, gnome_canvas_line_get_type(), "points", points, "fill_color_rgba", 0x000000ff, "width_units", 4.0, NULL); gnome_canvas_points_unref(points); } void dibuja_dividendo(gint numero) { gchar *texto ; GString *cadena; gchar *temporal; char buf[G_ASCII_DTOSTR_BUF_SIZE]; cadena=g_string_new(NULL); temporal=g_ascii_dtostr(buf, sizeof(buf), numero); g_string_append(cadena, temporal); switch (num_digitos(numero)) { case 1:g_string_prepend (cadena," "); break; case 2:g_string_prepend (cadena," "); break; case 3:g_string_prepend (cadena," "); break; case 4:g_string_prepend (cadena," "); break; } texto = g_string_free (cadena, FALSE); /* escribir el texto en el canvas */ gnome_canvas_item_new(root, gnome_canvas_text_get_type(), "size-points", 14.0, "markup", texto, "fill_color", "black", "x", Cx, "y", Cy, "anchor", GTK_ANCHOR_WEST, NULL); } void dibuja_divisor(gint numero) { gchar *texto ; GString *cadena; gchar *temporal; char buf[G_ASCII_DTOSTR_BUF_SIZE]; cadena=g_string_new(NULL); temporal=g_ascii_dtostr(buf, sizeof(buf), numero); g_string_append(cadena, temporal); texto = g_string_free (cadena, FALSE); /* escribir el texto en el canvas */ gnome_canvas_item_new(root, gnome_canvas_text_get_type(), "size-points", 14.0, "markup", texto, "fill_color", "black", "x", Cx+70, "y", Cy, "anchor", GTK_ANCHOR_WEST, NULL); } void avanza_scroll() { gtk_text_view_set_editable (view, FALSE); gtk_text_buffer_get_iter_at_offset( bufer, &start, -1 ); gtk_text_buffer_place_cursor( bufer, &start ); gtk_text_view_scroll_mark_onscreen (view, gtk_text_buffer_get_insert(bufer)); } void siguiente () { gboolean primo=FALSE; gint i; gchar *temporal; char buf[G_ASCII_DTOSTR_BUF_SIZE]; g_string_erase(linea,0,linea->len); if (dividendo!=1) { for (i=k; i<=num_primos; i++) if (dividendo==g_array_index(primos, gint, i)) { k=i; primo=TRUE; break; } if (dividendo%g_array_index(primos, gint, k)==0) { g_array_append_val (factores, g_array_index(primos, gint, k)); num_factores++; if (primeravez) dibuja_dividendo(dividendo); primeravez=FALSE; dibuja_divisor(g_array_index(primos, gint, k)); /*baja_linea*/ Cx=100.0; Cy=Cy+25.0; dibuja_dividendo(dividendo/g_array_index(primos, gint, k)); dibuja_raya(); g_string_append(linea, "El número "); temporal=g_ascii_dtostr(buf, sizeof(buf), dividendo); g_string_append(linea, temporal); if (primo) temporal=_(" es PRIMO "); else temporal=_(" es divisible por "); g_string_append(linea, temporal); if (primo) temporal=" ***** " ; else temporal=g_ascii_dtostr(buf, sizeof(buf), g_array_index(primos, gint, k)); g_string_append(linea, temporal); g_string_append(linea, _(": Dividimos --> ")); temporal=g_ascii_dtostr(buf, sizeof(buf), dividendo); g_string_append(linea, temporal); g_string_append(linea, " : "); temporal=g_ascii_dtostr(buf, sizeof(buf), g_array_index(primos, gint, k)); g_string_append(linea, temporal); g_string_append(linea, " = "); dividendo=dividendo/g_array_index(primos, gint, k); temporal=g_ascii_dtostr(buf, sizeof(buf), dividendo); g_string_append(linea, temporal); g_string_append(linea, "\n"); g_string_prepend(etiqueta, linea->str); gtk_text_view_set_editable (view, TRUE); if (primo) gtk_text_buffer_insert_with_tags_by_name (bufer, &start, linea->str, -1, "negrita","color_azul", "fuente_11", NULL); else gtk_text_buffer_insert_with_tags_by_name (bufer, &start, linea->str, -1, "negrita","color_verde", "fuente_11", NULL); avanza_scroll(); } else { if (primeravez) dibuja_dividendo(dividendo); primeravez=FALSE; g_string_append(linea, _("- El número ")); temporal=g_ascii_dtostr(buf, sizeof(buf), dividendo); g_string_append(linea, temporal); temporal=_(" NO es divisible por "); g_string_append(linea, temporal); temporal=g_ascii_dtostr(buf, sizeof(buf), g_array_index(primos, gint, k)); g_string_append(linea, temporal); g_string_append(linea, _(". Pasamos al siguiente primo\n")); k=k+1; g_string_prepend(etiqueta, linea->str); gtk_text_view_set_editable (view, TRUE); gtk_text_buffer_insert_with_tags_by_name (bufer, &start, linea->str, -1, "negrita","color_rojo", "fuente_11", NULL); avanza_scroll(); } } else { dibuja_dividendo(1); fin (); } } void Aceptar() { captura_numero(numero); gchar *temporal; char buf[G_ASCII_DTOSTR_BUF_SIZE]; primeravez=TRUE; gtk_widget_show(canvas); /*borrar el canvas con un rectángulo blanco*/ gtk_text_buffer_set_text(bufer2, "", -1); gnome_canvas_item_new(root, gnome_canvas_rect_get_type(), "x1", 0.0, /*cordenas de la */ "y1", 0.0, /*esquina sup-izq */ "x2", 660.0, /*ancho */ /*coord de la esquina inf-der*/ "y2", 2505.0, /*alto */ "fill_color_rgba", 0xffffffff, /*color de relleno*/ "outline_color_rgba", 0x000000ff, /*color del borde */ "width_units", 1.0, /*tamaño del borde*/ NULL); if (num_int>1) { gtk_widget_set_sensitive(boton1, FALSE); lista_primos (num_int); if (num_int==g_array_index(primos, gint, num_primos)) /* si el número es primo */ { gtk_text_view_set_editable (view, TRUE); gtk_text_buffer_insert_with_tags_by_name (bufer, &start, "\n---------------------------------------------------------------------------\n", -1, "fuente_13", NULL); temporal=g_ascii_dtostr(buf, sizeof(buf), num_int); gtk_text_buffer_insert_with_tags_by_name (bufer, &start, _(" -- El número "), -1, "fuente_12", NULL); gtk_text_buffer_insert_with_tags_by_name (bufer, &start, temporal, -1, "fuente_13", "color_rojo", "negrita", NULL); gtk_text_buffer_insert_with_tags_by_name (bufer, &start, _(" es PRIMO (ya está factorizado) --\n"), -1, "fuente_12", NULL); avanza_scroll(); gtk_widget_set_sensitive(boton1, TRUE); } else { crea_arrays(); num_factores=0; Cx=100.0; Cy=30.0; terminado=FALSE; gtk_entry_set_editable (GTK_ENTRY(entry1), FALSE); gtk_widget_show(boton2); gtk_widget_grab_focus (boton2); gtk_widget_show(boton3); gtk_label_set_markup (GTK_LABEL(label6), _(" AYUDA: Pulsa Adelante para ir paso a paso. Pulsa Último para llegar hasta el final ")); etiqueta=g_string_new(NULL); linea=g_string_new(NULL); dividendo=num_int; k=1; primo_actual=g_array_index(primos, gint, k); dibuja_raya(); gtk_text_view_set_editable (view, TRUE); gtk_text_buffer_insert_with_tags_by_name (bufer, &start, "\n---------------------------------------------------------------------------\n", -1, "fuente_13", NULL); avanza_scroll(); siguiente(); } /* fin de else */ } else { GtkWidget *dialog; dialog = gtk_message_dialog_new (GTK_WINDOW (ventana1), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, _(" Introduce un número mayor que 1 ")); gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); gtk_entry_set_editable (GTK_ENTRY(entry1), TRUE); } } /*fin de calback factorizar*/ void callback (GtkWidget *widget, gchar data) { Aceptar(); } void callback2 (GtkWidget *widget, gchar data) { siguiente(); } void callback3 (GtkWidget *widget, gchar data) /*al pulsar |==> */ { while (!terminado) siguiente(); gtk_widget_set_sensitive(boton1, TRUE); }