Trim trailing white spaces on empty lines.
[geeqie.git] / src / logwindow.c
index 04ed55e..440efbc 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Geeqie
- * Copyright (C) 2008 The Geeqie Team
+ * Copyright (C) 2008 - 2012 The Geeqie Team
  *
  * Author: Vladimir Nadvornik, Laurent Monin
  * based on logwindow.[ch] from Sylpheed 2.4.7 (C) Hiroyuki Yamamoto
 #include "main.h"
 #include "logwindow.h"
 
+#include "misc.h"
 #include "window.h"
 
 #include <gdk/gdkkeysyms.h>
 
-#define TRIM_LINES     25
-
 
 typedef struct _LogWindow LogWindow;
 
@@ -27,10 +26,10 @@ struct _LogWindow
        GtkWidget *window;
        GtkWidget *scrolledwin;
        GtkWidget *text;
-       
+
        GdkColor colors[LOG_COUNT];
 
-       gint lines;
+       guint lines;
 };
 
 typedef struct _LogDef LogDef;
@@ -58,7 +57,7 @@ static void hide_cb(GtkWidget *widget, LogWindow *logwin)
 static gboolean key_pressed(GtkWidget *widget, GdkEventKey *event,
                            LogWindow *logwin)
 {
-       if (event && event->keyval == GDK_Escape)
+       if (event && event->keyval == GDK_KEY_Escape)
                gtk_widget_hide(logwin->window);
        return FALSE;
 }
@@ -112,13 +111,15 @@ static LogWindow *log_window_create(void)
 static void log_window_init(LogWindow *logwin)
 {
        GtkTextBuffer *buffer;
+#if !GTK_CHECK_VERSION(3,0,0)
        GdkColormap *colormap;
-       gboolean success[LOG_COUNT - 1];
+       gboolean success[LOG_COUNT];
+#endif
        gint i;
 
        g_assert(logwin != NULL);
        g_assert(logwin->colors != NULL);
-
+#if !GTK_CHECK_VERSION(3,0,0)
        for (i = LOG_NORMAL; i < LOG_COUNT; i++)
                {
                gboolean ok = gdk_color_parse(logdefs[i].color, &logwin->colors[i]);
@@ -128,7 +129,7 @@ static void log_window_init(LogWindow *logwin)
                memcpy(&logwin->colors[i], &logwin->colors[LOG_NORMAL], sizeof(GdkColor));
                }
 
-       colormap = gdk_drawable_get_colormap(logwin->window->window);
+       colormap = gdk_drawable_get_colormap(gtk_widget_get_window(logwin->window));
        gdk_colormap_alloc_colors(colormap, logwin->colors, LOG_COUNT, FALSE, TRUE, success);
 
        for (i = LOG_NORMAL; i < LOG_COUNT; i++)
@@ -145,11 +146,12 @@ static void log_window_init(LogWindow *logwin)
                        break;
                        }
                }
-
+#endif
        buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(logwin->text));
        for (i = LOG_NORMAL; i < LOG_COUNT; i++)
                gtk_text_buffer_create_tag(buffer, logdefs[i].tag,
                                           "foreground-gdk", &logwin->colors[i],
+                                          "family", "MonoSpace",
                                           NULL);
 }
 
@@ -158,7 +160,7 @@ static void log_window_show(LogWindow *logwin)
        GtkTextView *text = GTK_TEXT_VIEW(logwin->text);
        GtkTextBuffer *buffer;
        GtkTextMark *mark;
-       
+
        g_assert(logwin != NULL);
 
        buffer = gtk_text_view_get_buffer(text);
@@ -166,8 +168,9 @@ static void log_window_show(LogWindow *logwin)
        gtk_text_view_scroll_mark_onscreen(text, mark);
 
        gtk_window_present(GTK_WINDOW(logwin->window));
-}
 
+       log_window_append("", LOG_NORMAL); // to flush memorized lines
+}
 
 void log_window_new(void)
 {
@@ -183,15 +186,56 @@ void log_window_new(void)
        log_window_show(logwindow);
 }
 
+typedef struct _LogMsg LogMsg;
+
+struct _LogMsg {
+       gchar *text;
+       LogType type;
+};
+
+
+static void log_window_insert_text(GtkTextBuffer *buffer, GtkTextIter *iter,
+                                  const gchar *text, const gchar *tag)
+{
+       gchar *str_utf8;
+
+       if (!text || !*text) return;
+
+       str_utf8 = utf8_validate_or_convert(text);
+       gtk_text_buffer_insert_with_tags_by_name(buffer, iter, str_utf8, -1, tag, NULL);
+       g_free(str_utf8);
+}
+
+
 void log_window_append(const gchar *str, LogType type)
 {
        GtkTextView *text;
        GtkTextBuffer *buffer;
        GtkTextIter iter;
-       gint line_limit = 1000; //FIXME: option
-       gchar *str_utf8;
+       guint line_limit = 1000; //FIXME: option
+       static GList *memory = NULL;
+
+       if (logwindow == NULL)
+               {
+               if (*str) {
+                       LogMsg *msg = g_new(LogMsg, 1);
 
-       if (logwindow == NULL) return;
+                       msg->text = g_strdup(str);
+                       msg->type = type;
+
+                       memory = g_list_prepend(memory, msg);
+
+                       while (g_list_length(memory) >= line_limit)
+                               {
+                               GList *work = g_list_last(memory);
+                               LogMsg *oldest_msg = work->data;
+
+                               g_free(oldest_msg->text);
+                               memory = g_list_delete_link(memory, work);
+                               }
+                       }
+               return;
+               }
 
        text = GTK_TEXT_VIEW(logwindow->text);
        buffer = gtk_text_view_get_buffer(text);
@@ -202,24 +246,38 @@ void log_window_append(const gchar *str, LogType type)
 
                gtk_text_buffer_get_start_iter(buffer, &start);
                end = start;
-               gtk_text_iter_forward_lines(&end, TRIM_LINES);
+               gtk_text_iter_forward_lines(&end, logwindow->lines - line_limit);
                gtk_text_buffer_delete(buffer, &start, &end);
-               logwindow->lines = gtk_text_buffer_get_line_count(buffer);
                }
 
        gtk_text_buffer_get_end_iter(buffer, &iter);
 
-       str_utf8 = utf8_validate_or_convert((gchar *)str);
-       gtk_text_buffer_insert_with_tags_by_name
-                       (buffer, &iter, str_utf8, -1, logdefs[type].tag, NULL);
+       {
+       GList *work = g_list_last(memory);
+
+       while (work)
+               {
+               GList *prev;
+               LogMsg *oldest_msg = work->data;
+
+               log_window_insert_text(buffer, &iter, oldest_msg->text, logdefs[oldest_msg->type].tag);
 
-       if (GTK_WIDGET_VISIBLE(text))
+               prev = work->prev;
+               memory = g_list_delete_link(memory, work);
+               work = prev;
+               }
+       }
+
+       log_window_insert_text(buffer, &iter, str, logdefs[type].tag);
+
+       if (gtk_widget_get_visible(GTK_WIDGET(text)))
                {
                GtkTextMark *mark;
-               
+
                mark = gtk_text_buffer_get_mark(buffer, "end");
                gtk_text_view_scroll_mark_onscreen(text, mark);
                }
 
-       logwindow->lines++;
+       logwindow->lines = gtk_text_buffer_get_line_count(buffer);
 }
+/* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */