📄 editor.c
字号:
/******************************************************************
* SEAL 2.0 *
* Copyright (c) 1999-2002 SEAL Developers. All Rights Reserved. *
* *
* Web site: http://sealsystem.sourceforge.net/ *
* E-mail (current maintainer): orudge@users.sourceforge.net *
******************************************************************/
/*
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
(at your option) 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.
*/
#include <seal.h>
#include <dialogs.h>
#include <editor.h>
p_editor (*editor_init) ( p_editor o, t_rect r, l_int flags ) = &_editor_init;
l_bool editor_done ( p_object o ) {
//afree(&EDITOR(o)->text);
return scroller_done(o);
};
void set_edited ( p_editor o ) {
if ( !(o->flags & EF_HAVEBEENEDITED) ) o->flags |= EF_HAVEBEENEDITED;
};
void set_notedited ( p_editor o ) {
if ( o->flags & EF_HAVEBEENEDITED ) o->flags &= ~EF_HAVEBEENEDITED;
};
/*
Get data from editor, if editor is selected from line1,pos1 to line2,pos2
it return this selected text if rec->style comes as DS_SELECTED. If line1,
pos1 and line2,pos2 are same = there is no selected area, it store all text
to rec->data.
This function return DAT_TEXT id if some of styles are supported.
Styles supported by textline :
DS_SELECTED - rec->data is set to selected text, if some is,
else set all text
DS_ALL - set rec->data to all text
DS_WHATEVER - set rec->data to text, which textline want to send
[ if some selected it return this, else return all,
same as DS_SELECTED in this case ]
*/
l_bool editor_get_data ( p_object o, t_data *rec )
{
if ( rec ) {
rec->info_obj = o;
l_tag_cpy(rec->id, DAT_TEXT);
switch ( rec->style ) {
case DS_SELECTED : {
p_editor ed = EDITOR(o);
if ( ed_is_sel(ed) ) {
l_text startt = ed->posptr(ed, ed->sel_from.a.y, ed->sel_from.a.x);
l_text endt = ed->posptr(ed, ed->sel_from.b.y, ed->sel_from.b.x);
rec->data = (void *)stridup(startt, strsize(startt, endt));
} else
rec->data = (void *)_strdup(EDITOR(o)->text);
return true;
}; break;
case DS_ALL : {
rec->data = (void *)_strdup(EDITOR(o)->text);
return true;
}; break;
case DS_WHATEVER : {
rec->style = DS_SELECTED;
return o->get_data(o, rec);
}; break;
};
l_tag_cpy(rec->id, DAT_NONE);
};
return false;
};
/*
drag_where control draging process, that's defined in t_view structure.
- First is called drag_data, when CTRL+mouse button is pressed. This set
new cursor and wait for unpressed button. While this operation run,
view_drag_data function call drag_where function for redrawing objects,
that placed right under mouse cursor.
*/
l_bool editor_drag_where ( p_view o, t_data *rec, t_point where )
{
/*
if mouse is under this object in drag_data function &&
rec->id == OBJECT(o)->data_type then redraw cursor
*/
if ( view_drag_where(o, rec, where) ) {
t_point m = EDITOR(o)->cursor_mouse_pos(EDITOR(o), where);
if ( !EDITOR(o)->cursor_visible )
EDITOR(o)->show_cursor(EDITOR(o), true);
if ( m.x != EDITOR(o)->line_pos || m.y != EDITOR(o)->line )
EDITOR(o)->redraw_text(EDITOR(o), m.y, m.x, 0);
return true;
} else /* Out of place || old */
if ( OBJECT(o)->is_state(OBJECT(o), OB_SF_FOCUSED) ) {
if ( rec ) EDITOR(o)->show_cursor(EDITOR(o), false);
else /* give things to right place, I'm focused so my cursor must be showed */
EDITOR(o)->show_cursor(EDITOR(o), true);
} else
EDITOR(o)->show_cursor(EDITOR(o), false);
return false;
};
/*
set_data
- set data to editor in these cases :
o editor is writeable [ ed_is_wable(o) ],
o rec->id is one of editor->data_type(s) ( standard is DAT_TEXT )
o rec->info_obj != this object, it means data are not from this object
*/
l_bool editor_set_data ( p_object o, t_data *rec )
{
if ( rec && ed_is_wable(EDITOR(o)) &&
l_tag_cmp(o->data_type, rec->id) ) {
p_editor ed = EDITOR(o);
l_bool was_sel = false;
l_bool ok = true;
l_text ltxt = ed->posptr(ed, ed->line, ed->line_pos);
l_long pos = strsize(ed->text, ltxt);
if ( rec->style & DS_DELETE ) { /* if data is deleted */
if ( rec->style & DS_ALL ) {
return ed->set_text(ed, NULL); /* delete all text */
} else {
if ( ed_is_sel(ed) ) { /* delete only selected text */
ed->redraw_text(ed, ed->line, ed->line_pos, TO_KEY(KB_DEL));
ok = true;
};
ok = false;
};
} else { /* if data is inserted to */
if ( ed_is_sel(ed) ) { // if I'm inserted text, at the first I will delete selected one
ed->redraw_text(ed, ed->line, ed->line_pos, TO_KEY(KB_DEL));
};
ok = ed->insstr(ed, pos, (l_text)rec->data);
};
ed_sel_clear(ed);
if ( !was_sel || ok ) {
ed->draw_box(ed);
ed->draw_cursor(ed, -1, -1);
draw_scroller_bars(o);
};
return ok;
};
return false;
};
void editor_set_state ( p_object o, l_dword st, l_bool set )
{
view_set_state(o, st, set);
if ( st & OB_SF_SELECTED ) {
EDITOR(o)->show_cursor(EDITOR(o), set);
};
};
void editor_set_options ( p_object o, l_dword op, l_bool set )
{
obj_set_options(o, op, set);
if ( op & OB_OF_ENABLE ) {
VIEW(o)->draw_view(VIEW(o));
};
};
t_rect editor_scroll_limits ( p_scroller o )
{
t_rect r = VIEW(o)->size_limits(VIEW(o));
return r;
};
void editor_scroll_size ( p_scroller o, l_long *x, l_long *y )
{
p_editor ed = EDITOR(o);
l_long mx = 0;
l_long my = 0;
scroller_scroll_size(o, x, y);
if ( ed->text ) {
if ( x ) mx = *(x);
if ( y ) my = *(y);
o->deltax = FONT_GETWIDTH(VIEW(o)->font, 'w');
o->deltay = ed->ysize_of_line(ed, 0, 1, NULL);
if ( x ) *(x) = ed->line_longest + o->deltax;
if ( y ) *(y) = ed->ysize_of_line(ed, 0, ed->line_num+2, NULL);
if ( x ) *(x) = lmax(mx, calc_maxscrollx(o, (*x)));
if ( y ) *(y) = lmax(my, calc_maxscrolly(o, (*y)));
};
};
void editor_recalc_positions ( p_scroller o, l_long x, l_long y )
{
p_editor ed = EDITOR(o);
l_long l;
l_long p;
l = ed->line_from + (y / lmax(1, o->deltay));
l = lmax(0, lmin(ed->line_num, l));
p = ed->line_pos_from + (x / lmax(1, o->deltax));
ed->line_ptr = NULL;
ed->line_ptr = ed->lnptr(ed, l); /* set new line_ptr */
ed->line_from = l; /* set new line from where box is displayed */
ed->line_pos_from = p;
};
/*
insert string (str) to text-position (pos)
return true if successfull
*/
l_bool editor_insstr ( p_editor o, l_long pos, l_text str )
{
l_text n = insstr(o->text, str, pos, strlen(str));
if ( str && !n ) {
seal_error(ERR_INFO, TXT_NOTENOUGHMEMORY); /* write message */
return false;
};
o->text = n;
o->line_ptr = NULL; /* I must set it to null 'cause lnptr work with o->line_ptr */
o->line_num = o->lnmax(o, &(o->line_longest)); /* get number of lines */
o->line_ptr = NULL; /* I must set it to null 'cause lnptr work with o->line_ptr */
o->line_ptr = o->lnptr(o, o->line_from); /* get new line_ptr */
set_edited(o);
return true;
};
/*
delete string from text-position (pos) and by size (size)
return true if successfull
*/
l_bool editor_delstr ( p_editor o, l_long pos, l_long size )
{
l_text n = delstr(o->text, pos, size);
o->text = n;
o->line_ptr = NULL; /* I must set it to null 'cause lnptr work with o->line_ptr */
o->line_num = o->lnmax(o, &(o->line_longest)); /* get number of lines */
o->line_ptr = o->lnptr(o, o->line_from); /* get new line_ptr */
draw_scroller_bars(SCROLLER(o)); /* redraw scroll bars */
set_edited(o);
return true;
};
/*
delete char from line (line) and pos (pos)
return deleted char
*/
l_int editor_delchr ( p_editor o, l_long line, l_long pos )
{
l_long size;
l_text p = o->lntxtlen(o, line, &size);
l_char ch = 0;
if ( p ) {
l_text oldtext = o->text;
l_long where = p?(p-o->text)+lmin(size, pos):0;
ch = o->text[where]; /* get deleted char */
o->text = delstr(o->text, where, 1);
o->line_num = o->lnmax(o, &(o->line_longest)); /* get number of lines */
if ( oldtext != o->text ) { /* if insstr relloc o->text send new address */
o->line_ptr = NULL; /* I must set it to null 'cause lnptr work with o->line_ptr */
o->line_ptr = o->lnptr(o, o->line_from); /* get new line_ptr */
};
draw_scroller_bars(SCROLLER(o)); /* redraw scroll bars */
o->draw_line(o, line);
set_edited(o);
};
return (l_int)ch;
};
/*
insert char (chr) to line (line) and pos (pos)
return true if char was successfull inserted into the text
*/
l_bool editor_inschr ( p_editor o, l_char chr, l_long line, l_long pos )
{
l_long size;
l_text p;
if ( !chr ) return false;
p = o->lntxtlen(o, line, &size);
if ( p ) {
l_rect sizex = 0;
l_text oldtext = o->text;
l_char v[2] = {0, 0};
v[0] = chr;
/* insert new character into text o->text */
o->text = insstr(o->text, v, p?(p-o->text)+lmin(size, pos):0, 1);
/* get size of current line */
sizex = o->xsize_of_line(o, line, -1);
/* inserted character is EOL */
if ( chr == '\n' )
/* find the longest line and number of lines */
o->line_num = o->lnmax(o, &(o->line_longest)); /* get number of lines */
else
/* inserted character is not EOL and size of current line is greater then longest one */
if ( sizex > o->line_longest )
/* set longest line to size of current line */
o->line_longest = sizex;
if ( oldtext != o->text ) { /* if insstr relloc o->text send new address */
o->line_ptr = NULL; /* I must set it to null 'cause lnptr work with o->line_ptr */
o->line_ptr = o->lnptr(o, o->line_from); /* get new line_ptr */
};
draw_scroller_bars(SCROLLER(o)); /* redraw scroll bars */
/* redraw line */
o->draw_line(o, line);
set_edited(o);
return true;
};
return false;
};
/*
return first position of text from line (line)
(*len) will contains length of this line
*/
l_text editor_lntxtlen ( p_editor o, l_long line, l_long *len )
{
l_text text = o->posptr(o, line, 0); /* from line "line" and pos "pos" */
if ( len ) (*len) = o->sizeto(text, 1, 0);
return text;
};
/*
save into (longest) variable, pointer to longest line in text
- return number of lines
*/
l_long editor_lnmax ( p_editor o, l_long *longest )
{
l_text t = o->text;
l_long nlines = 0L; /* number of lines */
l_long longes = 0L; /* longest linein pixels */
if ( t ) /* o->text exist, so inc it */
do {
l_text old = t;
l_long l = 0;
t = strchr(t, EDITOR_CHAR_ENTER); /* find first "enter" in line */
l = FONT_GETSTRWIDTH(VIEW(o)->font, old, strsize(old, t));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -