[gthumb] image_print: allow to specify the header and the footer of the pages



commit 6f063212bd564c3eca41eecd43bebd3de5c35dda
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Thu Feb 3 21:49:29 2011 +0100

    image_print: allow to specify the header and the footer of the pages
    
    Added ability to specify the header and the footer of the pages;
    added a new tab in the preferences dialog to specify the fonts
    of the header, the footer and the images caption.
    
    [new feature]

 extensions/image_print/Makefile.am                 |    1 +
 extensions/image_print/actions.c                   |    2 +-
 .../image_print/data/gthumb_image_print.schemas.in |   28 ++-
 extensions/image_print/data/ui/Makefile.am         |    2 +-
 extensions/image_print/data/ui/print-layout.ui     |  181 ++++++------
 .../image_print/data/ui/print-preferences.ui       |  171 +++++++++++
 extensions/image_print/gth-image-info.c            |    3 +
 extensions/image_print/gth-image-print-job.c       |  300 ++++++++++++++------
 extensions/image_print/main.c                      |    3 +
 extensions/image_print/preferences.c               |   97 +++++++
 extensions/image_print/preferences.h               |   23 ++-
 11 files changed, 629 insertions(+), 182 deletions(-)
---
diff --git a/extensions/image_print/Makefile.am b/extensions/image_print/Makefile.am
index 52b9c7d..026dc86 100644
--- a/extensions/image_print/Makefile.am
+++ b/extensions/image_print/Makefile.am
@@ -14,6 +14,7 @@ libimage_print_la_SOURCES = 		\
 	gth-image-print-job.h		\
 	gth-load-image-info-task.c	\
 	gth-load-image-info-task.h	\
+	preferences.c			\
 	preferences.h			\
 	main.c
 
diff --git a/extensions/image_print/actions.c b/extensions/image_print/actions.c
index c807736..58fe34d 100644
--- a/extensions/image_print/actions.c
+++ b/extensions/image_print/actions.c
@@ -64,7 +64,7 @@ gth_browser_activate_action_file_print (GtkAction  *action,
 						 GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
 						 browser);
 		else
-			_gtk_error_dialog_from_gerror_run (GTK_WINDOW (browser), _("Could not print the selected files"), &error);
+			_gtk_error_dialog_from_gerror_show (GTK_WINDOW (browser), _("Could not print the selected files"), &error);
 	}
 
 	_g_object_list_unref (file_list);
diff --git a/extensions/image_print/data/gthumb_image_print.schemas.in b/extensions/image_print/data/gthumb_image_print.schemas.in
index 80891e2..5d9504e 100644
--- a/extensions/image_print/data/gthumb_image_print.schemas.in
+++ b/extensions/image_print/data/gthumb_image_print.schemas.in
@@ -19,7 +19,33 @@
 	<applyto>/apps/gthumb/ext/image_print/font_name</applyto>
 	<owner>gthumb</owner>
 	<type>string</type>
-	<default>sans normal 10</default>
+	<default>sans normal 12</default>
+	<locale name="C">
+	  <short></short>
+	  <long>
+	  </long>
+	</locale>
+      </schema>
+
+      <schema>
+	<key>/schemas/apps/gthumb/ext/image_print/header_font_name</key>
+	<applyto>/apps/gthumb/ext/image_print/header_font_name</applyto>
+	<owner>gthumb</owner>
+	<type>string</type>
+	<default>sans bold 12</default>
+	<locale name="C">
+	  <short></short>
+	  <long>
+	  </long>
+	</locale>
+      </schema>
+
+      <schema>
+	<key>/schemas/apps/gthumb/ext/image_print/footer_font_name</key>
+	<applyto>/apps/gthumb/ext/image_print/footer_font_name</applyto>
+	<owner>gthumb</owner>
+	<type>string</type>
+	<default>sans normal 8</default>
 	<locale name="C">
 	  <short></short>
 	  <long>
diff --git a/extensions/image_print/data/ui/Makefile.am b/extensions/image_print/data/ui/Makefile.am
index 7b3e18e..ca017c4 100644
--- a/extensions/image_print/data/ui/Makefile.am
+++ b/extensions/image_print/data/ui/Makefile.am
@@ -1,5 +1,5 @@
 uidir = $(pkgdatadir)/ui
-ui_DATA = print-layout.ui
+ui_DATA = print-layout.ui print-preferences.ui
 EXTRA_DIST = $(ui_DATA)
 
 -include $(top_srcdir)/git.mk
diff --git a/extensions/image_print/data/ui/print-layout.ui b/extensions/image_print/data/ui/print-layout.ui
index 39edf46..4f59d29 100644
--- a/extensions/image_print/data/ui/print-layout.ui
+++ b/extensions/image_print/data/ui/print-layout.ui
@@ -80,6 +80,69 @@
         <property name="visible">True</property>
         <property name="spacing">12</property>
         <child>
+          <object class="GtkTable" id="table3">
+            <property name="visible">True</property>
+            <property name="n_rows">2</property>
+            <property name="n_columns">2</property>
+            <property name="column_spacing">6</property>
+            <property name="row_spacing">6</property>
+            <child>
+              <object class="GtkLabel" id="label8">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">_Header:</property>
+                <property name="use_underline">True</property>
+                <property name="mnemonic_widget">header_entry</property>
+              </object>
+              <packing>
+                <property name="x_options">GTK_FILL</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel" id="label12">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">_Footer:</property>
+                <property name="use_underline">True</property>
+                <property name="mnemonic_widget">footer_entry</property>
+              </object>
+              <packing>
+                <property name="top_attach">1</property>
+                <property name="bottom_attach">2</property>
+                <property name="x_options">GTK_FILL</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkEntry" id="header_entry">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="invisible_char">&#x25CF;</property>
+              </object>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="right_attach">2</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkEntry" id="footer_entry">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="invisible_char">&#x25CF;</property>
+              </object>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="right_attach">2</property>
+                <property name="top_attach">1</property>
+                <property name="bottom_attach">2</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
           <object class="GtkVBox" id="vbox2">
             <property name="visible">True</property>
             <property name="spacing">6</property>
