Re: word wrap for logview



Heh, that's me told.

Here's an updated patch with those things fixed.

I am still not sure about the best way to deal with

> +        if (w > 100) w = w - 50; // hack to avoid the scrollbar and
> first column

but the solution I have put in seems to be correct, and seems to work.
Documentation is hard to find here, but see
http://maemo.org/maemowiki/MaemoGtk210Migration to explain this line:

 taken_width = taken_width * 2; // indented rows are indented twice...

I am unused to doing my own memory management, so apologies if there
are any howlers.

Cheers
David Hugh-Jones
PhD Candidate
Essex University Department of Government
http://davidhughjones.googlepages.com



2008/8/27 Emmanuele Bassi <ebassi gmail com>:
> On Fri, 2008-08-22 at 00:35 +0200, David Hugh-Jones wrote:
>> This patch (not very beautiful, apologies) adds word wrap to logview.
>> It also shows whole lines in tooltips.
>
> I can appreciate that logview does not have a consistent coding style,
> but please: avoid introducing something completely alien like this:
>
> +static void logview_scrollwindow_cb (GtkScrolledWindow *sw, GtkAllocation *al,
> +                                LogviewWindow *logview) {
> +    logview_update_grid_width(logview, al->width);
> +}
>
> it makes reviewing painful - and makes logview even worse to maintain.
>
> that should be:
>
> static void
> logview_scrollwindow_cb (GtkScrolledWindow *sw,
>                         GtkAllocation     *allocation,
>                         LogviewWindow     *logview)
> {
>  logview_update_grid_width (logview, allocation->width);
> }
>
> C is not for cuddly, touchy-feely variable names, but seriously: "al"?
> come on. ;-)
>
> +    logview->wordwrap = gtk_toggle_action_get_active(GTK_TOGGLE_ACTION (action));
> +    logview_update_grid_width(logview, -1);
> +    logview_save_prefs (logview);
>
> and please: consistency when using the parentesis; preferably, use a
> space between function name and arguments - this also stands for macros.
>
> +    if (!gtk_tree_view_get_tooltip_context(tree_view, &x, &y,
> keyboard_mode,
> +              &model, &path, &iter)) return FALSE;
>
> newline after the if.
>
> @@ -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);
>
> do not cast to GObject - it's useless (g_signal_connect() takes a
> gpointer) and might mask errors. yes, the existing lines do it: they
> should not.
>
> +    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);
> +    }
>
> this is really fugly (not just for the coding style), and will probably
> break for some combination of font-size and theme; what unit is the
> cut-off value of "100"? pixels? why one hundred pixels and not 80
> characters at the current font size and dpi?
>
> also you never check if cell_list is NULL or if data is NULL.
>
> ciao,
>  Emmanuele.
>
> --
> Emmanuele Bassi,
> W: http://www.emmanuelebassi.net
> B: http://log.emmanuelebassi.net
>
> _______________________________________________
> gnome-utils-list mailing list
> gnome-utils-list gnome org
> http://mail.gnome.org/mailman/listinfo/gnome-utils-list
>
Index: logview/logview.c
===================================================================
--- logview/logview.c	(revision 8031)
+++ 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 ();
     }
 }
