Code

Fix handle for LPERotateCopies
[inkscape.git] / src / select-context.cpp
index 089da65b840ea94824cc0d678a2829972c5469c1..010382376e9f7b8e3d50c6256eaaf075e6659da4 100644 (file)
@@ -16,6 +16,8 @@
 #ifdef HAVE_CONFIG_H
 # include "config.h"
 #endif
+#include <cstring>
+#include <string>
 #include <gdk/gdkkeysyms.h>
 #include "macros.h"
 #include "rubberband.h"
@@ -38,6 +40,7 @@
 #include "message-stack.h"
 #include "selection-describer.h"
 #include "seltrans.h"
+#include "box3d.h"
 
 static void sp_select_context_class_init(SPSelectContextClass *klass);
 static void sp_select_context_init(SPSelectContext *select_context);
@@ -299,7 +302,7 @@ sp_select_context_item_handler(SPEventContext *event_context, SPItem *item, GdkE
 
     switch (event->type) {
         case GDK_BUTTON_PRESS:
-            if (event->button.button == 1) {
+            if (event->button.button == 1 && !event_context->space_panning) {
                 /* Left mousebutton */
 
                 // save drag origin
@@ -338,7 +341,7 @@ sp_select_context_item_handler(SPEventContext *event_context, SPItem *item, GdkE
                     }
                     sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->drawing),
                                         GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK |
-                                        GDK_POINTER_MOTION_MASK,
+                                        GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK,
                                         NULL, event->button.time);
                     sc->grabbed = SP_CANVAS_ITEM(desktop->drawing);
 
@@ -412,7 +415,7 @@ sp_select_context_root_handler(SPEventContext *event_context, GdkEvent *event)
             if (event->button.button == 1) {
                 if (!selection->isEmpty()) {
                     SPItem *clicked_item = (SPItem *) selection->itemList()->data;
-                    if (SP_IS_GROUP (clicked_item)) { // enter group
+                    if (SP_IS_GROUP(clicked_item) && !SP_IS_BOX3D(clicked_item)) { // enter group if it's not a 3D box
                         desktop->setCurrentLayer(reinterpret_cast<SPObject *>(clicked_item));
                         sp_desktop_selection(desktop)->clear();
                         sc->dragging = false;
@@ -428,7 +431,7 @@ sp_select_context_root_handler(SPEventContext *event_context, GdkEvent *event)
             }
             break;
         case GDK_BUTTON_PRESS:
-            if (event->button.button == 1) {
+            if (event->button.button == 1 && !event_context->space_panning) {
 
                 // save drag origin
                 xp = (gint) event->button.x;
@@ -445,7 +448,7 @@ sp_select_context_root_handler(SPEventContext *event_context, GdkEvent *event)
                     sc->grabbed = NULL;
                 }
                 sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate),
-                                    GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK,
+                                    GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK,
                                     NULL, event->button.time);
                 sc->grabbed = SP_CANVAS_ITEM(desktop->acetate);
 
@@ -466,7 +469,7 @@ sp_select_context_root_handler(SPEventContext *event_context, GdkEvent *event)
             break;
 
         case GDK_MOTION_NOTIFY:
-            if (event->motion.state & GDK_BUTTON1_MASK) {
+            if (event->motion.state & GDK_BUTTON1_MASK && !event_context->space_panning) {
                 NR::Point const motion_pt(event->motion.x, event->motion.y);
                 NR::Point const p(desktop->w2d(motion_pt));
 
@@ -502,6 +505,14 @@ sp_select_context_root_handler(SPEventContext *event_context, GdkEvent *event)
                         if (!sc->moved) {
                             item_in_group = desktop->item_at_point(NR::Point(event->button.x, event->button.y), TRUE);
                             group_at_point = desktop->group_at_point(NR::Point(event->button.x, event->button.y));
+
+                            // group-at-point is meant to be topmost item if it's a group, 
+                            // not topmost group of all items at point
+                            if (group_at_point != item_in_group && 
+                                !(group_at_point && item_at_point && 
+                                  group_at_point->isAncestorOf(item_at_point)))
+                                group_at_point = NULL;
+
                             // if neither a group nor an item (possibly in a group) at point are selected, set selection to the item at point
                             if ((!item_in_group || !selection->includes(item_in_group)) &&
                                 (!group_at_point || !selection->includes(group_at_point))
@@ -519,9 +530,8 @@ sp_select_context_root_handler(SPEventContext *event_context, GdkEvent *event)
                         }
                         if (!seltrans->isEmpty())
                             seltrans->moveTo(p, event->button.state);
-                        if (desktop->scroll_to_point(&p))
-                            // unfortunately in complex drawings, gobbling results in losing grab of the object, for some mysterious reason
-                            ; //gobble_motion_events(GDK_BUTTON1_MASK);
+                        desktop->scroll_to_point(&p);
+                        gobble_motion_events(GDK_BUTTON1_MASK);
                         ret = TRUE;
                     } else {
                         sc->dragging = FALSE;
@@ -543,7 +553,7 @@ sp_select_context_root_handler(SPEventContext *event_context, GdkEvent *event)
             break;
         case GDK_BUTTON_RELEASE:
             xp = yp = 0;
-            if ((event->button.button == 1) && (sc->grabbed)) {
+            if ((event->button.button == 1) && (sc->grabbed) && !event_context->space_panning) {
                 if (sc->dragging) {
                     if (sc->moved) {
                         // item has been moved
@@ -713,13 +723,15 @@ sp_select_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) sp_selection_move_screen(-10, 0); // shift
-                            else sp_selection_move_screen(-1, 0); // no shift
+                            if (MOD__SHIFT) sp_selection_move_screen(mul*-10, 0); // shift
+                            else sp_selection_move_screen(mul*-1, 0); // no shift
                         }
                         else { // no alt
-                            if (MOD__SHIFT) sp_selection_move(-10*nudge, 0); // shift
-                            else sp_selection_move(-nudge, 0); // no shift
+                            if (MOD__SHIFT) sp_selection_move(mul*-10*nudge, 0); // shift
+                            else sp_selection_move(mul*-nudge, 0); // no shift
                         }
                         ret = TRUE;
                     }
@@ -728,13 +740,15 @@ sp_select_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) sp_selection_move_screen(0, 10); // shift
-                            else sp_selection_move_screen(0, 1); // no shift
+                            if (MOD__SHIFT) sp_selection_move_screen(0, mul*10); // shift
+                            else sp_selection_move_screen(0, mul*1); // no shift
                         }
                         else { // no alt
-                            if (MOD__SHIFT) sp_selection_move(0, 10*nudge); // shift
-                            else sp_selection_move(0, nudge); // no shift
+                            if (MOD__SHIFT) sp_selection_move(0, mul*10*nudge); // shift
+                            else sp_selection_move(0, mul*nudge); // no shift
                         }
                         ret = TRUE;
                     }
@@ -743,13 +757,15 @@ sp_select_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) sp_selection_move_screen(10, 0); // shift
-                            else sp_selection_move_screen(1, 0); // no shift
+                            if (MOD__SHIFT) sp_selection_move_screen(mul*10, 0); // shift
+                            else sp_selection_move_screen(mul*1, 0); // no shift
                         }
                         else { // no alt
-                            if (MOD__SHIFT) sp_selection_move(10*nudge, 0); // shift
-                            else sp_selection_move(nudge, 0); // no shift
+                            if (MOD__SHIFT) sp_selection_move(mul*10*nudge, 0); // shift
+                            else sp_selection_move(mul*nudge, 0); // no shift
                         }
                         ret = TRUE;
                     }
@@ -758,13 +774,15 @@ sp_select_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) sp_selection_move_screen(0, -10); // shift
-                            else sp_selection_move_screen(0, -1); // no shift
+                            if (MOD__SHIFT) sp_selection_move_screen(0, mul*-10); // shift
+                            else sp_selection_move_screen(0, mul*-1); // no shift
                         }
                         else { // no alt
-                            if (MOD__SHIFT) sp_selection_move(0, -10*nudge); // shift
-                            else sp_selection_move(0, -nudge); // no shift
+                            if (MOD__SHIFT) sp_selection_move(0, mul*-10*nudge); // shift
+                            else sp_selection_move(0, mul*-nudge); // no shift
                         }
                         ret = TRUE;
                     }
