/*** Copy selected text up to `Max' chars into buffer ***/ LONG copy_mark_to_buf(Project p, UBYTE *Buf, LONG Max) { LINE *ln; long s,e, nbc; ln = (p->ccp.yc < p->ccp.yp ? p->ccp.cline : p->ccp.line); for(nbc=0; Max && ln && ln->flags; ln=ln->next) { s = (ln->flags & FIRSTSEL ? find_nbc(ln, p->ccp.startsel) : 0); e = (ln->flags & LASTSEL ? find_nbc(ln, p->ccp.endsel) : ln->size); if(s>=e) continue; e-=s; if(e > Max) e=Max; CopyMem(ln->stream+s, Buf, e); Max-=e; Buf+=e; nbc+=e; } *Buf=0; return nbc; }
/*** Write strings to the clipboard.device ***/ BOOL CBWriteFTXT( LINE *stsel, struct cutcopypast *ccp ) { LINE *ln; long length; /* If clipboard not already allocated, makes it now */ if( clip == NULL && !CBOpen(STD_CLIP_UNIT) ) return FALSE; /* Compute how many chars are selected */ for(length=0, ln=stsel; ln && ln->flags; ln=ln->next) { length += ln->size; /* In block selection mode, always add a newline */ if(ccp->select == COLUMN_TYPE) length++; if(ln->flags & FIRSTSEL) length -= find_nbc(ln, ccp->startsel); if(ln->flags & LASTSEL) length += find_nbc(ln, ccp->endsel)-ln->size; else length++; /* New line */ } if(length == 0) return FALSE; if( !OpenIFF(clip, IFFF_WRITE) ) { /* Let iffparse manage main chunk size */ if( !PushChunk(clip, ID_FTXT, ID_FORM, IFFSIZE_UNKNOWN) ) { if( !PushChunk(clip, ID_FTXT, ID_CHRS, length) ) { /* In columnar selection, use '\r' as eol */ char eol = (ccp->select == COLUMN_TYPE ? '\r':'\n'), add_eol; /* Write the content of strings */ for(ln = stsel; ln && ln->flags; ln = ln->next) { STRPTR stream; ULONG length; stream = (STRPTR)ln->stream; length = ln->size; if(ln->flags & FIRSTSEL) { register long rc = find_nbc(ln, ccp->startsel); length -= rc; stream += rc; } if(ln->flags & LASTSEL) { length += find_nbc(ln, ccp->endsel) - ln->size; /* Add automatically a newline */ add_eol = (ccp->select == COLUMN_TYPE); } else add_eol = 1; WriteChunkBytes(clip, stream, length); if(add_eol) WriteChunkBytes(clip, &eol, 1); } PopChunk(clip); } else ThrowError(Wnd, ErrMsg(ERR_NOMEM)); PopChunk(clip); } else ThrowError(Wnd, ErrMsg(ERR_NOMEM)); CloseIFF(clip); } return TRUE; }
/*** Mark: stream selection ***/ BYTE move_stream_selection(Project p, LONG xn, LONG yn) { LONG yline; /* Nb. of line marked */ LINE *ln; /* Running pointer */ BYTE ret; /* Autoscroll ? */ WORD y; /* VPos of item sel */ /* Vertical autoscroll ? */ ret = (yn<p->top_line ? 2 : (yn>=(LONG)(p->top_line+gui.nbline) ? 1 : 0)); if(yn<0) yn=0; if(yn>=p->max_lines) yn=p->max_lines-1,ret=0; yline=p->ccp.yc; ln=p->ccp.cline; /* top_line may changed */ y=(yline-p->top_line)*YSIZE+gui.topcurs; /* If new selection point is situated after the prece- ** ** eding one (ie:looking afterward in linked list) */ if( yn>yline || (yn==yline && xn>p->ccp.xp) ) for(; yline<yn; yline++, ln=ln->next, y+=YSIZE) { if(ln->flags && yline<=p->ccp.yp) if(yline == p->ccp.yp ) p->ccp.startsel = (p->ccp.select != WORD_TYPE ? p->ccp.xp : x2pos(ln, backward_word(ln, find_nbc(ln,p->ccp.xp)))), ln->flags = (p->ccp.select == LINE_TYPE ? WHOLESEL : FIRSTSEL); else ln->flags=0; else ln->flags=WHOLESEL; if(gui.topcurs <= y && y <= gui.botcurs) Move(RP, gui.left, y),write_text(p,ln); } else /* New selection point is before the previous */ for(; yline>yn; yline--, ln=ln->prev, y-=YSIZE) { if(ln->flags && yline>=p->ccp.yp) if(yline == p->ccp.yp) p->ccp.endsel = (p->ccp.select != WORD_TYPE ? p->ccp.xp : x2pos(ln, forward_word(ln, find_nbc(ln,p->ccp.xp)))), ln->flags = (p->ccp.select == LINE_TYPE ? WHOLESEL : LASTSEL); else ln->flags=0; else ln->flags=WHOLESEL; if(gui.topcurs <= y && y <= gui.botcurs) Move(RP, gui.left, y),write_text(p,ln); } /* Current point will be the previous */ p->ccp.cline=ln; p->ccp.yc=yn; p->ccp.xc=xn; /* Update last-selected line */ { register UBYTE Set = 0; if(p->ccp.select != LINE_TYPE) if(yn == p->ccp.yp) { ln->flags = FIRSTSEL | LASTSEL; if(xn < p->ccp.xp) p->ccp.startsel=xn, p->ccp.endsel=p->ccp.xp; else p->ccp.startsel=p->ccp.xp, p->ccp.endsel=xn; Set = 3; } else if( yn > p->ccp.yp ) ln->flags=LASTSEL, p->ccp.endsel=xn, Set = 2; else ln->flags=FIRSTSEL,p->ccp.startsel=xn, Set = 1; else ln->flags = WHOLESEL; /* Adjust selection for word selection */ if(p->ccp.select == WORD_TYPE) { if(Set & 1) p->ccp.startsel = x2pos(ln, backward_word(ln, find_nbc(ln,p->ccp.startsel))); if(Set & 2) p->ccp.endsel = x2pos(ln, forward_word (ln, find_nbc(ln,p->ccp.endsel))); } } /* Last line can overlap edit area */ if(gui.topcurs<=y && y<=gui.botcurs) Move(RP, gui.left, y),write_text(p,ln); return ret; }