home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 5 Edit
/
05-Edit.zip
/
the25.zip
/
thesrc251.zip
/
box.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-09-10
|
17KB
|
454 lines
/***********************************************************************/
/* BOX.C - */
/* This file contains all functions relating to box operations. */
/***********************************************************************/
/*
* THE - The Hessling Editor. A text editor similar to VM/CMS xedit.
* Copyright (C) 1991-1997 Mark Hessling
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
*
* The Free Software Foundation, Inc.
* 675 Mass Ave,
* Cambridge, MA 02139 USA.
*
*
* If you make modifications to this software that you feel increases
* it usefulness for the rest of the community, please email the
* changes, enhancements, bug fixes as well as any and all ideas to me.
* This software is going to be maintained and enhanced as deemed
* necessary by the community.
*
* Mark Hessling Email: M.Hessling@qut.edu.au
* PO Box 203 Phone: +617 3802 0800
* Bellara http://www.gu.edu.au/gext/the/markh.html
* QLD 4507 **** Maintainer PDCurses & REXX/SQL ****
* Australia ************* Author of THE ************
*/
/*
$Id: box.c 2.1 1995/06/24 16:28:35 MH Rel MH $
*/
#include <the.h>
#include <proto.h>
#ifdef HAVE_PROTO
static short box_copy_to_temp(BOXP *);
static short box_copy_from_temp(BOXP *,bool);
#else
static short box_copy_to_temp();
static short box_copy_from_temp();
#endif
/*#define DEBUG 1*/
/***********************************************************************/
#ifdef HAVE_PROTO
void box_operations(short action,CHARTYPE reset,bool overlay,CHARTYPE fillchar)
#else
void box_operations(action,reset,overlay,fillchar)
short action;
CHARTYPE reset;
bool overlay;
CHARTYPE fillchar;
#endif
/***********************************************************************/
{
/*-------------------------- external data ----------------------------*/
extern VIEW_DETAILS *vd_mark;
/*--------------------------- local data ------------------------------*/
BOXP boxp;
short rc=RC_OK;
unsigned short y=0,x=0;
LENGTHTYPE offset=0;
short save_mark_type=MARK_VIEW->mark_type;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("box.c: box_operations");
#endif
/*---------------------------------------------------------------------*/
/* This procedure is for copying, deleting, filling, moving and */
/* overlaying box blocks. Box blocks consist of BOX, WORD and COLUMN */
/* blocks. */
/*---------------------------------------------------------------------*/
post_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL,TRUE);
/*---------------------------------------------------------------------*/
/* If the command was issued on the command line then the destination */
/* line is the current line and the destination column is 0; */
/*---------------------------------------------------------------------*/
if (CURRENT_VIEW->current_window == WINDOW_COMMAND)
{
if (CURRENT_VIEW->current_line == 0L)
boxp.dst_start_line = 1L;
else
boxp.dst_start_line = CURRENT_VIEW->current_line;
boxp.dst_start_col = 0;
}
else
{
if (CURRENT_VIEW->focus_line == 0L)
boxp.dst_start_line = 1L;
else
boxp.dst_start_line = CURRENT_VIEW->focus_line;
getyx(CURRENT_WINDOW,y,x);
boxp.dst_start_col = x + CURRENT_VIEW->verify_col-1;
}
/*---------------------------------------------------------------------*/
/* Set up the source and destination views... */
/*---------------------------------------------------------------------*/
boxp.src_view = MARK_VIEW;
boxp.dst_view = CURRENT_VIEW;
boxp.src_start_line = MARK_VIEW->mark_start_line;
boxp.src_start_col = MARK_VIEW->mark_start_col-1;
boxp.num_cols = MARK_VIEW->mark_end_col - MARK_VIEW->mark_start_col + 1;
/*---------------------------------------------------------------------*/
/* If the block type is COLUMN, the number of lines to operate on is */
/* the number of lines in the source file and the destination start */
/* line is line 1. Reset these values set above. */
/*---------------------------------------------------------------------*/
if (MARK_VIEW->mark_type == M_COLUMN)
{
boxp.num_lines = MARK_VIEW->file_for_view->number_lines - boxp.src_start_line +1L;
boxp.dst_start_line = 1L;
}
else
boxp.num_lines = MARK_VIEW->mark_end_line - boxp.src_start_line +1L;
/*---------------------------------------------------------------------*/
/* Find the current LINE pointer for both the source and destination */
/* lines. */
/*---------------------------------------------------------------------*/
boxp.curr_src = lll_find(MARK_FILE->first_line,MARK_FILE->last_line,boxp.src_start_line,MARK_FILE->number_lines);
if (action != BOX_D)
boxp.curr_dst = lll_find(CURRENT_FILE->first_line,CURRENT_FILE->last_line,boxp.dst_start_line,CURRENT_FILE->number_lines);
/*---------------------------------------------------------------------*/
/* Call the appropriate box function... */
/*---------------------------------------------------------------------*/
boxp.action = action;
switch(action)
{
case BOX_D:
rc = box_delete(&boxp);
break;
case BOX_M:
rc = box_move(&boxp,overlay);
break;
case BOX_C:
rc = box_move(&boxp,overlay);
break;
case BOX_F:
rc = box_fill(&boxp,fillchar);
break;
}
/*---------------------------------------------------------------------*/
/* Increment the alteration counts... */
/*---------------------------------------------------------------------*/
increment_alt(CURRENT_FILE);
/*---------------------------------------------------------------------*/
/* Set the parameters in the MARK_VIEW to OFF; */
/*---------------------------------------------------------------------*/
MARK_VIEW->marked_line = MARK_VIEW->marked_col = FALSE;
MARK_VIEW = (VIEW_DETAILS *)NULL;
/*---------------------------------------------------------------------*/
/* If we are not resetting the block, set up block markers... */
/*---------------------------------------------------------------------*/
if (reset != SOURCE_BLOCK_RESET)
{
if (boxp.src_start_col < boxp.dst_start_col
&& action == BOX_M)
offset = boxp.num_cols;
MARK_VIEW = CURRENT_VIEW;
MARK_VIEW->mark_start_line = boxp.dst_start_line;
MARK_VIEW->mark_end_line = boxp.dst_start_line+boxp.num_lines-1L;
MARK_VIEW->mark_start_col = boxp.dst_start_col+1-offset;
MARK_VIEW->mark_end_col = boxp.dst_start_col+boxp.num_cols-offset;
MARK_VIEW->mark_type = save_mark_type;
MARK_VIEW->marked_line = MARK_VIEW->marked_col = TRUE;
wmove(CURRENT_WINDOW,y,x-offset);
}
pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL);
build_screen(current_screen);
display_screen(current_screen); /* should only call this is the marked block is in view */
#ifdef TRACE
trace_return();
#endif
return;
}
/***********************************************************************/
#ifdef HAVE_PROTO
short box_delete(BOXP *prm)
#else
short box_delete(prm)
BOXP *prm;
#endif
/***********************************************************************/
{
/*-------------------------- external data ----------------------------*/
extern VIEW_DETAILS *vd_mark;
/*--------------------------- local data ------------------------------*/
LINETYPE i=0L;
LENGTHTYPE j=0;
LENGTHTYPE num_to_move=0,length_diff=0;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("box.c: box_delete");
#endif
for (i=0L;i<prm->num_lines;i++)
{
if (processable_line(prm->dst_view,prm->src_start_line+i,prm->curr_src) == LINE_LINE)
{
if ((LINETYPE)prm->curr_src->length >= (LINETYPE)MARK_VIEW->mark_start_col)
{
num_to_move = (LENGTHTYPE)max((LINETYPE)prm->curr_src->length -
(LINETYPE)MARK_VIEW->mark_end_col,0L);
length_diff = (LENGTHTYPE)min((LINETYPE)MARK_VIEW->mark_end_col-(LINETYPE)MARK_VIEW->mark_start_col+1L,
(LINETYPE)prm->curr_src->length-(LINETYPE)MARK_VIEW->mark_start_col+1L);
}
else
num_to_move = length_diff = 0;
if (length_diff != 0)
{
add_to_recovery_list(prm->curr_src->line,prm->curr_src->length);
prm->curr_src->length = (LENGTHTYPE)((LINETYPE)prm->curr_src->length-(LINETYPE)length_diff);
for (j=0;j<num_to_move;j++)
*(prm->curr_src->line+(LENGTHTYPE)((LINETYPE)j+(LINETYPE)MARK_VIEW->mark_start_col-1L)) = *(prm->curr_src->line+prm->src_start_col+j+prm->num_cols);
*(prm->curr_src->line+prm->curr_src->length) = '\0';/* null terminate */
}
}
prm->curr_src = prm->curr_src->next; /* this should NEVER go past the end */
}
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/***********************************************************************/
#ifdef HAVE_PROTO
short box_move(BOXP *prm,bool overlay)
#else
short box_move(prm,overlay)
BOXP *prm;
bool overlay;
#endif
/***********************************************************************/
{
/*-------------------------- external data ----------------------------*/
/*--------------------------- local data ------------------------------*/
LINE *first_save=NULL,*save_src=NULL,*temp_src=NULL;
LINETYPE save_src_start_line=0L;
LENGTHTYPE save_src_start_col=0;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("box.c: box_move");
#endif
save_src_start_col = prm->src_start_col;
save_src_start_line = prm->src_start_line;
save_src = prm->curr_src;
box_copy_to_temp(prm); /* copy box from file to temp */
if (prm->dst_start_col <= prm->src_start_col+prm->num_cols
&& prm->action == BOX_M)
{
temp_src = prm->curr_src; /* save the LINE pointer to temp src lines */
prm->curr_src = save_src; /* point to file src lines */
box_delete(prm);
prm->curr_src = temp_src; /* point to temp src lines */
}
prm->src_start_line = 0L;
prm->src_start_col = 0;
box_copy_from_temp(prm,overlay); /* copy box from temp to file */
first_save = lll_free(first_save);
prm->src_start_line = save_src_start_line;
prm->src_start_col = save_src_start_col;
prm->curr_src = save_src;
if (prm->dst_start_col > prm->src_start_col+prm->num_cols
&& prm->action == BOX_M)
box_delete(prm);
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/***********************************************************************/
#ifdef HAVE_PROTO
static short box_copy_to_temp(BOXP *prm)
#else
static short box_copy_to_temp(prm)
BOXP *prm;
#endif
/***********************************************************************/
{
/*-------------------------- external data ----------------------------*/
extern CHARTYPE *rec;
extern unsigned short rec_len;
/*--------------------------- local data ------------------------------*/
LINE *first_save=NULL,*save_src=NULL,*tmp=NULL;
LINETYPE i=0L;
short rc=RC_OK;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("box.c: box_copy_to_temp");
#endif
tmp = prm->curr_src;
for (i=0L;i<prm->num_lines;i++)
{
if (processable_line(prm->src_view,prm->src_start_line+i,tmp) == LINE_LINE)
{
memset(rec,' ',max_line_length); /* copy line into rec[] */
memcpy(rec,tmp->line,tmp->length);
rec_len = tmp->length;
if ((save_src = add_line(first_save,save_src,
rec+prm->src_start_col,prm->num_cols,0,TRUE)) == (LINE *)NULL)
{
#ifdef TRACE
trace_return();
#endif
return(RC_OUT_OF_MEMORY);
}
if (first_save == (LINE *)NULL)
first_save = save_src;
}
tmp = tmp->next;
}
prm->curr_src = first_save;
#ifdef TRACE
trace_return();
#endif
return(rc);
}
/***********************************************************************/
#ifdef HAVE_PROTO
static short box_copy_from_temp(BOXP *prm,bool overlay)
#else
static short box_copy_from_temp(prm,overlay)
BOXP *prm;
bool overlay;
#endif
/***********************************************************************/
{
/*-------------------------- external data ----------------------------*/
extern CHARTYPE *rec;
extern unsigned short rec_len;
/*--------------------------- local data ------------------------------*/
LINETYPE dst_lineno=0L;
LENGTHTYPE j=0;
CHARTYPE chr=0;
short rc=RC_OK,line_type=0;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("box.c: box_copy_from_temp");
#endif
dst_lineno = prm->dst_start_line;
while(prm->curr_src)
{
while(1)
{
line_type = processable_line(prm->dst_view,dst_lineno,prm->curr_dst);
if (line_type == LINE_LINE)
break;
/* if (line_type == LINE_TOF_EOF) MH12 */
if (line_type == LINE_TOF
|| line_type == LINE_EOF)
{
if ((prm->curr_dst = add_line(CURRENT_FILE->first_line,prm->curr_dst->prev,
(CHARTYPE *)"",0,0,TRUE)) == (LINE *)NULL)
{
#ifdef TRACE
trace_return();
#endif
return(RC_OUT_OF_MEMORY);
}
CURRENT_FILE->number_lines++;
break;
}
dst_lineno++;
prm->curr_dst = prm->curr_dst->next;
}
pre_process_line(prm->dst_view,dst_lineno,(LINE *)NULL);/* copy dest line into rec */
for (j=0;j<prm->num_cols;j++)
{
if (prm->src_start_col+j+1 > prm->curr_src->length)
chr = (CHARTYPE)' ';
else
chr = (CHARTYPE)*(prm->curr_src->line+prm->src_start_col+j);
if (overlay)
rec[prm->dst_start_col+j] = chr;
else
meminschr(rec,chr,prm->dst_start_col+j,max_line_length,rec_len++);
}
rc = memrevne(rec,' ',max_line_length);
if (rc == (-1))
rec_len = 0;
else
rec_len = rc+1;
post_process_line(prm->dst_view,dst_lineno,(LINE *)NULL,FALSE);
prm->curr_src = prm->curr_src->next; /* this should NEVER go past the end */
prm->curr_dst = prm->curr_dst->next; /* this should NEVER go past the end */
dst_lineno++;
}
prm->num_lines = dst_lineno - prm->dst_start_line;
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/***********************************************************************/
#ifdef HAVE_PROTO
short box_fill(BOXP *prm,CHARTYPE fillchar)
#else
short box_fill(prm,fillchar)
BOXP *prm;
CHARTYPE fillchar;
#endif
/***********************************************************************/
{
/*-------------------------- external data ----------------------------*/
extern CHARTYPE *rec;
extern unsigned short rec_len;
/*--------------------------- local data ------------------------------*/
LINETYPE i=0L;
LENGTHTYPE j=0;
short rc=RC_OK;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("box.c: box_fill");
#endif
for (i=0L;i<prm->num_lines;i++)
{
if (processable_line(CURRENT_VIEW,prm->src_start_line+i,prm->curr_src) == LINE_LINE)
{
pre_process_line(CURRENT_VIEW,prm->src_start_line+i,(LINE *)NULL);/* copy source line into rec */
for (j=0;j<prm->num_cols;j++)
rec[prm->src_start_col+j] = fillchar;
rc = memrevne(rec,' ',max_line_length);
if (rc == (-1))
rec_len = 0;
else
rec_len = rc+1;
post_process_line(CURRENT_VIEW,prm->src_start_line+i,(LINE *)NULL,FALSE);
}
prm->curr_src = prm->curr_src->next; /* this should NEVER go past the end */
}
prm->dst_start_col = prm->src_start_col;
prm->dst_start_line = prm->src_start_line;
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}