[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
About::about_button_pressed (WavesButton*)
{
MainMenuDisabled m;
MainMenuDisabler m;
LicenseDialog license_dialog;
license_dialog.set_position (WIN_POS_CENTER);
license_dialog.run ();

View File

@ -471,7 +471,7 @@ void
ARDOUR_UI::device_reset_started ()
{
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) {
_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
MainMenuDisabled m; // HOT FIX. (REWORK IT)
MainMenuDisabler m; // HOT FIX. (REWORK IT)
int r = _add_tracks_dialog->run();

View File

@ -123,7 +123,7 @@ class MidiTracer;
class NSM_Client;
class LevelMeterHBox;
class GUIObjectState;
class MainMenuDisabled;
class MainMenuDisabler;
namespace Gtkmm2ext {
class TearOff;
@ -481,7 +481,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
Gtk::HBox transport_hbox;
Gtk::Fixed transport_base;
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 {
enum ToggleType {

View File

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

View File

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

View File

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

View File

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

View File

@ -33,6 +33,7 @@
#include "dbg_msg.h"
#include "actions.h"
#include "ardour_ui.h"
#include "public_editor.h"
using namespace std;
using namespace Gtk;
@ -44,6 +45,7 @@ using namespace ARDOUR;
SessionLockDialog::SessionLockDialog ()
: WavesDialog (_("session_lock_dialog.xml"), true, false)
, _ok_button (get_waves_button ("ok_button"))
, _session_lock_dialog_menu_disabler (0)
{
set_keep_above (true);
set_position (WIN_POS_CENTER);
@ -66,15 +68,9 @@ SessionLockDialog::on_ok (WavesButton*)
void
SessionLockDialog::on_show ()
{
#ifdef __APPLE__
/* The global menu bar continues to be accessible to applications
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
if (!_session_lock_dialog_menu_disabler) {
_session_lock_dialog_menu_disabler = new MainMenuDisabler ();
}
WavesDialog::on_show ();
ARDOUR_UI::instance()->on_lock_session ();
}
@ -85,10 +81,10 @@ SessionLockDialog::on_hide ()
ARDOUR_UI::instance()->on_unlock_session ();
WavesDialog::on_hide ();
#ifdef __APPLE__
// enable Main menu on mac
ActionManager::pop_action_state ();
#endif
if (_session_lock_dialog_menu_disabler) {
delete _session_lock_dialog_menu_disabler;
_session_lock_dialog_menu_disabler = 0;
}
}
bool

View File

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

View File

@ -289,71 +289,63 @@ struct ActionState {
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>
get_action_state ()
void
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.
*/
GList* list = gtk_ui_manager_get_action_groups (ActionManager::ui_manager->gobj());
GList* node;
GList* acts;
for (node = list; node; node = g_list_next (node)) {
GtkActionGroup* group = (GtkActionGroup*) node->data;
/* 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;
/* 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;
for (node = list; node; node = g_list_next (node)) {
GtkActionGroup* group = (GtkActionGroup*) node->data;
for (acts = gtk_action_group_list_actions (group); acts; acts = g_list_next (acts)) {
GtkAction* action = (GtkAction*) acts->data;
action_states_to_restore.push_back (ActionState (action, gtk_action_get_sensitive (action)));
}
}
}
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
ActionManager::pop_action_state ()
ActionManager::disable_active_actions ()
{
if (state_stack.empty()) {
warning << string_compose (_("programming error: %1"), X_("ActionManager::pop_action_state called with empty stack")) << endmsg;
return;
}
boost::shared_ptr<ActionStates> as = state_stack.top ();
state_stack.pop ();
if (actions_disabled == true ) {
return ;
}
// save all action's states to action_states_to_restore
save_action_states ();
for (ActionStates::iterator i = as->begin(); i != as->end(); ++i) {
gtk_action_set_sensitive ((*i).action, (*i).sensitive);
}
}
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);
// set all action's states disabled
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);
}
}
actions_disabled = true;
}
void
@ -464,9 +456,25 @@ ActionManager::get_action_from_name (const char* name)
void
ActionManager::set_sensitive (vector<RefPtr<Action> >& actions, bool state)
{
for (vector<RefPtr<Action> >::iterator i = actions.begin(); i != actions.end(); ++i) {
(*i)->set_sensitive (state);
}
// if actions weren't disabled
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

View File

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