Re: [evolution-patches] Patch to enable cursor and keyboard navigation in mail reader,(v8)



Hi all,

Thanks for all the comments, new patch created. Please review.

Menu name and tip is changed as suggested, in evolution.diff.

According to Larry's suggestion, just use html_object_engine() directly,
instead of introducing a new function.

And replys to Radek's comments is inline below,


On Thu, 2003-07-03 at 04:59, Radek Doulík wrote: 
> Hi York,
> 
> On Wed, 2003-07-02 at 11:22, yuedong du wrote:
> > Hi Radek,
> > 
> > Sorry to be so pushy, :-(,
> 
> Ops, I lost track of this patch, I am sorry.
> 
> > But if it's possible that this patch can be finished before USA national
> > day (7.4)? Because the vacation is long and later patch will depend on
> > this patch.
> 
> > Index: src/gtkhtml.c
> > ===================================================================
> > RCS file: /cvs/gnome/gtkhtml/src/gtkhtml.c,v
> > retrieving revision 1.520
> > diff -u -r1.520 gtkhtml.c
> > -- src/gtkhtml.c       26 Jun 2003 15:57:10 -0000      1.520
> > +++ src/gtkhtml.c       27 Jun 2003 07:22:29 -0000
> > @@ -738,7 +738,7 @@
> >                 fixed_desc = pango_font_description_from_string
> > (fixed_name);
> >                 if (pango_font_description_get_family (fixed_desc)) {
> >                         fixed_size = PANGO_PIXELS
> > (pango_font_description_get_size (fixed_desc));
> > -                       fixed_family =
> > pango_font_description_get_family (fixed_desc);
> > +                       fixed_family =
> > g_strdup(pango_font_description_get_family (fixed_desc));
> >                 } else {
> >                         g_free (fixed_name);
> >                         fixed_name = NULL;
> > @@ -760,11 +760,30 @@
> >         g_free (fixed_name);
> >  }
> 
> 
> okie, as Larry said, this is already fixed in CVS
Yes, removed in new patch.

>  
> > +static void
> > +set_caret_mode(HTMLEngine *engine, gboolean caret_mode)
> > +{
> > +       if (engine->editable) return;
> 
> please could you indent this part like this
OK, changed.

> if (engine->editable)
> 	return;
> 
> > +
> > +       engine->caret_mode = caret_mode;
> > +
> > +       /* Normally, blink cursor handler is setup in focus in event.
> > +        * However, in the case focus already in this engine, and user
> > +        * type F7 to enable cursor, we must setup the handler by
> > +        * ourselves.
> > +        */
> > +       if (caret_mode && !engine->blinking_timer_id && engine->have_focus)
> > +               html_engine_setup_blinking_cursor (engine);
> > +
> > +       return;
> > +}
> > +
> >  /* GtkWidget methods.  */
> >  static void
> >  style_set (GtkWidget *widget, GtkStyle  *previous_style)
> >  {
> >         HTMLEngine *engine = GTK_HTML (widget)->engine;
> > +       gboolean caret_mode = FALSE;
> >  
> >         /* we don't need to set font's in idle time so call idle callback directly to avoid
> >            recalculating whole document
> > @@ -779,6 +798,8 @@
> >                 }
> >         }
> >  
> > +       gtk_widget_style_get (widget, "caret_mode", &caret_mode, NULL);
> > +       set_caret_mode(engine, caret_mode);
> >  
> >         html_colorset_set_style (engine->defaultSettings->color_set, widget);
> >         html_colorset_set_unchanged (engine->settings->color_set,
> > @@ -1485,8 +1506,10 @@
> >                                 if (obj && ((HTML_IS_IMAGE (obj) && HTML_IMAGE (obj)->url && *HTML_IMAGE (obj)->url)
> >                                             || HTML_IS_LINK_TEXT (obj)))
> >                                         html_engine_set_focus_object (orig_e, obj);
> > -                               else
> > +                               else {
> >                                         html_engine_set_focus_object (orig_e, NULL);
> > +                                       html_engine_jump_at (engine, x, y);
> 
> I guess you want to do this only when engine->caret_mode is TRUE

Previously , I thought jump to there event not in caret_mode is of no
harm. OK, now changed to only when caret_mode is true jumpt there.

> > +                               }
> >                         }
> >                         if (html->allow_selection) {
> >                                 if (event->state & GDK_SHIFT_MASK)
> > @@ -2605,6 +2628,13 @@
> >                                                                      _("The color of the spelling error markers"),
> >                                                                      GDK_TYPE_COLOR,
> >                                                                      G_PARAM_READABLE));
> > +       gtk_widget_class_install_style_property (widget_class,
> > +                                               g_param_spec_boxed ("caret_mode",
> > +                                                                   _("Caret Mode"),
> > +                                                                   _("Enable cursor when reading mail"),
> > +                                                                   G_TYPE_BOOLEAN,
> > +                                                                   G_PARAM_READABLE));
> > +
> >  
> >         widget_class->realize = realize;
> >         widget_class->unrealize = unrealize;
> > @@ -3794,9 +3824,6 @@
> >  cursor_move (GtkHTML *html, GtkDirectionType dir_type, GtkHTMLCursorSkipType skip)
> >  {
> >         gint amount;
> > -
> > -       if (!html_engine_get_editable (html->engine))
> > -               return;
> >  
> >         if (html->engine->selection_mode) {
> >                 if (!html->engine->mark)
> > Index: src/htmlengine-edit-cursor.c
> > ===================================================================
> > RCS file: /cvs/gnome/gtkhtml/src/htmlengine-edit-cursor.c,v
> > retrieving revision 1.22
> > diff -u -r1.22 htmlengine-edit-cursor.c
> > -- src/htmlengine-edit-cursor.c        2 Apr 2003 05:41:47 -0000       1.22
> > +++ src/htmlengine-edit-cursor.c        27 Jun 2003 07:22:29 -0000
> > @@ -29,6 +29,7 @@
> >  #include "htmlengine-edit-table.h"
> >  #include "htmlengine-edit-tablecell.h"
> >  #include "htmlimage.h"
> > +#include "htmliframe.h"
> >  #include "htmlobject.h"
> >  #include "htmltable.h"
> >  
> > @@ -47,14 +48,42 @@
> >  static GdkColor image_stipple_active_on      = { 0, 0xffff, 0,      0 };
> >  static GdkColor image_stipple_active_off     = { 0, 0xffff, 0xffff, 0xffff };
> >  
> > +static HTMLEngine *
> > +get_direct_engine(HTMLObject * obj)
> > +{
> > +        HTMLObject * parent;
> > +       int i = 0;
> > +                                                                                
> > +        parent = obj;
> > +        while (parent) {
> > +                if ((HTML_OBJECT_TYPE (parent) == HTML_TYPE_FRAME)
> > +                    || (HTML_OBJECT_TYPE (parent) == HTML_TYPE_IFRAME)) {
> > +                       return html_object_get_engine (parent, NULL);
> > +                }
> > +                parent = parent->parent;
> > +        }
> > +                                                                                
> > +        return NULL;
> > +}
> > +
> >  void
> >  html_engine_hide_cursor  (HTMLEngine *engine)
> >  {
> > +       HTMLEngine *e = engine;
> > +
> >         g_return_if_fail (engine != NULL);
> >         g_return_if_fail (HTML_IS_ENGINE (engine));
> >  
> > -       if (engine->editable && engine->cursor_hide_count == 0)
> > -               html_engine_draw_cursor_in_area (engine, 0, 0, -1, -1);
> > +       if ((engine->editable || engine->caret_mode) && engine->cursor_hide_count == 0) {
> > +               if (!engine->editable) {
> > +                       e = get_direct_engine(engine->cursor->object);
> > +                       if (e) {
> > +                               e->caret_mode = engine->caret_mode;
> > +                               html_cursor_copy(e->cursor, engine->cursor);
> > +                       } else  e = engine;
> > +               }
> > +               html_engine_draw_cursor_in_area (e, 0, 0, -1, -1);
> > +       }
> >  
> >         engine->cursor_hide_count++;
> >  }
> > @@ -62,22 +91,37 @@
> >  void
> >  html_engine_show_cursor  (HTMLEngine *engine)
> >  {
> > +        HTMLEngine * e = engine;
> > +
> >         g_return_if_fail (engine != NULL);
> >         g_return_if_fail (HTML_IS_ENGINE (engine));
> > +       g_return_if_fail (engine->cursor != NULL);
> >  
> >         if (engine->cursor_hide_count > 0) {
> >                 engine->cursor_hide_count--;
> > -               if (engine->editable && engine->cursor_hide_count == 0)
> > -                       html_engine_draw_cursor_in_area (engine, 0, 0, -1, -1);
> > +               if ((engine->editable || engine->caret_mode) && engine->cursor_hide_count == 0) {
> > +                       if (!engine->editable) {
> > +                               e = get_direct_engine(engine->cursor->object);
> > +                               if (e) {
> > +                                       e->caret_mode = engine->caret_mode;
> > +                                       html_cursor_copy(e->cursor, engine->cursor);
> > +                               } else e = engine;
> > +                       }
> > +                       html_engine_draw_cursor_in_area (e, 0, 0, -1, -1);
> > +               }
> >         }
> >  }
> >  
> >  static gboolean
> >  clip_rect (HTMLEngine *engine, gint x, gint y, gint width, gint height, gint *x1, gint *y1, gint *x2, gint *y2)
> >  {
> > -       if (*x1 >= x + width || *y1 >= y + height || *x2 < x || *y2 < y)
> > +       if (*x1 > x + width || *y1 > y + height || *x2 < x || *y2 < y)
> >                 return FALSE;
> >  
> > +       if (*x1 == x + width)
> > +               *x1 = x + width - 1;
> > +       if (*y1 == y + width)
> > +               *y1 = y + height - 1;
> 
> Larry, please could you check this doesn't break clipping?
> 
> >         if (*x2 >= x + width)
> >                 *x2 = x + width - 1;
> >         if (*y2 >= y + height)
> > @@ -265,15 +309,13 @@
> >         gint x1, y1, x2, y2;
> >         GdkRectangle pos;
> >  
> > -       g_assert (engine->editable);
> > -
> > -       if (engine->editable && (engine->cursor_hide_count <= 0 && !engine->thaw_idle_id)) {
> > +       if ((engine->editable || engine->caret_mode) && (engine->cursor_hide_count <= 0 && !engine->thaw_idle_id)) {
> >                 html_engine_draw_table_cursor (engine);
> >                 html_engine_draw_cell_cursor (engine);
> >                 html_engine_draw_image_cursor (engine);
> >         }
> >  
> > -       if (!cursor_enabled || engine->cursor_hide_count > 0 || ! engine->editable || engine->thaw_idle_id)
> > +       if (!cursor_enabled || engine->cursor_hide_count > 0 || !(engine->editable || engine->caret_mode) || engine->thaw_idle_id)
> >                 return;
> >  
> >         obj = engine->cursor->object;
> > @@ -289,14 +331,23 @@
> >                 y = 0;
> >         }
> >  
> > -       
> >         html_object_get_cursor (obj, engine->painter, offset, &x1, &y1, &x2, &y2);
> > -       
> >         pos.x = x1; 
> >         pos.y = y1;
> >         pos.width = x2 - x1;
> >         pos.height = x2 - x1;
> >         gtk_im_context_set_cursor_location (GTK_HTML (engine->widget)->priv->im_context, &pos);
> > +
> > +       obj = g_object_get_data(G_OBJECT(gtk_widget_get_parent(GTK_WIDGET(engine->widget))), "embeddedelement");        
> > +       if (obj) {
> > +               HTMLEmbedded * element;
> > +
> > +               element = HTML_EMBEDDED(obj);
> > +               x1 -= element->abs_x;
> > +               x2 -= element->abs_x;
> > +               y1 -= element->abs_y;
> > +               y2 -= element->abs_y;
> > +       }
> 
> I think this could be rather implemented as part of get_cursor of embedded object?

Because the focused object is not the embedded object, so I cannot
implement it into embeded object's get_cursor. But it can be implemented
in get_cursor of htmlobject.

Now I change it as below, deprecate using of "embeddedelement" on
g_object. Much cleaner I think.



> >  -- src/htmlobject.c    1 May 2003 16:41:23 -0000       1.160
+++ src/htmlobject.c    3 Jul 2003 10:42:41 -0000
@@ -1080,6 +1080,17 @@
                *y1 -= (missing >> 1) + ((missing >> 1) & 1);
                *y2 += missing >> 1;
        }
+
+       while (self) {
+               if (html_object_is_frame(self)) {
+                       *x1 -= HTML_EMBEDDED(self)->abs_x;
+                       *x2 -= HTML_EMBEDDED(self)->abs_x;
+                       *y1 -= HTML_EMBEDDED(self)->abs_y;
+                       *y2 -= HTML_EMBEDDED(self)->abs_y;
+                       break;
+               }
+               self = self->parent;
+       }
}




> >         if (clip_rect (engine, x, y, width, height, &x1, &y1, &x2, &y2)) {
> >                 gdk_draw_line (engine->window, engine->invert_gc, x1, y1, x2, y2);
> > Index: src/htmlengine-edit-movement.c
> > ===================================================================
> > RCS file: /cvs/gnome/gtkhtml/src/htmlengine-edit-movement.c,v
> > retrieving revision 1.15
> > diff -u -r1.15 htmlengine-edit-movement.c
> > -- src/htmlengine-edit-movement.c      25 Apr 2001 21:31:53 -0000      1.15
> > +++ src/htmlengine-edit-movement.c      27 Jun 2003 07:22:30 -0000
> > @@ -275,8 +275,10 @@
> >                 if (new_y == y)
> >                         break;
> >  
> > -               if (new_y < start_y)
> > +               if (new_y < start_y) {
> > +                       html_engine_show_cursor (engine);
> >                         return 0;
> > +               }
> 
> nice, this looks like bug I have been looking for some time, great
> 
> > 
> >                 if (new_y - start_y >= amount) {
> >                         html_cursor_copy (cursor, &prev_cursor);
> > Index: src/htmlengine.c
> > ===================================================================
> > RCS file: /cvs/gnome/gtkhtml/src/htmlengine.c,v
> > retrieving revision 1.545
> > diff -u -r1.545 htmlengine.c
> > -- src/htmlengine.c    25 Jun 2003 18:15:46 -0000      1.545
> > +++ src/htmlengine.c    27 Jun 2003 07:22:35 -0000
> > @@ -3583,6 +3583,7 @@
> >         engine->allow_frameset = FALSE;
> >  
> >         engine->editable = FALSE;
> > +       engine->caret_mode = FALSE;
> >         engine->clipboard = NULL;
> >         engine->clipboard_stack = NULL;
> >         engine->selection_stack  = NULL;
> > @@ -4603,12 +4604,14 @@
> >                 html_engine_ensure_editable (e);
> >                 html_cursor_home (e->cursor, e);
> >                 e->newPage = FALSE;
> > -
> >                 if (e->have_focus)
> >                         html_engine_setup_blinking_cursor (e);
> >         } else {
> > -               if (e->have_focus)
> > -                       html_engine_stop_blinking_cursor (e);
> > +               if (e->have_focus )
> > +                       if (e->caret_mode)
> > +                               html_engine_setup_blinking_cursor (e);
> > +                       else 
> > +                               html_engine_stop_blinking_cursor (e);
> >         }
> >  }
> >  
> > @@ -4640,7 +4643,7 @@
> >         g_return_if_fail (engine != NULL);
> >         g_return_if_fail (HTML_IS_ENGINE (engine));
> >  
> > -       if (engine->editable) {
> > +       if (engine->editable || engine->caret_mode) {
> >                 if (! engine->have_focus && have_focus)
> >                         html_engine_setup_blinking_cursor (engine);
> >                 else if (engine->have_focus && ! have_focus)
> > @@ -4679,9 +4682,6 @@
> >         gint x1, y1, x2, y2, xo, yo;
> >  
> >         g_return_val_if_fail (e != NULL, FALSE);
> > -
> > -       if (! e->editable)
> > -               return FALSE;
> 
> shouldn't this be rather
> 
> if (!e->editable && !e->caret_mode)
> 	return FALSE;
> 
> ?

The modification here made html_engine_make_cursor_visible() always made
cursor inside of view, either in editor/reader and caret mode/NOT caret
mode. Suppose you start evolution with caret mode disabled, and now you
scroll to somewhere in a mail, then F7 to enable caret mode. The cursor
maybe outside of user's view. 

> >  
> >         if (e->cursor->object == NULL)
> >                 return FALSE;
> > Index: src/htmlengine.h
> > ===================================================================
> > RCS file: /cvs/gnome/gtkhtml/src/htmlengine.h,v
> > retrieving revision 1.168
> > diff -u -r1.168 htmlengine.h
> > -- src/htmlengine.h    19 May 2003 12:58:36 -0000      1.168
> > +++ src/htmlengine.h    27 Jun 2003 07:22:36 -0000
> > @@ -65,6 +65,7 @@
> >         GdkGC *invert_gc;
> >  
> >         gboolean editable;
> > +       gboolean caret_mode;
> >  
> >         HTMLObject *clipboard;
> >         guint       clipboard_len;
> > Index: src/htmliframe.c
> > ===================================================================
> > RCS file: /cvs/gnome/gtkhtml/src/htmliframe.c,v
> > retrieving revision 1.74
> > diff -u -r1.74 htmliframe.c
> > -- src/htmliframe.c    19 May 2003 13:12:04 -0000      1.74
> > +++ src/htmliframe.c    27 Jun 2003 07:22:37 -0000
> > @@ -592,6 +592,7 @@
> >  
> >         new_widget = gtk_html_new ();
> >         new_html = GTK_HTML (new_widget);
> > +       new_html->engine->cursor_hide_count = 0;
> >  
> >         new_tokenizer = html_tokenizer_clone (parent_html->engine->ht);
> 
Index: mail/evolution-mail.schemas
===================================================================
RCS file: /cvs/gnome/evolution/mail/evolution-mail.schemas,v
retrieving revision 1.17
diff -u -r1.17 evolution-mail.schemas
--- mail/evolution-mail.schemas	25 Jun 2003 16:20:38 -0000	1.17
+++ mail/evolution-mail.schemas	3 Jul 2003 10:42:25 -0000
@@ -174,6 +174,34 @@
     </schema>
 
     <schema>
+      <key>/schemas/apps/evolution/mail/display/caret_mode</key>
+      <applyto>/apps/evolution/mail/display/caret_mode</applyto>
+      <owner>evolution-mail</owner>
+      <type>boolean</type>
+      <default>false</default>
+      <locale name="C">
+         <short>Enable/disable caret mode</short>
+         <long>
+	  Enable caret mode, so that you can see a cursor when reading mail.
+         </long>
+      </locale>
+    </schema>
+
+    <schema>
+      <key>/schemas/apps/evolution/mail/display/caret_mode</key>
+      <applyto>/apps/evolution/mail/display/caret_mode</applyto>
+      <owner>evolution-mail</owner>
+      <type>boolean</type>
+      <default>false</default>
+      <locale name="C">
+         <short>Enable/disable caret mode</short>
+         <long>
+	  Enable caret mode, so that you can see a cursor when reading mail.
+         </long>
+      </locale>
+    </schema>
+
+    <schema>
       <key>/schemas/apps/evolution/mail/display/load_http_images</key>
       <applyto>/apps/evolution/mail/display/load_http_images</applyto>
       <owner>evolution-mail</owner>
Index: mail/folder-browser-ui.c
===================================================================
RCS file: /cvs/gnome/evolution/mail/folder-browser-ui.c,v
retrieving revision 1.80
diff -u -r1.80 folder-browser-ui.c
--- mail/folder-browser-ui.c	11 Jun 2003 16:19:34 -0000	1.80
+++ mail/folder-browser-ui.c	3 Jul 2003 10:42:29 -0000
@@ -104,6 +104,7 @@
 	BONOBO_UI_UNSAFE_VERB ("ToolsVFolderSubject", vfolder_subject),
 	BONOBO_UI_UNSAFE_VERB ("ViewLoadImages", load_images),
 	/* ViewHeaders stuff is a radio */
+	/* CaretMode is a toggle */
 
 	BONOBO_UI_VERB_END
 };
@@ -238,6 +239,7 @@
 	{ "ViewFullHeaders", IS_0MESSAGE },
 	{ "ViewNormal",      IS_0MESSAGE },
 	{ "ViewSource",      IS_0MESSAGE },
+	{ "CaretMode",       IS_0MESSAGE },
 	
 	{ "AddSenderToAddressbook",   IS_INCOMING_FOLDER | SELECTION_SINGLE | ANY_THREADED | HAS_FLAGS },
 	
@@ -517,6 +519,7 @@
 	FolderBrowserSelectionState prev_state;
 	GConfClient *gconf;
 	int style;
+	gboolean caret_mode;
 	
 	gconf = mail_config_get_gconf_client ();
 	
@@ -527,6 +530,10 @@
 	
 	ui_add (fb, "message", message_verbs, message_pixcache);
 	
+	caret_mode = gconf_client_get_bool (gconf, "/apps/evolution/mail/display/caret_mode", NULL);
+	bonobo_ui_component_set_prop(uic, "/commands/CaretMode", "state", caret_mode?"1":"0", NULL);
+	bonobo_ui_component_add_listener (uic, "CaretMode", folder_browser_toggle_caret_mode, fb);
+
 	/* Display Style */
 	style = gconf_client_get_int (gconf, "/apps/evolution/mail/display/message_style", NULL);
 	style = style >= 0 && style < MAIL_CONFIG_DISPLAY_MAX ? style : 0;
Index: mail/folder-browser.c
===================================================================
RCS file: /cvs/gnome/evolution/mail/folder-browser.c,v
retrieving revision 1.347
diff -u -r1.347 folder-browser.c
--- mail/folder-browser.c	23 Jun 2003 16:56:26 -0000	1.347
+++ mail/folder-browser.c	3 Jul 2003 10:42:37 -0000
@@ -1361,6 +1361,24 @@
 }
 
 void
