Logo Search packages:      
Sourcecode: inkscape version File versions  Download package

void sp_node_selected_delete_segment ( Inkscape::NodePath::Path nodepath  ) 

Delete one or more segments between two selected nodes. This is the code for 'split'.

Definition at line 2653 of file nodepath.cpp.

References Inkscape::NodePath::Node::code, Inkscape::NodePath::Path::desktop, Geom::distance(), Inkscape::MessageStack::flash(), Inkscape::UI::View::View::messageStack(), Inkscape::NodePath::Node::n, NR_MOVETO, Inkscape::NodePath::Node::p, Inkscape::NodePath::Node::pos, Inkscape::NodePath::Path::selected, sp_nodepath_cleanup(), sp_nodepath_node_destroy(), sp_nodepath_node_new(), sp_nodepath_subpath_destroy(), sp_nodepath_subpath_new(), sp_nodepath_update_handles(), sp_nodepath_update_repr(), sp_nodepath_update_statusbar(), Inkscape::NodePath::Node::subpath, and Inkscape::NodePath::Node::type.

{
   Inkscape::NodePath::Node *start, *end;     //Start , end nodes.  not inclusive
   Inkscape::NodePath::Node *curr, *next;     //Iterators

    if (!nodepath) return; // there's no nodepath when editing rects, stars, spirals or ellipses

    if (g_list_length(nodepath->selected) != 2) {
        nodepath->desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE,
                                                 _("Select <b>two non-endpoint nodes</b> on a path between which to delete segments."));
        return;
    }

    //Selected nodes, not inclusive
   Inkscape::NodePath::Node *a = (Inkscape::NodePath::Node *) nodepath->selected->data;
   Inkscape::NodePath::Node *b = (Inkscape::NodePath::Node *) nodepath->selected->next->data;

    if ( ( a==b)                       ||  //same node
         (a->subpath  != b->subpath )  ||  //not the same path
         (!a->p.other || !a->n.other)  ||  //one of a's sides does not have a segment
         (!b->p.other || !b->n.other) )    //one of b's sides does not have a segment
    {
        nodepath->desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE,
                                                 _("Select <b>two non-endpoint nodes</b> on a path between which to delete segments."));
        return;
    }

    //###########################################
    //# BEGIN EDITS
    //###########################################
    //##################################
    //# CLOSED PATH
    //##################################
    if (a->subpath->closed) {


        gboolean reversed = FALSE;

        //Since we can go in a circle, we need to find the shorter distance.
        //  a->b or b->a
        start = end = NULL;
        int distance    = 0;
        int minDistance = 0;
        for (curr = a->n.other ; curr && curr!=a ; curr=curr->n.other) {
            if (curr==b) {
                //printf("a to b:%d\n", distance);
                start = a;//go from a to b
                end   = b;
                minDistance = distance;
                //printf("A to B :\n");
                break;
            }
            distance++;
        }

        //try again, the other direction
        distance = 0;
        for (curr = b->n.other ; curr && curr!=b ; curr=curr->n.other) {
            if (curr==a) {
                //printf("b to a:%d\n", distance);
                if (distance < minDistance) {
                    start    = b;  //we go from b to a
                    end      = a;
                    reversed = TRUE;
                    //printf("B to A\n");
                }
                break;
            }
            distance++;
        }


        //Copy everything from 'end' to 'start' to a new subpath
       Inkscape::NodePath::SubPath *t = sp_nodepath_subpath_new(nodepath);
        for (curr=end ; curr ; curr=curr->n.other) {
            NRPathcode code = (NRPathcode) curr->code;
            if (curr == end)
                code = NR_MOVETO;
            sp_nodepath_node_new(t, NULL,
                                 (Inkscape::NodePath::NodeType)curr->type, code,
                                 &curr->p.pos, &curr->pos, &curr->n.pos);
            if (curr == start)
                break;
        }
        sp_nodepath_subpath_destroy(a->subpath);


    }



    //##################################
    //# OPEN PATH
    //##################################
    else {

        //We need to get the direction of the list between A and B
        //Can we walk from a to b?
        start = end = NULL;
        for (curr = a->n.other ; curr && curr!=a ; curr=curr->n.other) {
            if (curr==b) {
                start = a;  //did it!  we go from a to b
                end   = b;
                //printf("A to B\n");
                break;
            }
        }
        if (!start) {//didn't work?  let's try the other direction
            for (curr = b->n.other ; curr && curr!=b ; curr=curr->n.other) {
                if (curr==a) {
                    start = b;  //did it!  we go from b to a
                    end   = a;
                    //printf("B to A\n");
                    break;
                }
            }
        }
        if (!start) {
            nodepath->desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE,
                                                     _("Cannot find path between nodes."));
            return;
        }



        //Copy everything after 'end' to a new subpath
       Inkscape::NodePath::SubPath *t = sp_nodepath_subpath_new(nodepath);
        for (curr=end ; curr ; curr=curr->n.other) {
            NRPathcode code = (NRPathcode) curr->code;
            if (curr == end)
                code = NR_MOVETO;
            sp_nodepath_node_new(t, NULL, (Inkscape::NodePath::NodeType)curr->type, code,
                                 &curr->p.pos, &curr->pos, &curr->n.pos);
        }

        //Now let us do our deletion.  Since the tail has been saved, go all the way to the end of the list
        for (curr = start->n.other ; curr  ; curr=next) {
            next = curr->n.other;
            sp_nodepath_node_destroy(curr);
        }

    }
    //###########################################
    //# END EDITS
    //###########################################

    //clean up the nodepath (such as for trivial subpaths)
    sp_nodepath_cleanup(nodepath);

    sp_nodepath_update_handles(nodepath);

    sp_nodepath_update_repr(nodepath, _("Delete segment"));

    sp_nodepath_update_statusbar(nodepath);
}


Generated by  Doxygen 1.6.0   Back to index