diff options
author | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2015-03-01 17:56:34 +0100 |
---|---|---|
committer | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2015-03-01 18:20:27 +0100 |
commit | 83ebaea1abc39cae990e0fd22b6e4b428abfa95f (patch) | |
tree | d297dab707836d05b9d46bad621b8e02d6506ab9 /src/interface-gtk.cpp | |
parent | 68eb8e5c427877abae43f2e2aba7fcca5a3471de (diff) | |
download | sciteco-83ebaea1abc39cae990e0fd22b6e4b428abfa95f.tar.gz |
keep rubbed out command line for later re-insertion and massive Cmdline cleanup/refactoring
* characters rubbed out are not totally removed from the command line,
but only from the *effective* command line.
* The rubbed out command line is displayed after the command line cursor.
On Curses it is grey and underlined.
* When characters are inserted that are on the rubbed out part of the command line,
the cursor simply moves forward.
NOTE: There's currently no immediate editing command for reinserting the
next character/word from the rubbed out command line.
* Characters resulting in errors are no longer simply discarded but rubbed out,
so they will stay in the rubbed out part of the command line, reminding you
which character caused the error.
* Improved Cmdline formatting on Curses UI:
* Asterisk is printed bold
* Control characters are printed in REVERSE style, similar to what
Scinterm does. The controll character formatting has thus been moved
from macro_echo() in cmdline.cpp to the UI implementations.
* Updated the GTK+ UI (UNTESTED): I did only, the most important API
adaptions. The command line still does not use any colors.
* Refactored entire command line handling:
* The command line is now a class (Cmdline), and most functions
in cmdline.cpp have been converted to methods.
* Esp. process_edit_cmd() (now Cmdline::process_edit_cmd()) has been
simplified. There is no longer the possibility of a buffer overflow
because of static insertion buffer sizes
* Cleaned up usage of the cmdline_pos variable (now Cmdline::pc) which
is really a program counter that used a different origin as macro_pc
which was really confusing.
* The new Cmdline class is theoretically 8-bit clean. However all of this
will change again when we introduce Scintilla views for the command line.
* Added 8-bit clean (null-byte aware) versions of QRegisterData::set_string()
and QRegisterData::append_string()
Diffstat (limited to 'src/interface-gtk.cpp')
-rw-r--r-- | src/interface-gtk.cpp | 88 |
1 files changed, 69 insertions, 19 deletions
diff --git a/src/interface-gtk.cpp b/src/interface-gtk.cpp index 7931957..e7f6927 100644 --- a/src/interface-gtk.cpp +++ b/src/interface-gtk.cpp @@ -20,6 +20,7 @@ #endif #include <stdarg.h> +#include <string.h> #include <glib.h> #include <glib/gprintf.h> @@ -77,6 +78,7 @@ ViewGtk::initialize_impl(void) void InterfaceGtk::main_impl(int &argc, char **&argv) { + static const Cmdline empty_cmdline; GtkWidget *info_content; gtk_init(&argc, &argv); @@ -109,7 +111,7 @@ InterfaceGtk::main_impl(int &argc, char **&argv) gtk_widget_grab_focus(cmdline_widget); - cmdline_update(""); + cmdline_update(&empty_cmdline); } void @@ -164,7 +166,7 @@ InterfaceGtk::show_view_impl(ViewGtk *view) } void -InterfaceGtk::info_update_impl(QRegister *reg) +InterfaceGtk::info_update_impl(const QRegister *reg) { gchar buf[255]; @@ -174,7 +176,7 @@ InterfaceGtk::info_update_impl(QRegister *reg) } void -InterfaceGtk::info_update_impl(Buffer *buffer) +InterfaceGtk::info_update_impl(const Buffer *buffer) { gchar buf[255]; @@ -185,18 +187,66 @@ InterfaceGtk::info_update_impl(Buffer *buffer) } void -InterfaceGtk::cmdline_update_impl(const gchar *cmdline) +InterfaceGtk::cmdline_insert_chr(gint &pos, gchar chr) { - gint pos = 1; + gchar buffer[5+1]; - if (!cmdline) - /* widget automatically redrawn */ - return; + /* + * NOTE: This mapping is similar to + * View::set_representations() + */ + switch (chr) { + case '\x1B': /* escape */ + strcpy(buffer, "$"); + break; + case '\r': + strcpy(buffer, "<CR>"); + break; + case '\n': + strcpy(buffer, "<LF>"); + break; + case '\t': + strcpy(buffer, "<TAB>"); + break; + default: + if (IS_CTL(chr)) { + buffer[0] = '^'; + buffer[1] = CTL_ECHO(chr); + buffer[2] = '\0'; + } else { + buffer[0] = chr; + buffer[1] = '\0'; + } + } - gtk_entry_set_text(GTK_ENTRY(cmdline_widget), "*"); gtk_editable_insert_text(GTK_EDITABLE(cmdline_widget), - cmdline, -1, &pos); - gtk_editable_set_position(GTK_EDITABLE(cmdline_widget), pos); + buffer, -1, &pos); +} + +void +InterfaceGtk::cmdline_update_impl(const Cmdline *cmdline) +{ + gint pos = 1; + gint cmdline_len; + + /* + * We don't know if the new command line is similar to + * the old one, so we can just as well rebuild it. + */ + gtk_entry_set_text(GTK_ENTRY(cmdline_widget), "*"); + + /* format effective command line */ + for (guint i = 0; i < cmdline->len; i++) + cmdline_insert_chr(pos, (*cmdline)[i]); + /* save end of effective command line */ + cmdline_len = pos; + + /* format rubbed out command line */ + for (guint i = cmdline->len; i < cmdline->len+cmdline->rubout_len; i++) + cmdline_insert_chr(pos, (*cmdline)[i]); + + /* set cursor after effective command line */ + gtk_editable_set_position(GTK_EDITABLE(cmdline_widget), cmdline_len); } void @@ -258,25 +308,25 @@ handle_key_press(bool is_shift, bool is_ctl, guint keyval) { switch (keyval) { case GDK_Escape: - cmdline_keypress('\x1B'); + cmdline.keypress('\x1B'); break; case GDK_BackSpace: - cmdline_keypress('\b'); + cmdline.keypress('\b'); break; case GDK_Tab: - cmdline_keypress('\t'); + cmdline.keypress('\t'); break; case GDK_Return: - cmdline_keypress(get_eol()); + cmdline.keypress(get_eol()); break; /* * Function key macros */ #define FN(KEY, MACRO) \ - case GDK_##KEY: cmdline_fnmacro(#MACRO); break + case GDK_##KEY: cmdline.fnmacro(#MACRO); break #define FNS(KEY, MACRO) \ - case GDK_##KEY: cmdline_fnmacro(is_shift ? "S" #MACRO : #MACRO); break + case GDK_##KEY: cmdline.fnmacro(is_shift ? "S" #MACRO : #MACRO); break FN(Down, DOWN); FN(Up, UP); FNS(Left, LEFT); FNS(Right, RIGHT); FN(KP_Down, DOWN); FN(KP_Up, UP); @@ -287,7 +337,7 @@ handle_key_press(bool is_shift, bool is_ctl, guint keyval) g_snprintf(macro_name, sizeof(macro_name), "F%d", keyval - GDK_F1 + 1); - cmdline_fnmacro(macro_name); + cmdline.fnmacro(macro_name); break; } FNS(Delete, DC); @@ -317,7 +367,7 @@ handle_key_press(bool is_shift, bool is_ctl, guint keyval) if (is_ctl) key = CTL_KEY(g_ascii_toupper(key)); - cmdline_keypress(key); + cmdline.keypress(key); } } } |