Customizable info overlay in fullscreen, based on the patch posted to gqview-devel...
authorLaurent Monin <geeqie@norz.org>
Mon, 31 Mar 2008 22:10:25 +0000 (22:10 +0000)
committerLaurent Monin <geeqie@norz.org>
Mon, 31 Mar 2008 22:10:25 +0000 (22:10 +0000)
src/globals.c
src/gqview.h
src/image-overlay.c
src/main.c
src/preferences.c
src/rcfile.c

index 9984c14..a4aacff 100644 (file)
@@ -100,6 +100,8 @@ gint fullscreen_screen = -1;
 gint fullscreen_clean_flip = FALSE;
 gint fullscreen_disable_saver = TRUE;
 gint fullscreen_above = FALSE;
+gint show_fullscreen_info = TRUE;
+gchar *fullscreen_info = NULL;
 
 gint dupe_custom_threshold = 99;
 
index 721ccc2..12a652e 100644 (file)
@@ -167,6 +167,8 @@ extern gint fullscreen_screen;
 extern gint fullscreen_clean_flip;
 extern gint fullscreen_disable_saver;
 extern gint fullscreen_above;
+extern gint show_fullscreen_info;
+extern gchar *fullscreen_info;
 
 extern gint dupe_custom_threshold;
 
index 109add7..c135541 100644 (file)
@@ -13,6 +13,7 @@
 #include "image-overlay.h"
 
 #include "collect.h"
+#include "exif.h"
 #include "filelist.h"
 #include "image.h"
 #include "img-view.h"
@@ -75,6 +76,72 @@ static OSDIcon osd_icons[] = {
 
 static void image_osd_timer_schedule(OverlayStateData *osd);
 
+static gchar *image_osd_mkinfo(const gchar *str, ImageWindow *imd, GHashTable *vars)
+{
+       gchar delim = '%', imp = '|', sep[] = " - ";
+       gchar *start, *end;
+       gint pos, prev;
+       gint last;
+       gchar *name, *data;
+       GString *new = g_string_new(str);
+       gchar *ret;
+       ExifData *exif;
+
+       exif = exif_read_fd(imd->image_fd, FALSE);
+       prev = 0;
+       last = FALSE;
+
+       while (TRUE)
+               {
+               start = strchr(new->str, delim);
+               if (!start)
+                       break;
+               end = strchr(start+1, delim);
+               if (!end)
+                       break;
+
+               name = g_strndup(start+1, end-start-1);
+               pos = start-new->str;
+               data = g_strdup(g_hash_table_lookup(vars, name));
+               if (!data && exif)
+                       data = exif_get_data_as_text(exif, name);
+
+               g_string_erase(new, pos, end-start+1);
+               if (data)
+                       g_string_insert(new, pos, data);
+               if (pos-prev == 2 && new->str[pos-1] == imp)
+                       {
+                       g_string_erase(new, --pos, 1);
+                       if (last && data)
+                               {
+                               g_string_insert(new, pos, sep);
+                               pos += strlen(sep);
+                               }
+                       }
+
+               prev = data ? pos+strlen(data)-1 : pos-1;
+               last = data ? TRUE : last;
+               g_free(name);
+               g_free(data);
+               }
+       
+       /* search and destroy empty lines */
+       end = new->str;
+       while (start = strchr(end, '\n'))
+               {
+               end = start;
+               while (*++(end) == '\n')
+                       ;
+               g_string_erase(new, start-new->str, end-start-1);
+               }
+
+       g_strchomp(new->str);
+
+       ret = new->str;
+       g_string_free(new, FALSE);
+
+       return ret;
+}
 
 static GdkPixbuf *image_osd_info_render(ImageWindow *imd)
 {
@@ -90,7 +157,11 @@ static GdkPixbuf *image_osd_info_render(ImageWindow *imd)
        CollectInfo *info;
        gchar *ct;
        int i;
-    
+       gint w, h;
+       GHashTable *vars;
+
+       vars = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_free);
+
        name = image_get_name(imd);
        if (name)
                {
@@ -148,20 +219,8 @@ static GdkPixbuf *image_osd_info_render(ImageWindow *imd)
                }
 
        size = text_from_size_abrev(imd->size);
-       if (!name_escaped)
-               {
-               text = g_strdup_printf(_("Untitled"));
-               }
-       else if (imd->unknown)
-               {
-               text = g_strdup_printf("%s(%d/%d) <b>%s</b>\n%s - %s", ct,
-                                      n, t, name_escaped,
-                                      text_from_time(imd->mtime), size);
-               }
-       else
+       if (!imd->unknown)
                {
-               gint w, h;
-
                if (imd->delay_flip &&
                    imd->il && imd->il->pixbuf &&
                    image_get_pixbuf(imd) != imd->il->pixbuf)
@@ -174,15 +233,31 @@ static GdkPixbuf *image_osd_info_render(ImageWindow *imd)
                        pixbuf_renderer_get_image_size(PIXBUF_RENDERER(imd->pr), &w, &h);
                        }
 
-               text = g_strdup_printf("%s(%d/%d) <b>%s</b>\n%d x %d - %s - %s", ct,
-                                      n, t, name_escaped,
-                                      w, h,
-                                      text_from_time(imd->mtime), size);
+               g_hash_table_insert(vars, "width", g_strdup_printf("%d", w));
+               g_hash_table_insert(vars, "height", g_strdup_printf("%d", h));
+               g_hash_table_insert(vars, "res", g_strdup_printf("%d × %d", w, h));
+               }
+  
+       g_hash_table_insert(vars, "collection", g_strdup(ct));
+       g_hash_table_insert(vars, "number", g_strdup_printf("%d", n));
+       g_hash_table_insert(vars, "total", g_strdup_printf("%d", t));
+       g_hash_table_insert(vars, "name", g_strdup(name_escaped));
+       g_hash_table_insert(vars, "date", g_strdup(text_from_time(imd->mtime)));
+       g_hash_table_insert(vars, "size", g_strdup(size));
+  
+       if (!name_escaped)
+               {
+               text = g_strdup_printf(_("Untitled"));
+               }
+       else
+               {
+               text = image_osd_mkinfo(fullscreen_info, imd, vars);
+               }
 
