word wrap for logview



This patch (not very beautiful, apologies) adds word wrap to logview.
It also shows whole lines in tooltips.
Comments welcome - but NB - I will be AFK until Tuesday....

David Hugh-Jones
PhD Candidate
Essex University Department of Government
http://davidhughjones.googlepages.com
Index: logview/logview.c
===================================================================
--- logview/logview.c	(revision 8011)
+++ logview/logview.c	(working copy)
@@ -70,6 +70,7 @@ static void logview_close_log (GtkAction
 static void logview_bigger_text (GtkAction *action, LogviewWindow *logview);
 static void logview_smaller_text (GtkAction *action, LogviewWindow *logview);
 static void logview_normal_text (GtkAction *action, LogviewWindow *logview);
+static void logview_toggle_wordwrap (GtkAction *action, LogviewWindow *logview);
 static void logview_calendar_set_state (LogviewWindow *logview);
 static void logview_search (GtkAction *action, LogviewWindow *logview);
 static void logview_help (GtkAction *action, GtkWidget *parent_window);
@@ -125,6 +126,8 @@ static GtkToggleActionEntry toggle_entri
 		G_CALLBACK (logview_toggle_sidebar), TRUE },
 	{ "MonitorLogs", NULL, N_("_Monitor"), "<control>M", N_("Monitor Current Log"),
 	  G_CALLBACK (logview_toggle_monitor), TRUE },
+	{ "TextWrap", NULL, N_("_Text Wrap"), "<control>T", N_("Enable Text Wrapping"),
+	  G_CALLBACK (logview_toggle_wordwrap), TRUE },
 	{"ShowCalendar", NULL,  N_("Ca_lendar"), "<control>L", N_("Show Calendar Log"), 
 	 G_CALLBACK (logview_toggle_calendar), TRUE },
 };
@@ -150,6 +153,7 @@ static const char *ui_description = 
 	"			<separator/>"
 	"			<menuitem action='Search'/>"
 	"			<menuitem action='CollapseAll'/>"
+	"			<menuitem action='TextWrap'/>"
 	"			<separator/>"
 	"			<menuitem action='ViewZoomIn'/>"
 	"			<menuitem action='ViewZoomOut'/>"
@@ -207,13 +211,11 @@ logview_select_log (LogviewWindow *logvi
     g_return_if_fail (LOGVIEW_IS_WINDOW (logview));
   
     logview_store_visible_range (logview);
-
     logview->curlog = log;
     logview_menus_set_state (logview);
     logview_calendar_set_state (logview);
     logview_repaint (logview);
     logview_update_findbar_visibility (logview);
-    
     logview_update_version_bar (logview);
     logview_save_prefs (logview); 
     gtk_widget_grab_focus (logview->view);
@@ -281,6 +283,7 @@ logview_menus_set_state (LogviewWindow *
     logview_menu_item_set_state (logview, "/LogviewMenu/ViewMenu/Search", (log != NULL));
     logview_menu_item_set_state (logview, "/LogviewMenu/EditMenu/Copy", (log != NULL));
     logview_menu_item_set_state (logview, "/LogviewMenu/EditMenu/SelectAll", (log != NULL));
+    logview_menu_item_toggle_set_active (logview, "/LogviewMenu/ViewMenu/TextWrap", prefs_get_wordwrap());
 }
 
 void
@@ -367,6 +370,7 @@ logview_save_prefs (LogviewWindow *logvi
 	    prefs_store_active_log (logview->curlog->name);
 	}
         prefs_store_fontsize (logview->fontsize);
+        prefs_store_wordwrap (logview->wordwrap);
 	prefs_save ();
     }
 }
@@ -670,6 +674,53 @@ logview_normal_text (GtkAction *action, 
 	logview->fontsize = logview->original_fontsize;
 	logview_set_fontsize (logview);
 }
