#help_index "DolDoc/Clip"

sys_clip_doc = DocNew;

public U0 ClipDel()
{//Delete everything on clip.
        DocReset(sys_clip_doc, TRUE);
}

public U0 ClipCopy(CDoc *doc)
{//Copy DOCET_SEL flagged entries to clip.
        CDoc            *doc2 = sys_clip_doc;
        Bool             unlock_doc = DocLock(doc), unlock_doc2 = DocLock(doc2);
        CDocEntry       *doc_e = doc->head.next, *doc_ne;

        ClipDel;
        while (doc_e != doc)
        {
                if (doc_e->type & DOCET_SEL)
                {
                        doc_e->type &= ~DOCET_SEL;
                        if (!Bt(doldoc.type_flags_data, doc_e->type_u8))
                        {
                                doc_ne = DocEntryCopy(doc2, doc_e);
                                QueueInsert(doc_ne, doc2->head.last);
                        }
                }
                doc_e = doc_e->next;
        }
        if (unlock_doc2)
                DocUnlock(doc2);
        if (unlock_doc)
                DocUnlock(doc);
}

public U0 ClipCut(CDoc *doc)
{//Remove sel entries and place on clip.
        CDoc            *doc2 = sys_clip_doc;
        Bool             unlock_doc = DocLock(doc), unlock_doc2 = DocLock(doc2);
        CDocEntry       *doc_e = doc->head.next, *doc_e1, *doc_ne, *doc_e2 = NULL;

        ClipDel;
        while (doc_e != doc)
        {
                doc_e1 = doc_e->next;
                if (doc_e->type & DOCET_SEL)
                {
                        doc_e->type &= ~DOCET_SEL;
                        if (!Bt(doldoc.type_flags_data, doc_e->type_u8))
                        {
                                doc_ne = DocEntryCopy(doc2, doc_e);
                                QueueInsert(doc_ne, doc2->head.last);
                        }
                        if (doc_e == doc->cur_entry || doc_e == doc_e2)
                                doc_e2 = doc_e->next;
                        DocEntryDel(doc, doc_e);
                }
                doc_e = doc_e1;
        }
        if (doc_e2)
        {
                doc->cur_entry  = doc_e2;
                doc->cur_col    = doc_e2->min_col;
        }
        DocRemSoftNewLines(doc, NULL);
        if (unlock_doc2)
                DocUnlock(doc2);
        if (unlock_doc)
                DocUnlock(doc);
}

public U0 ClipPaste(CDoc *doc)
{//Insert copy of clip at insert pt,  cur_entry.
        CDoc            *doc2 = sys_clip_doc;
        Bool             unlock_doc = DocLock(doc), unlock_doc2 = DocLock(doc2);
        CDocEntry       *doc_ce = doc->cur_entry, *doc_e;

        if (doc_ce->type_u8 == DOCT_DATA)
        {
                doc_e = doc2->head.next;
                while (doc_e != doc2)
                {
                        if (doc_e->de_flags & DOCEF_TAG)
                                DocPrintPartial(doc, "%s", doc_e->tag);
                        doc_e = doc_e->next;
                }
        }
        else
                DocInsDoc(doc, doc2);
        if (unlock_doc2)
                DocUnlock(doc2);
        if (unlock_doc)
                DocUnlock(doc);
}

public U0 DocCut(CDoc *doc, CDocEntry *start, CDocEntry *end)
{//Del start to end entry,  including end points.
        Bool             unlock_doc = DocLock(doc);
        CDocEntry       *doc_e1;

        if (start != doc && (start->last != end || end == doc))
                do
                {
                        doc_e1 = start->next;
                        if (start == doc->cur_entry)
                        {
                                doc->cur_entry  = start->next;
                                doc->cur_col    = doc->cur_entry->min_col;
                        }
                        DocEntryDel(doc, start);
                        if (start == end)
                                break;
                        start = doc_e1;
                }
                while (start != doc);

        DocRemSoftNewLines(doc, NULL);
        if (unlock_doc)
                DocUnlock(doc);
}

public CDoc *DocCopy(CDoc *doc, CDocEntry *start, CDocEntry *end)
{//Copies start to end entry,  including end points.
        CDoc            *doc2 = DocNew;
        Bool             unlock_doc = DocLock(doc);
        CDocEntry       *doc_ne;

        if (start != doc && (start->last != end || end == doc))
                do
                {
                        if (!Bt(doldoc.type_flags_data, start->type_u8))
                        {
                                doc_ne = DocEntryCopy(doc2, start);
                                QueueInsert(doc_ne, doc2->head.last);
                        }
                        if (start == end)
                                break;
                        start = start->next;
                }
                while (start != doc);

        if (unlock_doc)
                DocUnlock(doc);
        return doc2;
}