
/******************************************************************************
* MODULE     : edit_keyboard.gen.cc
* DESCRIPTION: Keyboard handling
* COPYRIGHT  : (C) 1999  Joris van der Hoeven
*******************************************************************************
* This software falls under the GNU general public license and comes WITHOUT
* ANY WARRANTY WHATSOEVER. See the file $TEXMACS_PATH/LICENSE for more details.
* If you don't have this file, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
******************************************************************************/

#module code_edit_keyboard

/******************************************************************************
* Keyboard
******************************************************************************/

int&
edit_interface_rep::the_input_mode () {
  return input_mode;
}

void
edit_interface_rep::set_input_normal () {
  sh_s  = string ("");    // avoids keyboard shorthands when
  sh_len= 0;              // using the menu between two keystrokes

  if (input_mode != INPUT_NORMAL) {
    selection_cancel ();
    input_mode= INPUT_NORMAL;
  }
}

bool
edit_interface_rep::in_normal_mode () {
  return input_mode == INPUT_NORMAL;
}

bool
edit_interface_rep::in_search_mode () {
  return input_mode == INPUT_SEARCH;
}

bool
edit_interface_rep::in_replace_mode () {
  return input_mode == INPUT_REPLACE;
}

bool
edit_interface_rep::in_spell_mode () {
  return input_mode == INPUT_SPELL;
}

/******************************************************************************
* Keyboard
******************************************************************************/

void
edit_interface_rep::key_press (string key) {
  switch (input_mode) {
  case INPUT_NORMAL:
    break;
  case INPUT_SEARCH:
    if (search_keypress (key)) return;
    break;
  case INPUT_REPLACE:
    if (replace_keypress (key)) return;
    break;
  case INPUT_SPELL:
    if (spell_keypress (key)) return;
    break;
  }

  int          status;
  scheme_tree  keym;
  string       shorth;
  string       help;
  string       new_sh= N(sh_s)==0? key: sh_s * " " * key;

  // ----------------- key combinations ---------------------
  sv->get_keycomb (new_sh, status, keym, shorth, help);
  if ((status & 1) == 1) {
    if (sh_len>0) {
      tp= path_add (tp, -sh_len);
      remove (tp, sh_len);
    }
    if (exec (keym)) set_message (message_l, "keyboard#" * new_sh);
    sh_s  = string ("");
    sh_len= 0;
    return;
  }
  sv->get_keycomb (key, status, keym, shorth, help);
  if ((status & 1) == 1) {
    if (exec (keym)) set_message (message_l, "keyboard#" * key);
    sh_s  = string ("");
    sh_len= 0;
    return;
  }

  // ---------- variants and uncompleted shorthands ---------
  sv->get_keycomb (new_sh, status, keym, shorth, help);
  if ((status & 2) == 0) {
    if ((key == "*") && ends (sh_s, " *")) {
      int i;
      for (i=N(sh_s)-2; i>=2; i-=2)
	if ((sh_s[i-1]!='*') || (sh_s[i-2]!=' ')) break;
      tp= path_add (tp, -sh_len);
      if (sh_len>0) remove (tp, sh_len);
      sh_s= sh_s (0, i);
      sv->get_keycomb (sh_s, status, keym, shorth, help);
      if (N(shorth)>0) insert_tree (shorth);
      sh_len= N (shorth);
      if (N(help)>0) set_message (help, sh_s);
      else set_message ("keyboard shorthand: " * sh_s, shorth);
      return;
    }
    else {
      sh_s  = string ("");
      sh_len= 0;
      new_sh= key;
    }
  }

  // -------------------- shorthands ------------------------
  sv->get_keycomb (new_sh, status, keym, shorth, help);
  if ((status & 2) == 2) {
    sh_s  = new_sh;
    if (sh_len>0) {
      tp= path_add (tp, -sh_len);
      if (sh_len>0) remove (tp, sh_len);
    }
    if (N(shorth)>0) insert_tree (shorth);
    sh_len= N (shorth);
    if (N(help)>0) set_message (help, sh_s);
    else set_message ("keyboard shorthand: " * sh_s, shorth);
    return;
  }

  // ----------------------- default ------------------------
  if (N(key)==1) {
    int i ((unsigned char) key[0]);
    if (((i>=32) && (i<=127)) ||
	((i>=128) && (i <=255))) insert_tree (key);
    sh_s  = string ("");
    sh_len= 0;
  }
}

void
edit_interface_rep::emulate_keyboard (string keys, string action) {
  string s= keys;
  while (s != "") {
    int i;
    for (i=1; i<N(s); i++)
      if (s[i]==' ') break;
    key_press (s (0, i));
    if (i<N(s)) i++;
    s= s (i, N(s));
  }
  if (N(action) != 0)
    set_message ("You can also obtain#" * action *
		 "#by typing#" * keys, action);
}

/******************************************************************************
* Event handlers
******************************************************************************/

void
edit_interface_rep::show_keymaps () {
  fatal_error ("no longer supported", "edit_interface_rep::show_keymaps");
}

void
edit_interface_rep::handle_keypress (keypress_event ev) {
  buf->mark_undo_block ();
  if (ev->key == "escape") {
    esc_s= "E-" * esc_s;
    if (esc_s == "E-")
      set_message ("Execute a TeXmacs command", "escape");
    else if (esc_s == "E-E-")
      set_message ("Insert a TeXmacs symbol", "escape#escape");
    else {
      esc_s= "";
      set_message ("", "");
    }
  }
  else {
    key_press (esc_s * ev->key);
    esc_s= "";
  }
  notify_change (THE_DECORATIONS);
}

void
edit_interface_rep::handle_keyboard_focus (keyboard_focus_event ev) {
  got_focus= ev->flag;
  notify_change (THE_FOCUS);
  if (got_focus) {
    focus_on_this_editor ();
    notify_change (THE_DECORATIONS);
  }
}

#endmodule // code_edit_interface