+
+static gboolean logview_grid_changed(GtkTreeModel *tm, GtkTreePath *path,
+                                  GtkTreeIter *iter, gpointer data) {
+    gtk_tree_model_row_changed(tm, path, iter);
+    return FALSE;
+}
+
+static void
+logview_update_grid_width(LogviewWindow *logview, gint w) {
+    GtkTreeView *tv;
+    GtkTreeViewColumn *col;
+    GList *cell_list;
+
+    tv = GTK_TREE_VIEW(logview->view);
+    col = gtk_tree_view_get_column(tv, 0);
+    if (! col) return;
+    cell_list =  gtk_tree_view_column_get_cell_renderers(col);
+    if (logview->wordwrap) {
+        if (w == -1) w = GTK_WIDGET(logview->scrolled)->allocation.width;
+        if (w > 100) w = w - 50; // hack to avoid the scrollbar and first column
+        g_object_set(G_OBJECT(cell_list->data), "wrap-width", w,
+                                "wrap-mode", PANGO_WRAP_WORD_CHAR,
+                                NULL);
+    }
+    else {
+        g_object_set(G_OBJECT(cell_list->data), "wrap-width", -1, NULL);
+    } 
+
+    GtkTreeModel *tm = GTK_TREE_MODEL(gtk_tree_view_get_model(tv));
+    if (tm) gtk_tree_model_foreach(tm, logview_grid_changed, NULL);
+}
+
+static void logview_scrollwindow_cb (GtkScrolledWindow *sw, GtkAllocation *al,
+                                LogviewWindow *logview) {
+    logview_update_grid_width(logview, al->width); 
+}
+
+static void
+logview_toggle_wordwrap (GtkAction *action, LogviewWindow *logview) 
+{
+    g_assert (LOGVIEW_IS_WINDOW (logview));
+
+    logview->wordwrap = gtk_toggle_action_get_active(GTK_TOGGLE_ACTION (action));
+    logview_update_grid_width(logview, -1);
+    logview_save_prefs (logview);
+    // free everything
+}
 	
 static void
 logview_search (GtkAction *action, LogviewWindow *logview)
@@ -786,6 +837,28 @@ window_size_changed_cb (GtkWidget *widge
     return FALSE;
 }
 
+static gboolean
+query_tooltip_cb (GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, 
+GtkTooltip *tooltip, gpointer data) 
+{
+    GtkTreeIter iter;
+    GtkTreeView *tree_view = GTK_TREE_VIEW (widget);
+    GtkTreeModel *model = gtk_tree_view_get_model (tree_view);
+    GtkTreePath *path = NULL;
+    gchar *wholeline;
+    gchar *pathstring;
+
+    if (!gtk_tree_view_get_tooltip_context(tree_view, &x, &y, keyboard_mode, 
+              &model, &path, &iter)) return FALSE;
+    gtk_tree_model_get (model, &iter, 0, &wholeline, -1);
+    gtk_tooltip_set_text(tooltip, wholeline);
+    gtk_tree_view_set_tooltip_row (tree_view, tooltip, path);
+    gtk_tree_path_free(path);
+    g_free(wholeline);
+
+    return TRUE;
+}
+
 static void
 logview_window_finalize (GObject *object)
 {
@@ -811,7 +884,7 @@ logview_init (LogviewWindow *logview)
    GtkWidget *hpaned;
    GtkWidget *label;
    GtkWidget *main_view;
-   GtkWidget *loglist_scrolled, *scrolled;
+   GtkWidget *loglist_scrolled;
    PangoContext *context;
    PangoFontDescription *fontdesc;
    gchar *monospace_font_name;
@@ -870,23 +943,27 @@ logview_init (LogviewWindow *logview)
    gtk_paned_pack2 (GTK_PANED (hpaned), GTK_WIDGET (main_view), TRUE, TRUE);
 
    /* Scrolled window for the main view */
-   scrolled = gtk_scrolled_window_new (NULL, NULL);
-   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
+   logview->scrolled = gtk_scrolled_window_new (NULL, NULL);
+   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (logview->scrolled),
                GTK_POLICY_AUTOMATIC,
                GTK_POLICY_AUTOMATIC);
-   gtk_box_pack_start (GTK_BOX(main_view), scrolled, TRUE, TRUE, 0);
+   gtk_box_pack_start (GTK_BOX(main_view), logview->scrolled, TRUE, TRUE, 0);
 
    /* Main Tree View */
    logview->view = gtk_tree_view_new ();
    gtk_tree_view_set_fixed_height_mode (GTK_TREE_VIEW (logview->view), FALSE);
    gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (logview->view), FALSE);
+   g_object_set(G_OBJECT(logview->view), "has-tooltip", TRUE, NULL);
 
    /* Use the desktop monospace font */
    monospace_font_name = prefs_get_monospace ();
    logview_set_font (logview, monospace_font_name);
    g_free (monospace_font_name);
+   logview->wordwrap = prefs_get_wordwrap ();
 
    renderer = gtk_cell_renderer_text_new ();
+   g_object_set(G_OBJECT(renderer), "wrap-width", -1, "wrap-mode",
+                                        PANGO_WRAP_WORD_CHAR, NULL);
    column = gtk_tree_view_column_new ();
    gtk_tree_view_column_pack_start (column, renderer, TRUE);
    gtk_tree_view_column_set_attributes (column, renderer, 
@@ -919,8 +996,8 @@ logview_init (LogviewWindow *logview)
    logview->original_fontsize = pango_font_description_get_size (fontdesc) / PANGO_SCALE;
    logview->fontsize = logview->original_fontsize;
 
-   gtk_container_add (GTK_CONTAINER (scrolled), GTK_WIDGET (logview->view));
-   gtk_widget_show_all (scrolled);
+   gtk_container_add (GTK_CONTAINER (logview->scrolled), GTK_WIDGET (logview->view));
+   gtk_widget_show_all (logview->scrolled);
    
    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (logview->view));
    gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
@@ -932,8 +1009,12 @@ logview_init (LogviewWindow *logview)
                      G_CALLBACK (row_toggled_cb), logview);
    g_signal_connect (G_OBJECT (logview->view), "row-collapsed",
                      G_CALLBACK (row_toggled_cb), logview);
+   g_signal_connect (G_OBJECT(logview->view), "query-tooltip", 
+                     G_CALLBACK(query_tooltip_cb), NULL);
    g_signal_connect (G_OBJECT (logview), "configure_event",
                      G_CALLBACK (window_size_changed_cb), logview);
+   g_signal_connect (G_OBJECT (logview->scrolled), "size-allocate",
+                     G_CALLBACK (logview_scrollwindow_cb), logview);
 
    /* Status area at bottom */
    logview->statusbar = gtk_statusbar_new ();
Index: logview/userprefs.c
===================================================================
--- logview/userprefs.c	(revision 8011)
+++ logview/userprefs.c	(working copy)
@@ -33,6 +33,7 @@
 
 #define LOGVIEW_DEFAULT_HEIGHT 400
 #define LOGVIEW_DEFAULT_WIDTH 600
+#define LOGVIEW_DEFAULT_WORDWRAP FALSE
 
 /* logview settings */
 #define GCONF_DIR 		"/apps/gnome-system-log"
@@ -41,6 +42,7 @@
 #define GCONF_LOGFILE 		GCONF_DIR "/logfile"
 #define GCONF_LOGFILES 		GCONF_DIR "/logfiles"
 #define GCONF_FONTSIZE_KEY 	GCONF_DIR "/fontsize"
+#define GCONF_WORDWRAP_KEY 	GCONF_DIR "/wordwrap"
 
 /* desktop-wide settings */
 #define GCONF_MONOSPACE_FONT_NAME "/desktop/gnome/interface/monospace_font_name"
@@ -145,6 +147,7 @@ prefs_load (void)
 {
 	gchar *logfile;
 	int width, height, fontsize;
+        gboolean wordwrap;
 	UserPrefs *p;
 	GError *err;
 
@@ -180,10 +183,12 @@ prefs_load (void)
 	width = gconf_client_get_int (gconf_client, GCONF_WIDTH_KEY, NULL);
 	height = gconf_client_get_int (gconf_client, GCONF_HEIGHT_KEY, NULL);
 	fontsize = gconf_client_get_int (gconf_client, GCONF_FONTSIZE_KEY, NULL);
+        wordwrap = gconf_client_get_bool(gconf_client, GCONF_WORDWRAP_KEY, NULL);
 
 	p->width = (width == 0 ? LOGVIEW_DEFAULT_WIDTH : width);
 	p->height = (height == 0 ? LOGVIEW_DEFAULT_HEIGHT : height);
 	p->fontsize = fontsize;
+        p->wordwrap = wordwrap;
 
 	return p;
 }
@@ -257,6 +262,12 @@ prefs_get_height (void)
 	return prefs->height;
 }
 
+gboolean
+prefs_get_wordwrap (void)
+{
+	return prefs->wordwrap;
+}
+
 void
 prefs_free_loglist ()
 {
@@ -285,6 +296,12 @@ prefs_store_fontsize (int fontsize)
 }
 
 void
+prefs_store_wordwrap (gboolean wordwrap) 
+{
+	prefs->wordwrap = wordwrap;
+}
+
+void
 prefs_save (void)
 {
 	GSList *logs;
@@ -327,6 +344,12 @@ prefs_save (void)
 					      prefs->fontsize,
 					      NULL);
 	}
+
+	if (gconf_client_key_is_writable (gconf_client, GCONF_WORDWRAP_KEY, NULL))
+		gconf_client_set_bool(gconf_client,
+				      GCONF_WORDWRAP_KEY,
+				      prefs->wordwrap,
+				      NULL);
 }
 
 void
Index: logview/logview.h
===================================================================
--- logview/logview.h	(revision 8011)
+++ logview/logview.h	(working copy)
@@ -39,6 +39,7 @@ typedef struct _LogviewWindowClass Logvi
 struct _LogviewWindow {
 	GtkWindow parent_instance;
 
+        GtkWidget *scrolled;
 	GtkWidget *view;		
 	GtkWidget *statusbar;
 	GtkUIManager *ui_manager;
@@ -55,6 +56,7 @@ struct _LogviewWindow {
 	Log *curlog;
 
 	int original_fontsize, fontsize;
+	gboolean wordwrap;
 };
 
 struct _LogviewWindowClass {
Index: logview/userprefs.h
===================================================================
--- logview/userprefs.h	(revision 8011)
+++ logview/userprefs.h	(working copy)
@@ -25,6 +25,7 @@ typedef struct
 	gchar *logfile;
 	GSList *logs;
 	int width, height, fontsize;
+        gboolean wordwrap;
 } UserPrefs;
 
 gboolean prefs_get_have_tearoff (void);
@@ -33,6 +34,7 @@ gchar *prefs_get_active_log (void);
 GSList *prefs_get_logs (void);
 int prefs_get_width (void);
 int prefs_get_height (void);
+gboolean prefs_get_wordwrap (void);
 void prefs_store_log (gchar *name);
 void prefs_store_active_log (gchar *name);
 void prefs_store_fontsize (int fontsize);
Index: logview/logview.schemas.in
===================================================================
--- logview/logview.schemas.in	(revision 8011)
+++ logview/logview.schemas.in	(working copy)
@@ -66,6 +66,20 @@
       <applyto>/apps/gnome-system-log/logfiles</applyto>
       <owner>logview</owner>
       <type>list</type>
+      <default>false</default>
+      <locale name="C">
+        <short>Wrap lines in log files</short>
+        <long>Specifies whether or not lines should be wrapped when
+        viewing text files.
+       </long>
+      </locale>
+      </schema>
+
+      <schema>
+      <key>/schemas/apps/gnome-system-log/wordwrap</key>
+      <applyto>/apps/gnome-system-log/wordwrap</applyto>
+      <owner>logview</owner>
+      <type>bool</type>
       <list_type>string</list_type>
       <locale name="C">
         <short>Log files to open up on startup</short>
@@ -74,7 +88,6 @@
        </long>
       </locale>
       </schema>
-
   </schemalist>
   
 </gconfschemafile>
Index: logview/main.c
===================================================================
--- logview/main.c	(revision 8011)
+++ logview/main.c	(working copy)
@@ -158,8 +158,9 @@ main (int argc, char *argv[])
 	}
 
 	gtk_window_set_default_icon_name ("logviewer");
-	
+
 	prefs_connect (logview);
+
 	logview_menus_set_state (logview);
 	
 	gtk_widget_show (GTK_WIDGET (logview));


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