[dia] l10n: handle % at either end of zoom level



commit 40413ba97d740d38e35208cdc3a8557d94646fc2
Author: Zander Brown <zbrown gnome org>
Date:   Fri Dec 13 15:53:31 2019 +0000

    l10n: handle % at either end of zoom level
    
    (Hopefully) fix https://gitlab.gnome.org/GNOME/dia/issues/441

 app/display.c   | 375 +++++++++++++++++++++++++++++++++++---------------------
 app/display.h   |  61 ++++-----
 app/interface.c |  76 +++++++++---
 app/interface.h |   4 +-
 app/menus.c     | 136 +++++++++++++++-----
 5 files changed, 437 insertions(+), 215 deletions(-)
---
diff --git a/app/display.c b/app/display.c
index e81ae7a2..e3242a39 100644
--- a/app/display.c
+++ b/app/display.c
@@ -69,7 +69,7 @@ update_zoom_status (DDisplay *ddisp)
     zoom_text = g_strdup_printf ("%.1f%%",
                                  ddisp->zoom_factor * 100.0 / DDISPLAY_NORMAL_ZOOM);
     zoomcombo = ddisp->zoom_status;
-    gtk_entry_set_text (GTK_ENTRY (g_object_get_data (G_OBJECT(zoomcombo), "user_data")),
+    gtk_entry_set_text (GTK_ENTRY (g_object_get_data (G_OBJECT (zoomcombo), "user_data")),
                         zoom_text);
   }
 
@@ -297,8 +297,8 @@ ddisplay_transform_coords_double (DDisplay *ddisp,
   double width = dia_interactive_renderer_get_width_pixels (DIA_INTERACTIVE_RENDERER (ddisp->renderer));
   double height = dia_interactive_renderer_get_height_pixels (DIA_INTERACTIVE_RENDERER (ddisp->renderer));
 
-  *xi = (x - visible->left)  * (real) width / (visible->right - visible->left);
-  *yi = (y - visible->top)  * (real) height / (visible->bottom - visible->top);
+  *xi = (x - visible->left)  * (double) width / (visible->right - visible->left);
+  *yi = (y - visible->top)  * (double) height / (visible->bottom - visible->top);
 }
 
 
