[Summary]: fix bug #46893. Main menu commands inactive after Tracks stopped after longterm record session. Rename MainMenuDiabled -> MainMenuDiabler

This commit is contained in:
YPozdnyakov 2015-04-01 17:08:29 +03:00
parent ea97ebc817
commit f49d31a820
11 changed files with 93 additions and 87 deletions

View file

@ -89,7 +89,7 @@ About::on_esc_pressed ()
void void
About::about_button_pressed (WavesButton*) About::about_button_pressed (WavesButton*)
{ {
MainMenuDisabled m; MainMenuDisabler m;
LicenseDialog license_dialog; LicenseDialog license_dialog;
license_dialog.set_position (WIN_POS_CENTER); license_dialog.set_position (WIN_POS_CENTER);
license_dialog.run (); license_dialog.run ();

View file

@ -471,7 +471,7 @@ void
ARDOUR_UI::device_reset_started () ARDOUR_UI::device_reset_started ()
{ {
if (!_audio_engine_reset_menu_disabler) { if (!_audio_engine_reset_menu_disabler) {
_audio_engine_reset_menu_disabler = new MainMenuDisabled (); _audio_engine_reset_menu_disabler = new MainMenuDisabler ();
} }
if (!_audio_engine_reset_info_dialog) { if (!_audio_engine_reset_info_dialog) {
_audio_engine_reset_info_dialog = new WavesDialog ("audio_engine_reset_info_dialog.xml"); // HOT FIX. (REWORK IT) _audio_engine_reset_info_dialog = new WavesDialog ("audio_engine_reset_info_dialog.xml"); // HOT FIX. (REWORK IT)
@ -3756,7 +3756,7 @@ ARDOUR_UI::add_route (Gtk::Window* float_window)
// disable Main menu // disable Main menu
MainMenuDisabled m; // HOT FIX. (REWORK IT) MainMenuDisabler m; // HOT FIX. (REWORK IT)
int r = _add_tracks_dialog->run(); int r = _add_tracks_dialog->run();

View file

@ -123,7 +123,7 @@ class MidiTracer;
class NSM_Client; class NSM_Client;
class LevelMeterHBox; class LevelMeterHBox;
class GUIObjectState; class GUIObjectState;
class MainMenuDisabled; class MainMenuDisabler;
namespace Gtkmm2ext { namespace Gtkmm2ext {
class TearOff; class TearOff;
@ -481,7 +481,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
Gtk::HBox transport_hbox; Gtk::HBox transport_hbox;
Gtk::Fixed transport_base; Gtk::Fixed transport_base;
WavesDialog *_audio_engine_reset_info_dialog; // HOT FIX. (REWORK IT) WavesDialog *_audio_engine_reset_info_dialog; // HOT FIX. (REWORK IT)
MainMenuDisabled *_audio_engine_reset_menu_disabler; // HOT FIX. (REWORK IT) MainMenuDisabler *_audio_engine_reset_menu_disabler; // HOT FIX. (REWORK IT)
struct TransportControllable : public PBD::Controllable { struct TransportControllable : public PBD::Controllable {
enum ToggleType { enum ToggleType {

View file

@ -3367,7 +3367,7 @@ Editor::duplicate_range (bool with_dialog)
} }
// disable Main menu // disable Main menu
MainMenuDisabled m; // HOT FIX. (REWORK IT) MainMenuDisabler m; // HOT FIX. (REWORK IT)
if (with_dialog) { if (with_dialog) {

View file

@ -65,7 +65,7 @@ void
Editor::export_audio () Editor::export_audio ()
{ {
// disable Main menu // disable Main menu
MainMenuDisabled m; // HOT FIX. (REWORK IT) MainMenuDisabler m; // HOT FIX. (REWORK IT)
if (Config->get_output_auto_connect() & AutoConnectPhysical) { if (Config->get_output_auto_connect() & AutoConnectPhysical) {
WavesMessageDialog read_only_session_dialog ("", WavesMessageDialog read_only_session_dialog ("",
@ -84,7 +84,7 @@ void
Editor::stem_export () Editor::stem_export ()
{ {
// disable Main menu // disable Main menu
MainMenuDisabled m; // HOT FIX. (REWORK IT) MainMenuDisabler m; // HOT FIX. (REWORK IT)
WavesStemExportDialog dialog (*this); WavesStemExportDialog dialog (*this);
dialog.set_session (_session); dialog.set_session (_session);
@ -132,7 +132,7 @@ Editor::export_region ()
boost::shared_ptr<MidiRegion> midi_region = boost::dynamic_pointer_cast<MidiRegion>(r); boost::shared_ptr<MidiRegion> midi_region = boost::dynamic_pointer_cast<MidiRegion>(r);
// disable Main menu // disable Main menu
MainMenuDisabled m; // HOT FIX. (REWORK IT) MainMenuDisabler m; // HOT FIX. (REWORK IT)
if (audio_region) { if (audio_region) {

View file

@ -2569,7 +2569,7 @@ Editor::rename_region ()
waves_edit_dialog.set_entry_text (rs.front()->region()->name()); waves_edit_dialog.set_entry_text (rs.front()->region()->name());
// disable Main menu // disable Main menu
MainMenuDisabled m; // HOT FIX. (REWORK IT) MainMenuDisabler m; // HOT FIX. (REWORK IT)
int const ret = waves_edit_dialog.run (); int const ret = waves_edit_dialog.run ();

View file

@ -445,20 +445,20 @@ class DisplaySuspender {
} }
}; };
class MainMenuDisabled { class MainMenuDisabler {
public: public:
MainMenuDisabled() { MainMenuDisabler () {
#ifdef __APPLE__ #ifdef __APPLE__
/* The global menu bar continues to be accessible to applications /* The global menu bar continues to be accessible to applications
with modal dialogs on mac, which means that we need to desensitize with modal dialogs on mac, which means that we need to desensitize
all items in the menu bar. all items in the menu bar.
*/ */
ActionManager::disable_all_actions (); // HOT FIX. (REWORK IT) ActionManager::disable_active_actions (); // HOT FIX. (REWORK IT)
#endif #endif
} }
~MainMenuDisabled () { ~MainMenuDisabler () {
#ifdef __APPLE__ #ifdef __APPLE__
ActionManager::pop_action_state (); // HOT FIX. (REWORK IT) ActionManager::enable_active_actions (); // HOT FIX. (REWORK IT)
#endif #endif
} }
}; };

View file

@ -33,6 +33,7 @@
#include "dbg_msg.h" #include "dbg_msg.h"
#include "actions.h" #include "actions.h"
#include "ardour_ui.h" #include "ardour_ui.h"
#include "public_editor.h"
using namespace std; using namespace std;
using namespace Gtk; using namespace Gtk;
@ -44,6 +45,7 @@ using namespace ARDOUR;
SessionLockDialog::SessionLockDialog () SessionLockDialog::SessionLockDialog ()
: WavesDialog (_("session_lock_dialog.xml"), true, false) : WavesDialog (_("session_lock_dialog.xml"), true, false)
, _ok_button (get_waves_button ("ok_button")) , _ok_button (get_waves_button ("ok_button"))
, _session_lock_dialog_menu_disabler (0)
{ {
set_keep_above (true); set_keep_above (true);
set_position (WIN_POS_CENTER); set_position (WIN_POS_CENTER);
@ -66,15 +68,9 @@ SessionLockDialog::on_ok (WavesButton*)
void void
SessionLockDialog::on_show () SessionLockDialog::on_show ()
{ {
#ifdef __APPLE__ if (!_session_lock_dialog_menu_disabler) {
/* The global menu bar continues to be accessible to applications _session_lock_dialog_menu_disabler = new MainMenuDisabler ();
with modal dialogs, which means that we need to desensitize }
all items in the menu bar. Since those items are really just
proxies for actions, that means disabling all actions.
*/
ActionManager::disable_all_actions ();
#endif
WavesDialog::on_show (); WavesDialog::on_show ();
ARDOUR_UI::instance()->on_lock_session (); ARDOUR_UI::instance()->on_lock_session ();
} }
@ -85,10 +81,10 @@ SessionLockDialog::on_hide ()
ARDOUR_UI::instance()->on_unlock_session (); ARDOUR_UI::instance()->on_unlock_session ();
WavesDialog::on_hide (); WavesDialog::on_hide ();
#ifdef __APPLE__ if (_session_lock_dialog_menu_disabler) {
// enable Main menu on mac delete _session_lock_dialog_menu_disabler;
ActionManager::pop_action_state (); _session_lock_dialog_menu_disabler = 0;
#endif }
} }
bool bool

View file

@ -43,6 +43,7 @@
//#include "ardour/utils.h" //#include "ardour/utils.h"
class EngineControl; class EngineControl;
class MainMenuDisabler;
#define MAX_RECENT_SESSION_COUNT 10 #define MAX_RECENT_SESSION_COUNT 10
class SessionLockDialog : public WavesDialog { class SessionLockDialog : public WavesDialog {
public: public:
@ -57,6 +58,7 @@ class SessionLockDialog : public WavesDialog {
private: private:
WavesButton& _ok_button; WavesButton& _ok_button;
void on_ok(WavesButton*); void on_ok(WavesButton*);
MainMenuDisabler *_session_lock_dialog_menu_disabler; // HOT FIX. (REWORK IT)
}; };
#endif /* __gtk2_session_lock_dialog_h__ */ #endif /* __gtk2_session_lock_dialog_h__ */

View file

@ -289,71 +289,63 @@ struct ActionState {
typedef std::vector<ActionState> ActionStates; typedef std::vector<ActionState> ActionStates;
static std::stack<boost::shared_ptr<ActionStates> > state_stack; static ActionStates action_states_to_restore;
static bool actions_disabled = false;
static boost::shared_ptr<ActionStates> void
get_action_state () ActionManager::save_action_states ()
{ {
boost::shared_ptr<ActionStates> state = boost::shared_ptr<ActionStates>(new ActionStates); /* the C++ API for functions used here appears to be broken in
gtkmm2.6, so we fall back to the C level.
/* the C++ API for functions used here appears to be broken in */
gtkmm2.6, so we fall back to the C level. GList* list = gtk_ui_manager_get_action_groups (ActionManager::ui_manager->gobj());
*/ GList* node;
GList* acts;
GList* list = gtk_ui_manager_get_action_groups (ActionManager::ui_manager->gobj());
GList* node; for (node = list; node; node = g_list_next (node)) {
GList* acts;
GtkActionGroup* group = (GtkActionGroup*) node->data;
for (node = list; node; node = g_list_next (node)) {
for (acts = gtk_action_group_list_actions (group); acts; acts = g_list_next (acts)) {
GtkActionGroup* group = (GtkActionGroup*) node->data; GtkAction* action = (GtkAction*) acts->data;
action_states_to_restore.push_back (ActionState (action, gtk_action_get_sensitive (action)));
/* first pass: collect them all */ }
}
typedef std::list<Glib::RefPtr<Gtk::Action> > action_list;
action_list the_acts;
for (acts = gtk_action_group_list_actions (group); acts; acts = g_list_next (acts)) {
GtkAction* action = (GtkAction*) acts->data;
state->push_back (ActionState (action, gtk_action_get_sensitive (action)));
}
}
return state;
} }
void void
ActionManager::push_action_state () ActionManager::enable_active_actions ()
{ {
state_stack.push (get_action_state()); if (!actions_disabled) {
return ;
}
for (ActionStates::iterator i = action_states_to_restore.begin(); i != action_states_to_restore.end(); ++i) {
if ((*i).action && (*i).sensitive) {
gtk_action_set_sensitive ((*i).action, true);
}
}
action_states_to_restore.clear ();
actions_disabled = false;
} }
void void
ActionManager::pop_action_state () ActionManager::disable_active_actions ()
{ {
if (state_stack.empty()) { if (actions_disabled == true ) {
warning << string_compose (_("programming error: %1"), X_("ActionManager::pop_action_state called with empty stack")) << endmsg; return ;
return; }
} // save all action's states to action_states_to_restore
save_action_states ();
boost::shared_ptr<ActionStates> as = state_stack.top ();
state_stack.pop ();
for (ActionStates::iterator i = as->begin(); i != as->end(); ++i) { // set all action's states disabled
gtk_action_set_sensitive ((*i).action, (*i).sensitive); for (ActionStates::iterator i = action_states_to_restore.begin(); i != action_states_to_restore.end(); ++i) {
} if ((*i).sensitive) {
} gtk_action_set_sensitive ((*i).action, false);
}
void
ActionManager::disable_all_actions ()
{
push_action_state ();
boost::shared_ptr<ActionStates> as = state_stack.top ();
for (ActionStates::iterator i = as->begin(); i != as->end(); ++i) {
gtk_action_set_sensitive ((*i).action, false);
} }
actions_disabled = true;
} }
void void
@ -464,9 +456,25 @@ ActionManager::get_action_from_name (const char* name)
void void
ActionManager::set_sensitive (vector<RefPtr<Action> >& actions, bool state) ActionManager::set_sensitive (vector<RefPtr<Action> >& actions, bool state)
{ {
for (vector<RefPtr<Action> >::iterator i = actions.begin(); i != actions.end(); ++i) { // if actions weren't disabled
(*i)->set_sensitive (state); if (!actions_disabled) {
} for (vector<RefPtr<Action> >::iterator i = actions.begin(); i != actions.end(); ++i) {
(*i)->set_sensitive (state);
}
}
else {
// actions were disabled
// so we should just set necessary action's states in action_states_to_restore
for (vector<RefPtr<Action> >::iterator i = actions.begin(); i != actions.end(); ++i) {
// go through action_states_to_restore and set state of actions
for (ActionStates::iterator j = action_states_to_restore.begin(); j != action_states_to_restore.end(); ++j) {
// all actions should have their individual name, so we can use it for comparison
if (gtk_action_get_name ((*j).action) == (*i)->get_name ()) {
(*j).sensitive = state;
}
}
}
}
} }
void void

View file

@ -94,9 +94,9 @@ namespace ActionManager {
LIBGTKMM2EXT_API extern void set_toggleaction_state (std::string, bool); LIBGTKMM2EXT_API extern void set_toggleaction_state (std::string, bool);
LIBGTKMM2EXT_API extern void push_action_state (); LIBGTKMM2EXT_API extern void save_action_states ();
LIBGTKMM2EXT_API extern void pop_action_state (); LIBGTKMM2EXT_API extern void enable_active_actions ();
LIBGTKMM2EXT_API extern void disable_all_actions (); LIBGTKMM2EXT_API extern void disable_active_actions ();
}; };
#endif /* __libgtkmm2ext_actions_h__ */ #endif /* __libgtkmm2ext_actions_h__ */