@@ -123,39 +186,35 @@
                         <property name="column_spacing">6</property>
                         <property name="row_spacing">6</property>
                         <child>
-                          <object class="GtkLabel" id="label9">
+                          <object class="GtkSpinButton" id="columns_spinbutton">
                             <property name="visible">True</property>
-                            <property name="xalign">0</property>
-                            <property name="label" translatable="yes">_Rows:</property>
-                            <property name="use_underline">True</property>
-                            <property name="mnemonic_widget">rows_spinbutton</property>
+                            <property name="can_focus">True</property>
+                            <property name="invisible_char">&#x25CF;</property>
+                            <property name="width_chars">6</property>
+                            <property name="adjustment">columns_adjustment</property>
+                            <property name="climb_rate">1</property>
                           </object>
                           <packing>
+                            <property name="left_attach">1</property>
+                            <property name="right_attach">2</property>
+                            <property name="top_attach">1</property>
+                            <property name="bottom_attach">2</property>
                             <property name="x_options">GTK_FILL</property>
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkHBox" id="hbox10">
+                          <object class="GtkSpinButton" id="rows_spinbutton">
                             <property name="visible">True</property>
-                            <property name="spacing">6</property>
-                            <child>
-                              <object class="GtkSpinButton" id="rows_spinbutton">
-                                <property name="visible">True</property>
-                                <property name="can_focus">True</property>
-                                <property name="invisible_char">&#x25CF;</property>
-                                <property name="width_chars">6</property>
-                                <property name="adjustment">rows_adjustment</property>
-                                <property name="climb_rate">1</property>
-                              </object>
-                              <packing>
-                                <property name="expand">False</property>
-                                <property name="position">0</property>
-                              </packing>
-                            </child>
+                            <property name="can_focus">True</property>
+                            <property name="invisible_char">&#x25CF;</property>
+                            <property name="width_chars">6</property>
+                            <property name="adjustment">rows_adjustment</property>
+                            <property name="climb_rate">1</property>
                           </object>
                           <packing>
                             <property name="left_attach">1</property>
                             <property name="right_attach">2</property>
+                            <property name="x_options">GTK_FILL</property>
                           </packing>
                         </child>
                         <child>
@@ -164,7 +223,6 @@
                             <property name="xalign">0</property>
                             <property name="label" translatable="yes">Columns:</property>
                             <property name="use_underline">True</property>
-                            <property name="mnemonic_widget">columns_spinbutton</property>
                           </object>
                           <packing>
                             <property name="top_attach">1</property>
@@ -173,29 +231,14 @@
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkHBox" id="hbox12">
+                          <object class="GtkLabel" id="label9">
                             <property name="visible">True</property>
-                            <property name="spacing">6</property>
-                            <child>
-                              <object class="GtkSpinButton" id="columns_spinbutton">
-                                <property name="visible">True</property>
-                                <property name="can_focus">True</property>
-                                <property name="invisible_char">&#x25CF;</property>
-                                <property name="width_chars">6</property>
-                                <property name="adjustment">columns_adjustment</property>
-                                <property name="climb_rate">1</property>
-                              </object>
-                              <packing>
-                                <property name="expand">False</property>
-                                <property name="position">0</property>
-                              </packing>
-                            </child>
+                            <property name="xalign">0</property>
+                            <property name="label" translatable="yes">_Rows:</property>
+                            <property name="use_underline">True</property>
                           </object>
                           <packing>
-                            <property name="left_attach">1</property>
-                            <property name="right_attach">2</property>
-                            <property name="top_attach">1</property>
-                            <property name="bottom_attach">2</property>
+                            <property name="x_options">GTK_FILL</property>
                           </packing>
                         </child>
                       </object>
@@ -213,7 +256,7 @@
           </object>
           <packing>
             <property name="expand">False</property>
-            <property name="position">0</property>
+            <property name="position">1</property>
           </packing>
         </child>
         <child>
@@ -230,6 +273,7 @@
                 </attributes>
               </object>
               <packing>
+                <property name="expand">False</property>
                 <property name="position">0</property>
               </packing>
             </child>
@@ -244,7 +288,7 @@
                     <child>
                       <object class="GtkScrolledWindow" id="caption_scrolledwindow">
                         <property name="width_request">300</property>
-                        <property name="height_request">190</property>
+                        <property name="height_request">150</property>
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
                         <property name="hscrollbar_policy">automatic</property>
@@ -258,50 +302,6 @@
                         <property name="position">0</property>
                       </packing>
                     </child>
-                    <child>
-                      <object class="GtkHBox" id="hbox3">
-                        <property name="visible">True</property>
-                        <child>
-                          <object class="GtkHBox" id="hbox8">
-                            <property name="visible">True</property>
-                            <property name="spacing">6</property>
-                            <child>
-                              <object class="GtkLabel" id="label6">
-                                <property name="visible">True</property>
-                                <property name="xalign">0</property>
-                                <property name="label" translatable="yes">_Font:</property>
-                                <property name="use_underline">True</property>
-                              </object>
-                              <packing>
-                                <property name="expand">False</property>
-                                <property name="position">0</property>
-                              </packing>
-                            </child>
-                            <child>
-                              <object class="GtkFontButton" id="caption_fontbutton">
-                                <property name="visible">True</property>
-                                <property name="can_focus">True</property>
-                                <property name="receives_default">True</property>
-                                <property name="title" translatable="yes">Select Caption Font</property>
-                              </object>
-                              <packing>
-                                <property name="position">1</property>
-                              </packing>
-                            </child>
-                          </object>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="pack_type">end</property>
-                            <property name="position">0</property>
-                          </packing>
-                        </child>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="pack_type">end</property>
-                        <property name="position">1</property>
-                      </packing>
-                    </child>
                   </object>
                 </child>
               </object>
