a) fix special button press handling for solo+mute buttons
[ardour.git] / gtk2_ardour / ardour_ui.cc
index eb084fb5eaddf9c17847ffc6a37d498e9318c088..23074fa827d33041eb6a91dcfc07aa9851b55a42 100644 (file)
 
 #include <iostream>
 
+#include <gtkmm/messagedialog.h>
+
 #include <pbd/error.h>
 #include <pbd/compose.h>
 #include <pbd/basename.h>
 #include <pbd/pathscanner.h>
 #include <pbd/failed_constructor.h>
 #include <gtkmm2ext/gtk_ui.h>
-#include <gtkmm2ext/pix.h>
 #include <gtkmm2ext/utils.h>
 #include <gtkmm2ext/click_box.h>
 #include <gtkmm2ext/fastmeter.h>
@@ -58,7 +59,6 @@
 
 #include "actions.h"
 #include "ardour_ui.h"
-#include "ardour_message.h"
 #include "public_editor.h"
 #include "audio_clock.h"
 #include "keyboard.h"
@@ -71,7 +71,7 @@
 #include "about.h"
 #include "utils.h"
 #include "gui_thread.h"
-#include "meter_xpms.h"
+#include "color_manager.h"
 
 #include "i18n.h"
 
@@ -129,11 +129,7 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], string rcfile)
        using namespace Gtk::Menu_Helpers;
 
        Gtkmm2ext::init();
-
-       /* actually, its already loaded, but ... */
-
-       cerr << "Loading UI configuration file " << rcfile << endl;
-
+       
        about = 0;
 
        if (theArdourUI == 0) {
@@ -141,7 +137,15 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], string rcfile)
        }
 
        ActionManager::init ();
+
+       /* load colors */
+
+       color_manager = new ColorManager();
+
+       std::string color_file = ARDOUR::find_config_file("ardour.colors");
        
+       color_manager->load (color_file);
+
        m_new_session_dialog = 0;
        m_new_session_dialog_ref = NewSessionDialogFactory::create();
        m_new_session_dialog_ref->get_widget_derived (NewSessionDialogFactory::top_level_widget_name(), m_new_session_dialog);
@@ -171,6 +175,7 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], string rcfile)
 
        shuttle_grabbed = false;
        shuttle_fract = 0.0;
+       shuttle_max_speed = 8.0f;
 
        set_shuttle_units (Percentage);
        set_shuttle_behaviour (Sprung);
@@ -205,7 +210,8 @@ because it has no input connections.\n\
 You would be wasting space recording silence."),
                              ds->name());
 
-       ArdourMessage message (editor, X_("cannotrecord"), msg);
+       MessageDialog message (*editor, msg);
+       message.run ();
 }
 
 void
@@ -223,8 +229,21 @@ ARDOUR_UI::set_engine (AudioEngine& e)
        keyboard = new Keyboard;
        install_keybindings ();
 
-       FastMeter::set_vertical_xpm (v_meter_strip_xpm);
-       FastMeter::set_horizontal_xpm (h_meter_strip_xpm);
+       string meter_path;
+
+       meter_path = ARDOUR::find_data_file("v_meter_strip.xpm", "pixmaps");
+       if (meter_path.empty()) {
+               error << _("no vertical meter strip image found") << endmsg;
+               exit (1);
+       }
+       FastMeter::set_vertical_xpm (meter_path);
+
+       meter_path = ARDOUR::find_data_file("h_meter_strip.xpm", "pixmaps");
+       if (meter_path.empty()) {
+               error << _("no horizontal meter strip image found") << endmsg;
+               exit (1);
+       }
+       FastMeter::set_horizontal_xpm (meter_path);
 
        if (setup_windows ()) {
                throw failed_constructor ();
@@ -252,6 +271,10 @@ ARDOUR_UI::set_engine (AudioEngine& e)
        
        blink_timeout_tag = -1;
 
+       /* the global configuration object is now valid */
+
+       use_config ();
+
        /* this being a GUI and all, we want peakfiles */
 
        FileSource::set_build_peakfiles (true);
@@ -358,8 +381,8 @@ ARDOUR_UI::save_ardour_state ()
                session->add_instant_xml(enode, session->path());
                session->add_instant_xml(mnode, session->path());
        } else {
-               Config->add_instant_xml(enode, Config->get_user_ardour_path());
-               Config->add_instant_xml(mnode, Config->get_user_ardour_path());
+               Config->add_instant_xml(enode, get_user_ardour_path());
+               Config->add_instant_xml(mnode, get_user_ardour_path());
        }
 }
 
