static void sp_item_create_link(GtkMenuItem *menuitem, SPItem *item) { g_assert(SP_IS_ITEM(item)); g_assert(!SP_IS_ANCHOR(item)); SPDesktop *desktop = (SPDesktop*)gtk_object_get_data(GTK_OBJECT(menuitem), "desktop"); g_return_if_fail(desktop != NULL); Inkscape::XML::Document *xml_doc = sp_document_repr_doc(desktop->doc()); Inkscape::XML::Node *repr = xml_doc->createElement("svg:a"); SP_OBJECT_REPR(SP_OBJECT_PARENT(item))->addChild(repr, SP_OBJECT_REPR(item)); SPObject *object = SP_OBJECT_DOCUMENT(item)->getObjectByRepr(repr); g_return_if_fail(SP_IS_ANCHOR(object)); const char *id = SP_OBJECT_REPR(item)->attribute("id"); Inkscape::XML::Node *child = SP_OBJECT_REPR(item)->duplicate(xml_doc); SP_OBJECT(item)->deleteObject(false); repr->addChild(child, NULL); child->setAttribute("id", id); Inkscape::GC::release(repr); Inkscape::GC::release(child); sp_document_done(SP_OBJECT_DOCUMENT(object), SP_VERB_NONE, _("Create link")); sp_object_attributes_dialog(object, "SPAnchor"); sp_desktop_selection(desktop)->set(SP_ITEM(object)); }
/** * Drops any allocated memory. */ static void sp_fepointlight_release(SPObject *object) { //SPFePointLight *fepointlight = SP_FEPOINTLIGHT(object); if (SP_OBJECT_DOCUMENT(object)) { /* Unregister ourselves */ sp_document_remove_resource(SP_OBJECT_DOCUMENT(object), "fepointlight", SP_OBJECT(object)); } //TODO: release resources here }
void GuidelinePropertiesDialog::_onDelete() { SPDocument *doc = SP_OBJECT_DOCUMENT(_guide); sp_guide_remove(_guide); sp_document_done(doc, SP_VERB_NONE, _("Delete guide")); }
void SPDocument::queueForOrphanCollection(SPObject *object) { g_return_if_fail(object != NULL); g_return_if_fail(SP_OBJECT_DOCUMENT(object) == this); sp_object_ref(object, NULL); _collection_queue = g_slist_prepend(_collection_queue, object); }
static void sp_mask_child_added (SPObject *object, SPRepr *child, SPRepr *ref) { SPMask *cp; SPObject *ochild; cp = SP_MASK (object); /* Invoke SPObjectGroup implementation */ ((SPObjectClass *) (parent_class))->child_added (object, child, ref); /* Show new object */ ochild = sp_document_lookup_id (SP_OBJECT_DOCUMENT (object), sp_repr_attr (child, "id")); if (SP_IS_ITEM (ochild)) { SPMaskView *v; for (v = cp->display; v != NULL; v = v->next) { NRArenaItem *ac; ac = sp_item_invoke_show (SP_ITEM (ochild), NR_ARENA_ITEM_ARENA (v->arenaitem), v->key, SP_ITEM_REFERENCE_FLAGS); if (ac) { nr_arena_item_add_child (v->arenaitem, ac, NULL); nr_arena_item_unref (ac); } } } }
void GuidelinePropertiesDialog::_onApply() { double deg_angle = _spin_angle.get_value(); if (!_mode) deg_angle += _oldangle; Geom::Point normal; if ( deg_angle == 90. || deg_angle == 270. || deg_angle == -90. || deg_angle == -270.) { normal = Geom::Point(1.,0.); } else if ( deg_angle == 0. || deg_angle == 180. || deg_angle == -180.) { normal = Geom::Point(0.,1.); } else { double rad_angle = Geom::deg_to_rad( deg_angle ); normal = Geom::rot90(Geom::Point::polar(rad_angle, 1.0)); } sp_guide_set_normal(*_guide, normal, true); SPUnit const &unit = *sp_unit_selector_get_unit(SP_UNIT_SELECTOR(_unit_selector->gobj())); gdouble const raw_dist_x = _spin_button_x.get_value(); gdouble const points_x = sp_units_get_pixels(raw_dist_x, unit); gdouble const raw_dist_y = _spin_button_y.get_value(); gdouble const points_y = sp_units_get_pixels(raw_dist_y, unit); Geom::Point newpos(points_x, points_y); if (!_mode) newpos += _oldpos; sp_guide_moveto(*_guide, newpos, true); sp_document_done(SP_OBJECT_DOCUMENT(_guide), SP_VERB_NONE, _("Set guide properties")); }
static void sp_clippath_release(SPObject * object) { if (SP_OBJECT_DOCUMENT(object)) { /* Unregister ourselves */ sp_document_remove_resource(SP_OBJECT_DOCUMENT(object), "clipPath", object); } SPClipPath *cp = SP_CLIPPATH(object); while (cp->display) { /* We simply unref and let item manage this in handler */ cp->display = sp_clippath_view_list_remove(cp->display, cp->display); } if (((SPObjectClass *) (parent_class))->release) { ((SPObjectClass *) parent_class)->release(object); } }
static void sp_mask_release (SPObject * object) { SPMask *cp; cp = SP_MASK (object); if (SP_OBJECT_DOCUMENT (object)) { /* Unregister ourselves */ sp_document_remove_resource (SP_OBJECT_DOCUMENT (object), "mask", object); } while (cp->display) { /* We simply unref and let item to manage this in handler */ cp->display = sp_mask_view_list_remove (cp->display, cp->display); } if (((SPObjectClass *) (parent_class))->release) ((SPObjectClass *) parent_class)->release (object); }
static void sp_gradient_context_add_stops_between_selected_stops (SPGradientContext *rc) { SPDocument *doc = NULL; GrDrag *drag = rc->_grdrag; GSList *these_stops = NULL; GSList *next_stops = NULL; std::vector<Geom::Point> coords = sp_gradient_context_get_stop_intervals (drag, &these_stops, &next_stops); if (g_slist_length(these_stops) == 0 && drag->numSelected() == 1) { // if a single stop is selected, add between that stop and the next one GrDragger *dragger = (GrDragger *) drag->selected->data; for (GSList const* j = dragger->draggables; j != NULL; j = j->next) { GrDraggable *d = (GrDraggable *) j->data; SPGradient *gradient = sp_item_gradient (d->item, d->fill_or_stroke); SPGradient *vector = sp_gradient_get_forked_vector_if_necessary (gradient, false); SPStop *this_stop = sp_get_stop_i (vector, d->point_i); SPStop *next_stop = sp_next_stop (this_stop); if (this_stop && next_stop) { these_stops = g_slist_prepend (these_stops, this_stop); next_stops = g_slist_prepend (next_stops, next_stop); } } } // now actually create the new stops GSList *i = these_stops; GSList *j = next_stops; for (; i != NULL && j != NULL; i = i->next, j = j->next) { SPStop *this_stop = (SPStop *) i->data; SPStop *next_stop = (SPStop *) j->data; gfloat offset = 0.5*(this_stop->offset + next_stop->offset); SPObject *parent = SP_OBJECT_PARENT(this_stop); if (SP_IS_GRADIENT (parent)) { doc = SP_OBJECT_DOCUMENT (parent); sp_vector_add_stop (SP_GRADIENT (parent), this_stop, next_stop, offset); sp_gradient_ensure_vector (SP_GRADIENT (parent)); } } if (g_slist_length(these_stops) > 0 && doc) { sp_document_done (doc, SP_VERB_CONTEXT_GRADIENT, _("Add gradient stop")); drag->updateDraggers(); // so that it does not automatically update draggers in idle loop, as this would deselect drag->local_change = true; // select all the old selected and new created draggers drag->selectByCoords(coords); } g_slist_free (these_stops); g_slist_free (next_stops); }
static void knot_ungrabbed_handler (SPKnot *knot, unsigned int state, SPKnotHolder *kh) { if (kh->released) { kh->released (kh->item); } else { SPObject *object; object = (SPObject *) kh->item; sp_object_invoke_write (object, object->repr, SP_OBJECT_WRITE_EXT); sp_document_done (SP_OBJECT_DOCUMENT (kh->item)); } }
static bool evaluateSystemLanguage(SPItem const *item, gchar const *value) { if ( NULL == value ) return true; std::set<Glib::ustring> language_codes; gchar *str = NULL; gchar **strlist = g_strsplit( value, ",", 0); for ( int i = 0 ; (str = strlist[i]) ; i++ ) { gchar *lngcode = preprocessLanguageCode(str); if ( 0 == *lngcode ) continue; language_codes.insert(lngcode); gchar *pos = strchr (lngcode, '-'); if (pos) { // if subtag is used, primary tag is still a perfect match *pos = 0; if ( language_codes.find(lngcode) == language_codes.end() ) { language_codes.insert(lngcode); } } } g_strfreev(strlist); if (language_codes.empty()) return false; SPDocument *document = SP_OBJECT_DOCUMENT(item); Glib::ustring document_language = document->getLanguage(); if (document_language.size() == 0) return false; bool match = true; strlist = g_strsplit( document_language.c_str(), ",", 0); for ( int i = 0 ; (str = strlist[i]) ; i++ ) { gchar *lngcode = preprocessLanguageCode(str); if ( 0 == *lngcode ) continue; if ( language_codes.find(lngcode) != language_codes.end() ) { match = true; break; } match = false; } g_strfreev(strlist); return match; }
static bool sp_select_context_abort(SPEventContext *event_context) { SPDesktop *desktop = event_context->desktop; SPSelectContext *sc = SP_SELECT_CONTEXT(event_context); Inkscape::SelTrans *seltrans = sc->_seltrans; if (sc->dragging) { if (sc->moved) { // cancel dragging an object seltrans->ungrab(); sc->moved = FALSE; sc->dragging = FALSE; sp_event_context_discard_delayed_snap_event(event_context); drag_escaped = 1; if (sc->item) { // only undo if the item is still valid if (SP_OBJECT_DOCUMENT( SP_OBJECT(sc->item))) { sp_document_undo(sp_desktop_document(desktop)); } sp_object_unref( SP_OBJECT(sc->item), NULL); } else if (sc->button_press_ctrl) { // NOTE: This is a workaround to a bug. // When the ctrl key is held, sc->item is not defined // so in this case (only), we skip the object doc check sp_document_undo(sp_desktop_document(desktop)); } sc->item = NULL; SP_EVENT_CONTEXT(sc)->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Move canceled.")); return true; } } else { if (Inkscape::Rubberband::get(desktop)->is_started()) { Inkscape::Rubberband::get(desktop)->stop(); rb_escaped = 1; SP_EVENT_CONTEXT(sc)->defaultMessageContext()->clear(); SP_EVENT_CONTEXT(sc)->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Selection canceled.")); return true; } } return false; }
static void sp_clippath_child_added(SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref) { /* Invoke SPObjectGroup implementation */ ((SPObjectClass *) (parent_class))->child_added(object, child, ref); /* Show new object */ SPObject *ochild = SP_OBJECT_DOCUMENT(object)->getObjectByRepr(child); if (SP_IS_ITEM(ochild)) { SPClipPath *cp = SP_CLIPPATH(object); for (SPClipPathView *v = cp->display; v != NULL; v = v->next) { NRArenaItem *ac = sp_item_invoke_show(SP_ITEM(ochild), NR_ARENA_ITEM_ARENA(v->arenaitem), v->key, SP_ITEM_REFERENCE_FLAGS); if (ac) { nr_arena_item_add_child(v->arenaitem, ac, NULL); } } } }
static gint sp_select_context_root_handler(SPEventContext *event_context, GdkEvent *event) { SPItem *item = NULL; SPItem *item_at_point = NULL, *group_at_point = NULL, *item_in_group = NULL; gint ret = FALSE; SPDesktop *desktop = event_context->desktop; SPSelectContext *sc = SP_SELECT_CONTEXT(event_context); Inkscape::SelTrans *seltrans = sc->_seltrans; Inkscape::Selection *selection = sp_desktop_selection(desktop); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); // make sure we still have valid objects to move around if (sc->item && SP_OBJECT_DOCUMENT( SP_OBJECT(sc->item))==NULL) { sp_select_context_abort(event_context); } switch (event->type) { case GDK_2BUTTON_PRESS: if (event->button.button == 1) { if (!selection->isEmpty()) { SPItem *clicked_item = (SPItem *) selection->itemList()->data; 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; sp_event_context_discard_delayed_snap_event(event_context); desktop->canvas->end_forced_full_redraws(); } else { // switch tool Geom::Point const button_pt(event->button.x, event->button.y); Geom::Point const p(desktop->w2d(button_pt)); tools_switch_by_item (desktop, clicked_item, p); } } else { sp_select_context_up_one_layer(desktop); } ret = TRUE; } break; case GDK_BUTTON_PRESS: if (event->button.button == 1 && !event_context->space_panning) { // save drag origin xp = (gint) event->button.x; yp = (gint) event->button.y; within_tolerance = true; Geom::Point const button_pt(event->button.x, event->button.y); Geom::Point const p(desktop->w2d(button_pt)); if (event->button.state & GDK_MOD1_MASK) Inkscape::Rubberband::get(desktop)->setMode(RUBBERBAND_MODE_TOUCHPATH); Inkscape::Rubberband::get(desktop)->start(desktop, p); if (sc->grabbed) { sp_canvas_item_ungrab(sc->grabbed, event->button.time); 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_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK, NULL, event->button.time); sc->grabbed = SP_CANVAS_ITEM(desktop->acetate); // remember what modifiers were on before button press sc->button_press_shift = (event->button.state & GDK_SHIFT_MASK) ? true : false; sc->button_press_ctrl = (event->button.state & GDK_CONTROL_MASK) ? true : false; sc->button_press_alt = (event->button.state & GDK_MOD1_MASK) ? true : false; sc->moved = FALSE; rb_escaped = drag_escaped = 0; ret = TRUE; } else if (event->button.button == 3) { // right click; do not eat it so that right-click menu can appear, but cancel dragging & rubberband sp_select_context_abort(event_context); } break; case GDK_MOTION_NOTIFY: tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100); if (event->motion.state & GDK_BUTTON1_MASK && !event_context->space_panning) { Geom::Point const motion_pt(event->motion.x, event->motion.y); Geom::Point const p(desktop->w2d(motion_pt)); if ( within_tolerance && ( abs( (gint) event->motion.x - xp ) < tolerance ) && ( abs( (gint) event->motion.y - yp ) < tolerance ) ) { break; // do not drag if we're within tolerance from origin } // Once the user has moved farther than tolerance from the original location // (indicating they intend to move the object, not click), then always process the // motion notify coordinates as given (no snapping back to origin) within_tolerance = false; if (sc->button_press_ctrl || (sc->button_press_alt && !sc->button_press_shift && !selection->isEmpty())) { // if it's not click and ctrl or alt was pressed (the latter with some selection // but not with shift) we want to drag rather than rubberband sc->dragging = TRUE; desktop->setCursor(SP_SELECT_D_CURSOR); desktop->canvas->force_full_redraw_after_interruptions(5); } if (sc->dragging) { /* User has dragged fast, so we get events on root (lauris)*/ // not only that; we will end up here when ctrl-dragging as well // and also when we started within tolerance, but trespassed tolerance outside of item Inkscape::Rubberband::get(desktop)->stop(); SP_EVENT_CONTEXT(sc)->defaultMessageContext()->clear(); item_at_point = desktop->item_at_point(Geom::Point(event->button.x, event->button.y), FALSE); if (!item_at_point) // if no item at this point, try at the click point (bug 1012200) item_at_point = desktop->item_at_point(Geom::Point(xp, yp), FALSE); if (item_at_point || sc->moved || sc->button_press_alt) { // drag only if starting from an item, or if something is already grabbed, or if alt-dragging if (!sc->moved) { item_in_group = desktop->item_at_point(Geom::Point(event->button.x, event->button.y), TRUE); group_at_point = desktop->group_at_point(Geom::Point(event->button.x, event->button.y)); if (SP_IS_LAYER(selection->single())) group_at_point = SP_GROUP(selection->single()); // 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)) && !sc->button_press_alt) { // select what is under cursor if (!seltrans->isEmpty()) { seltrans->resetState(); } // when simply ctrl-dragging, we don't want to go into groups if (item_at_point && !selection->includes(item_at_point)) selection->set(item_at_point); } // otherwise, do not change selection so that dragging selected-within-group items, as well as alt-dragging, is possible seltrans->grab(p, -1, -1, FALSE, TRUE); sc->moved = TRUE; } if (!seltrans->isEmpty()) seltrans->moveTo(p, event->button.state); desktop->scroll_to_point(p); gobble_motion_events(GDK_BUTTON1_MASK); ret = TRUE; } else { sc->dragging = FALSE; sp_event_context_discard_delayed_snap_event(event_context); desktop->canvas->end_forced_full_redraws(); } } else { if (Inkscape::Rubberband::get(desktop)->is_started()) { Inkscape::Rubberband::get(desktop)->move(p); if (Inkscape::Rubberband::get(desktop)->getMode() == RUBBERBAND_MODE_TOUCHPATH) { event_context->defaultMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("<b>Draw over</b> objects to select them; release <b>Alt</b> to switch to rubberband selection")); } else { event_context->defaultMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("<b>Drag around</b> objects to select them; press <b>Alt</b> to switch to touch selection")); } gobble_motion_events(GDK_BUTTON1_MASK); } } } break; case GDK_BUTTON_RELEASE: xp = yp = 0; if ((event->button.button == 1) && (sc->grabbed) && !event_context->space_panning) { if (sc->dragging) { if (sc->moved) { // item has been moved seltrans->ungrab(); sc->moved = FALSE; } else if (sc->item && !drag_escaped) { // item has not been moved -> simply a click, do selecting if (!selection->isEmpty()) { if (event->button.state & GDK_SHIFT_MASK) { // with shift, toggle selection seltrans->resetState(); selection->toggle(sc->item); } else { SPObject* single = selection->single(); // without shift, increase state (i.e. toggle scale/rotation handles) if (selection->includes(sc->item)) { seltrans->increaseState(); } else if (SP_IS_LAYER(single) && single->isAncestorOf(sc->item)) { seltrans->increaseState(); } else { seltrans->resetState(); selection->set(sc->item); } } } else { // simple or shift click, no previous selection seltrans->resetState(); selection->set(sc->item); } } sc->dragging = FALSE; desktop->setCursor(SP_SELECT_CURSOR); sp_event_context_discard_delayed_snap_event(event_context); desktop->canvas->end_forced_full_redraws(); if (sc->item) { sp_object_unref( SP_OBJECT(sc->item), NULL); } sc->item = NULL; } else { Inkscape::Rubberband *r = Inkscape::Rubberband::get(desktop); if (r->is_started() && !within_tolerance) { // this was a rubberband drag GSList *items = NULL; if (r->getMode() == RUBBERBAND_MODE_RECT) { Geom::OptRect const b = r->getRectangle(); items = sp_document_items_in_box(sp_desktop_document(desktop), desktop->dkey, *b); } else if (r->getMode() == RUBBERBAND_MODE_TOUCHPATH) { items = sp_document_items_at_points(sp_desktop_document(desktop), desktop->dkey, r->getPoints()); } seltrans->resetState(); r->stop(); SP_EVENT_CONTEXT(sc)->defaultMessageContext()->clear(); if (event->button.state & GDK_SHIFT_MASK) { // with shift, add to selection selection->addList (items); } else { // without shift, simply select anew selection->setList (items); } g_slist_free (items); } else { // it was just a click, or a too small rubberband r->stop(); if (sc->button_press_shift && !rb_escaped && !drag_escaped) { // this was a shift+click or alt+shift+click, select what was clicked upon sc->button_press_shift = false; if (sc->button_press_ctrl) { // go into groups, honoring Alt item = sp_event_context_find_item (desktop, Geom::Point(event->button.x, event->button.y), event->button.state & GDK_MOD1_MASK, TRUE); sc->button_press_ctrl = FALSE; } else { // don't go into groups, honoring Alt item = sp_event_context_find_item (desktop, Geom::Point(event->button.x, event->button.y), event->button.state & GDK_MOD1_MASK, FALSE); } if (item) { selection->toggle(item); item = NULL; } } else if ((sc->button_press_ctrl || sc->button_press_alt) && !rb_escaped && !drag_escaped) { // ctrl+click, alt+click item = sp_event_context_find_item (desktop, Geom::Point(event->button.x, event->button.y), sc->button_press_alt, sc->button_press_ctrl); sc->button_press_ctrl = FALSE; sc->button_press_alt = FALSE; if (item) { if (selection->includes(item)) { seltrans->increaseState(); } else { seltrans->resetState(); selection->set(item); } item = NULL; } } else { // click without shift, simply deselect, unless with Alt or something was cancelled if (!selection->isEmpty()) { if (!(rb_escaped) && !(drag_escaped) && !(event->button.state & GDK_MOD1_MASK)) selection->clear(); rb_escaped = 0; ret = TRUE; } } } ret = TRUE; } if (sc->grabbed) { sp_canvas_item_ungrab(sc->grabbed, event->button.time); sc->grabbed = NULL; } desktop->updateNow(); } if (event->button.button == 1) { Inkscape::Rubberband::get(desktop)->stop(); // might have been started in another tool! } sc->button_press_shift = false; sc->button_press_ctrl = false; sc->button_press_alt = false; break; case GDK_KEY_PRESS: // keybindings for select context { { guint keyval = get_group0_keyval(&event->key); bool alt = ( MOD__ALT || (keyval == GDK_Alt_L) || (keyval == GDK_Alt_R) || (keyval == GDK_Meta_L) || (keyval == GDK_Meta_R)); if (!key_is_a_modifier (keyval)) { event_context->defaultMessageContext()->clear(); } else if (sc->grabbed || seltrans->isGrabbed()) { if (Inkscape::Rubberband::get(desktop)->is_started()) { // if Alt then change cursor to moving cursor: if (alt) { Inkscape::Rubberband::get(desktop)->setMode(RUBBERBAND_MODE_TOUCHPATH); } } else { // do not change the statusbar text when mousekey is down to move or transform the object, // because the statusbar text is already updated somewhere else. break; } } else { sp_event_show_modifier_tip (event_context->defaultMessageContext(), event, _("<b>Ctrl</b>: click to select in groups; drag to move hor/vert"), _("<b>Shift</b>: click to toggle select; drag for rubberband selection"), _("<b>Alt</b>: click to select under; drag to move selected or select by touch")); // if Alt and nonempty selection, show moving cursor ("move selected"): if (alt && !selection->isEmpty() && !desktop->isWaitingCursor()) { desktop->setCursor(SP_SELECT_D_CURSOR); } //*/ break; } } gdouble const nudge = prefs->getDoubleLimited("/options/nudgedistance/value", 2, 0, 1000); // in px gdouble const offset = prefs->getDoubleLimited("/options/defaultscale/value", 2, 0, 1000); int const snaps = prefs->getInt("/options/rotationsnapsperpi/value", 12); switch (get_group0_keyval (&event->key)) { case GDK_Left: // move selection left 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(desktop, mul*-10, 0); // shift else sp_selection_move_screen(desktop, mul*-1, 0); // no shift } else { // no alt if (MOD__SHIFT) sp_selection_move(desktop, mul*-10*nudge, 0); // shift else sp_selection_move(desktop, mul*-nudge, 0); // no shift } ret = TRUE; } break; case GDK_Up: // move selection up 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(desktop, 0, mul*10); // shift else sp_selection_move_screen(desktop, 0, mul*1); // no shift } else { // no alt if (MOD__SHIFT) sp_selection_move(desktop, 0, mul*10*nudge); // shift else sp_selection_move(desktop, 0, mul*nudge); // no shift } ret = TRUE; } break; case GDK_Right: // move selection right 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(desktop, mul*10, 0); // shift else sp_selection_move_screen(desktop, mul*1, 0); // no shift } else { // no alt if (MOD__SHIFT) sp_selection_move(desktop, mul*10*nudge, 0); // shift else sp_selection_move(desktop, mul*nudge, 0); // no shift } ret = TRUE; } break; case GDK_Down: // move selection down 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(desktop, 0, mul*-10); // shift else sp_selection_move_screen(desktop, 0, mul*-1); // no shift } else { // no alt if (MOD__SHIFT) sp_selection_move(desktop, 0, mul*-10*nudge); // shift else sp_selection_move(desktop, 0, mul*-nudge); // no shift } ret = TRUE; } break; case GDK_Escape: if (!sp_select_context_abort(event_context)) selection->clear(); ret = TRUE; break; case GDK_a: case GDK_A: if (MOD__CTRL_ONLY) { sp_edit_select_all(desktop); ret = TRUE; } break; case GDK_space: /* stamping mode: show outline mode moving */ /* FIXME: Is next condition ok? (lauris) */ if (sc->dragging && sc->grabbed) { seltrans->stamp(); ret = TRUE; } break; case GDK_x: case GDK_X: if (MOD__ALT_ONLY) { desktop->setToolboxFocusTo ("altx"); ret = TRUE; } break; case GDK_bracketleft: if (MOD__ALT) { 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) { sp_selection_rotate(selection, 180.0/snaps); } ret = TRUE; break; case GDK_bracketright: if (MOD__ALT) { 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) { sp_selection_rotate(selection, -180.0/snaps); } ret = TRUE; break; case GDK_less: case GDK_comma: if (MOD__ALT) { 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 { 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) { 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 { 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_Return: if (MOD__CTRL_ONLY) { if (selection->singleItem()) { SPItem *clicked_item = selection->singleItem(); 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 { SP_EVENT_CONTEXT(sc)->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Selected object is not a group. Cannot enter.")); } } ret = TRUE; } break; case GDK_BackSpace: if (MOD__CTRL_ONLY) { sp_select_context_up_one_layer(desktop); 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(desktop); ret = true; } break; default: break; } break; } case GDK_KEY_RELEASE: { guint keyval = get_group0_keyval(&event->key); if (key_is_a_modifier (keyval)) event_context->defaultMessageContext()->clear(); bool alt = ( MOD__ALT || (keyval == GDK_Alt_L) || (keyval == GDK_Alt_R) || (keyval == GDK_Meta_L) || (keyval == GDK_Meta_R)); if (Inkscape::Rubberband::get(desktop)->is_started()) { // if Alt then change cursor to moving cursor: if (alt) { Inkscape::Rubberband::get(desktop)->setMode(RUBBERBAND_MODE_RECT); } } } // set cursor to default. if (!desktop->isWaitingCursor()) { desktop->setCursor(event_context->cursor_shape); } break; default: break; } if (!ret) { if (((SPEventContextClass *) parent_class)->root_handler) ret = ((SPEventContextClass *) parent_class)->root_handler(event_context, event); } return ret; }
static gint sp_select_context_item_handler(SPEventContext *event_context, SPItem *item, GdkEvent *event) { gint ret = FALSE; SPDesktop *desktop = event_context->desktop; SPSelectContext *sc = SP_SELECT_CONTEXT(event_context); Inkscape::SelTrans *seltrans = sc->_seltrans; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100); // make sure we still have valid objects to move around if (sc->item && SP_OBJECT_DOCUMENT( SP_OBJECT(sc->item))==NULL) { sp_select_context_abort(event_context); } switch (event->type) { case GDK_BUTTON_PRESS: if (event->button.button == 1 && !event_context->space_panning) { /* Left mousebutton */ // save drag origin xp = (gint) event->button.x; yp = (gint) event->button.y; within_tolerance = true; // remember what modifiers were on before button press sc->button_press_shift = (event->button.state & GDK_SHIFT_MASK) ? true : false; sc->button_press_ctrl = (event->button.state & GDK_CONTROL_MASK) ? true : false; sc->button_press_alt = (event->button.state & GDK_MOD1_MASK) ? true : false; if (event->button.state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK)) { // if shift or ctrl was pressed, do not move objects; // pass the event to root handler which will perform rubberband, shift-click, ctrl-click, ctrl-drag } else { sc->dragging = TRUE; sc->moved = FALSE; desktop->setCursor(SP_SELECT_D_CURSOR); desktop->canvas->force_full_redraw_after_interruptions(5); // remember the clicked item in sc->item: if (sc->item) { sp_object_unref(sc->item, NULL); sc->item = NULL; } sc->item = sp_event_context_find_item (desktop, Geom::Point(event->button.x, event->button.y), event->button.state & GDK_MOD1_MASK, FALSE); sp_object_ref(sc->item, NULL); rb_escaped = drag_escaped = 0; if (sc->grabbed) { sp_canvas_item_ungrab(sc->grabbed, event->button.time); sc->grabbed = NULL; } 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_HINT_MASK, NULL, event->button.time); sc->grabbed = SP_CANVAS_ITEM(desktop->drawing); desktop->canvas->force_full_redraw_after_interruptions(5); ret = TRUE; } } else if (event->button.button == 3) { // right click; do not eat it so that right-click menu can appear, but cancel dragging & rubberband sp_select_context_abort(event_context); } break; case GDK_ENTER_NOTIFY: { if (!desktop->isWaitingCursor() && !sc->dragging) { desktop->setCursor(SP_SELECT_CURSOR); } break; } case GDK_LEAVE_NOTIFY: if (!desktop->isWaitingCursor() && !sc->dragging) desktop->setCursor(event_context->cursor_shape); break; case GDK_KEY_PRESS: if (get_group0_keyval (&event->key) == GDK_space) { if (sc->dragging && sc->grabbed) { /* stamping mode: show content mode moving */ seltrans->stamp(); ret = TRUE; } } break; default: break; } if (!ret) { if (((SPEventContextClass *) parent_class)->item_handler) ret = ((SPEventContextClass *) parent_class)->item_handler(event_context, item, event); } return ret; }
static void sp_gradient_simplify(SPGradientContext *rc, double tolerance) { SPDocument *doc = NULL; GrDrag *drag = rc->_grdrag; GSList *these_stops = NULL; GSList *next_stops = NULL; std::vector<Geom::Point> coords = sp_gradient_context_get_stop_intervals (drag, &these_stops, &next_stops); GSList *todel = NULL; GSList *i = these_stops; GSList *j = next_stops; for (; i != NULL && j != NULL; i = i->next, j = j->next) { SPStop *stop0 = (SPStop *) i->data; SPStop *stop1 = (SPStop *) j->data; gint i1 = g_slist_index(these_stops, stop1); if (i1 != -1) { GSList *next_next = g_slist_nth (next_stops, i1); if (next_next) { SPStop *stop2 = (SPStop *) next_next->data; if (g_slist_find(todel, stop0) || g_slist_find(todel, stop2)) continue; guint32 const c0 = sp_stop_get_rgba32(stop0); guint32 const c2 = sp_stop_get_rgba32(stop2); guint32 const c1r = sp_stop_get_rgba32(stop1); guint32 c1 = average_color (c0, c2, (stop1->offset - stop0->offset) / (stop2->offset - stop0->offset)); double diff = sqr(SP_RGBA32_R_F(c1) - SP_RGBA32_R_F(c1r)) + sqr(SP_RGBA32_G_F(c1) - SP_RGBA32_G_F(c1r)) + sqr(SP_RGBA32_B_F(c1) - SP_RGBA32_B_F(c1r)) + sqr(SP_RGBA32_A_F(c1) - SP_RGBA32_A_F(c1r)); if (diff < tolerance) todel = g_slist_prepend (todel, stop1); } } } for (i = todel; i != NULL; i = i->next) { SPStop *stop = (SPStop*) i->data; doc = SP_OBJECT_DOCUMENT (stop); Inkscape::XML::Node * parent = SP_OBJECT_REPR(stop)->parent(); parent->removeChild(SP_OBJECT_REPR(stop)); } if (g_slist_length(todel) > 0) { sp_document_done (doc, SP_VERB_CONTEXT_GRADIENT, _("Simplify gradient")); drag->local_change = true; drag->updateDraggers(); drag->selectByCoords(coords); } g_slist_free (todel); g_slist_free (these_stops); g_slist_free (next_stops); }
static void sp_text_edit_dialog_update_object (SPText *text, SPRepr *repr) { g_object_set_data (G_OBJECT (dlg), "blocked", GINT_TO_POINTER (TRUE)); if (text) { GtkTextBuffer *tb; GtkTextIter start, end; gchar *str; tb = (GtkTextBuffer*)g_object_get_data (G_OBJECT (dlg), "text"); /* Content */ gtk_text_buffer_get_bounds (tb, &start, &end); str = gtk_text_buffer_get_text (tb, &start, &end, TRUE); sp_text_set_repr_text_multiline (text, str); g_free (str); } if (repr) { GtkWidget *fontsel, *preview, *b, *combo; SPCSSAttr *css; NRFont *font; gchar c[256]; const char *sstr; fontsel = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "fontsel"); preview = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "preview"); css = sp_repr_css_attr_new (); /* font */ font = sp_font_selector_get_font (SP_FONT_SELECTOR (fontsel)); nr_typeface_family_name_get (NR_FONT_TYPEFACE (font), c, 256); sp_repr_css_set_property (css, "font-family", c); nr_typeface_attribute_get (NR_FONT_TYPEFACE (font), "weight", c, 256); g_strdown (c); sp_repr_css_set_property (css, "font-weight", c); nr_typeface_attribute_get (NR_FONT_TYPEFACE (font), "style", c, 256); g_strdown (c); sp_repr_css_set_property (css, "font-style", c); g_snprintf (c, 64, "%g", NR_FONT_SIZE (font)); sp_repr_css_set_property (css, "font-size", c); nr_font_unref (font); /* Layout */ b = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "text_anchor_start"); if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (b))) { sp_repr_css_set_property (css, "text-anchor", "start"); } else { b = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "text_anchor_middle"); if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (b))) { sp_repr_css_set_property (css, "text-anchor", "middle"); } else { sp_repr_css_set_property (css, "text-anchor", "end"); } } b = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "writing_mode_lr"); if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (b))) { sp_repr_css_set_property (css, "writing-mode", "lr"); } else { sp_repr_css_set_property (css, "writing-mode", "tb"); } combo = (GtkWidget*)g_object_get_data ((GObject *) dlg, "line_spacing"); sstr = gtk_entry_get_text ((GtkEntry *) ((GtkCombo *) (combo))->entry); sp_repr_set_attr (repr, "sodipodi:linespacing", sstr); sp_repr_css_change (repr, css, "style"); sp_repr_css_attr_unref (css); } if (text) { sp_document_done (SP_DT_DOCUMENT (SP_ACTIVE_DESKTOP)); sp_document_ensure_up_to_date (SP_OBJECT_DOCUMENT (text)); } g_object_set_data (G_OBJECT (dlg), "blocked", NULL); }