[Buoh-dev] Parche para guardar un comic como jpeg
Carlos Garcia Campos
carlosgc at gnome.org
Wed Aug 17 06:08:46 MDT 2005
El mié, 17-08-2005 a las 01:03 +0200, Esteban Sánchez escribió:
> El mar, 16-08-2005 a las 19:40 +0200, Carlos Garcia Campos escribió:
> <snip>
>
> > > > > Index: src/buoh-view.c
> > > > >
> > > ===================================================================
> > > > > RCS file: /cvsroot/buoh/buoh/src/buoh-view.c,v
> > > > > retrieving revision 1.6
> > > > > diff -u -p -u -r1.6 buoh-view.c
> > > > > --- src/buoh-view.c 15 Aug 2005 15:04:09 -0000 1.6
> > > > > +++ src/buoh-view.c 15 Aug 2005 19:31:19 -0000
> > > > > @@ -587,3 +587,4 @@ buoh_view_clear (BuohView *view)
> > > > > {
> > > > > gtk_notebook_set_current_page (GTK_NOTEBOOK (view),
> > > > > VIEW_PAGE_EMPTY);
> > > > > }
> > > > > +
> > > >
> > > > interesante cambio :-DD
> > >
> > > Uno de esos que cambias sin querer... Creo que sigue compilando :P
> > > Ahora
> > > lo quito para que no salga en el parche (hay que hacer de nuevo
> > > autogen,
> > > sorry)
> >
> > era broma, eso pasa mucho
>
> Ups! Cuando dije lo del compilar era broma, lo del autogen era por el
> fichero po/Makefile.in.in que habia antes
>
> <snip>
> > > >
> > > > mania mia, pero prefiero que las cosas se vayan liberando segun se
> > > vayan
> > > > dejando de necesitar en vez de todo al final. Creo que es mas facil
> > > que
> > > > no se olvide nada, pero bueno, es mania mia, no digo que esté mal ni
> > > > mucho menos.
> >
> > mas abajo veras que mis manias tienen algo de sentido (lo siento pero es
> > que me lo has puesto a huevo con tu parche)
>
> Te lo he dejado a huevo xD
>
> <snip>
> > > > En cuanto al diálogo de error, tiene alguna posiblidad el usuario?
> > > por
> > > > que podría fallar? lo digo porque si algo falla y el usuario puede
> > > hacer
> > > > algo, en este caso se cerrarán el message_dialog y el fielchooser,
> > > con
> > > > lo que el user tendrá que volver a seleccionar guardar en el menu
> > > para
> > > > volver a intentarlo. Si hay posibilidad de rectificar para el
> > > usuario,
> > > > lo suyo es hacer un bucle y en caso de error volver a hacer el run
> > > para
> > > > que el usuario pueda volver a probar en el mismo filechooser.
> > >
> > > Podría fallar porque no tuviese permisos de escritura (prueba a
> > > guardar
> > > en /). Lo que no he conseguido es sacar el error, porque el
> > > gdk_pixbuf_save () falla si le pasas un GError (curioso).
> >
> > como declaras el error y como se lo pasas? porque funciona
> > perfectamente . . .
>
> GError *error;
> gdk_pixbuf_save (pixbuf, blah, bleh, &error, NULL);
>
> Intenté hacer un g_error_new () pero tiene parámetros que no sé ni lo
> que son, al final me fijé en el evince y tenia un NULL como una casa :P
exacto! eso es, de nuevo, una variable sin inicializar.
> > > Tienes razón con lo del bucle. No me di cuenta. Voy a cambiarlo.
> >
> > de nuevo se ve que lo has cambiado con prisas (lo comento abajo)
> >
> > > > > +static void
> > > > > buoh_window_menu_properties_cb (GtkMenuItem *menuitem, gpointer
> > > > > gdata)
> > > > > {
> > > > > BuohWindow *window = BUOH_WINDOW (gdata);
> > > > > @@ -556,6 +621,7 @@ buoh_window_comic_actions_set_sensitive
> > > > > buoh_window_zoom_out_set_sensitive (window, sensitive);
> > > > > buoh_window_normal_size_set_sensitive (window, sensitive);
> > > > > buoh_window_set_sensitive (window, "menu_properties",
> > > > > sensitive);
> > > > > + buoh_window_set_sensitive (window, "menu_save",
> > > sensitive);
> > > > > }
> > > > >
> > > > > static void
> > >
> > >
> > > Ahi va el nuevo parche
>
> >
> > > Index: interfaces/buoh.glade
> > > ===================================================================
> > > RCS file: /cvsroot/buoh/buoh/interfaces/buoh.glade,v
> > > retrieving revision 1.6
> > > diff -u -p -u -r1.6 buoh.glade
> > > --- interfaces/buoh.glade 26 Jul 2005 22:04:44 -0000 1.6
> > > +++ interfaces/buoh.glade 16 Aug 2005 14:30:58 -0000
> > > @@ -45,6 +45,27 @@
> > > </child>
> > >
> > > <child>
> > > + <widget class="GtkImageMenuItem" id="menu_save">
> > > + <property name="visible">True</property>
> > > + <property name="label"
> > > translatable="yes">_Guardar una copia</property>
> >
> > el nombre está en castellano?????
>
> Antes estuve con la práctica de isi y tuve un pequeño desliz :P
>
> > > + <property name="use_underline">True</property>
> > > + <signal name="activate"
> > > handler="on_menu_save_activate"/>
> > > +
> > > + <child internal-child="image">
> > > + <widget class="GtkImage" id="image248">
> > > + <property name="visible">True</property>
> > > + <property name="stock">gtk-save</property>
> > > + <property name="icon_size">1</property>
> > > + <property name="xalign">0.5</property>
> > > + <property name="yalign">0.5</property>
> > > + <property name="xpad">0</property>
> > > + <property name="ypad">0</property>
> > > + </widget>
> > > + </child>
> > > + </widget>
> > > + </child>
> > > +
> > > + <child>
> > > <widget class="GtkImageMenuItem"
> > > id="menu_properties">
> > > <property name="visible">True</property>
> > > <property name="label">gtk-properties</property>
> > > @@ -87,7 +108,7 @@
> > > <accelerator key="plus"
> > > modifiers="GDK_CONTROL_MASK" signal="activate"/>
> > >
> > > <child internal-child="image">
> > > - <widget class="GtkImage" id="image229">
> > > + <widget class="GtkImage" id="image249">
> > > <property name="visible">True</property>
> > > <property
> > > name="stock">gtk-zoom-in</property>
> > > <property name="icon_size">1</property>
> > > @@ -108,7 +129,7 @@
> > > <accelerator key="minus"
> > > modifiers="GDK_CONTROL_MASK" signal="activate"/>
> > >
> > > <child internal-child="image">
> > > - <widget class="GtkImage" id="image230">
> > > + <widget class="GtkImage" id="image250">
> > > <property name="visible">True</property>
> > > <property
> > > name="stock">gtk-zoom-out</property>
> > > <property name="icon_size">1</property>
> > > @@ -129,7 +150,7 @@
> > > <accelerator key="0"
> > > modifiers="GDK_CONTROL_MASK" signal="activate"/>
> > >
> > > <child internal-child="image">
> > > - <widget class="GtkImage" id="image231">
> > > + <widget class="GtkImage" id="image251">
> > > <property name="visible">True</property>
> > > <property
> > > name="stock">gtk-zoom-100</property>
> > > <property name="icon_size">1</property>
> > > @@ -163,7 +184,7 @@
> > > <accelerator key="Page_Up" modifiers="0"
> > > signal="activate"/>
> > >
> > > <child internal-child="image">
> > > - <widget class="GtkImage" id="image232">
> > > + <widget class="GtkImage" id="image252">
> > > <property name="visible">True</property>
> > > <property
> > > name="stock">gtk-go-back</property>
> > > <property name="icon_size">1</property>
> > > @@ -184,7 +205,7 @@
> > > <accelerator key="Page_Down" modifiers="0"
> > > signal="activate"/>
> > >
> > > <child internal-child="image">
> > > - <widget class="GtkImage" id="image233">
> > > + <widget class="GtkImage" id="image253">
> > > <property name="visible">True</property>
> > > <property
> > > name="stock">gtk-media-forward</property>
> > > <property name="icon_size">1</property>
> > > @@ -211,7 +232,7 @@
> > > <accelerator key="Home"
> > > modifiers="GDK_CONTROL_MASK" signal="activate"/>
> > >
> > > <child internal-child="image">
> > > - <widget class="GtkImage" id="image234">
> > > + <widget class="GtkImage" id="image254">
> > > <property name="visible">True</property>
> > > <property
> > > name="stock">gtk-goto-first</property>
> > > <property name="icon_size">1</property>
> > > @@ -232,7 +253,7 @@
> > > <accelerator key="End"
> > > modifiers="GDK_CONTROL_MASK" signal="activate"/>
> > >
> > > <child internal-child="image">
> > > - <widget class="GtkImage" id="image235">
> > > + <widget class="GtkImage" id="image255">
> > > <property name="visible">True</property>
> > > <property
> > > name="stock">gtk-goto-last</property>
> > > <property name="icon_size">1</property>
> > > Index: src/buoh-window.c
> > > ===================================================================
> > > RCS file: /cvsroot/buoh/buoh/src/buoh-window.c,v
> > > retrieving revision 1.5
> > > diff -u -p -u -r1.5 buoh-window.c
> > > --- src/buoh-window.c 5 Aug 2005 09:14:54 -0000 1.5
> > > +++ src/buoh-window.c 16 Aug 2005 14:31:02 -0000
> > > @@ -59,6 +59,8 @@ static void buoh_window_menu_quit_cb
> > > gpointer
> > > gdata);
> > > static void buoh_window_menu_add_cb (GtkMenuItem
> > > *menuitem,
> > > gpointer
> > > gdata);
> > > +static void buoh_window_menu_save_cb (GtkMenuItem
> > > *menuitem,
> > > + gpointer
> > > gdata);
> > > static void buoh_window_menu_properties_cb (GtkMenuItem
> > > *menuitem,
> > > gpointer
> > > gdata);
> > > static void buoh_window_menu_zoom_in_cb (GtkMenuItem
> > > *menuitem,
> > > @@ -242,6 +244,10 @@ buoh_window_init (BuohWindow *buoh_windo
> > > g_signal_connect (G_OBJECT (widget), "activate",
> > > G_CALLBACK (buoh_window_menu_add_cb),
> > > (gpointer) buoh_window);
> > > + widget = glade_xml_get_widget (buoh_window->priv->gui,
> > > "menu_save");
> > > + g_signal_connect (G_OBJECT (widget), "activate",
> > > + G_CALLBACK (buoh_window_menu_save_cb),
> > > + (gpointer) buoh_window);
> > > widget = glade_xml_get_widget (buoh_window->priv->gui,
> > > "menu_properties");
> > > g_signal_connect (G_OBJECT (widget), "activate",
> > > G_CALLBACK (buoh_window_menu_properties_cb),
> > > @@ -378,6 +384,82 @@ buoh_window_menu_add_cb (GtkMenuItem *me
> > > }
> > >
> > > static void
> > > +buoh_window_menu_save_cb (GtkMenuItem *menuitem, gpointer gdata)
> > > +{
> > > + GtkWidget *chooser;
> > > + GtkFileFilter *filter;
> > > + gchar *suggested;
> > > + gchar *name;
> > > + gchar *page;
> > > + gchar *filename;
> > > + static gchar *folder;
> >
> > al ser static tiene que tener inicialización, sino la primera vez
> > estarás haciendo un if de una vartiable sin inicializar (y encima es que
> > el compilador da un warning!!!)
>
> Hay un par de warnings de variables sin usar que me ocultaron ese
> otro :(
sip warnings que no quité porque me recuerdan que hay cosas por
implementar. Quizás con el TODO sobra, pero pensé que con esos warning
terminaría por implementar eso antes sólo por no ver mas los
warning :-DD
> > > + BuohWindow *window = BUOH_WINDOW (gdata);
> > > + BuohComic *comic;
> > > + GdkPixbuf *pixbuf;
> > > + GtkWidget *dialog;
> > > +
> > > + filter = gtk_file_filter_new ();
> > > + gtk_file_filter_add_pattern (filter, "*.jpg");
> > > + gtk_file_filter_add_pattern (filter, "*.jpeg");
> > > + gtk_file_filter_set_name (filter, _("JPEG Images"));
> > > +
> > > + chooser = gtk_file_chooser_dialog_new (_("Save comic"),
> > > + GTK_WINDOW (window),
> > > +
> > > GTK_FILE_CHOOSER_ACTION_SAVE,
> > > + GTK_STOCK_CANCEL,
> > > GTK_RESPONSE_CANCEL,
> > > + GTK_STOCK_SAVE,
> > > GTK_RESPONSE_ACCEPT,
> > > + NULL);
> > > + gtk_file_chooser_set_do_overwrite_confirmation
> > > (GTK_FILE_CHOOSER (chooser), TRUE);
> > > + gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser),
> > > filter);
> > > +
> > > + if (folder) {
> > > + gtk_file_chooser_set_current_folder_uri
> > > (GTK_FILE_CHOOSER (chooser),
> > > + folder);
> > > + }
> > > +
> > > + comic = buoh_view_get_comic (window->priv->view);
> > > + name = buoh_comic_get_title (comic);
> > > + page = buoh_comic_get_page (comic);
> > > + suggested = g_strconcat (name, " (", page, ").jpeg", NULL);
> > > +
> > > + gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (chooser),
> > > + suggested);
> > > + do {
> > > + if (gtk_dialog_run (GTK_DIALOG (chooser)) ==
> > > GTK_RESPONSE_ACCEPT) {
> > > + pixbuf = buoh_comic_get_pixbuf (comic);
> >
> > si hemos dicho que el dialogo es modal, el comic no va a cambiar, porque
> > pedir el pixbuf cada vez en caso que el bucle de mas de una vuelta? esto
> > sacalo mejor fuera. Además, si sacas el dialogo y cancelas no pasa por
> > aqui, con lo que a la salida estarás haciendo un unref de un pixbuf que
> > encima has declarado sin inicializar, esto no pasa si liberas el pixbuf
> > después de usarlo . . .
>
> Tenia más sentido sin el bucle, lo cambio y lo libero donde tu dices.
no, que no hay que liberarlo.
> > > + filename = gtk_file_chooser_get_filename
> > > (GTK_FILE_CHOOSER (chooser));
> >
> > de la misma manera si sales del bucle porque has cancelado el chooser la
> > variable filename que está declarada sin inicializar será liberada,
> > chungo. El g_free actua bien con variables a NULL, pero variables sin
> > inicializar tienen resultados inesperados. De nuevo esto no pasa si
> > liberas la variable después de usarla en lugar de todo al final
>
> Cambiado pues.
>
> > > +
> > > + if (folder != NULL)
> > > + g_free (folder);
> > > +
> > > + folder =
> > > gtk_file_chooser_get_current_folder_uri (GTK_FILE_CHOOSER (chooser));
> > > +
> > > + if (!gdk_pixbuf_save (pixbuf, filename,
> > > "jpeg", NULL, NULL)) {
> > > + dialog = gtk_message_dialog_new
> > > (GTK_WINDOW (window),
> >
> > su padre debería ser el chooser, no la ventana del buoh
>
> Cambiado
>
> > > +
> > > GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
> > > +
> > > GTK_MESSAGE_ERROR,
> > > +
> > > GTK_BUTTONS_CLOSE,
> > > +
> > > _("Unable to save comic"));
> >
> > usa un GError y muestra el mensaje que te devuelva. Además el diálogo no
> > respeta las HIG, debería llevar el texto principal en negrita
> > ( PANGO_WEIGHT_BOLD) y con letra mas grande (PANGO_SCALE_LARGE).
>
> Necesito ayuda con ambas cosas (el GError y el pango) pues no encuentro
> aplicaciones con eso :(
lo del GError es cuestión de inicializarlo a NULL.
GError *error = NULL;
gdk_pixbuf_save (pixbuf, filename, "jpeg", &error, NULL)
error->message
g_error_free (error);
Lo del diálogo HIG. Tienes dos formas de hacerlo:
* Por una lado si das formato al texto secundario, automáticamente se
tranforma el texto primario a negrita y grande. Como no tenemos texto
secundario, hay que formatear una cadena vacia. Desventajas: parece un
poco chapucero.
gtk_message_dialog_format_secondary_text (
GTK_MESSAGE_DIALOG (dialog), "
");
* Por otro lado, si miras el código del message dialog, tiene un campo
label (que apunta al texto primario) que es público. Puedes formatear
directamente esa label. El problema es que el atributo es público pero
está marcado como /* <private >*/ por lo que no se si se debería usar,
puede que en un futuro se haga private y nuestro código deje de
funcionar:
gint size;
PangoFontDescription *font_desc;
gtk_widget_modify_font (dialog->label, NULL);
size = pango_font_description_get_size
(dialog->label->style->font_desc);
font_desc = pango_font_description_new ();
pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
pango_font_description_set_size (font_desc, size * PANGO_SCALE_LARGE);
gtk_widget_modify_font (dialog->label, font_desc);
pango_font_description_free (font_desc);
Tu verás que forma te parece mas correcta . . .
> > > + gtk_dialog_run (GTK_DIALOG (dialog));
> > > + gtk_widget_destroy (dialog);
> > > + g_free (filename);
> > > + } else
> > > + break;
> > > + } else
> > > + break;
> > > + } while (1);
> > > +
> >
> > esto es un poco feo la verdad, quizás una variable booleana y quitar lo
> > breaks haría el código mas legible y comprensible.
>
> Si te digo que no sabia como llamar a la variable? Sé que es triste pero
> a veces me pasa... al final le he llamado "successful"
>
> > > + g_object_unref (pixbuf);
> >
> > buoh_comic_get_pixbuf no aumenta el contador de referencias al
> > devolverte el pixbuf, por lo que no hay motivo para decrementarlo aqui.
> >
> > > + g_free (filename);
> > > + g_free (name);
> > > + g_free (page);
> > > + g_free (suggested);
> > > + gtk_widget_destroy (chooser);
> > > + g_object_unref (filter);
> >
> > Creo que el filechooser no incrementa el contador de referencias y
> > libera él el filter al hacer el destroy, lo que es seguro es que aquí no
> > llega el filter.
>
> Pardiez! Me la han jugado mis suposiciones sobre los gtk_x_add_y
>
> > > +}
> > > +
> > > +static void
> > > buoh_window_menu_properties_cb (GtkMenuItem *menuitem, gpointer
> > > gdata)
> > > {
> > > BuohWindow *window = BUOH_WINDOW (gdata);
> > > @@ -556,6 +638,7 @@ buoh_window_comic_actions_set_sensitive
> > > buoh_window_zoom_out_set_sensitive (window, sensitive);
> > > buoh_window_normal_size_set_sensitive (window, sensitive);
> > > buoh_window_set_sensitive (window, "menu_properties",
> > > sensitive);
> > > + buoh_window_set_sensitive (window, "menu_save", sensitive);
> > > }
> > >
> > > static void
> >
> > hay una última cosa que se me olvidó mencionar. Existe un lokdown global
> > de gnome para los casos de guardar copia. el buoh, como aplicación de
> > GNOME, debería respetarlo. La clave de GConf correspondiente
> > es /desktop/gnome/lockdown/disable_save_to_disk
>
> Uoh!! No tenia ni idea :) ¿Te importa hacerte cargo una vez haya hecho
> commit del parche? Si para una cosa como "guardar" necesitamos un hilo
> de correos así imaginate para algo que lee una clave de GConf (ojú)
sin problemas
> Otra cosa que me he dado cuenta es de que los programas comparten una
> "memoria" de cual ha sido el ultimo path donde se ha usado el
> file-chooser. Por ejemplo si guardas una cosa con Epiphany
> en /home/yo/mis/cosas y luego guardas algo con Gedit, el file-chooser se
> abre en /home/yo/mis/cosas ¿Eso también está en GConf? Tiene toda la
> pinta
epiphany usa su propia clave ("/apps/epiphany/directories/open") a menos
que otros programas miren en su clave, creo que no hay ninguna
compartida de forma global. Para nuestro caso, creo que con mantener el
directorio de la sessión es suficiente. Si en el futuro nos vemos
obligados a añadir alguna clave de GConf del buoh podríamos plantearnos
añadir una para el diálogo de guardar propia del buoh.
> > Casi todos los errores vienen por la prisas, y por dejadez, porque
> > algunos te los dice el compilador y otros los escupe el propio buoh en
> > tiempo de ejecución, al menos ese tipo de errores se pueden evitar en
> > los parches. En algunas circunstancias incluso el buoh daba un fallo de
> > crash!!! eso quiere decir que los cambios no se han probado suficiente.
>
> Si fuese por dejadez ni enviaría el parche, así que es mejor decir
> prisas, ansias, interés y un poco de "argh! sé que puedo hacerlo" que
> conlleva estas cosas :)
quizás dejadez no es la palabra mas adecuada . . .
> No paro de recordar las charla de Fernando Herrera sobre gnome-love y su
> frase "y te tiras hasta las 3 de la mañana, le mandas tu maravilloso
> parche y te lo tira...". Ese es el "argh!" que siento, jejeje
pues eso está bien, pero una cosa no quita para que una vez que tienes
el código que funciona pierdas (en realidad ganes) 5 minutos en
probarlo. Ahorras trabajo al maintainer y en el futuro se fiará mas de
tus parches.
> > Igual os parece que soy muy exigente, pero si realmente queremos que el
> > buoh sea un programa de calidad y para aprender, creo que hay que serlo.
>
> Yo lo prefiero así, y de hecho a veces me parece que hasta abuso de ti
> (ouh yeah!). Mientras tengas paciencia y yo siga igual de borrico...
me alegro que pienses así, porque temía que lo tomaras a mal.
> Tu figura es curiosa, no eres oficialmente mantainer, pero de alguna
> manera recurrimos a ti para comprobar nuestros parches. ¿Hay que hacer
> un fichero ESPIRITUAL-GUIDES? jejejeje
bueno, maintainer no es solo revisar parches, también es hacer las
releases (con todo lo que ello conlleva), coordinar el equipo, etc. Yo
tan solo reviso los parches, en principio, hasta que no sea necesario.
> gtk_about_dialog_set_espiritual_guides ("kal");
>
> > Salu2
>
> Saludos
>
> No hay parche porque espero a que me guies con lo del GError y el Pango
hecho, sigo sin ver lo de guardar copia y exportar a otro formato, Hay
que llegar a un acuerdo de como hacerlo. Lo que es seguro es que guardar
copia no puede significar exportar a jpeg
> --
> Esteban Sánchez
> esteban at steve-0.com
> http://steve-o.org
> http://subanales.com/
> ------------------------------------------------
> PGP key: http://pgp.mit.edu:11371/pks/lookup?op=get&search=0xB6E0F8AF
Salu2
--
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Carlos Garcia Campos a.k.a. KaL
elkalmail at yahoo.es
carlosgc at gnome.org
http://carlosgc.linups.org
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
PGP key: http://pgp.mit.edu:11371/pks/lookup?op=get&search=0x523E6462
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part
Url : http://forge.novell.com/pipermail/buoh-dev/attachments/20050817/0300aff7/attachment.pgp
More information about the Buoh-dev
mailing list