+folder_browser_toggle_caret_mode(BonoboUIComponent	*component,
+				   const char		* path,
+				   Bonobo_UIComponent_EventType type,
+				   const char		* state,
+				   gpointer		user_data)
+{
+	FolderBrowser *fb = user_data;
+	GConfClient *gconf;
+	
+        if (type != Bonobo_UIComponent_STATE_CHANGED)
+		return;
+
+	gconf = mail_config_get_gconf_client ();
+	gconf_client_set_bool (gconf, "/apps/evolution/mail/display/caret_mode",
+			       atoi(state), NULL);
+}
+
+void
 folder_browser_set_message_display_style (BonoboUIComponent           *component,
 					  const char                  *path,
 					  Bonobo_UIComponent_EventType type,
Index: mail/folder-browser.h
===================================================================
RCS file: /cvs/gnome/evolution/mail/folder-browser.h,v
retrieving revision 1.69
diff -u -r1.69 folder-browser.h
--- mail/folder-browser.h	24 Mar 2003 13:27:32 -0000	1.69
+++ mail/folder-browser.h	3 Jul 2003 10:42:40 -0000
@@ -169,6 +169,12 @@
 					 const char                  *state,
 					 gpointer                     user_data);
 
+void folder_browser_toggle_caret_mode (BonoboUIComponent           *component,
+				       const char                  *path,
+				       Bonobo_UIComponent_EventType type,
+				       const char                  *state,
+				       gpointer                     user_data);
+
 void folder_browser_set_message_display_style (BonoboUIComponent           *component,
 					       const char                  *path,
 					       Bonobo_UIComponent_EventType type,
Index: mail/mail-config.c
===================================================================
RCS file: /cvs/gnome/evolution/mail/mail-config.c,v
retrieving revision 1.284
diff -u -r1.284 mail-config.c
--- mail/mail-config.c	25 Jun 2003 16:54:17 -0000	1.284
+++ mail/mail-config.c	3 Jul 2003 10:42:42 -0000
@@ -85,6 +85,7 @@
 	
 	guint font_notify_id;
 	guint spell_notify_id;
+	guint caret_mode_notify_id;
 
 	GPtrArray *mime_types;
 	guint mime_types_notify_id;
@@ -441,6 +442,7 @@
 	char *fix_font;
 	char *var_font;
 	gint red = 0xffff, green = 0, blue = 0;
+	gboolean caret_mode;
 	
 	/*
 	 * This is the wrong way to get the path but it needs to 
@@ -463,12 +465,14 @@
 	custom = gconf_client_get_bool (config->gconf, "/apps/evolution/mail/display/fonts/use_custom", NULL);
 	var_font = gconf_client_get_string (config->gconf, "/apps/evolution/mail/display/fonts/variable", NULL);
 	fix_font = gconf_client_get_string (config->gconf, "/apps/evolution/mail/display/fonts/monospace", NULL);
+	caret_mode = gconf_client_get_bool (config->gconf, "/apps/evolution/mail/display/caret_mode", NULL);
 
  	CONFIG_GET_SPELL_VALUE (int, "/spell_error_color_red",   red, (void)0, (int));
  	CONFIG_GET_SPELL_VALUE (int, "/spell_error_color_green", green, (void)0, (int));
  	CONFIG_GET_SPELL_VALUE (int, "/spell_error_color_blue",  blue, (void)0, (int));
 
 	fprintf (rc, "style \"evolution-mail-custom-fonts\" {\n");
+	fprintf (rc, "        GtkHTML::caret_mode = %d\n", caret_mode ? 1 :0);
 	fprintf (rc, "        GtkHTML::spell_error_color = \"#%02x%02x%02x\"\n",
 		 0xff & (red >> 8), 0xff & (green >> 8), 0xff & (blue >> 8));
 
@@ -542,6 +546,8 @@
 							  gconf_style_changed, NULL, NULL, NULL);
 	config->spell_notify_id = gconf_client_notify_add (config->gconf, "/GNOME/Spell",
 							   gconf_style_changed, NULL, NULL, NULL);
+	config->caret_mode_notify_id = gconf_client_notify_add (config->gconf, "/apps/evolution/mail/display/caret_mode",
+							        gconf_style_changed, NULL, NULL, NULL);
 
 	gconf_client_add_dir (config->gconf, "/apps/evolution/mail/labels",
 			      GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
Index: ui/evolution-mail-message.xml
===================================================================
RCS file: /cvs/gnome/evolution/ui/evolution-mail-message.xml,v
retrieving revision 1.46
diff -u -r1.46 evolution-mail-message.xml
--- ui/evolution-mail-message.xml	28 Feb 2003 17:26:24 -0000	1.46
+++ ui/evolution-mail-message.xml	3 Jul 2003 10:42:49 -0000
@@ -5,6 +5,10 @@
     <cmd name="AddSenderToAddressbook"
      _tip="Add Sender to Addressbook"/>
 
+    <cmd name="CaretMode"
+    _tip="Show a blinking cursor in the body of displayed messages"
+    type = "toggle" state = "0" accel="F7"/>
+
     <cmd name="MailNext"
      _tip="Display the next message"/>
 
@@ -264,6 +268,7 @@
 	</submenu>
         <submenu name="MessageDisplay" _label="_Message Display">
           <menuitem name="ViewLoadImages" verb="" _label="Load _Images"/>
+          <menuitem name="CaretMode" verb="" _label="Caret _Mode"/>
 
 	  <separator f="" name="emaillist"/>
 
Index: src/gtkhtml.c
===================================================================
RCS file: /cvs/gnome/gtkhtml/src/gtkhtml.c,v
retrieving revision 1.521
diff -u -r1.521 gtkhtml.c
--- src/gtkhtml.c	27 Jun 2003 15:51:06 -0000	1.521
+++ src/gtkhtml.c	3 Jul 2003 10:42:10 -0000
@@ -760,11 +760,31 @@
 	g_free (fixed_name);
 }
 
+static void
+set_caret_mode(HTMLEngine *engine, gboolean caret_mode)
+{
+	if (engine->editable)
+		return;
+
+	engine->caret_mode = caret_mode;
+
+	/* Normally, blink cursor handler is setup in focus in event.
+	 * However, in the case focus already in this engine, and user
+	 * type F7 to enable cursor, we must setup the handler by
+	 * ourselves.
+	 */
+	if (caret_mode && !engine->blinking_timer_id && engine->have_focus)
+		html_engine_setup_blinking_cursor (engine);
+
+	return;
+}
+
 /* GtkWidget methods.  */
 static void
 style_set (GtkWidget *widget, GtkStyle  *previous_style)
 {
 	HTMLEngine *engine = GTK_HTML (widget)->engine;
+	gboolean caret_mode = FALSE;
 
 	/* we don't need to set font's in idle time so call idle callback directly to avoid
 	   recalculating whole document
@@ -779,6 +799,8 @@
 		}
 	}
 
+	gtk_widget_style_get (widget, "caret_mode", &caret_mode, NULL);
+	set_caret_mode(engine, caret_mode);
 
 	html_colorset_set_style (engine->defaultSettings->color_set, widget);
 	html_colorset_set_unchanged (engine->settings->color_set,
@@ -1485,8 +1507,11 @@
 				if (obj && ((HTML_IS_IMAGE (obj) && HTML_IMAGE (obj)->url && *HTML_IMAGE (obj)->url)
 					    || HTML_IS_LINK_TEXT (obj)))
 					html_engine_set_focus_object (orig_e, obj);
-				else
+				else {
 					html_engine_set_focus_object (orig_e, NULL);
+					if (orig_e->caret_mode)
+						html_engine_jump_at (engine, x, y);
+				}
 			}
 			if (html->allow_selection) {
 				if (event->state & GDK_SHIFT_MASK)
@@ -2605,6 +2630,13 @@
 								     _("The color of the spelling error markers"),
 								     GDK_TYPE_COLOR,
 								     G_PARAM_READABLE));
+	gtk_widget_class_install_style_property (widget_class,
+						g_param_spec_boxed ("caret_mode",
+								    _("Caret Mode"),
+								    _("Enable cursor when reading mail"),
+								    G_TYPE_BOOLEAN,
+								    G_PARAM_READABLE));
+
 
 	widget_class->realize = realize;
 	widget_class->unrealize = unrealize;
@@ -3794,9 +3826,6 @@
 cursor_move (GtkHTML *html, GtkDirectionType dir_type, GtkHTMLCursorSkipType skip)
 {
 	gint amount;
-
-	if (!html_engine_get_editable (html->engine))
-		return;
 
 	if (html->engine->selection_mode) {
 		if (!html->engine->mark)
Index: src/htmlengine-edit-cursor.c
===================================================================
RCS file: /cvs/gnome/gtkhtml/src/htmlengine-edit-cursor.c,v
retrieving revision 1.22
diff -u -r1.22 htmlengine-edit-cursor.c
--- src/htmlengine-edit-cursor.c	2 Apr 2003 05:41:47 -0000	1.22
+++ src/htmlengine-edit-cursor.c	3 Jul 2003 10:42:11 -0000
@@ -50,11 +50,21 @@
 void
 html_engine_hide_cursor  (HTMLEngine *engine)
 {
+	HTMLEngine *e = engine;
+
 	g_return_if_fail (engine != NULL);
 	g_return_if_fail (HTML_IS_ENGINE (engine));
 
-	if (engine->editable && engine->cursor_hide_count == 0)
-		html_engine_draw_cursor_in_area (engine, 0, 0, -1, -1);
+	if ((engine->editable || engine->caret_mode) && engine->cursor_hide_count == 0) {
+		if (!engine->editable) {
+			e = html_object_engine(engine->cursor->object, NULL);
+			if (e) {
+				e->caret_mode = engine->caret_mode;
+				html_cursor_copy(e->cursor, engine->cursor);
+			} else 	e = engine;
+		}
+		html_engine_draw_cursor_in_area (e, 0, 0, -1, -1);
+	}
 
 	engine->cursor_hide_count++;
 }
@@ -62,22 +72,37 @@
 void
 html_engine_show_cursor  (HTMLEngine *engine)
 {
+        HTMLEngine * e = engine;
+
 	g_return_if_fail (engine != NULL);
 	g_return_if_fail (HTML_IS_ENGINE (engine));
+	g_return_if_fail (engine->cursor != NULL);
 
 	if (engine->cursor_hide_count > 0) {
 		engine->cursor_hide_count--;
-		if (engine->editable && engine->cursor_hide_count == 0)
-			html_engine_draw_cursor_in_area (engine, 0, 0, -1, -1);
+		if ((engine->editable || engine->caret_mode) && engine->cursor_hide_count == 0) {
+			if (!engine->editable) {
+				e = html_object_engine(engine->cursor->object, NULL);
+				if (e) {
+					e->caret_mode = engine->caret_mode;
+					html_cursor_copy(e->cursor, engine->cursor);
+				} else e = engine;
+			}
+			html_engine_draw_cursor_in_area (e, 0, 0, -1, -1);
+		}
 	}
 }
 
 static gboolean
 clip_rect (HTMLEngine *engine, gint x, gint y, gint width, gint height, gint *x1, gint *y1, gint *x2, gint *y2)
 {
-	if (*x1 >= x + width || *y1 >= y + height || *x2 < x || *y2 < y)
+	if (*x1 > x + width || *y1 > y + height || *x2 < x || *y2 < y)
 		return FALSE;
 
+	if (*x1 == x + width)
+		*x1 = x + width - 1;
+	if (*y1 == y + width)
+		*y1 = y + height - 1;
 	if (*x2 >= x + width)
 		*x2 = x + width - 1;
 	if (*y2 >= y + height)
@@ -265,15 +290,13 @@
 	gint x1, y1, x2, y2;
 	GdkRectangle pos;
 
-	g_assert (engine->editable);
-
-	if (engine->editable && (engine->cursor_hide_count <= 0 && !engine->thaw_idle_id)) {
+	if ((engine->editable || engine->caret_mode) && (engine->cursor_hide_count <= 0 && !engine->thaw_idle_id)) {
 		html_engine_draw_table_cursor (engine);
 		html_engine_draw_cell_cursor (engine);
 		html_engine_draw_image_cursor (engine);
 	}
 
-	if (!cursor_enabled || engine->cursor_hide_count > 0 || ! engine->editable || engine->thaw_idle_id)
+	if (!cursor_enabled || engine->cursor_hide_count > 0 || !(engine->editable || engine->caret_mode) || engine->thaw_idle_id)
 		return;
 
 	obj = engine->cursor->object;
Index: src/htmlengine-edit-movement.c
===================================================================
RCS file: /cvs/gnome/gtkhtml/src/htmlengine-edit-movement.c,v
retrieving revision 1.15
diff -u -r1.15 htmlengine-edit-movement.c
--- src/htmlengine-edit-movement.c	25 Apr 2001 21:31:53 -0000	1.15
+++ src/htmlengine-edit-movement.c	3 Jul 2003 10:42:12 -0000
@@ -275,8 +275,10 @@
 		if (new_y == y)
 			break;
 
-		if (new_y < start_y)
+		if (new_y < start_y) {
+			html_engine_show_cursor (engine);
 			return 0;
+		}
 
 		if (new_y - start_y >= amount) {
 			html_cursor_copy (cursor, &prev_cursor);
Index: src/htmlengine.c
===================================================================
RCS file: /cvs/gnome/gtkhtml/src/htmlengine.c,v
retrieving revision 1.545
diff -u -r1.545 htmlengine.c
--- src/htmlengine.c	25 Jun 2003 18:15:46 -0000	1.545
+++ src/htmlengine.c	3 Jul 2003 10:42:32 -0000
@@ -3583,6 +3583,7 @@
 	engine->allow_frameset = FALSE;
 
 	engine->editable = FALSE;
+	engine->caret_mode = FALSE;
 	engine->clipboard = NULL;
 	engine->clipboard_stack = NULL;
 	engine->selection_stack  = NULL;
@@ -4603,12 +4604,14 @@
 		html_engine_ensure_editable (e);
 		html_cursor_home (e->cursor, e);
 		e->newPage = FALSE;
-
 		if (e->have_focus)
 			html_engine_setup_blinking_cursor (e);
 	} else {
-		if (e->have_focus)
-			html_engine_stop_blinking_cursor (e);
+		if (e->have_focus )
+			if (e->caret_mode)
+				html_engine_setup_blinking_cursor (e);
+			else 
+				html_engine_stop_blinking_cursor (e);
 	}
 }
 
@@ -4640,7 +4643,7 @@
 	g_return_if_fail (engine != NULL);
 	g_return_if_fail (HTML_IS_ENGINE (engine));
 
-	if (engine->editable) {
+	if (engine->editable || engine->caret_mode) {
 		if (! engine->have_focus && have_focus)
 			html_engine_setup_blinking_cursor (engine);
 		else if (engine->have_focus && ! have_focus)
@@ -4679,9 +4682,6 @@
 	gint x1, y1, x2, y2, xo, yo;
 
 	g_return_val_if_fail (e != NULL, FALSE);
-
-	if (! e->editable)
-		return FALSE;
 
 	if (e->cursor->object == NULL)
 		return FALSE;
Index: src/htmlengine.h
===================================================================
RCS file: /cvs/gnome/gtkhtml/src/htmlengine.h,v
retrieving revision 1.168
diff -u -r1.168 htmlengine.h
--- src/htmlengine.h	19 May 2003 12:58:36 -0000	1.168
+++ src/htmlengine.h	3 Jul 2003 10:42:33 -0000
@@ -65,6 +65,7 @@
 	GdkGC *invert_gc;
 
 	gboolean editable;
+	gboolean caret_mode;
 
 	HTMLObject *clipboard;
 	guint       clipboard_len;
Index: src/htmliframe.c
===================================================================
RCS file: /cvs/gnome/gtkhtml/src/htmliframe.c,v
retrieving revision 1.74
diff -u -r1.74 htmliframe.c
--- src/htmliframe.c	19 May 2003 13:12:04 -0000	1.74
+++ src/htmliframe.c	3 Jul 2003 10:42:35 -0000
@@ -592,6 +592,7 @@
 
 	new_widget = gtk_html_new ();
 	new_html = GTK_HTML (new_widget);
+	new_html->engine->cursor_hide_count = 0;
 
 	new_tokenizer = html_tokenizer_clone (parent_html->engine->ht);
 
Index: src/htmlobject.c
===================================================================
RCS file: /cvs/gnome/gtkhtml/src/htmlobject.c,v
retrieving revision 1.160
diff -u -r1.160 htmlobject.c
--- src/htmlobject.c	1 May 2003 16:41:23 -0000	1.160
+++ src/htmlobject.c	3 Jul 2003 10:42:41 -0000
@@ -1080,6 +1080,17 @@
 		*y1 -= (missing >> 1) + ((missing >> 1) & 1);
 		*y2 += missing >> 1;
 	}
+
+	while (self) {
+		if (html_object_is_frame(self)) {
+			*x1 -= HTML_EMBEDDED(self)->abs_x;
+			*x2 -= HTML_EMBEDDED(self)->abs_x;
+			*y1 -= HTML_EMBEDDED(self)->abs_y;
+			*y2 -= HTML_EMBEDDED(self)->abs_y;
+			break;
+		}
+		self = self->parent;
+	}
 }
 
 /* Warning: `calc_size()' must have been called on `self' before this so that


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