@@ -798,7 +816,9 @@ sp_select_context_root_handler(SPEventContext *event_context, GdkEvent *event)
                     break;
                 case GDK_bracketleft:
                     if (MOD__ALT) {
-                        sp_selection_rotate_screen(selection, 1);
+                        gint mul = 1 + gobble_key_events(
+                            get_group0_keyval(&event->key), 0); // with any mask
+                        sp_selection_rotate_screen(selection, mul*1);
                     } else if (MOD__CTRL) {
                         sp_selection_rotate(selection, 90);
                     } else if (snaps) {
@@ -808,7 +828,9 @@ sp_select_context_root_handler(SPEventContext *event_context, GdkEvent *event)
                     break;
                 case GDK_bracketright:
                     if (MOD__ALT) {
-                        sp_selection_rotate_screen(selection, -1);
+                        gint mul = 1 + gobble_key_events(
+                            get_group0_keyval(&event->key), 0); // with any mask
+                        sp_selection_rotate_screen(selection, -1*mul);
                     } else if (MOD__CTRL) {
                         sp_selection_rotate(selection, -90);
                     } else if (snaps) {
@@ -819,22 +841,30 @@ sp_select_context_root_handler(SPEventContext *event_context, GdkEvent *event)
                 case GDK_less:
                 case GDK_comma:
                     if (MOD__ALT) {
-                        sp_selection_scale_screen(selection, -2);
+                        gint mul = 1 + gobble_key_events(
+                            get_group0_keyval(&event->key), 0); // with any mask
+                        sp_selection_scale_screen(selection, -2*mul);
                     } else if (MOD__CTRL) {
                         sp_selection_scale_times(selection, 0.5);
                     } else {
-                        sp_selection_scale(selection, -offset);
+                        gint mul = 1 + gobble_key_events(
+                            get_group0_keyval(&event->key), 0); // with any mask
+                        sp_selection_scale(selection, -offset*mul);
                     }
                     ret = TRUE;
                     break;
                 case GDK_greater:
                 case GDK_period:
                     if (MOD__ALT) {
-                        sp_selection_scale_screen(selection, 2);
+                        gint mul = 1 + gobble_key_events(
+                            get_group0_keyval(&event->key), 0); // with any mask
+                        sp_selection_scale_screen(selection, 2*mul);
                     } else if (MOD__CTRL) {
                         sp_selection_scale_times(selection, 2);
                     } else {
-                        sp_selection_scale(selection, offset);
+                        gint mul = 1 + gobble_key_events(
+                            get_group0_keyval(&event->key), 0); // with any mask
+                        sp_selection_scale(selection, offset*mul);
                     }
                     ret = TRUE;
                     break;
@@ -842,7 +872,8 @@ sp_select_context_root_handler(SPEventContext *event_context, GdkEvent *event)
                     if (MOD__CTRL_ONLY) {
                         if (selection->singleItem()) {
                             SPItem *clicked_item = selection->singleItem();
-                            if (SP_IS_GROUP (clicked_item)) { // enter group
+                            if ( SP_IS_GROUP(clicked_item) ||
+                                 SP_IS_BOX3D(clicked_item)) { // enter group or a 3D box
                                 desktop->setCurrentLayer(reinterpret_cast<SPObject *>(clicked_item));
                                 sp_desktop_selection(desktop)->clear();
                             } else {
@@ -858,6 +889,22 @@ sp_select_context_root_handler(SPEventContext *event_context, GdkEvent *event)
                         ret = TRUE;
                     }
                     break;
+                case GDK_s:
+                case GDK_S:
+                    if (MOD__SHIFT_ONLY) {
+                        if (!selection->isEmpty()) {
+                            seltrans->increaseState();
+                        }
+                        ret = TRUE;
+                    }
+                    break;                  
+                case GDK_g:
+                case GDK_G:
+                    if (MOD__SHIFT_ONLY) {
+                        sp_selection_to_guides();
+                        ret = true;
+                    }
+                    break;
                 default:
                     break;
             }