| home
| contents
| previous
| next page
| send comment
| send link
| add bookmark |
IDE_MAIN.CPP
main editor file
/*-------------------------------------------------------------------*
Screen Editor
Main file for editor of ascii text files
Compile using large memory model.
File: ide_main.cpp
Module: editor
Link to: ide_menu.cpp
by: Stephen R. Schmitt
*-------------------------------------------------------------------*/
#include "ide_data.h"
/*-------------------------------------------------------------------*
Data Section
*-------------------------------------------------------------------*/
/*
* external declarations
*/
extern FILE *Program;
extern char File_name[];
extern bool File_changed;
/*
* global declarations
*/
struct line *First_line, // pointer to first line
*Text_line, // pointer to current line
*Last_line; // pointer to last line
struct line *Clip_first_line; // start of clipboard
struct edit Select_begin, // beginning of selected text
Select_end; // ending of selected text
bool Select_text; // text selected flag
int Text_line_num; // current text line number
int Last_line_num; // number of last text line
int Lin; // current screen line
int Col; // current screen column
int Top = 2; // top line of screen
int Bottom = 25; // bottom line of screen
int Right = 80; // right column of screen
int Left = 1; // left column of screen
int Tab_size = 4; // default tab size
int Msg_col = 70; // column for messages
int Msg_lin = 1; // line for messages
bool Insert; // insert/overwrite flag
bool Run_editor; // loop flag
char *Screen_buffer; // full screen buffer
char *Dos_screen; // full screen buffer
int Dos_lin, Dos_col; // Dos screen data
/*-------------------------------------------------------------------*
Code Section
*-------------------------------------------------------------------*/
void main(int argc, char *argv[])
{
union scancode key;
bool usage_message = false;
// save dos screen
Dos_screen = new char[4000];
if (Dos_screen == NULL)
Run_editor = false;
else
{
Dos_col = wherex();
Dos_lin = wherey();
gettext(1, 1, 80, 25, Dos_screen);
}
Screen_buffer = new char[4000];
if (Screen_buffer == NULL)
Run_editor = false;
else if (argc == 2) // command line file name
{
Program = fopen(argv[1], "r+");
if (Program == NULL)
{
usage_message = true;
Run_editor = false;
}
else
{
file_new();
strcpy(File_name, argv[1]);
file_load_process();
Run_editor = true;
}
}
else
{
file_new();
Run_editor = true;
}
// loop indefinitely while reading keyboard
while (Run_editor == true)
{
cursor_position();
key.ch = get_key(); // get next input
switch (key.c[0])
{
case 0:
function_key(key.c[1]);
break;
case 2: /* Ctrl+B keys */
case 5: /* Ctrl+E keys */
case 18: /* Ctrl+R keys */
select_text(key.c[0]);
break;
case 3: /* Ctrl+C keys */
copy_text();
break;
case 4: /* Ctrl+D keys */
delete_text();
break;
case 8: /* Backspace key */
backspace();
break;
case 9: /* Tab key */
File_changed = true;
tab_right();
break;
case 13: /* Enter key */
File_changed = true;
enter_line();
break;
case 16: /* Ctrl+P keys */
File_changed = true;
paste_text();
break;
case 20: /* Ctrl+T keys */
File_changed = true;
copy_text();
delete_text();
break;
case 22: /* Ctrl+V keys */
copy_text();
delete_text();
paste_text();
break;
case 25: /* Ctrl+Y keys */
File_changed = true;
delete_line();
break;
default:
if (Col == Right)
/* do nothing : at end of line */;
else if (isprint(key.c[0]))
{
File_changed = true;
if (Insert == true)
insert_character(key.c[0]);
else
overwrite_character(key.c[0]);
}
break;
}
}
_setcursortype(_NORMALCURSOR);
window(1, 1, 80, 25);
puttext(1, 1, 80, 25, Dos_screen);
gotoxy(Dos_col, Dos_lin);
assert(Dos_screen != NULL);
delete Dos_screen;
assert(Screen_buffer != NULL);
delete Screen_buffer;
if (usage_message)
{
printf("\n\n");
printf("\t\t T Editor\n\n");
printf("\t\t Usage: te [filename.ext]\n\n");
printf("\t\t Author:\n\n");
printf("\t\t\t Stephen R. Schmitt\n\n\n\n");
}
exit(0);
}
/*
* "cursor_position" update cursor position indicator and the
* message block
*
* returns: nothing
*/
void cursor_position()
{
textcolor(LIGHTGRAY);
gotoxy(Left, Top - 1);
clreol();
cprintf(" %d:%d ", Text_line_num, Col);
gotoxy(30, 1);
cputs(File_name);
gotoxy(Msg_col, Msg_lin);
cprintf("F10 Help ");
textcolor(WHITE);
gotoxy(Col, Lin);
}
/*
* "function_key" selects an action when a function key is pressed
*
* returns: nothing
*/
void function_key(unsigned char key) // of function key
{
switch (key)
{
case 15: /* Shift+Tab keys */
File_changed = true;
tab_left();
break;
case 59: /* F1 key */
files();
break;
case 60: /* F2 key */
gettext(1, 1, 80, 25, Screen_buffer);
file_save();
File_changed = false;
break;
case 61: /* F3 key */
production();
break;
case 62: /* F4 key */
search();
break;
case 68: /* F10 key */
help();
break;
case 71: /* Home key */
Col = Left;
gotoxy(Col, Lin);
break;
case 72: /* up arrow key */
up_arrow();
break;
case 73: /* Page Up key */
page_up();
break;
case 75: /* left arrow key */
left_arrow();
break;
case 77: /* right arrow key */
right_arrow();
break;
case 79: /* End key */
end();
break;
case 80: /* down arrow key */
down_arrow();
break;
case 81: /* Page Down key */
page_down();
break;
case 82: /* Insert key */
switch_insert_overwrite();
delay(1000);
break;
case 83: /* Delete key */
File_changed = true;
delete_character();
break;
case 114: /* Ctrl + Print Screen key */
save_screen();
break;
case 118: /* Ctrl + Page Down key */
goto_end_of_file();
break;
case 132: /* Ctrl + Page Up key */
goto_start_of_file();
break;
default:
break;
}
}
/*-------------------------------------------------------------------*
Text Editing Functions
*-------------------------------------------------------------------*/
/*
* "get_key" obtains a two byte character code from the keyboard
*
* returns: the scancode of the key
*/
int get_key()
{
union REGS r;
r.h.ah = 0;
return int86(0x16, &r, &r);
}
/*
* "first_text_line" sets editor to first text line
*
* returns: new text line number
*/
int first_text_line()
{
assert(First_line != NULL);
Text_line = First_line;
Text_line_num = 1;
return Text_line_num;
}
/*
* "incr_text_line" sets editor to next text line
*
* returns: new text line number
*/
int incr_text_line()
{
assert(Text_line != NULL);
Text_line = Text_line->next;
Text_line_num++;
return Text_line_num;
}
/*
* "decr_text_line" sets editor to previous text line
*
* returns: new text line number
*/
int decr_text_line()
{
assert(Text_line != NULL);
Text_line = Text_line->prev;
Text_line_num--;
return Text_line_num;
}
/*
* "enter_line" adds a new line of text by allocating a new line
* structure and re-connecting pointers.
*
* returns: nothing
*/
void enter_line()
{
line *new_line = new line;
if (new_line == NULL)
{
gettext(1, 1, 80, 25, Screen_buffer);
error_message("System is out of memory!");
get_key();
restore_edit_window();
return;
}
memset(new_line->string, '\0', MAX_LINE_LENGTH);
// rearrange pointers
line *above = Text_line;
line *below = Text_line->next;
above->next = new_line;
new_line->prev = above;
new_line->next = below;
below->prev = new_line;
// move characters from cursor to the end of the line to the new line
int i = Col - 1;
int j = 0;
while ((above->string[i] != NULL)&&(i < MAX_LINE_LENGTH - 1))
{
new_line->string[j] = above->string[i];
above->string[i] = NULL;
i++;
j++;
}
new_line->string[j] = NULL;
// update display and reset cursor
clreol(); // current line
if (Lin == Bottom) // at bottom of screen
{
// move all lines in text screen up by one line
movetext(Left, Top + 1, Right, Bottom, Left, Top);
}
else
{
// move all lines below current line down by one line
Lin++;
movetext(Left, Lin, Right, Bottom - 1, Left, Lin + 1);
}
if (Select_text)
{
if (Select_begin.line_num > Text_line_num)
{
Select_begin.line_num++;
Select_end.line_num++;
}
else if (Select_end.line_num > Text_line_num)
Select_end.line_num++;
if ((Select_begin.line_num == Text_line_num) &&
(Select_begin.char_num >= Col - 1))
{
// select begins on the new line
Select_begin.line_num++;
Select_begin.char_num = Select_begin.char_num - Col + 1;
}
if ((Select_end.line_num == Text_line_num) &&
(Select_end.char_num >= Col - 1))
{
// select ends on the new line
Select_end.line_num++;
Select_end.char_num = Select_end.char_num - Col + 1;
}
}
Text_line_num++; // update editor
Text_line = new_line;
Last_line_num++;
write_line(Text_line, Text_line_num, Lin);
Col = Left; // on the new line
gotoxy(Col, Lin);
}
/*
* "delete_line" removes a line of text by re-connecting pointers
* and deallocating the line structure.
*
* returns: nothing
*/
void delete_line()
{
int j, text_num;
line *text;
line *above = Text_line->prev;
line *below = Text_line->next;
if (Select_text)
{
if (Select_begin.line_num > Text_line_num)
{
Select_begin.line_num--;
Select_end.line_num--;
}
else if (Select_end.line_num > Text_line_num)
Select_end.line_num--;
if ((Select_begin.line_num == Text_line_num) &&
(Select_end.line_num == Text_line_num))
{
// clear select
Select_begin.line_ptr = NULL;
Select_begin.line_num = 0;
Select_begin.char_num = 0;
Select_end.line_ptr = NULL;
Select_end.line_num = 0;
Select_end.char_num = 0;
}
else if (Select_begin.line_num == Text_line_num)
{
// select begins on the line below
Select_begin.char_num = 0;
}
else if (Select_end.line_num == Text_line_num)
{
// select ends on the line below
Select_end.char_num = 0;
}
}
if (above == NULL) // on first line
{
if (below == Last_line) // only one line
{
// just remove data; note: should never be on the last line
Col = Left;
gotoxy(Col, Lin);
clreol(); // clear screen
strnset(Text_line->string, 0, MAX_LINE_LENGTH);
}
else // more than one line
{
// first copy string from line below and reconnect pointers
strnset(Text_line->string, 0, MAX_LINE_LENGTH);
strcpy(Text_line->string, below->string);
text = below;
below = below->next;
Text_line->next = below;
below->prev = Text_line;
// then free the line below and move the text screen up by one line
assert(text != NULL);
delete text;
movetext(Left, Lin + 1, Right, Bottom, Left, Lin);
gotoxy(Left, Bottom);
clreol();
// then fill in bottom line if there is one
j = Lin;
text_num = Text_line_num;
text = Text_line;
while ((j < Bottom) && (text_num < Last_line_num))
{
text = text->next;
text_num++;
j++;
}
if (j == Bottom)
write_line(text, text_num, j);
// reset the editor
Last_line_num--;
Col = Left;
gotoxy(Col, Lin);
}
}
else // not on first line
{
// first reconnect pointers
above->next = below;
below->prev = above;
// free current text line and move all lines
// in text screen from line below up by one
assert(Text_line != NULL);
delete Text_line;
Text_line = below;
movetext(Left, Lin + 1, Right, Bottom, Left, Lin);
gotoxy(Left, Bottom);
clreol();
// then fill in bottom line if there is one
j = Lin;
text_num = Text_line_num;
text = Text_line;
while ((j < Bottom)&&(text_num < Last_line_num))
{
text = text->next;
text_num++;
j++;
}
if (j == Bottom)
write_line(text, text_num, j);
// reset the editor; the line below gets the line number of
// the deleted line unless deletion of a text line puts the
// cursor on the last line
Last_line_num--;
if (Text_line == Last_line)
up_arrow();
Col = Left;
gotoxy(Col, Lin);
}
}
/*
* "insert_character" adds a new character to the current text line
*
* returns: nothing
*/
void insert_character(char ch) // character to enter
{
// find end of line and shift characters right
int i = Col - 1;
while (Text_line->string[i] != NULL)
i++;
while (i >= Col - 1)
{
Text_line->string[i + 1] = Text_line->string[i];
i--;
}
Text_line->string[Col - 1] = ch;
// this ensures that lines will not exceed available space
Text_line->string[MAX_LINE_LENGTH - 1] = NULL;
// if nulls are on the right of the new character, fill in with spaces
i = Col - 2;
while (i >= 0)
{
if (Text_line->string[i] == NULL)
Text_line->string[i] = ' ';
else
break;
i--;
}
if (Select_text)
{
if ((Select_begin.line_num == Text_line_num)&&
(Select_begin.char_num > Col - 1))
Select_begin.char_num++;
if ((Select_end.line_num == Text_line_num)&&
(Select_end.char_num > Col - 1))
Select_end.char_num++;
}
// update display and reset cursor
write_line(Text_line, Text_line_num, Lin);
Col++;
gotoxy(Col, Lin);
}
/*
* "overwrite_character" replaces a character in the current
* text line
*
* returns: nothing
*/
void overwrite_character(char ch) // character to enter
{
Text_line->string[Col - 1] = ch;
// if nulls are on the right of the new character, fill in with spaces
int i = Col - 2;
while (i >= 0)
{
if (Text_line->string[i] == NULL)
Text_line->string[i] = ' ';
else
break;
i--;
}
// update display and reset cursor
putch(ch);
Col++;
gotoxy(Col, Lin);
}
/*
* "delete_character" removes a character from the current test line
*
* returns: nothing
*/
void delete_character()
{
// shift characters left
int i = Col - 1;
while (i < MAX_LINE_LENGTH)
{
Text_line->string[i] = Text_line->string[i + 1];
if (Text_line->string[i] == NULL)
break;
i++;
}
if (Select_text)
{
if ((Select_begin.line_num == Text_line_num)&&
(Select_begin.char_num > Col - 1))
Select_begin.char_num--;
if ((Select_end.line_num == Text_line_num)&&
(Select_end.char_num > Col - 1))
Select_end.char_num--;
}
write_line(Text_line, Text_line_num, Lin);
gotoxy(Col, Lin);
}
/*
* "switch_insert_overwrite" toggles the character insertion mode
*
* returns: nothing
*/
void switch_insert_overwrite()
{
textcolor(YELLOW);
if (Insert)
{
Insert = false;
gotoxy(Msg_col, Msg_lin);
cputs("overwrite");
_setcursortype(_SOLIDCURSOR);
}
else
{
Insert = true;
gotoxy(Msg_col, Msg_lin);
cputs("insert ");
_setcursortype(_NORMALCURSOR);
}
textcolor(WHITE);
gotoxy(Col, Lin);
}
/*
* "backspace" deletes the character to the left of the cursor
* and moves it one space left
*
* returns: nothing
*/
void backspace()
{
int offset, // end of line above
length; // of current line
line *above; // above current line
if (Col > Left)
{
Col--;
delete_character();
}
else if (Text_line_num > 1) // below first line
{
above = Text_line->prev;
length = strlen(Text_line->string);
offset = strlen(above->string);
if ((offset + length) < MAX_LINE_LENGTH)
{
if (Select_text)
{
if (Select_begin.line_num == Text_line_num)
{
Select_begin.line_num--;
Select_begin.char_num = Select_begin.char_num + offset;
}
if (Select_end.line_num == Text_line_num)
{
Select_end.line_num--;
Select_end.char_num = Select_end.char_num + offset;
}
}
strcat(above->string, Text_line->string);
delete_line();
Col = offset + 1;
if (Col > Right)
Col = Right;
if (Text_line_num == Last_line_num)
gotoxy(Col, Lin);
else
up_arrow();
write_line(Text_line, Text_line_num, Lin);
}
else
{
textcolor(YELLOW);
gotoxy(Msg_col, Msg_lin);
cputs("too long ");
delay(1000);
}
}
}
/*
* "tab_right" moves the cursor right by Tab_size spaces and
* inserts spaces
*
* returns: nothing
*/
void tab_right()
{
if (Col < Right - Tab_size)
{
int n = Tab_size - ((Col - Left) % Tab_size);
for (int i = 0; i < n; i++)
insert_character(' ');
}
}
/*
* "tab_left" moves the cursor left by Tab_size spaces and
* deletes characters
*
* returns: nothing
*/
void tab_left()
{
if (Col >= Left + Tab_size)
{
int n = Tab_size - ((Col - Left) % Tab_size);
for (int i = 0; i < n; i++)
backspace();
}
}
/*
* "up_arrow" moves the cursor up
*
* returns: nothing
*/
void up_arrow()
{
if (Text_line_num == 1)
/* do nothing */;
else if (Lin == 2)
{
// move screen down
movetext(1, 2, 80, 24, 1, 3);
decr_text_line();
gotoxy(1, 2);
write_line(Text_line, Text_line_num, Lin);
}
else
{
decr_text_line();
Lin--;
}
gotoxy(Col, Lin);
}
/*
* "page_up" moves the screen down by 20 lines toward the beginning
* of the file
*
* returns: nothing
*/
void page_up()
{
// find text line which is to be at top of text screen
int top_line = Text_line_num - (Lin - Top);
int next_top_line = top_line - 20;
if (next_top_line <= 1)
{
next_top_line = 1;
first_text_line();
}
else
{
while (next_top_line != Text_line_num)
decr_text_line();
}
write_screen(Text_line, Text_line_num);
// reset editor
int j = Top;
while (j != Lin)
{
if (Text_line_num == Last_line_num)
{
Lin = j;
break;
}
else
{
incr_text_line();
j++;
}
}
gotoxy(Col, Lin);
}
/*
* "left_arrow" moves the cursor left
*
* returns: nothing
*/
void left_arrow()
{
if (Col > Left)
{
Col--;
gotoxy(Col, Lin);
}
}
/*
* "right_arrow" moves the cursor right but no farther than first
* end of line null.
*
* returns: nothing
*/
void right_arrow()
{
if (Col == Right)
/* do nothing */;
else
{
Col++;
gotoxy(Col, Lin);
}
}
/*
* "end" moves the cursor to the end of the current line
*
* returns: nothing
*/
void end()
{
int i = 0;
while (Text_line->string[i] != NULL)
i++;
if (i < Right)
{
Col = i + 1;
gotoxy(Col, Lin);
}
else
{
textcolor(YELLOW);
gotoxy(Msg_col, Msg_lin);
cputs("too long ");
delay(1000);
}
}
/*
* "down_arrow" moves the cursor down
*
* returns: nothing
*/
void down_arrow()
{
if (Text_line_num == Last_line_num)
/* do nothing */;
else if (Lin == 25)
{
// move screen up
movetext(1, 3, 80, 25, 1, 2);
incr_text_line();
gotoxy(1, 25);
write_line(Text_line, Text_line_num, Lin);
}
else
{
incr_text_line();
Lin++;
}
gotoxy(Col, Lin);
}
/*
* "page_down" moves the screen up by 20 lines
*
* returns: nothing
*/
void page_down()
{
// find text line which is to be at top of text screen
int top_line = Text_line_num - (Lin - Top);
int next_top_line = top_line + 20;
if (next_top_line < Last_line_num)
{
if (next_top_line > Text_line_num)
{
while (next_top_line != Text_line_num)
incr_text_line();
}
else
{
while (next_top_line != Text_line_num)
decr_text_line();
}
write_screen(Text_line, Text_line_num);
// reset editor
int j = Top;
while (j != Lin)
{
if (Text_line_num == Last_line_num)
{
Lin = j;
break;
}
else
{
incr_text_line();
j++;
}
}
gotoxy(Col, Lin);
}
}
/*
* "goto_end_of_file" sets the editor to the end of the file
*
* returns: nothing
*/
void goto_end_of_file()
{
// find text line which is to be at top of text screen
int next_top_line = Last_line_num - 20;
if (next_top_line < 1)
next_top_line = 1;
if (next_top_line > Text_line_num)
{
while (next_top_line != Text_line_num)
incr_text_line();
}
else
{
while (next_top_line != Text_line_num)
decr_text_line();
}
write_screen(Text_line, Text_line_num);
// reset editor
Lin = Top;
Col = Left;
gotoxy(Col, Lin);
}
/*
* "goto_start_of_file" sets editor to the beginning of the file
*
* returns: nothing
*/
void goto_start_of_file()
{
first_text_line();
write_screen(Text_line, Text_line_num);
// reset editor
Lin = Top;
Col = Left;
gotoxy(Col, Lin);
}
/*
* "write_line" refreshes a text line by clearing the entire line
* and then re-writing it
*
* returns: nothing
*/
void write_line(struct line *text_line, // text line to write
int text_line_num, // text line number
int screen_line) // screen line of text
{
char buffer[MAX_LINE_LENGTH];
int begin_line, begin_char;
int end_line, end_char, i;
_setcursortype(_NOCURSOR);
gotoxy(Left, screen_line); // left edge of window
clreol();
strcpy(buffer, text_line->string);
buffer[Right - Left] = NULL; // keep line in window
if (Select_text == true)
{
begin_line = Select_begin.line_num;
begin_char = Select_begin.char_num;
end_line = Select_end.line_num;
end_char = Select_end.char_num;
if ((begin_line < text_line_num)&&(end_line > text_line_num))
{
textattr(LIGHTGRAY*16 + BLACK);
cputs(buffer);
}
else if ((begin_line == text_line_num)&&(end_line == text_line_num))
{
cputs(buffer);
textattr(LIGHTGRAY*16 + BLACK);
gotoxy(begin_char + 1, screen_line);
for (i = begin_char; i < end_char; i++)
putch(text_line->string[i]);
}
else if (begin_line == text_line_num)
{
cputs(buffer);
textattr(LIGHTGRAY*16 + BLACK);
gotoxy(begin_char + 1, screen_line);
for (i = begin_char; i < Right; i++)
{
if (text_line->string[i] == NULL)
break;
putch(text_line->string[i]);
}
}
else if (end_line == text_line_num)
{
cputs(buffer);
textattr(LIGHTGRAY*16 + BLACK);
gotoxy(Left, screen_line);
for (i = Left - 1; i < end_char; i++)
putch(text_line->string[i]);
}
else
cputs(buffer);
textattr(BLACK*16 + WHITE);
}
else
cputs(buffer);
if (Insert)
_setcursortype(_NORMALCURSOR);
else
_setcursortype(_SOLIDCURSOR);
}
/*
* "save_screen" saves the screen to a disk file
*
* returns: nothing
*/
void save_screen()
{
char buffer[4000];
FILE *save = fopen("screen.txt", "w");
if (save)
{
gettext(1, 1, 80, 25, buffer);
for (int j = 0; j < 25; j++)
{
for (int i = 0; i < 80; i++)
fputc(buffer[160*j + 2*i], save);
fputc('\n', save);
}
fclose(save);
}
gotoxy(Col, Lin); // reset cursor
}
/*
* "write_screen" refreshes the screen by clearing each text line
* and then re-writing it
*
* returns: nothing
*/
void write_screen(struct line *text_line, // line at top of screen
int text_line_num) // text line number
{
int j = Top; // from the top
while (j <= Bottom) // write new text lines
{
write_line(text_line, text_line_num, j);
if (text_line_num < Last_line_num)
{
text_line = text_line->next;
text_line_num++;
j++;
}
else
break;
}
j++;
while (j <= Bottom) // clear the rest
{
gotoxy(Left, j);
clreol();
j++;
}
}
/*
* "select_text" sets or resets the location of the beginning or
* ending of a selected region of text
*
* returns: nothing
*/
void select_text(unsigned char key) // Ctrl + key
{
switch (key)
{
case 2: /* Ctrl+B */
Select_begin.line_ptr = Text_line;
Select_begin.line_num = Text_line_num;
Select_begin.char_num = Col - 1;
break;
case 5: /* Ctrl+E */
Select_end.line_ptr = Text_line;
Select_end.line_num = Text_line_num;
Select_end.char_num = Col - 1;
break;
case 18: /* Ctrl+R */
Select_begin.line_ptr = NULL;
Select_begin.line_num = 0;
Select_begin.char_num = 0;
Select_end.line_ptr = NULL;
Select_end.line_num = 0;
Select_end.char_num = 0;
break;
default:
assert(0);
break;
}
// check for valid select region
if ((Select_begin.line_ptr == NULL) ||
(Select_end.line_ptr == NULL))
Select_text = false;
else if (Select_begin.line_num < Select_end.line_num)
Select_text = true;
else if ((Select_begin.line_num == Select_end.line_num) &&
(Select_begin.char_num < Select_end.char_num))
Select_text = true;
else
Select_text = false;
// rewrite the text screen
int text_num = Text_line_num;
line *text = Text_line;
int j = Lin;
while (j != Top) // find top text line
{
text = text->prev;
text_num--;
j--;
}
write_screen(text, text_num);
gotoxy(Col, Lin);
}
/*
* "copy_text" clears the previous clipboard and copies a selected
* region of text to the clipboard
*
* returns: nothing
*/
void copy_text()
{
int begin_char, end_char;
// make new clipboard
FILE *clip = fopen("clip.txt", "w");
if (clip == NULL)
{
gettext(1, 1, 80, 25, Screen_buffer);
error_message("no clipboard");
get_key();
restore_edit_window();
return;
}
line *text = Select_begin.line_ptr;
for (int i = Select_begin.line_num; i <= Select_end.line_num; i++)
{
if (text == Select_begin.line_ptr)
begin_char = Select_begin.char_num;
else
begin_char = 0;
if (text == Select_end.line_ptr)
end_char = Select_end.char_num;
else
end_char = MAX_LINE_LENGTH - 1;
for (int j = begin_char; j < end_char; j++)
{
fputc(text->string[j], clip);
if (text->string[j] == NULL)
{
fputc('\n', clip);
break;
}
}
if (i < Select_end.line_num)
text = text->next;
}
fclose(clip);
}
/*
* "delete_text" deletes a selected region of text
*
* returns: nothing
*/
void delete_text()
{
int begin_char, end_char;
line *text = Select_begin.line_ptr;
for (int i = Select_begin.line_num; i <= Select_end.line_num; i++)
{
if (text == Select_begin.line_ptr)
begin_char = Select_begin.char_num;
else
begin_char = 0;
if (text == Select_end.line_ptr)
end_char = Select_end.char_num;
else
end_char = MAX_LINE_LENGTH - 1;
for (int j = begin_char; j < end_char; j++)
{
int k = begin_char;
while (k < MAX_LINE_LENGTH)
{
text->string[k] = text->string[k + 1];
if (text->string[k] == NULL)
break;
k++;
}
}
text = text->next;
}
// clear select locators and re-write the text screen
select_text(18); // Ctrl + R
}
/*
* "paste_text" copies a selected region of text on the clipboard
* to the current cursor location
*
* returns: nothing
*/
void paste_text()
{
// open clipboard
FILE *clip = fopen("clip.txt", "r");
if (clip == NULL)
{
gettext(1, 1, 80, 25, Screen_buffer);
error_message("no clipboard");
get_key();
restore_edit_window();
return;
}
select_text(18); // clear select pointers
select_text(2); // set new begin
int n = fgetc(clip);
while (EOF != n)
{
char ch = (char) n;
if (ch == '\n')
enter_line();
else
insert_character(ch);
n = fgetc(clip);
}
select_text(5); // set new end
fclose(clip);
}
| home
| contents
| previous
| next page
| send comment
| send link
| add bookmark |
Copyright © 2004, Stephen R. Schmitt