@@ -311,8 +311,7 @@
             </child>
           </object>
           <packing>
-            <property name="expand">False</property>
-            <property name="position">1</property>
+            <property name="position">2</property>
           </packing>
         </child>
         <child>
@@ -592,7 +591,7 @@
           </object>
           <packing>
             <property name="expand">False</property>
-            <property name="position">2</property>
+            <property name="position">3</property>
           </packing>
         </child>
       </object>
diff --git a/extensions/image_print/data/ui/print-preferences.ui b/extensions/image_print/data/ui/print-preferences.ui
new file mode 100644
index 0000000..6424217
--- /dev/null
+++ b/extensions/image_print/data/ui/print-preferences.ui
@@ -0,0 +1,171 @@
+<?xml version="1.0"?>
+<interface>
+  <requires lib="gtk+" version="2.16"/>
+  <!-- interface-naming-policy project-wide -->
+  <object class="GtkListStore" id="file_type_liststore">
+    <columns>
+      <!-- column-name gint1 -->
+      <column type="gint"/>
+      <!-- column-name GObject1 -->
+      <column type="GObject"/>
+      <!-- column-name gchararray1 -->
+      <column type="gchararray"/>
+    </columns>
+  </object>
+  <object class="GtkVBox" id="preferences_page">
+    <property name="visible">True</property>
+    <property name="border_width">12</property>
+    <property name="spacing">12</property>
+    <child>
+      <object class="GtkVBox" id="vbox2">
+        <property name="visible">True</property>
+        <property name="spacing">6</property>
+        <child>
+          <object class="GtkVBox" id="vbox1">
+            <property name="visible">True</property>
+            <property name="spacing">6</property>
+            <child>
+              <object class="GtkLabel" id="label1">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">Fonts</property>
+                <attributes>
+                  <attribute name="weight" value="bold"/>
+                </attributes>
+              </object>
+              <packing>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkAlignment" id="alignment1">
+                <property name="visible">True</property>
+                <property name="left_padding">12</property>
+                <child>
+                  <object class="GtkVBox" id="vbox3">
+                    <property name="visible">True</property>
+                    <child>
+                      <object class="GtkTable" id="table1">
+                        <property name="visible">True</property>
+                        <property name="n_rows">3</property>
+                        <property name="n_columns">2</property>
+                        <property name="column_spacing">6</property>
+                        <property name="row_spacing">6</property>
+                        <child>
+                          <object class="GtkLabel" id="label6">
+                            <property name="visible">True</property>
+                            <property name="xalign">0</property>
+                            <property name="label" translatable="yes">Caption:</property>
+                            <property name="use_underline">True</property>
+                            <property name="mnemonic_widget">caption_fontbutton</property>
+                          </object>
+                          <packing>
+                            <property name="x_options">GTK_FILL</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkFontButton" id="caption_fontbutton">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">True</property>
+                            <property name="title" translatable="yes">Select Caption Font</property>
+                            <property name="use_font">True</property>
+                            <property name="use_size">True</property>
+                          </object>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="right_attach">2</property>
+                            <property name="x_options">GTK_FILL</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label2">
+                            <property name="visible">True</property>
+                            <property name="xalign">0</property>
+                            <property name="label" translatable="yes">_Header:</property>
+                            <property name="use_underline">True</property>
+                            <property name="mnemonic_widget">header_fontbutton</property>
+                          </object>
+                          <packing>
+                            <property name="top_attach">1</property>
+                            <property name="bottom_attach">2</property>
+                            <property name="x_options">GTK_FILL</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label3">
+                            <property name="visible">True</property>
+                            <property name="xalign">0</property>
+                            <property name="label" translatable="yes">_Footer:</property>
+                            <property name="use_underline">True</property>
+                            <property name="mnemonic_widget">footer_fontbutton</property>
+                          </object>
+                          <packing>
+                            <property name="top_attach">2</property>
+                            <property name="bottom_attach">3</property>
+                            <property name="x_options">GTK_FILL</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkFontButton" id="header_fontbutton">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">True</property>
+                            <property name="title" translatable="yes">Select Header Font</property>
+                            <property name="font_name">Sans Bold 12</property>
+                            <property name="use_font">True</property>
+                            <property name="use_size">True</property>
+                          </object>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="right_attach">2</property>
+                            <property name="top_attach">1</property>
+                            <property name="bottom_attach">2</property>
+                            <property name="x_options">GTK_FILL</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkFontButton" id="footer_fontbutton">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">True</property>
+                            <property name="title" translatable="yes">Select Footer Font</property>
+                            <property name="font_name">Sans 8</property>
+                            <property name="use_font">True</property>
+                            <property name="use_size">True</property>
+                          </object>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="right_attach">2</property>
+                            <property name="top_attach">2</property>
+                            <property name="bottom_attach">3</property>
+                            <property name="x_options">GTK_FILL</property>
+                          </packing>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+      </object>
+      <packing>
+        <property name="position">0</property>
+      </packing>
+    </child>
+  </object>
+  <object class="GtkTreeViewColumn" id="file_type_treeviewcolumn"/>
+</interface>
diff --git a/extensions/image_print/gth-image-info.c b/extensions/image_print/gth-image-info.c
index 7a25bfe..fd92be4 100644
--- a/extensions/image_print/gth-image-info.c
+++ b/extensions/image_print/gth-image-info.c
@@ -77,6 +77,9 @@ gth_image_info_ref (GthImageInfo *image_info)
 void
 gth_image_info_unref (GthImageInfo *image_info)
 {
+	if (image_info == NULL)
+		return;
+
 	image_info->ref_count--;
 	if (image_info->ref_count > 0)
 		return;
diff --git a/extensions/image_print/gth-image-print-job.c b/extensions/image_print/gth-image-print-job.c
index d499c3e..5e9912a 100644
--- a/extensions/image_print/gth-image-print-job.c
+++ b/extensions/image_print/gth-image-print-job.c
@@ -30,7 +30,6 @@
 #include "preferences.h"
 
 
-#define DEFAULT_FONT_NAME "sans normal 10"
 #define GET_WIDGET(name) _gtk_builder_get_widget (self->priv->builder, (name))
 
 
@@ -64,9 +63,13 @@ struct _GthImagePrintJobPrivate {
 	int                 image_height;
 	GtkPageSetup       *page_setup;
 	char               *caption_attributes;
-	char               *font_name;
+	char               *caption_font_name;
+	char               *header_font_name;
+	char               *footer_font_name;
 	double              scale_factor;
 	int                 dpi;
+	char               *header;
+	char               *footer;
 
 	/* layout info */
 
@@ -75,6 +78,8 @@ struct _GthImagePrintJobPrivate {
 	double		    max_image_height;
 	double              x_padding;
 	double              y_padding;
+	GthRectangle        header_rectangle;
+	GthRectangle        footer_rectangle;
 	int                 n_pages;
 	int                 current_page;
 };
@@ -96,7 +101,7 @@ gth_image_print_job_finalize (GObject *base)
 	g_free (self->priv->images);
 	_g_object_unref (self->priv->page_setup);
 	g_free (self->priv->caption_attributes);
-	g_free (self->priv->font_name);
+	g_free (self->priv->caption_font_name);
 
 	G_OBJECT_CLASS (parent_class)->finalize (base);
 }
@@ -124,11 +129,15 @@ gth_image_print_job_init (GthImagePrintJob *self)
 	self->priv->page_setup = NULL;
 	self->priv->current_page = 0;
 	self->priv->caption_attributes = eel_gconf_get_string (PREF_IMAGE_PRINT_CAPTION, "");
-	self->priv->font_name = eel_gconf_get_string (PREF_IMAGE_PRINT_FONT_NAME, DEFAULT_FONT_NAME);
+	self->priv->caption_font_name = eel_gconf_get_string (PREF_IMAGE_PRINT_FONT_NAME, DEFAULT_CAPTION_FONT_NAME);
+	self->priv->header_font_name = eel_gconf_get_string (PREF_IMAGE_PRINT_HEADER_FONT_NAME, DEFAULT_HEADER_FONT_NAME);
+	self->priv->footer_font_name = eel_gconf_get_string (PREF_IMAGE_PRINT_FOOTER_FONT_NAME, DEFAULT_FOOTER_FONT_NAME);
 	self->priv->selected = NULL;
 	self->priv->n_rows = eel_gconf_get_integer (PREF_IMAGE_PRINT_N_ROWS, 1);
 	self->priv->n_columns = eel_gconf_get_integer (PREF_IMAGE_PRINT_N_COLUMNS, 1);
 	self->priv->unit = eel_gconf_get_enum (PREF_IMAGE_PRINT_UNIT, GTH_TYPE_METRIC, GTH_METRIC_PIXELS);
+	self->priv->header_rectangle.height = 0;
+	self->priv->footer_rectangle.height = 0;
 }
 
 