-                }
        g_free(size);
-       g_free(ct);
-       g_free(name_escaped);
+       g_free(ct);
+       g_free(name_escaped);
+       g_hash_table_destroy(vars);
 
        {
        GString *buf = g_string_sized_new(FILEDATA_MARKS_SIZE * 2);
@@ -206,6 +281,7 @@ static GdkPixbuf *image_osd_info_render(ImageWindow *imd)
        width += 10;
        height += 10;
 
+       /* TODO: make osd color configurable --Zas */
        pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, width, height);
        pixbuf_set_rect_fill(pixbuf, 3, 3, width-6, height-6, 240, 240, 240, 210);
        pixbuf_set_rect(pixbuf, 0, 0, width, height, 240, 240, 240, 80, 1, 1, 1, 1);
index 2779013..1b52cee 100644 (file)
@@ -18,6 +18,7 @@
 #include "dnd.h"
 #include "editors.h"
 #include "filelist.h"
+#include "image-overlay.h"
 #include "img-view.h"
 #include "layout.h"
 #include "layout_image.h"
@@ -1134,6 +1135,11 @@ static void setup_default_options(void)
                color_profile_input_name[i] = NULL;
                }
 
+       fullscreen_info = g_strdup("%collection%(%number%/%total%) <b>%name%</b>\n"
+                                  "%res%|%date%|%size%\n"
+                                  "%fAperture%|%fShutterSpeed%|%fISOSpeedRating%|%fFocalLength%|%fExposureBias%\n"
+                                  "%fCamera%|%fFlash%");
+
        sidecar_ext_add_defaults();
 }
 
@@ -1155,6 +1161,7 @@ static void exit_gqview_final(void)
                        layout_geometry_get(NULL, &main_window_x, &main_window_y,
                                            &main_window_w, &main_window_h);
                        }
+               show_fullscreen_info = image_osd_get(lw->image, NULL, NULL);
                }
 
        layout_geometry_get_dividers(NULL, &window_hdivider_pos, &window_vdivider_pos);
@@ -1418,6 +1425,7 @@ int main (int argc, char *argv[])
                                                    collection_get_first(first_collection));
                        }
                }
+       image_osd_set(lw->image, FALSE, show_fullscreen_info);
 
        g_free(geometry);
        g_free(cmd_path);
index 6334d22..186e852 100644 (file)
@@ -123,6 +123,8 @@ static gint fullscreen_screen_c;
 static gint fullscreen_clean_flip_c;
 static gint fullscreen_disable_saver_c;
 static gint fullscreen_above_c;
+static gint show_fullscreen_info_c;
+static gchar *fullscreen_info_c = NULL;
 
 static gint dupe_custom_threshold_c;
 
@@ -295,6 +297,12 @@ static void config_window_apply(void)
        fullscreen_clean_flip = fullscreen_clean_flip_c;
        fullscreen_disable_saver = fullscreen_disable_saver_c;
        fullscreen_above = fullscreen_above_c;
+       show_fullscreen_info = show_fullscreen_info_c;
+       if (fullscreen_info_c)
+               {
+               g_free(fullscreen_info);
+               fullscreen_info = g_strdup(fullscreen_info_c);
+               }
 
        update_on_time_change = update_on_time_change_c;
        exif_rotate_enable = exif_rotate_enable_c;
@@ -781,6 +789,23 @@ static void safe_delete_clear_cb(GtkWidget* widget, gpointer data)
        gtk_widget_show(gd->dialog);
 }
 
