Logo Search packages:      
Sourcecode: inkscape version File versions

void sp_node_selected_delete_segment ( void   ) 

Delete one or more segments between two selected nodes.

This is the code for 'split'

Definition at line 1352 of file nodepath.cpp.

References Path::Node::code, Path::Path::desktop, Path::Node::n, Path::Node::p, Path::Node::pos, Path::Path::selected, Path::Node::subpath, Path::Path::subpaths, and Path::Node::type.

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

    Path::Path *nodepath = sp_nodepath_current();
    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
    Path::Node *a = (Path::Node *) nodepath->selected->data;
    Path::Node *b = (Path::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
        Path::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,
                                 (Path::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
        Path::SubPath *t = sp_nodepath_subpath_new(nodepath);
        for (curr=end ; curr ; curr=curr->n.other) {
            sp_nodepath_node_new(t, NULL, (Path::NodeType)curr->type, (NRPathcode)curr->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_ensure_ctrls(nodepath);

    update_repr(nodepath);

    // if the entire nodepath is removed, delete the selected object.
    if (nodepath->subpaths == NULL ||
        sp_nodepath_get_node_count(nodepath) < 2) {
        sp_nodepath_destroy(nodepath);
        sp_selection_delete();
        return;
    }

    sp_nodepath_update_statusbar(nodepath);
}


Generated by  Doxygen 1.6.0   Back to index