From 78033261fc599d8d986e1c32b68523132b853d40 Mon Sep 17 00:00:00 2001 From: Jason Gross Date: Thu, 23 Jun 2011 23:58:21 -0400 Subject: [PATCH] editwin callback for canceling the editwin The code for editwin callbacks (called when the editwin is created) has been extended so that callbacks are called when the editwin is canceled. The old (perl) editwin callbacks still exist and have the same functionality that they always have. They are now deprecated. --- commands.c | 10 +++++++++- editwin.c | 18 +++++++++--------- functions.c | 19 ++++++++++++++----- perl/lib/BarnOwl.pm | 24 ++++++++++++++++++++---- perlconfig.c | 3 ++- viewwin.c | 3 ++- 6 files changed, 56 insertions(+), 21 deletions(-) diff --git a/commands.c b/commands.c index c05f457b1..48d169d81 100644 --- a/commands.c +++ b/commands.c @@ -2795,7 +2795,15 @@ void owl_command_edit_cancel(owl_editwin *e) if (hist) owl_history_store(hist, owl_editwin_get_text(e), false); + /* Take a reference to the editwin, so that it survives the pop + * context. TODO: We should perhaps refcount or otherwise protect + * the context so that, even if a command pops a context, the + * context itself will last until the command returns. */ + owl_editwin_ref(e); owl_global_pop_context(&g); + + owl_editwin_do_callback(e, false); + owl_editwin_unref(e); } void owl_command_edit_history_prev(owl_editwin *e) @@ -2855,7 +2863,7 @@ void owl_command_edit_done(owl_editwin *e) owl_editwin_ref(e); owl_global_pop_context(&g); - owl_editwin_do_callback(e); + owl_editwin_do_callback(e, true); owl_editwin_unref(e); } diff --git a/editwin.c b/editwin.c index 21e3d41b4..b967e9698 100644 --- a/editwin.c +++ b/editwin.c @@ -32,7 +32,7 @@ struct _owl_editwin { /*noproto*/ int echochar; oe_excursion *excursions; - void (*callback)(struct _owl_editwin*); + void (*callback)(struct _owl_editwin *e, bool success); void (*destroy_cbdata)(void *); void *cbdata; }; @@ -219,12 +219,12 @@ void owl_editwin_set_dotsend(owl_editwin *e) e->dotsend=1; } -void owl_editwin_set_callback(owl_editwin *e, void (*cb)(owl_editwin*)) +void owl_editwin_set_callback(owl_editwin *e, void (*cb)(owl_editwin *, bool)) { e->callback = cb; } -void (*owl_editwin_get_callback(owl_editwin *e))(owl_editwin*) +void (*owl_editwin_get_callback(owl_editwin *e))(owl_editwin *, bool) { return e->callback; } @@ -247,14 +247,14 @@ void *owl_editwin_get_cbdata(owl_editwin *e) { return e->cbdata; } -void owl_editwin_do_callback(owl_editwin *e) { - void (*cb)(owl_editwin*); - cb=owl_editwin_get_callback(e); - if(!cb) { +void owl_editwin_do_callback(owl_editwin *e, bool success) +{ + void (*cb)(owl_editwin *, bool); + cb = owl_editwin_get_callback(e); + if (!cb) { owl_function_error("Internal error: No editwin callback!"); } else { - /* owl_function_error("text: |%s|", owl_editwin_get_text(e)); */ - cb(e); + cb(e, success); } } diff --git a/functions.c b/functions.c index 76dcbc3e6..1370cd9ab 100644 --- a/functions.c +++ b/functions.c @@ -340,7 +340,9 @@ void owl_function_loopwrite_setup(void) owl_editwin_set_callback(e, &owl_callback_loopwrite); } -void owl_callback_zwrite(owl_editwin *e) { +void owl_callback_zwrite(owl_editwin *e, bool success) +{ + if (!success) return; owl_zwrite *z = owl_editwin_get_cbdata(e); owl_function_zwrite(z, owl_editwin_get_text(e)); } @@ -435,7 +437,9 @@ void owl_function_zcrypt(owl_zwrite *z, const char *msg) g_free(cryptmsg); } -void owl_callback_aimwrite(owl_editwin *e) { +void owl_callback_aimwrite(owl_editwin *e, bool success) +{ + if (!success) return; char *to = owl_editwin_get_cbdata(e); owl_function_aimwrite(to, owl_editwin_get_text(e), true); } @@ -499,7 +503,9 @@ void owl_function_send_aimawymsg(const char *to, const char *msg) g_free(format_msg); } -void owl_callback_loopwrite(owl_editwin *e) { +void owl_callback_loopwrite(owl_editwin *e, bool success) +{ + if (!success) return; owl_function_loopwrite(owl_editwin_get_text(e)); } @@ -910,7 +916,9 @@ void owl_function_loadloginsubs(const char *file) } } -void owl_callback_aimlogin(owl_editwin *e) { +void owl_callback_aimlogin(owl_editwin *e, bool success) +{ + if (!success) return; char *user = owl_editwin_get_cbdata(e); owl_function_aimlogin(user, owl_editwin_get_text(e)); @@ -1932,8 +1940,9 @@ void owl_function_zlocate(int argc, const char *const *argv, int auth) owl_fmtext_cleanup(&fm); } -void owl_callback_command(owl_editwin *e) +void owl_callback_command(owl_editwin *e, bool success) { + if (!success) return; char *rv; const char *line = owl_editwin_get_text(e); diff --git a/perl/lib/BarnOwl.pm b/perl/lib/BarnOwl.pm index 51e1b1f8d..d86b9b592 100644 --- a/perl/lib/BarnOwl.pm +++ b/perl/lib/BarnOwl.pm @@ -149,6 +149,9 @@ input. =item callback A Perl subroutine that is called when the user closes the edit_win. +C gets called with two parameters: the text the user entered, +and a C boolean parameter which is false if the user canceled +the edit_win and true otherwise. =back @@ -158,7 +161,11 @@ A Perl subroutine that is called when the user closes the edit_win. =head2 start_edit_win PROMPT CALLBACK -Equivalent to C called with the appropriate parameters. +Roughly equivalent to C called with the appropriate parameters. +C is only called on success, for compatibility. + +These are deprecated wrappers around L, and should not +be uesd in new code. =cut @@ -169,17 +176,26 @@ sub start_edit { sub start_question { my ($prompt, $callback) = @_; - BarnOwl::start_edit(type => 'question', prompt => $prompt, callback => $callback); + BarnOwl::start_edit(type => 'question', prompt => $prompt, callback => sub { + my ($text, $success) = @_; + $callback->($text) if $success; + }); } sub start_password { my ($prompt, $callback) = @_; - BarnOwl::start_edit(type => 'password', prompt => $prompt, callback => $callback); + BarnOwl::start_edit(type => 'password', prompt => $prompt, callback => sub { + my ($text, $success) = @_; + $callback->($text) if $success; + }); } sub start_edit_win { my ($prompt, $callback) = @_; - BarnOwl::start_edit(type => 'edit_win', prompt => $prompt, callback => $callback); + BarnOwl::start_edit(type => 'edit_win', prompt => $prompt, callback => sub { + my ($text, $success) = @_; + $callback->($text) if $success; + }); } =head2 get_data_dir diff --git a/perlconfig.c b/perlconfig.c index c94c1faab..e6cc05095 100644 --- a/perlconfig.c +++ b/perlconfig.c @@ -519,7 +519,7 @@ void owl_perlconfig_cmd_cleanup(owl_cmd *cmd) SvREFCNT_dec(cmd->cmd_perl); } -void owl_perlconfig_edit_callback(owl_editwin *e) +void owl_perlconfig_edit_callback(owl_editwin *e, bool success) { SV *cb = owl_editwin_get_cbdata(e); SV *text; @@ -536,6 +536,7 @@ void owl_perlconfig_edit_callback(owl_editwin *e) PUSHMARK(SP); XPUSHs(sv_2mortal(text)); + XPUSHs(sv_2mortal(newSViv(success))); PUTBACK; call_sv(cb, G_DISCARD|G_EVAL); diff --git a/viewwin.c b/viewwin.c index d2238b48d..5791401fd 100644 --- a/viewwin.c +++ b/viewwin.c @@ -157,8 +157,9 @@ typedef struct _owl_viewwin_search_data { /*noproto*/ int direction; } owl_viewwin_search_data; -static void owl_viewwin_callback_search(owl_editwin *e) +static void owl_viewwin_callback_search(owl_editwin *e, bool success) { + if (!success) return; int consider_current = false; const char *line = owl_editwin_get_text(e); owl_viewwin_search_data *data = owl_editwin_get_cbdata(e);