@@ -160,22 +169,103 @@ gth_image_print_job_get_type (void)
 }
 
 
+static double
+get_text_height (GthImagePrintJob *self,
+		 PangoLayout      *pango_layout,
+		 const char       *text,
+		 int               width)
+{
+	PangoRectangle logical_rect;
+
+	if (text == NULL)
+		return 0.0;
+
+	pango_layout_set_text (pango_layout, text, -1);
+	pango_layout_set_width (pango_layout, width * self->priv->scale_factor * PANGO_SCALE);
+	pango_layout_get_pixel_extents (pango_layout, NULL, &logical_rect);
+
+	return logical_rect.height / self->priv->scale_factor;
+}
+
+
+static void
+gth_image_print_job_set_font_options (GthImagePrintJob *self,
+				      PangoLayout      *pango_layout,
+				      const char       *font_name,
+				      gboolean          preview)
+{
+	PangoFontDescription *font_desc;
+	double                size_in_points;
+	cairo_font_options_t *options;
+	PangoContext         *pango_context;
+
+	pango_layout_set_wrap (pango_layout, PANGO_WRAP_WORD_CHAR);
+	pango_layout_set_justify (pango_layout, FALSE);
+	pango_layout_set_alignment (pango_layout, PANGO_ALIGN_CENTER);
+
+	font_desc = pango_font_description_from_string (font_name);
+	if (preview)
+		self->priv->scale_factor = 2.83;
+	else
+		self->priv->scale_factor = 1.0;
+
+	size_in_points = (double) pango_font_description_get_size (font_desc) / PANGO_SCALE;
+	pango_font_description_set_absolute_size (font_desc, size_in_points * PANGO_SCALE);
+	pango_layout_set_font_description (pango_layout, font_desc);
+
+	options = cairo_font_options_create ();
+	cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_OFF);
+	pango_context = pango_layout_get_context (pango_layout);
+	pango_cairo_context_set_font_options (pango_context, options);
+
+	cairo_font_options_destroy (options);
+	pango_font_description_free (font_desc);
+}
+
+
 static void
 gth_image_print_job_update_layout_info (GthImagePrintJob   *self,
 				        gdouble             page_width,
 				        gdouble             page_height,
-				        GtkPageOrientation  orientation)
+				        GtkPageOrientation  orientation,
+				        PangoLayout        *pango_layout,
+				        gboolean            preview)
 {
-	int rows;
-	int columns;
-	int current_page;
-	int current_row;
-	int current_column;
-	int i;
+	gboolean height_changed = FALSE;
+	int      height;
+	int      rows;
+	int      columns;
+	int      current_page;
+	int      current_row;
+	int      current_column;
+	int      i;
 
 	self->priv->x_padding = page_width / 40.0;
 	self->priv->y_padding = page_height / 40.0;
 
+	gth_image_print_job_set_font_options (self, pango_layout, self->priv->header_font_name, preview);
+	height = get_text_height (self, pango_layout, self->priv->header, page_width);
+	if (height != self->priv->header_rectangle.height)
+		height_changed = TRUE;
+	self->priv->header_rectangle.height = height;
+	self->priv->header_rectangle.y = 0.0;
+	self->priv->header_rectangle.x = 0.0;
+	self->priv->header_rectangle.width = page_width;
+
+	gth_image_print_job_set_font_options (self, pango_layout, self->priv->header_font_name, preview);
+	height = get_text_height (self, pango_layout, self->priv->footer, page_width);
+	if (height != self->priv->footer_rectangle.height)
+		height_changed = TRUE;
+	self->priv->footer_rectangle.height = height;
+	self->priv->footer_rectangle.y = page_height - self->priv->footer_rectangle.height;
+	self->priv->footer_rectangle.x = 0.0;
+	self->priv->footer_rectangle.width = page_width;
+
+	if (height_changed) {
+		for (i = 0; i < self->priv->n_images; i++)
+			gth_image_info_reset (self->priv->images[i]);
+	}
+
 	rows = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (GET_WIDGET ("rows_spinbutton")));
 	columns = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (GET_WIDGET ("columns_spinbutton")));
 	if ((orientation == GTK_PAGE_ORIENTATION_LANDSCAPE)
@@ -186,6 +276,11 @@ gth_image_print_job_update_layout_info (GthImagePrintJob   *self,
 		columns = tmp;
 	}
 
+	if (self->priv->header_rectangle.height > 0)
+		page_height -= self->priv->header_rectangle.height + self->priv->y_padding;
+	if (self->priv->footer_rectangle.height > 0)
+		page_height -= self->priv->footer_rectangle.height + self->priv->y_padding;
+
 	self->priv->n_rows = rows;
 	self->priv->n_columns = columns;
 	self->priv->max_image_width = (page_width - ((columns - 1) * self->priv->x_padding)) / columns;
@@ -239,6 +334,8 @@ gth_image_print_job_update_image_layout (GthImagePrintJob    *self,
 
 	image_info->boundary.x = (image_info->col - 1) * (self->priv->max_image_width + self->priv->x_padding);
 	image_info->boundary.y = (image_info->row - 1) * (self->priv->max_image_height + self->priv->y_padding);
+	if (self->priv->header_rectangle.height > 0)
+		image_info->boundary.y += self->priv->header_rectangle.height + self->priv->y_padding;
 	image_info->boundary.width = self->priv->max_image_width;
 	image_info->boundary.height = self->priv->max_image_height;
 
@@ -337,65 +434,19 @@ gth_image_print_job_update_image_layout (GthImagePrintJob    *self,
 
 
 static void
-gth_image_print_job_set_font_options (GthImagePrintJob *self,
-				      PangoLayout      *pango_layout,
-				      gboolean          preview)
-{
-	PangoFontDescription *font_desc;
-	double                size_in_points;
-	cairo_font_options_t *options;
-	PangoContext         *pango_context;
-
-	pango_layout_set_wrap (pango_layout, PANGO_WRAP_WORD_CHAR);
-	pango_layout_set_justify (pango_layout, FALSE);
-	pango_layout_set_alignment (pango_layout, PANGO_ALIGN_CENTER);
-
-	font_desc = pango_font_description_from_string (self->priv->font_name);
-	if (preview)
-		self->priv->scale_factor = 2.83;
-	else
-		self->priv->scale_factor = 1.0;
-
-	size_in_points = (double) pango_font_description_get_size (font_desc) / PANGO_SCALE;
-	pango_font_description_set_absolute_size (font_desc, size_in_points * PANGO_SCALE);
-	pango_layout_set_font_description (pango_layout, font_desc);
-
-	options = cairo_font_options_create ();
-	cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_OFF);
-	pango_context = pango_layout_get_context (pango_layout);
-	pango_cairo_context_set_font_options (pango_context, options);
-
-	cairo_font_options_destroy (options);
-	pango_font_description_free (font_desc);
-}
-
-
-static PangoLayout *
-gth_image_print_job_create_pango_layout (GthImagePrintJob *self,
-					 gboolean          preview)
-{
-	PangoLayout *pango_layout;
-
-	pango_layout = gtk_widget_create_pango_layout (GTK_WIDGET (self->priv->browser), NULL);
-	gth_image_print_job_set_font_options (self, pango_layout, preview);
-
-	return pango_layout;
-}
-
-
-static void
 gth_image_print_job_update_page_layout (GthImagePrintJob   *self,
 					int                 page,
 					gdouble             page_width,
 					gdouble             page_height,
 					GtkPageOrientation  orientation,
+					PangoLayout        *pango_layout,
 					gboolean            preview)
 {
-	PangoLayout  *pango_layout;
-	char        **attributes_v;
-	int           i;
+	char **attributes_v;
+	int    i;
+
+	gth_image_print_job_set_font_options (self, pango_layout, self->priv->caption_font_name, preview);
 
-	pango_layout = gth_image_print_job_create_pango_layout (self, preview);
 	attributes_v = g_strsplit (self->priv->caption_attributes, ",", -1);
 	for (i = 0; i < self->priv->n_images; i++) {
 		GthImageInfo *image_info = self->priv->images[i];
@@ -414,7 +465,6 @@ gth_image_print_job_update_page_layout (GthImagePrintJob   *self,
 	}
 
 	g_strfreev (attributes_v);
-	g_object_unref (pango_layout);
 }
 
 
@@ -424,8 +474,24 @@ gth_image_print_job_update_layout (GthImagePrintJob   *self,
 			  	   gdouble             page_height,
 			  	   GtkPageOrientation  orientation)
 {
-	gth_image_print_job_update_layout_info (self, page_width, page_height, orientation);
-	gth_image_print_job_update_page_layout (self, self->priv->current_page, page_width, page_height, orientation, TRUE);
+	PangoLayout *pango_layout;
+
+	pango_layout = gtk_widget_create_pango_layout (GTK_WIDGET (self->priv->browser), NULL);
+	gth_image_print_job_update_layout_info (self,
+						page_width,
+						page_height,
+						orientation,
+						pango_layout,
+						TRUE);
+	gth_image_print_job_update_page_layout (self,
+						self->priv->current_page,
+						page_width,
+						page_height,
+						orientation,
+						pango_layout,
+						TRUE);
+
+	g_object_unref (pango_layout);
 }
 
 
@@ -540,7 +606,46 @@ gth_image_print_job_paint (GthImagePrintJob *self,
 {
 	int i;
 
-	gth_image_print_job_set_font_options (self, pango_layout, preview);
+	if (self->priv->header != NULL) {
+		gth_image_print_job_set_font_options (self, pango_layout, self->priv->header_font_name, preview);
+
+		cairo_save (cr);
+
+		pango_layout_set_width (pango_layout, self->priv->header_rectangle.width * self->priv->scale_factor * PANGO_SCALE);
+		pango_layout_set_text (pango_layout, self->priv->header, -1);
+
+		cairo_move_to (cr, x_offset + self->priv->header_rectangle.x, y_offset + self->priv->header_rectangle.y);
+		if (preview)
+			cairo_scale (cr, 1.0 / self->priv->scale_factor, 1.0 / self->priv->scale_factor);
+
+		pango_cairo_layout_path (cr, pango_layout);
+		cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+		cairo_fill (cr);
+
+		cairo_restore (cr);
+	}
+
+	if (self->priv->footer != NULL) {
+		gth_image_print_job_set_font_options (self, pango_layout, self->priv->footer_font_name, preview);
+
+		cairo_save (cr);
+
+		pango_layout_set_width (pango_layout, self->priv->footer_rectangle.width * self->priv->scale_factor * PANGO_SCALE);
+		pango_layout_set_text (pango_layout, self->priv->footer, -1);
+
+		cairo_move_to (cr, x_offset + self->priv->footer_rectangle.x, y_offset + self->priv->footer_rectangle.y);
+		if (preview)
+			cairo_scale (cr, 1.0 / self->priv->scale_factor, 1.0 / self->priv->scale_factor);
+
+		pango_cairo_layout_path (cr, pango_layout);
+		cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+		cairo_fill (cr);
+
+		cairo_restore (cr);
+	}
+
+	gth_image_print_job_set_font_options (self, pango_layout, self->priv->caption_font_name, preview);
+
 	for (i = 0; i < self->priv->n_images; i++) {
 		GthImageInfo *image_info = self->priv->images[i];
 		GdkPixbuf    *fullsize_pixbuf;
@@ -795,7 +900,8 @@ gth_image_print_job_update_image_preview (GthImagePrintJob *self,
 	PangoLayout  *pango_layout;
 	char        **attributes_v;
 
-	pango_layout = gth_image_print_job_create_pango_layout (self, TRUE);
+	pango_layout = gtk_widget_create_pango_layout (GTK_WIDGET (self->priv->browser), NULL);
+
 	attributes_v = g_strsplit (self->priv->caption_attributes, ",", -1);
 	gth_image_print_job_update_image_layout (self,
 						 image_info,
@@ -1093,14 +1199,32 @@ unit_combobox_changed_cb (GtkComboBox *combo_box,
 
 
 static void
-caption_fontbutton_font_set_cb (GtkFontButton *font_button,
-				gpointer       user_data)
+header_entry_changed_cb (GtkEditable *editable,
+			 gpointer     user_data)
+{
+	GthImagePrintJob *self = user_data;
+
+	_g_strset (&self->priv->header, gtk_entry_get_text (GTK_ENTRY (editable)));
+	if (g_strcmp0 (self->priv->header, "") == 0) {
+		g_free (self->priv->header);
+		self->priv->header = NULL;
+	}
+
+	gth_image_print_job_update_preview (self);
+}
+
+
+static void
+footer_entry_changed_cb (GtkEditable *editable,
+			 gpointer     user_data)
 {
 	GthImagePrintJob *self = user_data;
 
-	g_free (self->priv->font_name);
-	self->priv->font_name = g_strdup (gtk_font_button_get_font_name (font_button));
-	eel_gconf_set_string (PREF_IMAGE_PRINT_FONT_NAME, self->priv->font_name);
+	_g_strset (&self->priv->footer, gtk_entry_get_text (GTK_ENTRY (editable)));
+	if (g_strcmp0 (self->priv->footer, "") == 0) {
+		g_free (self->priv->footer);
+		self->priv->footer = NULL;
+	}
 
 	gth_image_print_job_update_preview (self);
 }
@@ -1259,7 +1383,6 @@ operation_create_custom_widget_cb (GtkPrintOperation *operation,
 
 	gth_metadata_chooser_set_selection (GTH_METADATA_CHOOSER (self->priv->caption_chooser), self->priv->caption_attributes);
 	gtk_combo_box_set_active (GTK_COMBO_BOX (GET_WIDGET ("unit_combobox")), self->priv->unit);
-	gtk_font_button_set_font_name (GTK_FONT_BUTTON (GET_WIDGET ("caption_fontbutton")), self->priv->font_name);
 
 	gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("rows_spinbutton")), self->priv->n_rows);
 	gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("columns_spinbutton")), self->priv->n_columns);
@@ -1306,10 +1429,14 @@ operation_create_custom_widget_cb (GtkPrintOperation *operation,
 			  "changed",
 	                  G_CALLBACK (unit_combobox_changed_cb),
 	                  self);
-	g_signal_connect (GET_WIDGET ("caption_fontbutton"),
-			  "font-set",
-			  G_CALLBACK (caption_fontbutton_font_set_cb),
-			  self);
+	g_signal_connect (GET_WIDGET ("header_entry"),
+			  "changed",
+	                  G_CALLBACK (header_entry_changed_cb),
+	                  self);
+	g_signal_connect (GET_WIDGET ("footer_entry"),
+			  "changed",
+	                  G_CALLBACK (footer_entry_changed_cb),
+	                  self);
 
 	self->priv->rotation_combobox_changed_event =
 			g_signal_connect (GET_WIDGET ("rotation_combobox"),
@@ -1414,6 +1541,7 @@ print_operation_begin_print_cb (GtkPrintOperation *operation,
 	GthImagePrintJob *self = user_data;
 	GtkPrintSettings *settings;
 	char             *filename;
+	PangoLayout      *pango_layout;
 
 	_g_object_unref (self->priv->page_setup);
 	self->priv->page_setup = gtk_page_setup_copy (gtk_print_context_get_page_setup (context));
@@ -1427,11 +1555,16 @@ print_operation_begin_print_cb (GtkPrintOperation *operation,
 	gtk_page_setup_to_file (self->priv->page_setup, filename, NULL);
 	g_free (filename);
 
+	pango_layout = gtk_print_context_create_pango_layout (context);
 	gth_image_print_job_update_layout_info (self,
 						gtk_print_context_get_width (context),
 						gtk_print_context_get_height (context),
-						gtk_page_setup_get_orientation (self->priv->page_setup));
+						gtk_page_setup_get_orientation (self->priv->page_setup),
+						pango_layout,
+						FALSE);
 	gtk_print_operation_set_n_pages (operation, self->priv->n_pages);
+
+	g_object_unref (pango_layout);
 }
 
 
@@ -1442,20 +1575,21 @@ print_operation_draw_page_cb (GtkPrintOperation *operation,
 			      gpointer           user_data)
 {
 	GthImagePrintJob *self = user_data;
-	GtkPageSetup     *setup;
 	cairo_t          *cr;
 	PangoLayout      *pango_layout;
+	GtkPageSetup     *setup;
 
+	cr = gtk_print_context_get_cairo_context (context);
+	pango_layout = gtk_print_context_create_pango_layout (context);
 	setup = gtk_print_context_get_page_setup (context);
+
 	gth_image_print_job_update_page_layout (self,
 						page_nr,
 						gtk_print_context_get_width (context),
 						gtk_print_context_get_height (context),
 						gtk_page_setup_get_orientation (setup),
+						pango_layout,
 						FALSE);
-
-	cr = gtk_print_context_get_cairo_context (context);
-	pango_layout = gtk_print_context_create_pango_layout (context);
 	gth_image_print_job_paint (self,
 				   cr,
 				   pango_layout,
@@ -1537,7 +1671,7 @@ gth_image_print_job_new (GList        *file_data_list,
 
 	self->priv->print_operation = gtk_print_operation_new ();
 	gtk_print_operation_set_allow_async (self->priv->print_operation, TRUE);
-	gtk_print_operation_set_custom_tab_label (self->priv->print_operation, _("Layout"));
+	gtk_print_operation_set_custom_tab_label (self->priv->print_operation, _("Images"));
 	gtk_print_operation_set_embed_page_setup (self->priv->print_operation, TRUE);
 	gtk_print_operation_set_show_progress (self->priv->print_operation, TRUE);
 
diff --git a/extensions/image_print/main.c b/extensions/image_print/main.c
index 1df668e..9fc9057 100644
--- a/extensions/image_print/main.c
+++ b/extensions/image_print/main.c
@@ -24,6 +24,7 @@
 #include <gtk/gtk.h>
 #include <gthumb.h>
 #include "callbacks.h"
+#include "preferences.h"
 
 
 G_MODULE_EXPORT void
@@ -31,6 +32,8 @@ gthumb_extension_activate (void)
 {
 	gth_hook_add_callback ("gth-browser-construct", 10, G_CALLBACK (ip__gth_browser_construct_cb), NULL);
 	gth_hook_add_callback ("gth-browser-update-sensitivity", 10, G_CALLBACK (ip__gth_browser_update_sensitivity_cb), NULL);
+	gth_hook_add_callback ("dlg-preferences-construct", 40, G_CALLBACK (ip__dlg_preferences_construct_cb), NULL);
+	gth_hook_add_callback ("dlg-preferences-apply", 10, G_CALLBACK (ip__dlg_preferences_apply_cb), NULL);
 }
 
 
diff --git a/extensions/image_print/preferences.c b/extensions/image_print/preferences.c
new file mode 100644
index 0000000..ff50c5c
--- /dev/null
+++ b/extensions/image_print/preferences.c
@@ -0,0 +1,97 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  GThumb
+ *
+ *  Copyright (C) 2011 Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <glib/gi18n.h>
+#include <gthumb.h>
+#include "preferences.h"
+
+
+#define GET_WIDGET(name) _gtk_builder_get_widget (data->builder, (name))
+#define BROWSER_DATA_KEY "print-options-preference-data"
+
+
+typedef struct {
+	GtkBuilder *builder;
+} BrowserData;
+
+
+static void
+browser_data_free (BrowserData *data)
+{
+	g_object_unref (data->builder);
+	g_free (data);
+}
+
+
+void
+ip__dlg_preferences_construct_cb (GtkWidget  *dialog,
+				  GthBrowser *browser,
+				  GtkBuilder *dialog_builder)
+{
+	BrowserData *data;
+	GtkWidget   *notebook;
+	GtkWidget   *page;
+	GtkWidget   *label;
+	char        *font_name;
+
+	data = g_new0 (BrowserData, 1);
+	data->builder = _gtk_builder_new_from_file ("print-preferences.ui", "image_print");
+
+	notebook = _gtk_builder_get_widget (dialog_builder, "notebook");
+
+	page = _gtk_builder_get_widget (data->builder, "preferences_page");
+	gtk_widget_show (page);
+
+	font_name = eel_gconf_get_string (PREF_IMAGE_PRINT_FONT_NAME, DEFAULT_CAPTION_FONT_NAME);
+	gtk_font_button_set_font_name (GTK_FONT_BUTTON (GET_WIDGET ("caption_fontbutton")), font_name);
+	g_free (font_name);
+
+	font_name = eel_gconf_get_string (PREF_IMAGE_PRINT_HEADER_FONT_NAME, DEFAULT_HEADER_FONT_NAME);
+	gtk_font_button_set_font_name (GTK_FONT_BUTTON (GET_WIDGET ("header_fontbutton")), font_name);
+	g_free (font_name);
+
+	font_name = eel_gconf_get_string (PREF_IMAGE_PRINT_FOOTER_FONT_NAME, DEFAULT_FOOTER_FONT_NAME);
+	gtk_font_button_set_font_name (GTK_FONT_BUTTON (GET_WIDGET ("footer_fontbutton")), font_name);
+	g_free (font_name);
+
+	label = gtk_label_new (_("Print"));
+	gtk_widget_show (label);
+
+	gtk_notebook_append_page (GTK_NOTEBOOK (notebook), page, label);
+	g_object_set_data_full (G_OBJECT (dialog), BROWSER_DATA_KEY, data, (GDestroyNotify) browser_data_free);
+}
+
+
+void
+ip__dlg_preferences_apply_cb (GtkWidget  *dialog,
+			      GthBrowser *browser,
+			      GtkBuilder *builder)
+{
+	BrowserData *data;
+
+	data = g_object_get_data (G_OBJECT (dialog), BROWSER_DATA_KEY);
+	g_return_if_fail (data != NULL);
+
+	eel_gconf_set_string (PREF_IMAGE_PRINT_FONT_NAME, gtk_font_button_get_font_name (GTK_FONT_BUTTON (GET_WIDGET ("caption_fontbutton"))));
+	eel_gconf_set_string (PREF_IMAGE_PRINT_HEADER_FONT_NAME, gtk_font_button_get_font_name (GTK_FONT_BUTTON (GET_WIDGET ("header_fontbutton"))));
+	eel_gconf_set_string (PREF_IMAGE_PRINT_FOOTER_FONT_NAME, gtk_font_button_get_font_name (GTK_FONT_BUTTON (GET_WIDGET ("footer_fontbutton"))));
+}
diff --git a/extensions/image_print/preferences.h b/extensions/image_print/preferences.h
index dcd16df..f18234e 100644
--- a/extensions/image_print/preferences.h
+++ b/extensions/image_print/preferences.h
@@ -26,11 +26,24 @@
 
 G_BEGIN_DECLS
 
-#define PREF_IMAGE_PRINT_CAPTION      "/apps/gthumb/ext/image_print/caption"
-#define PREF_IMAGE_PRINT_FONT_NAME    "/apps/gthumb/ext/image_print/font_name"
-#define PREF_IMAGE_PRINT_N_ROWS       "/apps/gthumb/ext/image_print/n_rows"
-#define PREF_IMAGE_PRINT_N_COLUMNS    "/apps/gthumb/ext/image_print/n_columns"
-#define PREF_IMAGE_PRINT_UNIT         "/apps/gthumb/ext/image_print/unit"
+#define PREF_IMAGE_PRINT_CAPTION           "/apps/gthumb/ext/image_print/caption"
+#define PREF_IMAGE_PRINT_FONT_NAME         "/apps/gthumb/ext/image_print/font_name"
+#define PREF_IMAGE_PRINT_HEADER_FONT_NAME  "/apps/gthumb/ext/image_print/header_font_name"
+#define PREF_IMAGE_PRINT_FOOTER_FONT_NAME  "/apps/gthumb/ext/image_print/footer_font_name"
+#define PREF_IMAGE_PRINT_N_ROWS            "/apps/gthumb/ext/image_print/n_rows"
+#define PREF_IMAGE_PRINT_N_COLUMNS         "/apps/gthumb/ext/image_print/n_columns"
+#define PREF_IMAGE_PRINT_UNIT              "/apps/gthumb/ext/image_print/unit"
+
+#define DEFAULT_CAPTION_FONT_NAME "sans normal 10"
+#define DEFAULT_HEADER_FONT_NAME  "sans bold 12"
+#define DEFAULT_FOOTER_FONT_NAME  "sans normal 8"
+
+void ip__dlg_preferences_construct_cb (GtkWidget  *dialog,
+				       GthBrowser *browser,
+				       GtkBuilder *builder);
+void ip__dlg_preferences_apply_cb     (GtkWidget  *dialog,
+				       GthBrowser *browser,
+				       GtkBuilder *builder);
 
 G_END_DECLS
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]