Code

Remove double unreffing of pointer in pdf-cairo.cpp. Fixes Bug #178985 with the...
[inkscape.git] / src / gradient-context.cpp
index 2176f3ea086e16c46f67b389465267b395a34012..230072e645b5624b35f54946395c280cdfe64a14 100644 (file)
@@ -29,7 +29,6 @@
 #include "message-stack.h"
 #include "pixmaps/cursor-gradient.xpm"
 #include "pixmaps/cursor-gradient-add.xpm"
-#include "pixmaps/cursor-gradient-delete.xpm"
 #include "gradient-context.h"
 #include "gradient-chemistry.h"
 #include <glibmm/i18n.h>
@@ -155,20 +154,37 @@ gradient_selection_changed (Inkscape::Selection *, gpointer data)
     guint n_tot = drag->numDraggers();
     guint n_sel = drag->numSelected();
 
+    //The use of ngettext in the following code is intentional even if the English singular form would never be used
     if (n_sel == 1) {
         if (drag->singleSelectedDraggerNumDraggables() == 1) {
-            rc->_message_context->setF(Inkscape::NORMAL_MESSAGE,
-                    _("%s selected out of %d gradient handles on %d selected object(s)"), gr_handle_descr[drag->singleSelectedDraggerSingleDraggableType()], n_tot, n_obj);
+               gchar * message = g_strconcat(
+                       //TRANSLATORS: %s will be substituted with the point name (see previous messages); This is part of a compound message
+                       _("%s selected"),
+                       //TRANSLATORS: Mind the space in front. This is part of a compound message
+                       ngettext(" out of %d gradient handle"," out of %d gradient handles",n_tot),
+                       ngettext(" on %d selected object"," on %d selected objects",n_obj),NULL);
+               rc->_message_context->setF(Inkscape::NORMAL_MESSAGE,
+                       message,_(gr_handle_descr[drag->singleSelectedDraggerSingleDraggableType()]), n_tot, n_obj);
         } else {
-            rc->_message_context->setF(Inkscape::NORMAL_MESSAGE,
-                    _("One handle merging %d stops (drag with <b>Shift</b> to separate) selected out of %d gradient handles on %d selected object(s)"), drag->singleSelectedDraggerNumDraggables(), n_tot, n_obj);
+               gchar * message = g_strconcat(
+                       //TRANSLATORS: This is a part of a compound message (out of two more indicating: grandint handle count & object count)
+                       ngettext("One handle merging %d stop (drag with <b>Shift</b> to separate) selected",
+                               "One handle merging %d stops (drag with <b>Shift</b> to separate) selected",drag->singleSelectedDraggerNumDraggables()),
+                       ngettext(" out of %d gradient handle"," out of %d gradient handles",n_tot),
+                       ngettext(" on %d selected object"," on %d selected objects",n_obj),NULL);
+               rc->_message_context->setF(Inkscape::NORMAL_MESSAGE,message,drag->singleSelectedDraggerNumDraggables(), n_tot, n_obj);
         }
     } else if (n_sel > 1) {
-        rc->_message_context->setF(Inkscape::NORMAL_MESSAGE,
-                                   _("<b>%d</b> gradient handles selected out of %d on %d selected object(s)"), n_sel, n_tot, n_obj);
+       //TRANSLATORS: The plural refers to number of selected gradient handles. This is part of a compound message (part two indicates selected object count)
+       gchar * message = g_strconcat(ngettext("<b>%d</b> gradient handle selected out of %d","<b>%d</b> gradient handles selected out of %d",n_sel),
+                                     //TRANSLATORS: Mind the space in front. (Refers to gradient handles selected). This is part of a compound message
+                                     ngettext(" on %d selected object"," on %d selected objects",n_obj),NULL);
+        rc->_message_context->setF(Inkscape::NORMAL_MESSAGE,message, n_sel, n_tot, n_obj);
     } else if (n_sel == 0) {
         rc->_message_context->setF(Inkscape::NORMAL_MESSAGE,
-                                   _("<b>No</b> gradient handles selected out of %d on %d selected object(s)"), n_tot, n_obj);
+               //TRANSLATORS: The plural refers to number of selected objects
+                ngettext("<b>No</b> gradient handles selected out of %d on %d selected object",
+                        "<b>No</b> gradient handles selected out of %d on %d selected objects",n_obj), n_tot, n_obj);
     }
 }
 
