[Buoh-dev] Parche para guardar un comic como jpeg

Carlos Garcia Campos carlosgc at gnome.org
Tue Aug 16 07:44:28 MDT 2005


El lun, 15-08-2005 a las 21:34 +0200, Esteban Sánchez escribió:
> Pues como hemos estado hablando antes de esto, al final me he picado y
> he hecho el guardar un comic a disco. Este es el código, espero
> opiniones :)

hay una cosa que no veo del todo claro. Por que se guarda solo en jpeg?
quiero decir, guardar una copia es pillar el comic y guardarlo tal cual
al disco. Si el comic es png o gif y se lo guardamos en jpeg en realidad
no estamos guardando una copia, lo estamos exportando a otro formato. Yo
creo que una de dos: o lo llamamos exportar a jpeg o tratamos de
respetar el formato que tiene. 

Para respetar el formato tenemos dos posibilidades: con gdk_pixbuf_save
y usando gdk_pixbuf_format_is_writable para ver si el formato está
soportado. Si lo está, se guarda y si no se le dice al usuario que el
formato no está soportado y que se exportará o algo así; la otra
posibilidad es bajar directamente el comic y guardarlo en disoc tal
cual, bit a bit y nos evitamos problemas de formatos.

Ahora paso de todas formas a comentarte cosas sobre el parche

> Saludos!
> -- 
> 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
> 
> 
> 
> 
> 
> 
> 
> diferencias entre
> ficheros adjunto
> (patch.diff)
> 
> ? Makefile
> ? Makefile.in
> ? aclocal.m4
> ? autom4te.cache
> ? config.guess
> ? config.h
> ? config.h.in
> ? config.log
> ? config.status
> ? config.sub
> ? configure
> ? depcomp
> ? install-sh
> ? intltool-extract
> ? intltool-extract.in
> ? intltool-merge
> ? intltool-merge.in
> ? intltool-update
> ? intltool-update.in
> ? libtool
> ? ltmain.sh
> ? missing
> ? mkinstalldirs
> ? stamp-h1
> ? data/Makefile
> ? data/Makefile.in
> ? interfaces/Makefile
> ? interfaces/Makefile.in
> ? pixmaps/Makefile
> ? pixmaps/Makefile.in
> ? po/Makefile
> ? po/Makefile.in
> ? po/POTFILES
> ? src/.deps
> ? src/Makefile
> ? src/Makefile.in
> ? src/buoh.desktop
> Index: ChangeLog
> ===================================================================
> RCS file: /cvsroot/buoh/buoh/ChangeLog,v
> retrieving revision 1.27
> diff -u -p -u -r1.27 ChangeLog
> --- ChangeLog   15 Aug 2005 15:04:09 -0000      1.27
> +++ ChangeLog   15 Aug 2005 19:31:14 -0000
> @@ -1,3 +1,10 @@
> +2005-08-15  Esteban Sanchez <esteban at steve-o.org>
> +
> +       * interface/buoh.glade: Added "Save a copy" menu
> +       
> +       * src/buoh-window.c: Added buoh_window_menu_save_cb for saving
> +       a comic to a jpg image
> +
>  2005-08-15  Carlos Garcia Campos  <carlosgc at gnome.org>
>  
>         * TODO: Updated
> 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       15 Aug 2005 19:31:17 -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>
> +                     <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: po/Makefile.in.in
> ===================================================================
> RCS file: /cvsroot/buoh/buoh/po/Makefile.in.in,v
> retrieving revision 1.2
> diff -u -p -u -r1.2 Makefile.in.in
> --- po/Makefile.in.in   4 Aug 2005 19:48:12 -0000       1.2
> +++ po/Makefile.in.in   15 Aug 2005 19:31:17 -0000
> @@ -32,13 +32,13 @@ VPATH = @srcdir@
>  prefix = @prefix@
>  exec_prefix = @exec_prefix@
>  datadir = @datadir@
> +datarootdir = @datarootdir@
>  libdir = @libdir@
>  localedir = $(libdir)/locale
>  gnulocaledir = $(datadir)/locale
>  gettextsrcdir = $(datadir)/glib-2.0/gettext/po
>  subdir = po
>  install_sh = @install_sh@
> -mkdir_p = @mkdir_p@
>  mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
>  
>  INSTALL = @INSTALL@

este es un fichero generado por el condifure y por lo tanto no debería
estar en el CVS (y menos es un parche)

> 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

> 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   15 Aug 2005 19:31:21 -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,65 @@ 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 = "juas.png";

juas.png??? que es esto tio?

> +       BuohWindow    *window = BUOH_WINDOW (gdata);
> +       BuohComic     *comic;
> +       GdkPixbuf     *pixbuf;
> +       GtkWidget     *dialog;
> +
> +       filter = gtk_file_filter_new ();
> +       gtk_file_filter_set_name (filter, _("JPEG Images"));

debes decirle al filtro cual es el patrón de los archivos además del
nombre

> +               
> +       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);
> +       
> +       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);
> +       
> +       if (gtk_dialog_run (GTK_DIALOG (chooser)) ==
> GTK_RESPONSE_ACCEPT)
> +       {

esa llave debería estar arriba

> +               pixbuf   = buoh_comic_get_pixbuf (comic);
> +               filename = gtk_file_chooser_get_filename
> (GTK_FILE_CHOOSER (chooser));
> +               
> +               if (!gdk_pixbuf_save (pixbuf, filename, "jpeg", NULL,
> NULL)) {
> +                       dialog = gtk_message_dialog_new (GTK_WINDOW
> (window),
> +
> GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
> +
> GTK_MESSAGE_ERROR,
> +
> GTK_BUTTONS_CLOSE,
> +                                                        _("Unable to
> save comic"));
> +                       gtk_dialog_run (dialog);
> +                       gtk_widget_destroy (dialog);
> +               }
> +               g_free (filename);
> +       }
> +
> +       g_object_unref (pixbuf);
> +       g_free (name);
> +       g_free (page);
> +       g_free (suggested);
> +       gtk_widget_destroy (chooser);
> +       g_object_unref (filter);

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.

> +}
> +

varias cosas sobre esta función. El filechooser debe ser un dialogo
modal. El tema es que cuando se ejecuta el callback, pillas el comic que
hay en la vista, ya que es el que se quiere guardar. Si el dialogo no es
modal, se podría cambiar el comic de la vista seleccionando otro de la
lista y sería confuso para el user saber que comic es el que se va a
guardar (que nosotros sabemos que es el que había cuando se seleccionó
el menu)

Por otro lado, si el usuario va a guardar varios comics es muy probable
que quiera guardarlos en la misma carpeta (por el principio de localidad
espacial, hoy estuve empollando AIC) por lo que conviene "recordar" el
último directorio accedido en la sessión. Para ello basta con usar una
variable static que guarde la uri de la carpeta.

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.

> +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

-- 
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 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/20050816/32712346/attachment.pgp


More information about the Buoh-dev mailing list