+static void fullscreen_info_view_changed_cb(GtkWidget* widget, gpointer data)
+{
+       GtkWidget *pTextView;
+       GtkTextBuffer* pTextBuffer;
+       GtkTextIter iStart;
+       GtkTextIter iEnd;
+
+       pTextView = GTK_WIDGET(data);
+
+       pTextBuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(pTextView));
+       gtk_text_buffer_get_start_iter(pTextBuffer, &iStart);
+       gtk_text_buffer_get_end_iter(pTextBuffer, &iEnd);
+
+       if (fullscreen_info_c) g_free(fullscreen_info_c);
+       fullscreen_info_c = gtk_text_buffer_get_text(pTextBuffer, &iStart, &iEnd, TRUE);
+}
+
 static void config_window_create(void)
 {
        GtkWidget *win_vbox;
@@ -799,9 +824,11 @@ static void config_window_create(void)
        GtkWidget *scrolled;
        GtkWidget *viewport;
        GtkWidget *filter_view;
+       GtkWidget *fullscreen_info_view;
        GtkCellRenderer *renderer;
        GtkTreeSelection *selection;
        GtkTreeViewColumn *column;
+       GtkTextBuffer *buffer;
        gint i;
 
        configwindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
@@ -1221,6 +1248,39 @@ static void config_window_create(void)
                              fullscreen_clean_flip, &fullscreen_clean_flip_c);
        pref_checkbox_new_int(group, _("Disable screen saver"),
                              fullscreen_disable_saver, &fullscreen_disable_saver_c);
+       pref_checkbox_new_int(group, _("Always show fullscreen info"),
+                             show_fullscreen_info, &show_fullscreen_info_c);
+       pref_label_new(group, _("Fullscreen info string"));
+
+       scrolled = gtk_scrolled_window_new(NULL, NULL);
+       gtk_widget_set_size_request(scrolled, 200, 150);
+       gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
+       gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
+                                      GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+       gtk_box_pack_start(GTK_BOX(group), scrolled, TRUE, TRUE, 5);
+       gtk_widget_show(scrolled);
+
+       fullscreen_info_view = gtk_text_view_new();
+       gtk_widget_set_tooltip_markup(fullscreen_info_view,
+       _("<i>%name%</i> results in the filename of the picture.\n"
+         "Also available: <i>%collection%</i>, <i>%number%</i>, <i>%total%</i>, <i>%date%</i>,\n"
+         "<i>%size%</i> (filesize), <i>%width%</i>, <i>%height%</i>, <i>%res%</i> (resolution)\n"
+         "To access exif data use the exif name, e. g. <i>%fCamera%</i> is the formatted camera name,\n"
+         "<i>%Exif.Photo.DateTimeOriginal%</i> the date of the original shot.\n"
+         "If two or more variables are connected with the |-sign, it prints available variables with a separator.\n"
+         "<i>%fShutterSpeed%</i>|<i>%fISOSpeedRating%</i>|<i>%fFocalLength%</i> could show \"1/20s - 400 - 80 mm\" or \"1/200 - 80 mm\",\n"
+         "if there's no ISO information in the Exif data.\n"
+         "If a line is empty, it is removed. This allows to add lines that totally disappear when no data is available.\n"
+));
+
+gtk_container_add(GTK_CONTAINER(scrolled), fullscreen_info_view);
+       gtk_widget_show(fullscreen_info_view);
+
+       buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(fullscreen_info_view));
+       gtk_text_buffer_set_text(buffer, fullscreen_info, -1);
+       g_signal_connect(G_OBJECT(buffer), "changed",
+                        G_CALLBACK(fullscreen_info_view_changed_cb), fullscreen_info_view);
+
 
        group = pref_group_new(vbox, FALSE, _("Delete"), GTK_ORIENTATION_VERTICAL);
 
index d8d0094..159d199 100644 (file)
@@ -357,6 +357,8 @@ void save_options(void)
        write_bool_option(f, "fullscreen_clean_flip", fullscreen_clean_flip);
        write_bool_option(f, "fullscreen_disable_saver", fullscreen_disable_saver);
        write_bool_option(f, "fullscreen_above", fullscreen_above);
+       write_bool_option(f, "show_fullscreen_info", show_fullscreen_info);
+       write_char_option(f, "fullscreen_info", fullscreen_info);
 
        write_int_option(f, "custom_similarity_threshold", dupe_custom_threshold);
 
@@ -632,6 +634,10 @@ void load_options(void)
                        "fullscreen_disable_saver", value, fullscreen_disable_saver);
                fullscreen_above = read_bool_option(f, option,
                        "fullscreen_above", value, fullscreen_above);
+               show_fullscreen_info = read_bool_option(f, option,
+                       "show_fullscreen_info", value, show_fullscreen_info);
+               fullscreen_info = read_char_option(f, option,
+                       "fullscreen_info", value_all, fullscreen_info);
 
                dupe_custom_threshold = read_int_option(f, option,
                        "custom_similarity_threshold", value, dupe_custom_threshold);