merge with master
[ardour.git] / libs / gtkmm2ext / prompter.cc
index 83a64e78d4f1260fafadb3d66d90af28f2dc92ab..4c3ff43a73a00fff070a39b59c081c4d217118b1 100644 (file)
@@ -20,6 +20,9 @@
 
 #include <string>
 
+#include <pbd/whitespace.h>
+
+#include <gtkmm/stock.h>
 #include <gtkmm2ext/prompter.h>
 
 #include "i18n.h"
 using namespace std;
 using namespace Gtkmm2ext;
 
+Prompter::Prompter (Gtk::Window& parent, bool modal)
+       : Gtk::Dialog ("", parent, modal)
+       , first_show (true)
+       , can_accept_from_entry (false)
+{
+       init ();
+}
+
 Prompter::Prompter (bool modal)
-       : Gtk::Window (Gtk::WINDOW_POPUP),
-         ok (_("OK")),
-         cancel (_("Cancel"))
+       : Gtk::Dialog ("", modal)
+       , first_show (true)
+       , can_accept_from_entry (false)
+{
+       init ();
+}
+
+void
+Prompter::init ()
 {
+       set_type_hint (Gdk::WINDOW_TYPE_HINT_DIALOG);
        set_position (Gtk::WIN_POS_MOUSE);
        set_name ("Prompter");
-       set_modal (modal);
-
-       add (packer);
-
+       
+       add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
+
+       /* 
+          Alas a generic 'affirmative' button seems a bit useless sometimes.
+          You will have to add your own.
+          After adding, use :
+          set_response_sensitive (Gtk::RESPONSE_ACCEPT, false)
+          to prevent the RESPONSE_ACCEPT button from permitting blank strings.
+       */
+       
        entryLabel.set_line_wrap (true);
        entryLabel.set_name ("PrompterLabel");
 
        entryBox.set_homogeneous (false);
-       entryBox.set_spacing (25);
+       entryBox.set_spacing (5);
        entryBox.set_border_width (10);
-       entryBox.pack_start (entryLabel);
-       entryBox.pack_start (entry, false, false);
-
-       buttonBox.set_homogeneous (true);
-       buttonBox.set_border_width (10);
-       buttonBox.pack_start (ok, false, true);
-       buttonBox.pack_start (cancel, false, true);
-       
-       packer.pack_start (entryBox);
-       packer.pack_start (buttonBox);
-
-       entry.signal_activate().connect(mem_fun(*this,&Prompter::activated));
-       ok.signal_clicked().connect(mem_fun(*this,&Prompter::activated));
-       cancel.signal_clicked().connect(mem_fun(*this,&Prompter::cancel_click));
-       signal_delete_event().connect (mem_fun (*this, &Prompter::deleted));
+       entryBox.pack_start (entryLabel, false, false);
+       entryBox.pack_start (entry, true, true);
 
+       get_vbox()->pack_start (entryBox);
+       show_all_children();
 }      
 
 void
-Prompter::change_labels (string okstr, string cancelstr)
+Prompter::on_show ()
 {
-       dynamic_cast<Gtk::Label*>(ok.get_child())->set_text (okstr);
-       dynamic_cast<Gtk::Label*>(cancel.get_child())->set_text (cancelstr);
+       /* don't connect to signals till shown, so that we don't change the
+          response sensitivity etc. when the setup of the dialog sets the text.
+       */
+
+       if (first_show) {
+               entry.signal_changed().connect (mem_fun (*this, &Prompter::on_entry_changed));
+               entry.signal_activate().connect (mem_fun (*this, &Prompter::entry_activated));
+               can_accept_from_entry = !entry.get_text().empty();
+               first_show = false;
+       }
+
+       Dialog::on_show ();
 }
 
 void
-Prompter::on_realize ()
+Prompter::change_labels (string /*okstr*/, string /*cancelstr*/)
 {
-       Gtk::Window::on_realize ();
-       Glib::RefPtr<Gdk::Window> win (get_window());
-       win->set_decorations (Gdk::WMDecoration (Gdk::DECOR_BORDER|Gdk::DECOR_RESIZEH|Gdk::DECOR_MENU));
+       // dynamic_cast<Gtk::Label*>(ok.get_child())->set_text (okstr);
+       // dynamic_cast<Gtk::Label*>(cancel.get_child())->set_text (cancelstr);
 }
 
 void
-Prompter::on_map ()
+Prompter::get_result (string &str, bool strip)
 {
-       entry.grab_focus();
-       Gtk::Window::on_map ();
-}
-       
-void
-Prompter::activated ()
-
-{
-       status = entered;
-       hide_all ();
-       done ();
+       str = entry.get_text ();
+       if (strip) {
+               PBD::strip_whitespace_edges (str);
+       }
 }
 
 void
-Prompter::cancel_click ()
-
+Prompter::entry_activated ()
 {
-       entry.set_text ("");
-       status = cancelled;
-       hide_all ();
-       done ();
-}
-
-bool
-Prompter::deleted (GdkEventAny *ev)
-{
-       cancel_click ();
-       return false;
-}
+       if (can_accept_from_entry) {
+               response (Gtk::RESPONSE_ACCEPT);
+       } else {
+               response (Gtk::RESPONSE_CANCEL);
+       }
+}              
 
 void
-Prompter::get_result (string &str)
-
+Prompter::on_entry_changed ()
 {
-       str = entry.get_text ();
+       /* 
+          This is set up so that entering text in the entry 
+          field makes the RESPONSE_ACCEPT button active. 
+          Of course if you haven't added a RESPONSE_ACCEPT 
+          button, nothing will happen at all.
+       */
+
+       if (!entry.get_text().empty()) {
+               set_response_sensitive (Gtk::RESPONSE_ACCEPT, true);
+               set_default_response (Gtk::RESPONSE_ACCEPT);
+               can_accept_from_entry = true;
+       } else {
+               set_response_sensitive (Gtk::RESPONSE_ACCEPT, false);
+       }
 }