@@ -447,7 +463,7 @@ sp_gradient_simplify(SPGradientContext *rc, double tolerance)
 
 
 static void
-sp_gradient_context_add_stop_near_point (SPGradientContext *rc, SPItem *item,  NR::Point mouse_p, guint32 etime)
+sp_gradient_context_add_stop_near_point (SPGradientContext *rc, SPItem *item,  NR::Point mouse_p, guint32 /*etime*/)
 {
     // item is the selected item. mouse_p the location in doc coordinates of where to add the stop
 
@@ -598,11 +614,13 @@ sp_gradient_context_root_handler(SPEventContext *event_context, GdkEvent *event)
                 if (drag->lines) {
                     for (GSList *l = drag->lines; (l != NULL) && (!over_line); l = l->next) {
                         line = (SPCtrlLine*) l->data;
-                        over_line |= sp_gradient_context_is_over_line (rc, (SPItem*) line, NR::Point(event->motion.x, event->motion.y));
+                        over_line = sp_gradient_context_is_over_line (rc, (SPItem*) line, NR::Point(event->motion.x, event->motion.y));
+                        if (over_line)
+                            break;
                     }
                 }
-                if (over_line) {
-                    sp_gradient_context_add_stop_near_point(rc, SP_ITEM(selection->itemList()->data), rc->mousepoint_doc, 0);
+                if (over_line && line) {
+                    sp_gradient_context_add_stop_near_point(rc, line->item, rc->mousepoint_doc, 0);
                     ret = TRUE;
                 }
             } else {
@@ -702,13 +720,15 @@ sp_gradient_context_root_handler(SPEventContext *event_context, GdkEvent *event)
         case GDK_KP_Left:
         case GDK_KP_4:
             if (!MOD__CTRL) { // not ctrl
+                gint mul = 1 + gobble_key_events(
+                    get_group0_keyval(&event->key), 0); // with any mask
                 if (MOD__ALT) { // alt
-                    if (MOD__SHIFT) drag->selected_move_screen(-10, 0); // shift
-                    else drag->selected_move_screen(-1, 0); // no shift
+                    if (MOD__SHIFT) drag->selected_move_screen(mul*-10, 0); // shift
+                    else drag->selected_move_screen(mul*-1, 0); // no shift
                 }
                 else { // no alt
-                    if (MOD__SHIFT) drag->selected_move(-10*nudge, 0); // shift
-                    else drag->selected_move(-nudge, 0); // no shift
+                    if (MOD__SHIFT) drag->selected_move(mul*-10*nudge, 0); // shift
+                    else drag->selected_move(mul*-nudge, 0); // no shift
                 }
                 ret = TRUE;
             }
@@ -717,13 +737,15 @@ sp_gradient_context_root_handler(SPEventContext *event_context, GdkEvent *event)
         case GDK_KP_Up:
         case GDK_KP_8:
             if (!MOD__CTRL) { // not ctrl
+                gint mul = 1 + gobble_key_events(
+                    get_group0_keyval(&event->key), 0); // with any mask
                 if (MOD__ALT) { // alt
-                    if (MOD__SHIFT) drag->selected_move_screen(0, 10); // shift
-                    else drag->selected_move_screen(0, 1); // no shift
+                    if (MOD__SHIFT) drag->selected_move_screen(0, mul*10); // shift
+                    else drag->selected_move_screen(0, mul*1); // no shift
                 }
                 else { // no alt
-                    if (MOD__SHIFT) drag->selected_move(0, 10*nudge); // shift
-                    else drag->selected_move(0, nudge); // no shift
+                    if (MOD__SHIFT) drag->selected_move(0, mul*10*nudge); // shift
+                    else drag->selected_move(0, mul*nudge); // no shift
                 }
                 ret = TRUE;
             }
@@ -732,13 +754,15 @@ sp_gradient_context_root_handler(SPEventContext *event_context, GdkEvent *event)
         case GDK_KP_Right:
         case GDK_KP_6:
             if (!MOD__CTRL) { // not ctrl
+                gint mul = 1 + gobble_key_events(
+                    get_group0_keyval(&event->key), 0); // with any mask
                 if (MOD__ALT) { // alt
-                    if (MOD__SHIFT) drag->selected_move_screen(10, 0); // shift
-                    else drag->selected_move_screen(1, 0); // no shift
+                    if (MOD__SHIFT) drag->selected_move_screen(mul*10, 0); // shift
+                    else drag->selected_move_screen(mul*1, 0); // no shift
                 }
                 else { // no alt
-                    if (MOD__SHIFT) drag->selected_move(10*nudge, 0); // shift
-                    else drag->selected_move(nudge, 0); // no shift
+                    if (MOD__SHIFT) drag->selected_move(mul*10*nudge, 0); // shift
+                    else drag->selected_move(mul*nudge, 0); // no shift
                 }
                 ret = TRUE;
             }
@@ -747,13 +771,15 @@ sp_gradient_context_root_handler(SPEventContext *event_context, GdkEvent *event)
         case GDK_KP_Down:
         case GDK_KP_2:
             if (!MOD__CTRL) { // not ctrl
+                gint mul = 1 + gobble_key_events(
+                    get_group0_keyval(&event->key), 0); // with any mask
                 if (MOD__ALT) { // alt
-                    if (MOD__SHIFT) drag->selected_move_screen(0, -10); // shift
-                    else drag->selected_move_screen(0, -1); // no shift
+                    if (MOD__SHIFT) drag->selected_move_screen(0, mul*-10); // shift
+                    else drag->selected_move_screen(0, mul*-1); // no shift
                 }
                 else { // no alt
-                    if (MOD__SHIFT) drag->selected_move(0, -10*nudge); // shift
-                    else drag->selected_move(0, -nudge); // no shift
+                    if (MOD__SHIFT) drag->selected_move(0, mul*-10*nudge); // shift
+                    else drag->selected_move(0, mul*-nudge); // no shift
                 }
                 ret = TRUE;
             }
@@ -825,7 +851,7 @@ sp_gradient_context_root_handler(SPEventContext *event_context, GdkEvent *event)
     return ret;
 }
 
-static void sp_gradient_drag(SPGradientContext &rc, NR::Point const pt, guint state, guint32 etime)
+static void sp_gradient_drag(SPGradientContext &rc, NR::Point const pt, guint /*state*/, guint32 etime)
 {
     SPDesktop *desktop = SP_EVENT_CONTEXT(&rc)->desktop;
     Inkscape::Selection *selection = sp_desktop_selection(desktop);
@@ -838,9 +864,16 @@ static void sp_gradient_drag(SPGradientContext &rc, NR::Point const pt, guint st
 
         SPGradient *vector;
         if (ec->item_to_select) {
+            // pick color from the object where drag started
             vector = sp_gradient_vector_for_object(document, desktop, ec->item_to_select, fill_or_stroke);
         } else {
-            vector = sp_gradient_vector_for_object(document, desktop, SP_ITEM(selection->itemList()->data), fill_or_stroke);
+            // Starting from empty space:
+            // Sort items so that the topmost comes last
+            GSList *items = g_slist_copy ((GSList *) selection->itemList());
+            items = g_slist_sort(items, (GCompareFunc) sp_item_repr_compare_position);
+            // take topmost
+            vector = sp_gradient_vector_for_object(document, desktop, SP_ITEM(g_slist_last(items)->data), fill_or_stroke);
+            g_slist_free (items);
         }
 
         // HACK: reset fill-opacity - that 0.75 is annoying; BUT remove this when we have an opacity slider for all tabs