⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 editor.c

📁 SEAL是DOS 下的32位保护模式的GUI程序
💻 C
📖 第 1 页 / 共 4 页
字号:
/******************************************************************
 * 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 + -