@@ -313,22 +313,24 @@ ddisplay_transform_coords (DDisplay *ddisp,
   int width = dia_interactive_renderer_get_width_pixels (DIA_INTERACTIVE_RENDERER (ddisp->renderer));
   int height = dia_interactive_renderer_get_height_pixels (DIA_INTERACTIVE_RENDERER (ddisp->renderer));
 
-  *xi = ROUND ( (x - visible->left) * (real) width /
+  *xi = ROUND ( (x - visible->left) * (double) width /
                 (visible->right - visible->left) );
-  *yi = ROUND ( (y - visible->top) * (real) height /
+  *yi = ROUND ( (y - visible->top) * (double) height /
                 (visible->bottom - visible->top) );
 }
 
+
 /* Takes real length and returns pixel length */
-real
-ddisplay_transform_length (DDisplay *ddisp, real len)
+double
+ddisplay_transform_length (DDisplay *ddisp, double len)
 {
   return len * ddisp->zoom_factor;
 }
 
+
 /* Takes pixel length and returns real length */
-real
-ddisplay_untransform_length (DDisplay *ddisp, real len)
+double
+ddisplay_untransform_length (DDisplay *ddisp, double len)
 {
   return len / ddisp->zoom_factor;
 }
@@ -345,8 +347,8 @@ ddisplay_untransform_coords (DDisplay *ddisp,
   int width = dia_interactive_renderer_get_width_pixels (DIA_INTERACTIVE_RENDERER (ddisp->renderer));
   int height = dia_interactive_renderer_get_height_pixels (DIA_INTERACTIVE_RENDERER (ddisp->renderer));
 
-  *x = visible->left + xi*(visible->right - visible->left) / (real)width;
-  *y = visible->top +  yi*(visible->bottom - visible->top) / (real)height;
+  *x = visible->left + xi*(visible->right - visible->left) / (double) width;
+  *y = visible->top +  yi*(visible->bottom - visible->top) / (double) height;
 }
 
 
@@ -357,22 +359,23 @@ ddisplay_add_update_pixels (DDisplay *ddisp,
                             int       pixel_height)
 {
   DiaRectangle rect;
-  real size_x, size_y;
+  double size_x, size_y;
 
-  size_x = ddisplay_untransform_length(ddisp, pixel_width+1);
-  size_y = ddisplay_untransform_length(ddisp, pixel_height+1);
+  size_x = ddisplay_untransform_length (ddisp, pixel_width+1);
+  size_y = ddisplay_untransform_length (ddisp, pixel_height+1);
 
   rect.left = point->x - size_x/2.0;
   rect.top = point->y - size_y/2.0;
   rect.right = point->x + size_x/2.0;
   rect.bottom = point->y + size_y/2.0;
 
-  ddisplay_add_update(ddisp, &rect);
+  ddisplay_add_update (ddisp, &rect);
 }
 
+
 /** Free update_areas list */
 static void
-ddisplay_free_update_areas(DDisplay *ddisp)
+ddisplay_free_update_areas (DDisplay *ddisp)
 {
   GSList *l;
   l = ddisp->update_areas;
@@ -396,7 +399,14 @@ ddisplay_add_update_all(DDisplay *ddisp)
   ddisplay_add_update(ddisp, &ddisp->visible);
 }
 
-/** Marks a rectangle for update, with a pixel border around it.
+
+/**
+ * ddisplay_add_update_with_border:
+ * @ddisp: the #DDisplay
+ * @rect: the area to update
+ * @pixel_border: the border size around the area
+ *
+ * Marks a rectangle for update, with a pixel border around it.
  */
 void
 ddisplay_add_update_with_border (DDisplay           *ddisp,
@@ -404,14 +414,14 @@ ddisplay_add_update_with_border (DDisplay           *ddisp,
                                  int                 pixel_border)
 {
   DiaRectangle r;
-  real size = ddisplay_untransform_length(ddisp, pixel_border+1);
+  double size = ddisplay_untransform_length (ddisp, pixel_border+1);
 
   r.left = rect->left-size;
   r.top = rect->top-size;
   r.right = rect->right+size;
   r.bottom = rect->bottom+size;
 
-  ddisplay_add_update(ddisp, &r);
+  ddisplay_add_update (ddisp, &r);
 }
 
 void
@@ -611,27 +621,32 @@ ddisplay_set_origo (DDisplay *ddisp, double x, double y)
   ddisplay_update_rulers (ddisp, extents, visible);
 }
 
+
 void
-ddisplay_zoom (DDisplay *ddisp, Point *point, real magnify)
+ddisplay_zoom (DDisplay *ddisp, Point *point, double magnify)
 {
   DiaRectangle *visible;
-  real width, height, old_zoom;
+  double width, height, old_zoom;
 
   visible = &ddisp->visible;
 
-  if ((ddisp->zoom_factor <= DDISPLAY_MIN_ZOOM) && (magnify<=1.0))
+  if ((ddisp->zoom_factor <= DDISPLAY_MIN_ZOOM) && (magnify<=1.0)) {
     return;
-  if ((ddisp->zoom_factor >= DDISPLAY_MAX_ZOOM) && (magnify>=1.0))
+  }
+
+  if ((ddisp->zoom_factor >= DDISPLAY_MAX_ZOOM) && (magnify>=1.0)) {
     return;
+  }
 
   old_zoom = ddisp->zoom_factor;
   ddisp->zoom_factor = old_zoom * magnify;
 
   /* clip once more */
-  if (ddisp->zoom_factor < DDISPLAY_MIN_ZOOM)
+  if (ddisp->zoom_factor < DDISPLAY_MIN_ZOOM) {
     ddisp->zoom_factor = DDISPLAY_MIN_ZOOM;
-  else if (ddisp->zoom_factor > DDISPLAY_MAX_ZOOM)
+  } else if (ddisp->zoom_factor > DDISPLAY_MAX_ZOOM) {
     ddisp->zoom_factor = DDISPLAY_MAX_ZOOM;
+  }
 
   /* the real one used - after clipping */
   magnify = ddisp->zoom_factor / old_zoom;
@@ -639,19 +654,25 @@ ddisplay_zoom (DDisplay *ddisp, Point *point, real magnify)
   height = (visible->bottom - visible->top)/magnify;
 
 
-  ddisplay_set_origo(ddisp, point->x - width/2.0, point->y - height/2.0);
+  ddisplay_set_origo (ddisp, point->x - width/2.0, point->y - height/2.0);
 
-  ddisplay_update_scrollbars(ddisp);
-  ddisplay_add_update_all(ddisp);
-  ddisplay_flush(ddisp);
+  ddisplay_update_scrollbars (ddisp);
+  ddisplay_add_update_all (ddisp);
+  ddisplay_flush (ddisp);
 
   update_zoom_status (ddisp);
 }
 
-/* Zoom around the middle point of the visible area
+
+/**
+ * ddisplay_zoom_middle:
+ * @ddisp: the #DDisplay
+ * @magnify: the zoom level
+ *
+ * Zoom around the middle point of the visible area
  */
 void
-ddisplay_zoom_middle (DDisplay *ddisp, real magnify)
+ddisplay_zoom_middle (DDisplay *ddisp, double magnify)
 {
   Point middle;
   DiaRectangle *visible;
@@ -663,6 +684,7 @@ ddisplay_zoom_middle (DDisplay *ddisp, real magnify)
   ddisplay_zoom (ddisp, &middle, magnify);
 }
 
+
 /*
    When using the mouse wheel button to zoom in and out, it is more
    intuitive to maintain the drawing zoom center-point based on the
@@ -670,17 +692,20 @@ ddisplay_zoom_middle (DDisplay *ddisp, real magnify)
    from "jumping" around while zooming in and out.
  */
 void
-ddisplay_zoom_centered (DDisplay *ddisp, Point *point, real magnify)
+ddisplay_zoom_centered (DDisplay *ddisp, Point *point, double magnify)
 {
   DiaRectangle *visible;
-  real width, height;
+  double width, height;
   /* cursor position ratios */
-  real rx,ry;
+  double rx, ry;
 
-  if ((ddisp->zoom_factor <= DDISPLAY_MIN_ZOOM) && (magnify<=1.0))
+  if ((ddisp->zoom_factor <= DDISPLAY_MIN_ZOOM) && (magnify <= 1.0)) {
     return;
-  if ((ddisp->zoom_factor >= DDISPLAY_MAX_ZOOM) && (magnify>=1.0))
+  }
+
+  if ((ddisp->zoom_factor >= DDISPLAY_MAX_ZOOM) && (magnify >= 1.0)) {
     return;
+  }
 
   visible = &ddisp->visible;
 
@@ -694,69 +719,86 @@ ddisplay_zoom_centered (DDisplay *ddisp, Point *point, real magnify)
   ddisp->zoom_factor *= magnify;
 
   /* set new origin based on the calculated ratios before zooming */
-  ddisplay_set_origo(ddisp, point->x-(width*rx),point->y-(height*ry));
+  ddisplay_set_origo (ddisp, point->x-(width*rx),point->y-(height*ry));
 
-  ddisplay_update_scrollbars(ddisp);
-  ddisplay_add_update_all(ddisp);
-  ddisplay_flush(ddisp);
+  ddisplay_update_scrollbars (ddisp);
+  ddisplay_add_update_all (ddisp);
+  ddisplay_flush (ddisp);
 
   update_zoom_status (ddisp);
 }
 
-/** Set the display's snap-to-grid setting, updating menu and button
- * in the process */
+
+/**
+ * ddisplay_set_snap_to_grid:
+ * @ddisp: the #DDisplay
+ * @snap: should snap to grid be enabled
+ *
+ * Set the display's snap-to-grid setting, updating menu and button
+ * in the process
+ */
 void
-ddisplay_set_snap_to_grid(DDisplay *ddisp, gboolean snap)
+ddisplay_set_snap_to_grid (DDisplay *ddisp, gboolean snap)
 {
   GtkToggleAction *snap_to_grid;
   ddisp->grid.snap = snap;
 
   snap_to_grid = GTK_TOGGLE_ACTION (menus_get_action ("ViewSnaptogrid"));
-  if (is_integrated_ui ())
+  if (is_integrated_ui ()) {
     integrated_ui_toolbar_grid_snap_synchronize_to_display (ddisp);
+  }
   /* Currently, this can cause double emit, but that's a small problem. */
   gtk_toggle_action_set_active (snap_to_grid, ddisp->grid.snap);
-  ddisplay_update_statusbar(ddisp);
+  ddisplay_update_statusbar (ddisp);
 }
 
-/** Update the button showing whether snap-to-grid is on */
+
+/* Update the button showing whether snap-to-grid is on */
 static void
-update_snap_grid_status(DDisplay *ddisp)
+update_snap_grid_status (DDisplay *ddisp)
 {
-  if (ddisp->grid_status)
-  {
+  if (ddisp->grid_status) {
     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ddisp->grid_status),
                                   ddisp->grid.snap);
   }
 }
 
-/** Set the display's mainpoint magnetism setting, updating menu and button
- * in the process */
+
+/**
+ * ddisplay_set_snap_to_objects:
+ * @ddisp: the #DDisplay
+ * @magnetic: should snap to objects
+ *
+ * Set the display's mainpoint magnetism setting, updating menu and button
+ * in the process
+ */
 void
-ddisplay_set_snap_to_objects(DDisplay *ddisp, gboolean magnetic)
+ddisplay_set_snap_to_objects (DDisplay *ddisp, gboolean magnetic)
 {
   GtkToggleAction *mainpoint_magnetism;
   ddisp->mainpoint_magnetism = magnetic;
 
   mainpoint_magnetism = GTK_TOGGLE_ACTION (menus_get_action ("ViewSnaptoobjects"));
-  if (is_integrated_ui ())
+  if (is_integrated_ui ()) {
     integrated_ui_toolbar_object_snap_synchronize_to_display (ddisp);
+  }
   /* Currently, this can cause double emit, but that's a small problem. */
   gtk_toggle_action_set_active (mainpoint_magnetism, ddisp->mainpoint_magnetism);
-  ddisplay_update_statusbar(ddisp);
+  ddisplay_update_statusbar (ddisp);
 }
 
-/** Update the button showing whether mainpoint magnetism is on */
+
+/* Update the button showing whether mainpoint magnetism is on */
 static void
-update_mainpoint_status(DDisplay *ddisp)
+update_mainpoint_status (DDisplay *ddisp)
 {
-  if (ddisp->mainpoint_status)
-  {
-    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ddisp->mainpoint_status),
-                                 ddisp->mainpoint_magnetism);
+  if (ddisp->mainpoint_status) {
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ddisp->mainpoint_status),
+                                  ddisp->mainpoint_magnetism);
   }
 }
 
+
 /** Scroll display to where point x,y (window coords) is visible */
 gboolean
 ddisplay_autoscroll (DDisplay *ddisp, int x, int y)
@@ -765,8 +807,9 @@ ddisplay_autoscroll (DDisplay *ddisp, int x, int y)
   Point scroll;
   GtkAllocation alloc;
 
-  if (! ddisp->autoscroll)
+  if (! ddisp->autoscroll) {
     return FALSE;
+  }
 
   scroll.x = scroll.y = 0;
 
@@ -775,124 +818,145 @@ ddisplay_autoscroll (DDisplay *ddisp, int x, int y)
   width = alloc.width;
   height = alloc.height;
 
-  if (x < 0)
-  {
+  if (x < 0) {
     scroll.x = x;
-  }
-  else if ( x > width)
-  {
+  } else if (x > width) {
     scroll.x = x - width;
   }
 
-  if (y < 0)
-  {
+  if (y < 0) {
     scroll.y = y;
-  }
-  else if (y > height)
-  {
+  } else if (y > height) {
     scroll.y = y - height;
   }
 
-  if ((scroll.x != 0) || (scroll.y != 0))
-  {
+  if ((scroll.x != 0) || (scroll.y != 0)) {
     gboolean scrolled;
 
-    scroll.x = ddisplay_untransform_length(ddisp, scroll.x);
-    scroll.y = ddisplay_untransform_length(ddisp, scroll.y);
+    scroll.x = ddisplay_untransform_length (ddisp, scroll.x);
+    scroll.y = ddisplay_untransform_length (ddisp, scroll.y);
 
-    scrolled = ddisplay_scroll(ddisp, &scroll);
+    scrolled = ddisplay_scroll (ddisp, &scroll);
 
     if (scrolled) {
-      ddisplay_flush(ddisp);
+      ddisplay_flush (ddisp);
       return TRUE;
     }
   }
   return FALSE;
 }
 
-/** Scroll the display by delta (diagram coords) */
+
+/**
+ * ddisplay_scroll:
+ * @ddisp: the #DDisplay
+ * @delta: about to move by
+ *
+ * Scroll the display by delta (diagram coords)
+ */
 gboolean
 ddisplay_scroll (DDisplay *ddisp, Point *delta)
 {
   DiaRectangle *visible = &ddisp->visible;
-  real width = visible->right - visible->left;
-  real height = visible->bottom - visible->top;
+  double width = visible->right - visible->left;
+  double height = visible->bottom - visible->top;
 
   DiaRectangle extents = ddisp->diagram->data->extents;
-  real ex_width = extents.right - extents.left;
-  real ex_height = extents.bottom - extents.top;
+  double ex_width = extents.right - extents.left;
+  double ex_height = extents.bottom - extents.top;
 
   Point new_origo = ddisp->origo;
   point_add(&new_origo, delta);
 
   rectangle_union(&extents, visible);
 
-  if (new_origo.x < extents.left - ex_width)
+  if (new_origo.x < extents.left - ex_width) {
     new_origo.x = extents.left - ex_width;
+  }
 
-  if (new_origo.x+width > extents.right + ex_width)
+  if (new_origo.x+width > extents.right + ex_width) {
     new_origo.x = extents.right - width + ex_width;
+  }
 
-  if (new_origo.y < extents.top - ex_height)
+  if (new_origo.y < extents.top - ex_height) {
     new_origo.y = extents.top - ex_height;
+  }
 
-  if (new_origo.y+height > extents.bottom + ex_height)
+  if (new_origo.y+height > extents.bottom + ex_height) {
     new_origo.y = extents.bottom - height + ex_height;
+  }
 
   if ( (new_origo.x != ddisp->origo.x) ||
        (new_origo.y != ddisp->origo.y) ) {
-    ddisplay_set_origo(ddisp, new_origo.x, new_origo.y);
-    ddisplay_update_scrollbars(ddisp);
-    ddisplay_add_update_all(ddisp);
+    ddisplay_set_origo (ddisp, new_origo.x, new_origo.y);
+    ddisplay_update_scrollbars (ddisp);
+    ddisplay_add_update_all (ddisp);
     return TRUE;
   }
+
   return FALSE;
 }
 
-void ddisplay_scroll_up(DDisplay *ddisp)
+
+void
+ddisplay_scroll_up (DDisplay *ddisp)
 {
   Point delta;
 
   delta.x = 0;
   delta.y = -(ddisp->visible.bottom - ddisp->visible.top)/4.0;
 
-  ddisplay_scroll(ddisp, &delta);
+  ddisplay_scroll (ddisp, &delta);
 }
 
-void ddisplay_scroll_down(DDisplay *ddisp)
+
+void
+ddisplay_scroll_down (DDisplay *ddisp)
 {
   Point delta;
 
   delta.x = 0;
   delta.y = (ddisp->visible.bottom - ddisp->visible.top)/4.0;
 
-  ddisplay_scroll(ddisp, &delta);
+  ddisplay_scroll (ddisp, &delta);
 }
 
-void ddisplay_scroll_left(DDisplay *ddisp)
+
+void
+ddisplay_scroll_left (DDisplay *ddisp)
 {
   Point delta;
 
   delta.x = -(ddisp->visible.right - ddisp->visible.left)/4.0;
   delta.y = 0;
 
-  ddisplay_scroll(ddisp, &delta);
+  ddisplay_scroll (ddisp, &delta);
 }
 
-void ddisplay_scroll_right(DDisplay *ddisp)
+
+void
+ddisplay_scroll_right (DDisplay *ddisp)
 {
   Point delta;
 
   delta.x = (ddisp->visible.right - ddisp->visible.left)/4.0;
   delta.y = 0;
 
-  ddisplay_scroll(ddisp, &delta);
+  ddisplay_scroll (ddisp, &delta);
 }
 
-/** Scroll display to have the diagram point p at the center.
- * Returns TRUE if anything changed. */
+
+/**
+ * ddisplay_scroll_center_point:
+ * @ddisp: the #DDisplay
+ * @p: the #Point
+ *
+ * Scroll display to have the diagram point p at the center.
+ *
+ * Returns: %TRUE if anything changed.
+ */
 gboolean
-ddisplay_scroll_center_point(DDisplay *ddisp, Point *p)
+ddisplay_scroll_center_point (DDisplay *ddisp, Point *p)
 {
   Point center;
 
@@ -901,12 +965,21 @@ ddisplay_scroll_center_point(DDisplay *ddisp, Point *p)
   center.x = (ddisp->visible.right+ddisp->visible.left)/2;
   center.y = (ddisp->visible.top+ddisp->visible.bottom)/2;
 
-  point_sub(p, &center);
-  return ddisplay_scroll(ddisp, p);
+  point_sub (p, &center);
+
+  return ddisplay_scroll (ddisp, p);
 }
 
-/** Scroll display so that obj is centered.
- * Returns TRUE if anything changed.  */
+
+/**
+ * ddisplay_scroll_to_object:
+ * @ddisp: the #DDisplay
+ * @obj: the #DiaObject
+ *
+ * Scroll display so that obj is centered.
+ *
+ * Returns: %TRUE if anything changed.
+ */
 gboolean
 ddisplay_scroll_to_object (DDisplay *ddisp, DiaObject *obj)
 {
@@ -916,20 +989,27 @@ ddisplay_scroll_to_object (DDisplay *ddisp, DiaObject *obj)
   p.x = (r.left+r.right)/2;
   p.y = (r.top+r.bottom)/2;
 
-  display_set_active(ddisp);
-  return ddisplay_scroll_center_point(ddisp, &p);
+  display_set_active (ddisp);
+
+  return ddisplay_scroll_center_point (ddisp, &p);
 }
 
-/** Ensure the object is visible but minimize scrolling
+
+/**
+ * ddisplay_present_object:
+ * @ddisp: the #DDisplay
+ * @obj: the #DiaObject
+ *
+ * Ensure the object is visible but minimize scrolling
  */
 gboolean
-ddisplay_present_object(DDisplay *ddisp, DiaObject *obj)
+ddisplay_present_object (DDisplay *ddisp, DiaObject *obj)
 {
-  const DiaRectangle *r = dia_object_get_enclosing_box(obj);
+  const DiaRectangle *r = dia_object_get_enclosing_box (obj);
   const DiaRectangle *v = &ddisp->visible;
 
-  display_set_active(ddisp);
-  if  (!rectangle_in_rectangle(v, r)) {
+  display_set_active (ddisp);
+  if (!rectangle_in_rectangle (v, r)) {
     Point delta = { 0, 0 };
 
     if ((r->right - r->left) > (v->right - v->left)) /* object bigger than visible area */
@@ -946,33 +1026,46 @@ ddisplay_present_object(DDisplay *ddisp, DiaObject *obj)
     else if  (r->bottom > v->bottom)
       delta.y = r->bottom - v->bottom;
 
-    ddisplay_scroll(ddisp, &delta);
+    ddisplay_scroll (ddisp, &delta);
+
     return TRUE;
   }
+
   return FALSE;
 }
 
-/*!
+
+/**
+ * @ddisp: the #DDisplay
+ * @x: the x position
+ * @y: the y position
+ *
  * Remember the last clicked point given in pixel coodinates
  */
 void
-ddisplay_set_clicked_point(DDisplay *ddisp, int x, int y)
+ddisplay_set_clicked_point (DDisplay *ddisp, int x, int y)
 {
   Point pt;
 
-  ddisplay_untransform_coords(ddisp, x, y, &pt.x, &pt.y);
+  ddisplay_untransform_coords (ddisp, x, y, &pt.x, &pt.y);
 
   ddisp->clicked_position = pt;
 }
 
-/*! Get the last clicked point in diagram coordinates
+
+/**
+ * ddisplay_get_clicked_position:
+ * @ddisp: the #DDisp
+ *
+ * Get the last clicked point in diagram coordinates
  */
 Point
-ddisplay_get_clicked_position(DDisplay *ddisp)
+ddisplay_get_clicked_position (DDisplay *ddisp)
 {
   return ddisp->clicked_position;
 }
 
+
 void
 ddisplay_set_renderer (DDisplay *ddisp, int aa_renderer)
 {
@@ -980,8 +1073,7 @@ ddisplay_set_renderer (DDisplay *ddisp, int aa_renderer)
   GdkWindow *window = gtk_widget_get_window (ddisp->canvas);
   GtkAllocation alloc;
 
-  if (ddisp->renderer)
-    g_object_unref (ddisp->renderer);
+  g_clear_object (&ddisp->renderer);
 
   ddisp->aa_renderer = aa_renderer;
 
@@ -1007,11 +1099,13 @@ ddisplay_set_renderer (DDisplay *ddisp, int aa_renderer)
   }
 }
 
+
 void
-ddisplay_resize_canvas(DDisplay *ddisp,
-                      int width,  int height)
+ddisplay_resize_canvas (DDisplay *ddisp,
+                        int       width,
+                        int       height)
 {
-  if (ddisp->renderer==NULL) {
+  if (ddisp->renderer == NULL) {
     if (!ddisp->aa_renderer){
       g_message ("Only antialias renderers supported");
     }
@@ -1033,49 +1127,54 @@ ddisplay_resize_canvas(DDisplay *ddisp,
   ddisplay_flush (ddisp);
 }
 
+
 DDisplay *
-ddisplay_active(void)
+ddisplay_active (void)
 {
   return active_display;
 }
 
+
 Diagram *
-ddisplay_active_diagram(void)
+ddisplay_active_diagram (void)
 {
   DDisplay *ddisp = ddisplay_active ();
 
   if (!ddisp) return NULL;
+
   return ddisp->diagram;
 }
 
+
 static void
-ddisp_destroy(DDisplay *ddisp)
+ddisp_destroy (DDisplay *ddisp)
 {
   g_signal_handlers_disconnect_by_func (ddisp->diagram, selection_changed, ddisp);
 
   g_object_unref (G_OBJECT (ddisp->im_context));
   ddisp->im_context = NULL;
 
-  ddisplay_im_context_preedit_reset(ddisp, get_active_focus((DiagramData *) ddisp->diagram));
+  ddisplay_im_context_preedit_reset (ddisp, get_active_focus ((DiagramData *) ddisp->diagram));
 
-  if (GTK_WINDOW(ddisp->shell) == gtk_window_get_transient_for(GTK_WINDOW(interface_get_toolbox_shell()))) {
+  if (GTK_WINDOW (ddisp->shell) == gtk_window_get_transient_for (GTK_WINDOW (interface_get_toolbox_shell 
()))) {
     /* we have to break the connection otherwise the toolbox will be closed */
-    gtk_window_set_transient_for(GTK_WINDOW(interface_get_toolbox_shell()), NULL);
+    gtk_window_set_transient_for (GTK_WINDOW (interface_get_toolbox_shell ()), NULL);
   }
 
   /* This calls ddisplay_really_destroy */
-  if (ddisp->is_standalone_window)
+  if (ddisp->is_standalone_window) {
     gtk_widget_destroy (ddisp->shell);
-  else {
+  } else {
     gtk_widget_destroy (ddisp->container);
     ddisplay_really_destroy (ddisp);
   }
 }
 
+
 static void
-are_you_sure_close_dialog_respond(GtkWidget *widget, /* the dialog */
-                                  gint       response_id,
-                                  gpointer   user_data) /* the display */
+are_you_sure_close_dialog_respond (GtkWidget *widget, /* the dialog */
+                                   gint       response_id,
+                                   gpointer   user_data) /* the display */
 {
   DDisplay *ddisp = (DDisplay *)user_data;
   gboolean close_ddisp = TRUE;
@@ -1524,7 +1623,7 @@ void
 ddisplay_show_all (DDisplay *ddisp)
 {
   Diagram *dia;
-  real magnify_x, magnify_y;
+  double magnify_x, magnify_y;
   int width, height;
   Point middle;
 
@@ -1545,14 +1644,14 @@ ddisplay_show_all (DDisplay *ddisp)
       rectangle_union(&extents, dia_object_get_enclosing_box (obj));
       list = g_list_next(list);
     }
-    magnify_x = (real)width / (extents.right - extents.left) / ddisp->zoom_factor;
-    magnify_y = (real)height / (extents.bottom - extents.top) / ddisp->zoom_factor;
+    magnify_x = (double)width / (extents.right - extents.left) / ddisp->zoom_factor;
+    magnify_y = (double)height / (extents.bottom - extents.top) / ddisp->zoom_factor;
     middle.x = extents.left + (extents.right - extents.left) / 2.0;
     middle.y = extents.top + (extents.bottom - extents.top) / 2.0;
   } else {
-    magnify_x = (real)width /
+    magnify_x = (double)width /
       (dia->data->extents.right - dia->data->extents.left) / ddisp->zoom_factor;
-    magnify_y = (real)height /
+    magnify_y = (double)height /
       (dia->data->extents.bottom - dia->data->extents.top) / ddisp->zoom_factor;
 
     middle.x = dia->data->extents.left +
diff --git a/app/display.h b/app/display.h
index 34ba089d..4c5a5b8c 100644
--- a/app/display.h
+++ b/app/display.h
@@ -71,8 +71,8 @@ struct _DDisplay {
   GtkAdjustment *vsbdata;         /* vertical data information         */
 
   Point origo;                    /* The origo (lower left) position   */
-  real zoom_factor;               /* zoom, 20.0 means 20 pixel == 1 cm */
-  DiaRectangle visible;              /* The part visible in this display  */
+  double zoom_factor;             /* zoom, 20.0 means 20 pixel == 1 cm */
+  DiaRectangle visible;           /* The part visible in this display  */
 
   Grid grid;                      /* the grid in this display          */
 
@@ -124,24 +124,26 @@ extern GdkCursor *default_cursor;
 DDisplay *new_display(Diagram *dia);
 DDisplay *copy_display(DDisplay *orig_ddisp);
 /* Normal destroy is done through shell widget destroy event. */
-void ddisplay_really_destroy(DDisplay *ddisp);
-void ddisplay_transform_coords_double (DDisplay *ddisp,
-                                       double    x,
-                                       double    y,
-                                       double   *xi,
-                                       double   *yi);
-void ddisplay_transform_coords        (DDisplay *ddisp,
-                                       double    x,
-                                       double    y,
-                                       int      *xi,
-                                       int      *yi);
-void ddisplay_untransform_coords      (DDisplay *ddisp,
-                                       int       xi,
-                                       int       yi,
-                                       double   *x,
-                                       double   *y);
-real ddisplay_transform_length(DDisplay *ddisp, real len);
-real ddisplay_untransform_length(DDisplay *ddisp, real len);
+void     ddisplay_really_destroy          (DDisplay *ddisp);
+void     ddisplay_transform_coords_double (DDisplay *ddisp,
+                                           double    x,
+                                           double    y,
+                                           double   *xi,
+                                           double   *yi);
+void     ddisplay_transform_coords        (DDisplay *ddisp,
+                                           double    x,
+                                           double    y,
+                                           int      *xi,
+                                           int      *yi);
+void     ddisplay_untransform_coords      (DDisplay *ddisp,
+                                           int       xi,
+                                           int       yi,
+                                           double   *x,
+                                           double   *y);
+double   ddisplay_transform_length        (DDisplay *ddisp,
+                                           double    len);
+double   ddisplay_untransform_length      (DDisplay *ddisp,
+                                           double    len);
 void ddisplay_add_update_pixels(DDisplay *ddisp, Point *point,
                                       int pixel_width, int pixel_height);
 void ddisplay_add_update_all(DDisplay *ddisp);
@@ -150,14 +152,17 @@ void ddisplay_add_update_with_border(DDisplay *ddisp, const DiaRectangle *rect,
 void ddisplay_add_update(DDisplay *ddisp, const DiaRectangle *rect);
 void ddisplay_flush(DDisplay *ddisp);
 void ddisplay_update_scrollbars(DDisplay *ddisp);
-void ddisplay_set_origo                 (DDisplay *ddisp,
-                                         double    x,
-                                         double    y);
-void ddisplay_zoom(DDisplay *ddisp, Point *point,
-                  real zoom_factor);
-void ddisplay_zoom_middle(DDisplay *ddisp, real magnify);
-
-void ddisplay_zoom_centered(DDisplay *ddisp, Point *point, real magnify);
+void     ddisplay_set_origo               (DDisplay *ddisp,
+                                           double    x,
+                                           double    y);
+void     ddisplay_zoom                    (DDisplay *ddisp,
+                                           Point    *point,
+                                           double    zoom_factor);
+void     ddisplay_zoom_middle             (DDisplay *ddisp,
+                                           double    magnify);
+void     ddisplay_zoom_centered           (DDisplay *ddisp,
+                                           Point    *point,
+                                           double    magnify);
 void ddisplay_set_snap_to_grid(DDisplay *ddisp, gboolean snap);
 void ddisplay_set_snap_to_guides(DDisplay *ddisp, gboolean snap);
 void ddisplay_set_snap_to_objects(DDisplay *ddisp, gboolean magnetic);
diff --git a/app/interface.c b/app/interface.c
index 009c703b..661c4654 100644
--- a/app/interface.c
+++ b/app/interface.c
@@ -210,45 +210,51 @@ origin_button_press(GtkWidget *widget, GdkEventButton *event, gpointer data)
   return FALSE;
 }
 
+
 void
-view_zoom_set (float factor)
+view_zoom_set (double factor)
 {
   DDisplay *ddisp;
-  real scale;
+  double scale;
 
   ddisp = ddisplay_active();
-  if (!ddisp) return;
+  g_return_if_fail (ddisp != NULL);
 
-  scale = ((real) factor)/1000.0 * DDISPLAY_NORMAL_ZOOM;
+  scale = ((double) factor) / 1000.0 * DDISPLAY_NORMAL_ZOOM;
 
-  ddisplay_zoom_middle(ddisp, scale / ddisp->zoom_factor);
+  ddisplay_zoom_middle (ddisp, scale / ddisp->zoom_factor);
 }
 
+
 static void
-zoom_activate_callback(GtkWidget *item, gpointer user_data)
+zoom_activate_callback (GtkWidget *item, gpointer user_data)
 {
-  DDisplay *ddisp = (DDisplay *)user_data;
+  DDisplay *ddisp = (DDisplay *) user_data;
   const gchar *zoom_text =
-      gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(ddisp->zoom_status), "user_data")));
-  float zoom_amount, magnify;
-  gchar *zoomamount = g_object_get_data(G_OBJECT(item), "zoomamount");
+      gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (ddisp->zoom_status), "user_data")));
+  double zoom_amount, magnify;
+  char *zoomamount = g_object_get_data (G_OBJECT (item), "zoomamount");
   if (zoomamount != NULL) {
     zoom_text = zoomamount;
   }
 
-  if (sscanf(zoom_text, "%f", &zoom_amount) == 1) {
+  zoom_amount = parse_zoom (zoom_text);
+
+  if (zoom_amount > 0) {
     /* Set limits to avoid crashes, see bug #483384 */
     if (zoom_amount < .1) {
       zoom_amount = .1;
     } else if (zoom_amount > 1e4) {
       zoom_amount = 1e4;
     }
-    zoomamount = g_strdup_printf("%f%%\n", zoom_amount);
-    gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(ddisp->zoom_status), "user_data")), zoomamount);
-    g_free(zoomamount);
+
+    // Translators: Current zoom level
+    zoomamount = g_strdup_printf (_("%f%%"), zoom_amount);
+    gtk_entry_set_text (GTK_ENTRY (g_object_get_data (G_OBJECT (ddisp->zoom_status), "user_data")), 
zoomamount);
+    g_free (zoomamount);
     magnify = (zoom_amount*DDISPLAY_NORMAL_ZOOM/100.0)/ddisp->zoom_factor;
-    if (fabs(magnify - 1.0) > 0.000001) {
-      ddisplay_zoom_middle(ddisp, magnify);
+    if (fabs (magnify - 1.0) > 0.000001) {
+      ddisplay_zoom_middle (ddisp, magnify);
     }
   }
 }
@@ -1414,3 +1420,41 @@ _ddisplay_vruler_motion_notify (GtkWidget *widget,
 
   return FALSE;
 }
+
+
+double
+parse_zoom (const char *zoom)
+{
+  static GRegex *extract_zoom = NULL;
+  GMatchInfo *match_info;
+  char *num;
+  double res = -1;
+
+  if (g_once_init_enter (&extract_zoom)) {
+    GError *error = NULL;
+    GRegex *regex = g_regex_new ("%?(\\d*)%?", G_REGEX_OPTIMIZE, 0, &error);
+
+    if (error) {
+      g_critical ("Failed to prepare regex: %s", error->message);
+
+      g_clear_error (&error);
+    }
+
+    g_once_init_leave (&extract_zoom, regex);
+  }
+
+  g_regex_match (extract_zoom, zoom, 0, &match_info);
+
+  if (!g_match_info_matches (match_info)) {
+    return -1;
+  }
+
+  num = g_match_info_fetch (match_info, 1);
+
+  res = g_ascii_strtod (num, NULL);
+
+  g_free (num);
+  g_match_info_free (match_info);
+
+  return res * 10;
+}
diff --git a/app/interface.h b/app/interface.h
index 9e9b9c0a..fe8f2931 100644
--- a/app/interface.h
+++ b/app/interface.h
@@ -53,10 +53,12 @@ void create_integrated_ui (void);
 void create_sheets(GtkWidget *parent);
 extern GtkWidget *modify_tool_button;
 
-void view_zoom_set (float zoom_factor); /* zoom_factor is 10 * percentage */
+void view_zoom_set (double zoom_factor); /* zoom_factor is 10 * percentage */
 
 void fill_sheet_menu(void);
 
 void close_notebook_page_callback (GtkButton *button, gpointer user_data);
 
+double parse_zoom (const char *zoom);
+
 #endif /* INTERFACE_H */
diff --git a/app/menus.c b/app/menus.c
index e6272063..760fb7ff 100644
--- a/app/menus.c
+++ b/app/menus.c
@@ -57,8 +57,6 @@
 #define DIA_INTEGRATED_TOOLBAR_OBJECT_SNAP "dia-integrated-toolbar-object-snap"
 #define DIA_INTEGRATED_TOOLBAR_GUIDES_SNAP "dia-integrated-toolbar-guides-snap"
 
-#define ZOOM_FIT        _("Fit")
-
 static void plugin_callback (GtkWidget *widget, gpointer data);
 
 static GtkWidget *create_integrated_ui_toolbar (void);
@@ -278,6 +276,14 @@ static const GtkRadioActionEntry display_select_radio_entries[] =
   { "SelectInverse", NULL, N_("In_verse"), NULL, NULL, SELECT_INVERT }
 };
 
+#define ZOOM_FIT -1
+
+enum {
+  COL_DISPLAY,
+  COL_AMOUNT,
+  N_COL,
+};
+
 /* need initialisation? */
 static gboolean initialise = TRUE;
 
@@ -488,35 +494,42 @@ integrated_ui_toolbar_zoom_activate (GtkWidget *item,
                                      gpointer   user_data)
 {
   const gchar *text = gtk_entry_get_text (GTK_ENTRY (item));
-  float        zoom_percent;
+  double       zoom_percent = parse_zoom (text);
 
-  if (sscanf (text, "%f", &zoom_percent) == 1) {
-      view_zoom_set (10.0 * zoom_percent);
+  if (zoom_percent > 0) {
+    view_zoom_set (zoom_percent);
   }
 }
 
+
 /* "DiaZoomCombo" probably could work for both UI cases */
 static void
 integrated_ui_toolbar_zoom_combo_selection_changed (GtkComboBox *combo,
                                                     gpointer     user_data)
 {
+  GtkTreeIter iter;
+  GtkTreeModel *store = gtk_combo_box_get_model (combo);
+
   /*
     * We call gtk_combo_get_get_active() so that typing in the combo entry
     * doesn't get handled as a selection change
     */
-  if (gtk_combo_box_get_active (combo) != -1) {
-    float zoom_percent;
-    gchar *text = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (combo));
-    if (sscanf (text, "%f", &zoom_percent) == 1) {
-      view_zoom_set (zoom_percent * 10.0);
-    } else if (g_ascii_strcasecmp (text, ZOOM_FIT) == 0) {
+  if (gtk_combo_box_get_active_iter (combo, &iter)) {
+    double zoom_percent;
+
+    gtk_tree_model_get (store, &iter,
+                        COL_AMOUNT, &zoom_percent,
+                        -1);
+
+    if (zoom_percent < 0) {
       view_show_all_callback (NULL);
+    } else {
+      view_zoom_set (zoom_percent);
     }
-
-    g_free (text);
   }
 }
 
+
 static guint
 ensure_menu_path (GtkUIManager   *ui_manager,
                   GtkActionGroup *actions,
@@ -568,42 +581,101 @@ ensure_menu_path (GtkUIManager   *ui_manager,
 static GtkWidget *
 create_integrated_ui_toolbar (void)
 {
-  GtkToolbar  *toolbar;
-  GtkToolItem *sep;
-  GtkWidget   *w;
-  GError      *error = NULL;
-  gchar *uifile;
+  GtkToolbar   *toolbar;
+  GtkToolItem  *sep;
+  GtkListStore *store;
+  GtkTreeIter   iter;
+  GtkWidget    *w;
+  GError       *error = NULL;
+  gchar        *uifile;
 
   uifile = build_ui_filename ("ui/toolbar-ui.xml");
   if (!gtk_ui_manager_add_ui_from_file (_ui_manager, uifile, &error)) {
-    g_warning ("building menus failed: %s", error->message);
+    g_critical ("building menus failed: %s", error->message);
     g_error_free (error);
     error = NULL;
     toolbar = GTK_TOOLBAR (gtk_toolbar_new ());
   } else {
-    toolbar =  GTK_TOOLBAR(gtk_ui_manager_get_widget (_ui_manager, "/Toolbar"));
+    toolbar = GTK_TOOLBAR (gtk_ui_manager_get_widget (_ui_manager, "/Toolbar"));
   }
   g_free (uifile);
 
+  store = gtk_list_store_new (N_COL, G_TYPE_STRING, G_TYPE_DOUBLE);
+
   /* Zoom Combo Box Entry */
-  w = gtk_combo_box_text_new_with_entry ();
+  w = gtk_combo_box_new_with_model_and_entry (GTK_TREE_MODEL (store));
+  gtk_combo_box_set_entry_text_column (GTK_COMBO_BOX (w), COL_DISPLAY);
 
   g_object_set_data (G_OBJECT (toolbar),
                      DIA_INTEGRATED_TOOLBAR_ZOOM_COMBO,
                      w);
   integrated_ui_toolbar_add_custom_item (toolbar, w);
 
-  gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (w), ZOOM_FIT);
-  gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (w), _("800%"));
-  gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (w), _("400%"));
-  gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (w), _("300%"));
-  gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (w), _("200%"));
-  gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (w), _("150%"));
-  gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (w), _("100%"));
-  gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (w), _("75%"));
-  gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (w), _("50%"));
-  gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (w), _("25%"));
-  gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (w), _("10%"));
+  gtk_list_store_append (store, &iter);
+  gtk_list_store_set (store, &iter,
+                      COL_DISPLAY, _("Fit"),
+                      COL_AMOUNT, ZOOM_FIT,
+                      -1);
+
+  gtk_list_store_append (store, &iter);
+  gtk_list_store_set (store, &iter,
+                      COL_DISPLAY, _("800%"),
+                      COL_AMOUNT, 8000.0,
+                      -1);
+
+  gtk_list_store_append (store, &iter);
+  gtk_list_store_set (store, &iter,
+                      COL_DISPLAY, _("400%"),
+                      COL_AMOUNT, 4000.0,
+                      -1);
+
+  gtk_list_store_append (store, &iter);
+  gtk_list_store_set (store, &iter,
+                      COL_DISPLAY, _("300%"),
+                      COL_AMOUNT, 3000.0,
+                      -1);
+
+  gtk_list_store_append (store, &iter);
+  gtk_list_store_set (store, &iter,
+                      COL_DISPLAY, _("200%"),
+                      COL_AMOUNT, 2000.0,
+                      -1);
+
+  gtk_list_store_append (store, &iter);
+  gtk_list_store_set (store, &iter,
+                      COL_DISPLAY, _("150%"),
+                      COL_AMOUNT, 1500.0,
+                      -1);
+
+  gtk_list_store_append (store, &iter);
+  gtk_list_store_set (store, &iter,
+                      COL_DISPLAY, _("100%"),
+                      COL_AMOUNT, 1000.0,
+                      -1);
+
+  gtk_list_store_append (store, &iter);
+  gtk_list_store_set (store, &iter,
+                      COL_DISPLAY, _("75%"),
+                      COL_AMOUNT, 750.0,
+                      -1);
+
+  gtk_list_store_append (store, &iter);
+  gtk_list_store_set (store, &iter,
+                      COL_DISPLAY, _("50%"),
+                      COL_AMOUNT, 500.0,
+                      -1);
+
+  gtk_list_store_append (store, &iter);
+  gtk_list_store_set (store, &iter,
+                      COL_DISPLAY, _("25%"),
+                      COL_AMOUNT, 250.0,
+                      -1);
+
+  gtk_list_store_append (store, &iter);
+  gtk_list_store_set (store, &iter,
+                      COL_DISPLAY, _("10%"),
+                      COL_AMOUNT, 100.0,
+                      -1);
 
   g_signal_connect (G_OBJECT (w),
                     "changed",



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