diff --git a/History.txt b/History.txt index 45610afac..108d85819 100644 --- a/History.txt +++ b/History.txt @@ -15,6 +15,9 @@ * Add optional drop-down terminal ('|') which has session-persistent working directory. Will silently be disabled if VTE is missing. +* Delay sending of message with configured time, in order to be able to + cancel wrongly sent messages. + == v0.7 / 2017-01-02 * Messages are marked unread after a delay (default 2 sec) in diff --git a/src/compose_message.cc b/src/compose_message.cc index 5934fbcbc..52d63570a 100644 --- a/src/compose_message.cc +++ b/src/compose_message.cc @@ -33,6 +33,8 @@ namespace Astroid { d_message_sent.connect ( sigc::mem_fun (this, &ComposeMessage::message_sent_event)); + d_message_send_status.connect ( + sigc::mem_fun (this, &ComposeMessage::message_send_status_event)); } ComposeMessage::~ComposeMessage () { @@ -312,6 +314,8 @@ namespace Astroid { } bool ComposeMessage::cancel_sending () { + cancel_send_during_delay = true; + if (pid > 0) { LOG (warn) << "cm: cancel sendmail pid: " << pid; @@ -330,6 +334,7 @@ namespace Astroid { void ComposeMessage::send_threaded () { LOG (info) << "cm: sending (threaded).."; + cancel_send_during_delay = false; Glib::Threads::Thread::create ( [&] () { this->send (true); @@ -339,6 +344,33 @@ namespace Astroid { bool ComposeMessage::send (bool output) { dryrun = astroid->config().get("astroid.debug.dryrun_sending"); + message_send_status_warn = false; + message_send_status_msg = ""; + + unsigned int delay = astroid->config ().get ("mail.send_delay"); + while (delay > 0 && !cancel_send_during_delay) { + LOG (debug) << "cm: sending in " << delay << " seconds.."; + message_send_status_msg = ustring::compose ("sending message in %1 seconds..", delay); + d_message_send_status (); + sleep (1); + delay--; + } + + if (cancel_send_during_delay) { + LOG (error) << "cm: cancelled sending before message could be sent."; + message_send_status_msg = "sending message.. cancelled before sending."; + message_send_status_warn = true; + d_message_send_status (); + + message_sent_result = false; + d_message_sent (); + pid = 0; + return false; + } + + message_send_status_msg = "sending message.."; + d_message_send_status (); + /* Send the message */ if (!dryrun) { if (output) @@ -360,6 +392,11 @@ namespace Astroid { } catch (Glib::SpawnError &ex) { if (output) LOG (error) << "cm: could not send message!"; + + message_send_status_msg = "message could not be sent!"; + message_send_status_warn = true; + d_message_send_status (); + message_sent_result = false; d_message_sent (); pid = 0; @@ -385,7 +422,6 @@ namespace Astroid { fclose (sendMailPipe); /* wait for sendmail to finish */ - int status; waitpid (pid, &status, 0); g_spawn_close_pid (pid); @@ -404,6 +440,10 @@ namespace Astroid { write (save_to.c_str()); } + message_send_status_msg = "message sent successfully!"; + message_send_status_warn = false; + d_message_send_status (); + pid = 0; message_sent_result = true; d_message_sent (); @@ -412,6 +452,11 @@ namespace Astroid { } else { if (output) LOG (error) << "cm: could not send message!"; + + message_send_status_msg = "message could not be sent!"; + message_send_status_warn = true; + d_message_send_status (); + message_sent_result = false; d_message_sent (); pid = 0; @@ -421,6 +466,9 @@ namespace Astroid { ustring fname = "/tmp/" + id; if (output) LOG (warn) << "cm: sending disabled in config, message written to: " << fname; + message_send_status_msg = "sending disabled, message written to: " + fname; + message_send_status_warn = true; + d_message_send_status (); write (fname); message_sent_result = false; @@ -491,6 +539,20 @@ namespace Astroid { emit_message_sent (message_sent_result); } + ComposeMessage::type_message_send_status + ComposeMessage::message_send_status () + { + return m_message_send_status; + } + + void ComposeMessage::emit_message_send_status (bool warn, ustring msg) { + m_message_send_status.emit (warn, msg); + } + + void ComposeMessage::message_send_status_event () { + emit_message_send_status (message_send_status_warn, message_send_status_msg); + } + ustring ComposeMessage::write_tmp () { char * temporaryFilePath; diff --git a/src/compose_message.hh b/src/compose_message.hh index 08ef9fdae..74ec00055 100644 --- a/src/compose_message.hh +++ b/src/compose_message.hh @@ -97,6 +97,7 @@ namespace Astroid { bool dryrun; /* sendmail process */ + bool cancel_send_during_delay = false; int pid; int stdin; int stdout; @@ -118,7 +119,20 @@ namespace Astroid { void message_sent_event (); Glib::Dispatcher d_message_sent; + /* message send status update */ + typedef sigc::signal type_message_send_status; + type_message_send_status message_send_status (); + + void emit_message_send_status (bool, ustring); + + bool message_send_status_warn = false; + ustring message_send_status_msg = ""; + + void message_send_status_event (); + Glib::Dispatcher d_message_send_status; + protected: type_message_sent m_message_sent; + type_message_send_status m_message_send_status; }; } diff --git a/src/config.cc b/src/config.cc index 5b075b5c0..f94b6e08a 100644 --- a/src/config.cc +++ b/src/config.cc @@ -200,6 +200,7 @@ namespace Astroid { default_config.put ("mail.message_id_fqdn", ""); // custom fqdn for the message id: default: local hostname default_config.put ("mail.message_id_user", ""); // custom user for the message id: default: 'astroid' default_config.put ("mail.user_agent", "default"); + default_config.put ("mail.send_delay", 2); // wait seconds before sending, allowing to cancel /* polling */ default_config.put ("poll.interval", Poll::DEFAULT_POLL_INTERVAL); // seconds diff --git a/src/modes/edit_message.cc b/src/modes/edit_message.cc index 1809ccb97..8c4af64e7 100644 --- a/src/modes/edit_message.cc +++ b/src/modes/edit_message.cc @@ -958,6 +958,8 @@ namespace Astroid { c->message_sent().connect ( sigc::mem_fun (this, &EditMessage::send_message_finished)); + c->message_send_status ().connect ( + sigc::mem_fun (this, &EditMessage::update_send_message_status)); fields_hide (); sending_in_progress.store (true); @@ -980,6 +982,18 @@ namespace Astroid { return true; } + void EditMessage::update_send_message_status (bool warn, ustring msg) { + if (warn) { + info_str = ""; + warning_str = msg; + } else { + info_str = msg; + warning_str = ""; + } + + on_tv_ready (); + } + void EditMessage::send_message_finished (bool result_from_sender) { LOG (info) << "em: message sending done."; status_icon_visible = true; @@ -988,8 +1002,6 @@ namespace Astroid { Glib::RefPtr pixbuf; if (result_from_sender) { - info_str = "message sent successfully!"; - warning_str = ""; lock_message_after_send (); pixbuf = theme->load_icon ( @@ -1004,8 +1016,6 @@ namespace Astroid { } } else { - warning_str = "message could not be sent!"; - info_str = ""; fields_show (); pixbuf = theme->load_icon ( @@ -1019,8 +1029,6 @@ namespace Astroid { delete sending_message; - on_tv_ready (); - emit_message_sent_attempt (result_from_sender); } diff --git a/src/modes/edit_message.hh b/src/modes/edit_message.hh index 21db15c8a..412ab6102 100644 --- a/src/modes/edit_message.hh +++ b/src/modes/edit_message.hh @@ -96,6 +96,7 @@ namespace Astroid { ComposeMessage * sending_message; std::atomic sending_in_progress; void send_message_finished (bool result); + void update_send_message_status (bool warn, ustring msg); /* make a draft message that can be edited */ void prepare_message ();