home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 5 Edit
/
05-Edit.zip
/
thesrc15.zip
/
box.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-11-17
|
13KB
|
387 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-1993 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@gu.edu.au
* 36 David Road Phone: +61 7 849 7731
* Holland Park Fax: +61 7 875 5314
* QLD 4121
* Australia
*/
/*
$Header: C:\THE\RCS\box.c 1.4 1993/09/01 16:25:30 MH Interim MH $
*/
#include <stdio.h>
#include "the.h"
#include "proto.h"
/*#define DEBUG 1*/
/*-------------------------- external data ----------------------------*/
extern VIEW_DETAILS *vd_current,*vd_mark;
extern char *rec;
extern unsigned short rec_len;
/***********************************************************************/
#ifdef PROTO
void box_operations(int action,char reset,bool overlay,char fillchar)
#else
void box_operations(action,reset,overlay,fillchar)
int action;
char reset;
bool overlay;
char fillchar;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
BOXP boxp;
int rc;
unsigned short y,x;
int offset=0;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:box_operations");
#endif
post_process_line(CURRENT_VIEW->focus_line);
/*---------------------------------------------------------------------*/
/* 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)
{
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;
}
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;
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. */
/*---------------------------------------------------------------------*/
#ifdef USE_VOID
boxp.curr_src = (LINE *)ll_find((void *)MARK_FILE->first_line,boxp.src_start_line);
#else
boxp.curr_src = lll_find(MARK_FILE->first_line,boxp.src_start_line);
#endif
if (action != BOX_D)
#ifdef USE_VOID
boxp.curr_dst = (LINE *)ll_find((void *)CURRENT_FILE->first_line,boxp.dst_start_line);
#else
boxp.curr_dst = lll_find(CURRENT_FILE->first_line,boxp.dst_start_line);
#endif
/*---------------------------------------------------------------------*/
/* 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_copy(&boxp,overlay);*/
rc = box_move(&boxp,overlay);
break;
case BOX_F:
rc = box_fill(&boxp,fillchar);
break;
}
if ((rc = increment_alt(CURRENT_FILE)) != RC_OK)
{
#ifdef TRACE
trace_return();
#endif
return; /* should return a value */
}
/*---------------------------------------------------------------------*/
/* Set the parameters in the MARK_VIEW to OFF; */
/*---------------------------------------------------------------------*/
MARK_VIEW->mark_start_line = MARK_VIEW->mark_end_line = (-1L);
MARK_VIEW->mark_start_col = MARK_VIEW->mark_end_col = (-1L);
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 = M_BOX;
wmove(CURRENT_WINDOW,y,x-offset);
}
pre_process_line(CURRENT_VIEW->focus_line);
show_page(); /* should only call this is the marked block is in view */
#ifdef TRACE
trace_return();
#endif
return;
}
/***********************************************************************/
#ifdef PROTO
int box_delete(BOXP *prm)
#else
int box_delete(prm)
BOXP *prm;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register int i,j;
int num_to_move;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:box_delete");
#endif
for (i=0;i<prm->num_lines;i++)
{
num_to_move = prm->curr_src->length - MARK_VIEW->mark_end_col;
if (num_to_move <= 0)
num_to_move = 0;
add_to_recovery_list(prm->curr_src->line,prm->curr_src->length);
prm->curr_src->length = min(prm->curr_src->length,prm->src_start_col+num_to_move);
for (j=0;j < num_to_move;j++)
*(prm->curr_src->line+j+prm->src_start_col) = *(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 PROTO
int box_move(BOXP *prm,bool overlay)
#else
int box_move(prm,overlay)
BOXP *prm;
bool overlay;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register int i,j;
int num_to_move;
LINE *first_save=NULL,*save_src=NULL,*tmp=NULL;
bool copy_first=FALSE;
int save_src_start_line,save_src_start_col;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:box_move");
#endif
if (prm->dst_start_col > prm->src_start_col+prm->num_cols)
copy_first = TRUE;
save_src_start_col = prm->src_start_col;
save_src_start_line = prm->src_start_line;
if (copy_first)
{
save_src = prm->curr_src;
box_copy(prm,overlay);
prm->src_start_line = save_src_start_line;
prm->src_start_col = save_src_start_col;
prm->curr_src = save_src;
if (prm->action == BOX_M)
box_delete(prm);
}
else
{
/*---------------------------------------------------------------------*/
/* Save the data that is to be deleted. It is saved in a format that */
/* can be used in copy_box() as the src line pointer. */
/*---------------------------------------------------------------------*/
tmp = prm->curr_src;
for (i=0;i<prm->num_lines;i++)
{
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)) == (LINE *)NULL)
{
#ifdef TRACE
trace_return();
#endif
return(RC_OUT_OF_MEMORY);
}
if (first_save == (LINE *)NULL)
first_save = save_src;
tmp = tmp->next;
}
if (prm->action == BOX_M)
box_delete(prm);
prm->src_start_line = 0L;
prm->src_start_col = 0;
prm->curr_src = first_save;
box_copy(prm,overlay);
#ifdef USE_VOID
ll_free((void *)first_save);
#else
first_save = lll_free(first_save);
#endif
prm->src_start_line = save_src_start_line;
prm->src_start_col = save_src_start_col;
}
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/***********************************************************************/
#ifdef PROTO
int box_copy(BOXP *prm,bool overlay)
#else
int box_copy(prm,overlay)
BOXP *prm;
bool overlay;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register int i,j;
char chr;
int rc;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:box_copy");
#endif
for (i=0;i<prm->num_lines;i++)
{
if (prm->curr_dst->next == (LINE *)NULL) /* on *** Bottom of File *** */
{
if ((prm->curr_dst = add_line(CURRENT_FILE->first_line,prm->curr_dst->prev,
(char *)"",0)) == (LINE *)NULL)
{
#ifdef TRACE
trace_return();
#endif
return(RC_OUT_OF_MEMORY);
}
CURRENT_FILE->number_lines++;
}
pre_process_line(prm->dst_start_line+i);/* 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 = ' ';
else
chr = *(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_start_line+i);
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 */
}
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/***********************************************************************/
#ifdef PROTO
int box_fill(BOXP *prm,char fillchar)
#else
int box_fill(prm,fillchar)
BOXP *prm;
char fillchar;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register int i,j;
int rc;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:box_fill");
#endif
for (i=0;i<prm->num_lines;i++)
{
pre_process_line(prm->src_start_line+i);/* 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(prm->src_start_line+i);
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);
}