@@ -613,7 +617,7 @@ logview_toggle_monitor (GtkAction *actio
 
 void
 logview_set_font (LogviewWindow *logview,
-                  const gchar   *fontname)
+              const gchar   *fontname)
 {
 	PangoFontDescription *font_desc;
 
@@ -635,7 +639,7 @@ logview_set_fontsize (LogviewWindow *log
 	PangoFontDescription *fontdesc;
 	PangoContext *context;
 	
-    g_assert (LOGVIEW_IS_WINDOW (logview));
+	g_assert (LOGVIEW_IS_WINDOW (logview));
 
 	context = gtk_widget_get_pango_context (logview->view);
 	fontdesc = pango_context_get_font_description (context);
@@ -670,6 +674,67 @@ 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;
+    gint taken_width = 0;
+
+    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 (cell_list == NULL || cell_list->data == NULL)
+        return;
+    if (logview->wordwrap) {
+        gtk_widget_style_get (GTK_WIDGET (tv), "expander-size", &taken_width, NULL);
+        taken_width = taken_width * 2; // indented rows are indented twice...
+        taken_width +=  gtk_scrolled_window_get_vscrollbar (GTK_SCROLLED_WINDOW 
+								(logview->scrolled))->allocation.width;
+        taken_width += 5; // prettier
+        if (w == -1) w = GTK_WIDGET (logview->scrolled)->allocation.width;
+        if (w > taken_width) w = w - taken_width; 
+        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 *allocation,
+						LogviewWindow *logview) 
+{
+    logview_update_grid_width (logview, allocation->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 +851,29 @@ 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 +899,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 +958,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, 
@@ -905,9 +997,9 @@ logview_init (LogviewWindow *logview)
                      G_CALLBACK (logview_version_selector_changed), logview);
    label = gtk_label_new (_("Version: "));
    
-   gtk_box_pack_end (GTK_BOX(logview->version_bar), logview->version_selector, FALSE, FALSE, 0);
-   gtk_box_pack_end (GTK_BOX(logview->version_bar), label, FALSE, FALSE, 0);
-   gtk_box_pack_end (GTK_BOX(main_view), logview->version_bar, FALSE, FALSE, 0);
+   gtk_box_pack_end (GTK_BOX (logview->version_bar), logview->version_selector, FALSE, FALSE, 0);
+   gtk_box_pack_end (GTK_BOX (logview->version_bar), label, FALSE, FALSE, 0);
+   gtk_box_pack_end (GTK_BOX (main_view), logview->version_bar, FALSE, FALSE, 0);
    
    logview->find_bar = logview_findbar_new ();
    gtk_box_pack_end (GTK_BOX (main_view), logview->find_bar, FALSE, FALSE, 0);
@@ -919,21 +1011,25 @@ 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);
 
    /* Add signal handlers */
-   g_signal_connect (G_OBJECT (selection), "changed",
+   g_signal_connect (selection, "changed",
                      G_CALLBACK (selection_changed_cb), logview);
-   g_signal_connect (G_OBJECT (logview->view), "row-expanded",
+   g_signal_connect (logview->view, "row-expanded",
                      G_CALLBACK (row_toggled_cb), logview);
-   g_signal_connect (G_OBJECT (logview->view), "row-collapsed",
+   g_signal_connect (logview->view, "row-collapsed",
                      G_CALLBACK (row_toggled_cb), logview);
-   g_signal_connect (G_OBJECT (logview), "configure_event",
+   g_signal_connect (logview->view, "query-tooltip", 
+                     G_CALLBACK(query_tooltip_cb), NULL);
+   g_signal_connect (logview, "configure_event",
                      G_CALLBACK (window_size_changed_cb), logview);
+   g_signal_connect (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 8031)
+++ 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 8031)
+++ 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;
@@ -49,12 +50,13 @@ struct _LogviewWindow {
 	GtkWidget *sidebar; 
 	GtkWidget *version_bar;
 	GtkWidget *version_selector;
-        GtkWidget *hpaned;
+	GtkWidget *hpaned;
     
-        GSList *logs;
+	GSList *logs;
 	Log *curlog;
 
 	int original_fontsize, fontsize;
+	gboolean wordwrap;
 };
 
 struct _LogviewWindowClass {
Index: logview/userprefs.h
===================================================================
--- logview/userprefs.h	(revision 8031)
+++ 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 8031)
+++ logview/logview.schemas.in	(working copy)
@@ -75,6 +75,20 @@
       </locale>
       </schema>
 
+      <schema>
+      <key>/schemas/apps/gnome-system-log/wordwrap</key>
+      <applyto>/apps/gnome-system-log/wordwrap</applyto>
+      <owner>logview</owner>
+      <type>bool</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>
+
   </schemalist>
   
 </gconfschemafile>
Index: logview/main.c
===================================================================
--- logview/main.c	(revision 8031)
+++ logview/main.c	(working copy)
@@ -158,7 +158,7 @@ main (int argc, char *argv[])
 	}
 
 	gtk_window_set_default_icon_name ("logviewer");
-	
+
 	prefs_connect (logview);
 	logview_menus_set_state (logview);
 	


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