@@ -388,11 +411,12 @@ ARDOUR_UI::finish()
                        /* use the default name */
                        if (save_state_canfail ("")) {
                                /* failed - don't quit */
-                               ArdourMessage (editor, X_("badsave dialog"),
+                               MessageDialog msg (*editor, 
                                               _("\
 Ardour was unable to save your session.\n\n\
 If you still wish to quit, please use the\n\n\
 \"Just quit\" option."));
+                               msg.run ();
                                return;
                        }
                        break;
@@ -922,11 +946,12 @@ ARDOUR_UI::session_add_audio_route (bool disk, int32_t input_channels, int32_t o
        }
 
        catch (...) {
-               ArdourMessage msg (editor, X_("noport dialog"),
+               MessageDialog msg (*editor, 
                                   _("There are insufficient JACK ports available\n\
 to create a new track or bus.\n\
 You should save Ardour, exit and\n\
 restart JACK with more ports."));
+               msg.run ();
        }
 }
 
@@ -955,6 +980,23 @@ ARDOUR_UI::do_transport_locate (jack_nframes_t new_position)
 
 void
 ARDOUR_UI::transport_goto_start ()
+{
+       if (session) {
+               session->goto_start();
+
+               
+               /* force displayed area in editor to start no matter
+                  what "follow playhead" setting is.
+               */
+               
+               if (editor) {
+                       editor->reposition_x_origin (session->current_start_frame());
+               }
+       }
+}
+
+void
+ARDOUR_UI::transport_goto_zero ()
 {
        if (session) {
                session->request_locate (0);
@@ -1030,7 +1072,8 @@ ARDOUR_UI::transport_record ()
                case Session::Disabled:
                        if (session->ntracks() == 0) {
                                string txt = _("Please create 1 or more track\nbefore trying to record.\nCheck the Session menu.");
-                               ArdourMessage msg (editor, X_("cannotrecenable"), txt);
+                               MessageDialog msg (*editor, txt);
+                               msg.run ();
                                return;
                        }
                        session->maybe_enable_record ();
@@ -1264,12 +1307,13 @@ ARDOUR_UI::engine_halted ()
 
        update_sample_rate (0);
 
-       ArdourMessage msg (editor, X_("halted"),
+       MessageDialog msg (*editor, 
                           _("\
 JACK has either been shutdown or it\n\
 disconnected Ardour because Ardour\n\
 was not fast enough. You can save the\n\
 session and/or try to reconnect to JACK ."));
+       msg.run ();
 }
 
 int32_t
@@ -1767,9 +1811,10 @@ ARDOUR_UI::load_session (const string & path, const string & snap_name, string*
        /* if it already exists, we must have write access */
 
        if (::access (path.c_str(), F_OK) == 0 && ::access (path.c_str(), W_OK)) {
-               ArdourMessage msg (editor, X_("noaccess dialog"), _("\
+               MessageDialog msg (*editor, _("\
 You do not have write access to this session.\n\
 This prevents the session from being loaded."));
+               msg.run ();
                return -1;
        }
 
@@ -1887,12 +1932,13 @@ ARDOUR_UI::display_cleanup_results (Session::cleanup_report& rep, const gchar* l
        removed = rep.paths.size();
 
        if (removed == 0) {
-               ArdourMessage msg (editor, X_("cleanupresults"),
+               MessageDialog msg (*editor, X_("cleanupresults"),
                                   _("\
 No audio files were ready for cleanup\n\n\
 If this seems suprising, check for any existing\n\
 snapshots. These may still include regions that\n\
 require some unused files to continue to exist."));
+               msg.run ();
                return;
        } 
 
@@ -2091,7 +2137,7 @@ ARDOUR_UI::mixer_settings () const
        if (session) {
                node = session->instant_xml(X_("Mixer"), session->path());
        } else {
-               node = Config->instant_xml(X_("Mixer"), Config->get_user_ardour_path());
+               node = Config->instant_xml(X_("Mixer"), get_user_ardour_path());
        }
 
        if (!node) {
@@ -2109,7 +2155,7 @@ ARDOUR_UI::editor_settings () const
        if (session) {
                node = session->instant_xml(X_("Editor"), session->path());
        } else {
-               node = Config->instant_xml(X_("Editor"), Config->get_user_ardour_path());
+               node = Config->instant_xml(X_("Editor"), get_user_ardour_path());
        }
 
        if (!node) {
@@ -2136,8 +2182,9 @@ ARDOUR_UI::halt_on_xrun_message ()
 {
        ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::halt_on_xrun_message));
 
-       ArdourMessage msg (editor, X_("haltonxrun"),
+       MessageDialog msg (*editor,
                           _("Recording was stopped because your system could not keep up."));
+       msg.run ();
 }
 
 void 
@@ -2159,12 +2206,13 @@ ARDOUR_UI::disk_overrun_handler ()
 
        if (!have_disk_overrun_displayed) {
                have_disk_overrun_displayed = true;
-               ArdourMessage msg (editor, X_("diskrate dialog"), _("\
+               MessageDialog msg (*editor, X_("diskrate dialog"), _("\
 The disk system on your computer\n\
 was not able to keep up with Ardour.\n\
 \n\
 Specifically, it failed to write data to disk\n\
 quickly enough to keep up with recording.\n"));
+               msg.run ();
                have_disk_overrun_displayed = false;
        }
 }
@@ -2176,12 +2224,13 @@ ARDOUR_UI::disk_underrun_handler ()
 
        if (!have_disk_underrun_displayed) {
                have_disk_underrun_displayed = true;
-               ArdourMessage msg (editor, X_("diskrate2 dialog"),
+               MessageDialog msg (*editor,
                        (_("The disk system on your computer\n\
 was not able to keep up with Ardour.\n\
 \n\
 Specifically, it failed to read data from disk\n\
 quickly enough to keep up with playback.\n")));
+               msg.run ();
                have_disk_underrun_displayed = false;
        } 
 }
@@ -2220,22 +2269,19 @@ what you would like to do.\n"));
        
        switch (dialog.run ()) {
        case RESPONSE_ACCEPT:
-               break;
-       default:
                return 1;
+       default:
+               return 0;
        }
-
-       return 0;
 }
        
-       
 void
 ARDOUR_UI::disconnect_from_jack ()
 {
        if (engine) {
                if( engine->disconnect_from_jack ()) {
-                       ArdourMessage msg (editor, X_("nojack dialog"),
-                                          _("Could not disconnect from JACK"));
+                       MessageDialog msg (*editor, _("Could not disconnect from JACK"));
+                       msg.run ();
                }
 
                update_sample_rate (0);
@@ -2247,8 +2293,8 @@ ARDOUR_UI::reconnect_to_jack ()
 {
        if (engine) {
                if (engine->reconnect_to_jack ()) {
-                       ArdourMessage msg (editor, X_("nojack dialog"),
-                                          _("Could not reconnect to JACK"));
+                       MessageDialog msg (*editor,  _("Could not reconnect to JACK"));
+                       msg.run ();
                }
 
                update_sample_rate (0);
@@ -2281,3 +2327,106 @@ ARDOUR_UI::cmdline_new_session (string path)
        _will_create_new_session_automatically = false; /* done it */
        return FALSE; /* don't call it again */
 }
+
+void
+ARDOUR_UI::set_native_file_header_format (HeaderFormat hf)
+{
+       Glib::RefPtr<Action> act;
+       
+       switch (hf) {
+       case BWF:
+               act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatBWF"));
+               break;
+       case WAVE:
+               act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE"));
+               break;
+       case WAVE64:
+               act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE64"));
+               break;
+       case iXML:
+               act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatiXML"));
+               break;
+       case RF64:
+               act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatRF64"));
+               break;
+       }
+
+       if (act) {
+               Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
+               if (ract && ract->get_active() && Config->get_native_file_header_format() != hf) {
+                       Config->set_native_file_header_format (hf);
+                       if (session) {
+                               session->reset_native_file_format ();
+                       }
+               }
+       }
+}
+
+void
+ARDOUR_UI::set_native_file_data_format (SampleFormat sf)
+{
+       Glib::RefPtr<Action> act;
+       
+       switch (sf) {
+       case FormatFloat:
+               act = ActionManager::get_action (X_("options"), X_("FileDataFormatFloat"));
+               break;
+       case FormatInt24:
+               act = ActionManager::get_action (X_("options"), X_("FileDataFormat24bit"));
+               break;
+       }
+
+       if (act) {
+               Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
+
+               if (ract && ract->get_active() && Config->get_native_file_data_format() != sf) {
+                       Config->set_native_file_data_format (sf);
+                       if (session) {
+                               session->reset_native_file_format ();
+                       }
+               }
+       }
+}
+
+void
+ARDOUR_UI::use_config ()
+{
+       Glib::RefPtr<Action> act;
+
+       switch (Config->get_native_file_data_format ()) {
+       case FormatFloat:
+               act = ActionManager::get_action (X_("options"), X_("FileDataFormatFloat"));
+               break;
+       case FormatInt24:
+               act = ActionManager::get_action (X_("options"), X_("FileDataFormat24bit"));
+               break;
+       }
+
+       if (act) {
+               Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
+               ract->set_active ();
+       }       
+
+       switch (Config->get_native_file_header_format ()) {
+       case BWF:
+               act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatBWF"));
+               break;
+       case WAVE:
+               act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE"));
+               break;
+       case WAVE64:
+               act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE64"));
+               break;
+       case iXML:
+               act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatiXML"));
+               break;
+       case RF64:
+               act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatRF64"));
+               break;
+       }
+
+       if (act) {
+               Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
+               ract->set_active ();
+       }       
+}