mirror of
https://github.com/cookiengineer/audacity
synced 2025-08-01 08:29:27 +02:00
Revert changes for Bug 1119 made by Paul.
These changes were made too close to release and are considered too dangerous for 2.4.0. We will use the changes Leland provided. We can review these proposed changes by Paul after 2.4.0 is released.
This commit is contained in:
parent
c3d0d0370b
commit
018a8681ef
@ -109,6 +109,10 @@ It handles initialization and termination by subclassing wxApp.
|
||||
#include "tracks/ui/Scrubbing.h"
|
||||
#include "widgets/FileHistory.h"
|
||||
|
||||
#if defined(__WXMAC__)
|
||||
#include "menus/WindowMenus.h"
|
||||
#endif
|
||||
|
||||
#ifdef EXPERIMENTAL_EASY_CHANGE_KEY_BINDINGS
|
||||
#include "prefs/KeyConfigPrefs.h"
|
||||
#endif
|
||||
@ -885,6 +889,11 @@ BEGIN_EVENT_TABLE(AudacityApp, wxApp)
|
||||
EVT_MENU_RANGE(FileHistory::ID_RECENT_FIRST, FileHistory::ID_RECENT_LAST,
|
||||
AudacityApp::OnMRUFile)
|
||||
|
||||
#if defined(__WXMAC__)
|
||||
// Window menu event handlers.
|
||||
EVT_MENU_RANGE(WindowActions::ID_BASE, WindowActions::ID_LAST, AudacityApp::OnWindow)
|
||||
#endif
|
||||
|
||||
// Handle AppCommandEvents (usually from a script)
|
||||
EVT_APP_COMMAND(wxID_ANY, AudacityApp::OnReceiveCommand)
|
||||
|
||||
@ -978,6 +987,35 @@ void AudacityApp::OnMRUFile(wxCommandEvent& event) {
|
||||
history.RemoveFileFromHistory(n);
|
||||
}
|
||||
|
||||
#if defined(__WXMAC__)
|
||||
// Handles switching projects when an item in the Window menu is selected
|
||||
void AudacityApp::OnWindow(wxCommandEvent& event)
|
||||
{
|
||||
// Get the project's number
|
||||
int projectNumber = event.GetId() - WindowActions::ID_BASE;
|
||||
|
||||
// Search for it
|
||||
for (auto project : AllProjects{})
|
||||
{
|
||||
if (project->GetProjectNumber() == projectNumber)
|
||||
{
|
||||
// Make it the active project
|
||||
SetActiveProject(project.get());
|
||||
|
||||
// And ensure it's visible
|
||||
wxFrame *frame = project->GetFrame();
|
||||
if (frame->IsIconized())
|
||||
{
|
||||
frame->Restore();
|
||||
}
|
||||
frame->Raise();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void AudacityApp::OnTimer(wxTimerEvent& WXUNUSED(event))
|
||||
{
|
||||
// Filenames are queued when Audacity receives a few of the
|
||||
|
@ -69,6 +69,10 @@ class AudacityApp final : public wxApp {
|
||||
// A wrapper of the above that does not throw
|
||||
bool SafeMRUOpen(const wxString &fileName);
|
||||
|
||||
#if defined(__WXMAC__)
|
||||
void OnWindow(wxCommandEvent &event);
|
||||
#endif
|
||||
|
||||
void OnReceiveCommand(AppCommandEvent &event);
|
||||
|
||||
void OnKeyDown(wxKeyEvent &event);
|
||||
|
@ -15,11 +15,14 @@
|
||||
#include "KeyboardCapture.h"
|
||||
#include "ondemand/ODTaskThread.h"
|
||||
|
||||
#if defined(__WXMAC__)
|
||||
#include "menus/WindowMenus.h"
|
||||
#endif
|
||||
|
||||
#include <wx/display.h>
|
||||
#include <wx/frame.h>
|
||||
|
||||
wxDEFINE_EVENT(EVT_TRACK_PANEL_TIMER, wxCommandEvent);
|
||||
wxDEFINE_EVENT(EVT_PROJECT_ACTIVATION, wxCommandEvent);
|
||||
|
||||
size_t AllProjects::size() const
|
||||
{
|
||||
@ -112,9 +115,13 @@ void SetActiveProject(AudacityProject * project)
|
||||
if ( gActiveProject != project ) {
|
||||
gActiveProject = project;
|
||||
KeyboardCapture::Capture( nullptr );
|
||||
wxTheApp->QueueEvent( safenew wxCommandEvent{ EVT_PROJECT_ACTIVATION } );
|
||||
}
|
||||
wxTheApp->SetTopWindow( FindProjectFrame( project ) );
|
||||
|
||||
#if defined(__WXMAC__)
|
||||
// Refresh the Window menu
|
||||
WindowActions::Refresh();
|
||||
#endif
|
||||
}
|
||||
|
||||
AudacityProject::AudacityProject()
|
||||
|
@ -93,11 +93,6 @@ using AttachedWindows = ClientData::Site<
|
||||
wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API,
|
||||
EVT_TRACK_PANEL_TIMER, wxCommandEvent);
|
||||
|
||||
// This event is emitted by the application object when there is a change
|
||||
// in the activated project
|
||||
wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API,
|
||||
EVT_PROJECT_ACTIVATION, wxCommandEvent);
|
||||
|
||||
///\brief The top-level handle to an Audacity project. It serves as a source
|
||||
/// of events that other objects can bind to, and a container of associated
|
||||
/// sub-objects that it treats opaquely. It stores a filename and a status
|
||||
|
@ -24,7 +24,9 @@ Paul Licameli split from AudacityProject.cpp
|
||||
#include "widgets/AudacityMessageBox.h"
|
||||
#include "widgets/NumericTextCtrl.h"
|
||||
|
||||
wxDEFINE_EVENT(EVT_PROJECT_TITLE_CHANGE, wxCommandEvent);
|
||||
#if defined(__WXMAC__)
|
||||
#include "menus/WindowMenus.h"
|
||||
#endif
|
||||
|
||||
static void RefreshAllTitles(bool bShowProjectNumbers )
|
||||
{
|
||||
@ -132,13 +134,13 @@ void ProjectFileIO::SetProjectTitle( int number)
|
||||
name += _("(Recovered)");
|
||||
}
|
||||
|
||||
if ( name != window.GetTitle() ) {
|
||||
window.SetTitle( name );
|
||||
window.SetName(name); // to make the nvda screen reader read the correct title
|
||||
window.SetTitle( name );
|
||||
window.SetName(name); // to make the nvda screen reader read the correct title
|
||||
|
||||
project.QueueEvent(
|
||||
safenew wxCommandEvent{ EVT_PROJECT_TITLE_CHANGE } );
|
||||
}
|
||||
#if defined(__WXMAC__)
|
||||
// Refresh the Window menu
|
||||
WindowActions::Refresh();
|
||||
#endif
|
||||
}
|
||||
|
||||
// Most of this string was duplicated 3 places. Made the warning consistent in this global.
|
||||
|
@ -96,9 +96,4 @@ public:
|
||||
size_t UnnamedCount;
|
||||
};
|
||||
|
||||
// This event is emitted by the project when there is a change
|
||||
// in its title
|
||||
wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API,
|
||||
EVT_PROJECT_TITLE_CHANGE, wxCommandEvent);
|
||||
|
||||
#endif
|
||||
|
@ -7,14 +7,16 @@
|
||||
|
||||
#ifdef __WXMAC__
|
||||
|
||||
#include "WindowMenus.h"
|
||||
|
||||
#include "../CommonCommandFlags.h"
|
||||
#include "../Menus.h"
|
||||
#include "../Project.h"
|
||||
#include "../ProjectFileIO.h"
|
||||
#include "../commands/CommandContext.h"
|
||||
|
||||
#include <wx/frame.h>
|
||||
#include <wx/menu.h>
|
||||
#include <wx/menuitem.h>
|
||||
|
||||
#undef USE_COCOA
|
||||
|
||||
@ -53,69 +55,74 @@ void DoMacMinimize(AudacityProject *project)
|
||||
}
|
||||
}
|
||||
|
||||
std::vector< wxWindowID > sReservedIds;
|
||||
std::vector< std::weak_ptr< AudacityProject > > sProjects;
|
||||
|
||||
void RebuildMenu(wxCommandEvent &evt)
|
||||
{
|
||||
// Let other listeners hear it too
|
||||
evt.Skip();
|
||||
|
||||
// This is a big hammer.
|
||||
// Really we just need to recreate just the Window menu.
|
||||
// This causes the checkmark to be put in the right place for the
|
||||
// currently active project
|
||||
MenuCreator::RebuildAllMenuBars();
|
||||
}
|
||||
|
||||
wxWindowID ReservedID(
|
||||
size_t index, const std::shared_ptr< AudacityProject > &pProject )
|
||||
{
|
||||
if ( sReservedIds.empty() ) {
|
||||
// Do this once only per session, and don't worry about unbinding
|
||||
wxTheApp->Bind( EVT_PROJECT_ACTIVATION, RebuildMenu );
|
||||
wxTheApp->Bind( EVT_PROJECT_TITLE_CHANGE, RebuildMenu );
|
||||
}
|
||||
|
||||
while ( sReservedIds.size() <= index )
|
||||
sReservedIds.emplace_back( wxIdManager::ReserveId() );
|
||||
|
||||
if ( sProjects.size() < sReservedIds.size() )
|
||||
sProjects.resize( sReservedIds.size() );
|
||||
sProjects[ index ] = pProject;
|
||||
|
||||
return sReservedIds[ index ];
|
||||
}
|
||||
|
||||
void OnWindow( wxCommandEvent &evt )
|
||||
{
|
||||
const auto begin = sReservedIds.begin(), end = sReservedIds.end(),
|
||||
iter = std::find( begin, end, evt.GetId() );
|
||||
size_t index = iter - begin;
|
||||
if ( index < sProjects.size() ) {
|
||||
auto pProject = sProjects[ index ].lock();
|
||||
if ( pProject ) {
|
||||
// Make it the active project
|
||||
SetActiveProject(pProject.get());
|
||||
|
||||
// And ensure it's visible
|
||||
wxFrame *frame = pProject->GetFrame();
|
||||
if (frame->IsIconized())
|
||||
{
|
||||
frame->Restore();
|
||||
}
|
||||
frame->Raise();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
/// Namespace for functions for window management (mac only?)
|
||||
namespace WindowActions {
|
||||
|
||||
// exported helper functions
|
||||
// none
|
||||
|
||||
// Refreshes the Window menu in all projects
|
||||
void Refresh()
|
||||
{
|
||||
// Must do it in all projects
|
||||
for (auto thisProject : AllProjects{})
|
||||
{
|
||||
// Need the projects frame, but this should always be successful
|
||||
wxFrame *frame = thisProject->GetFrame();
|
||||
wxASSERT(frame != NULL);
|
||||
if (!frame)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// This can happen if we are called before the menubar is set in the frame
|
||||
wxMenuBar *bar = frame->GetMenuBar();
|
||||
if (!bar)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Should always find the Window menu
|
||||
int pos = bar->FindMenu(wxT("Window"));
|
||||
wxASSERT(pos != wxNOT_FOUND);
|
||||
if (pos == wxNOT_FOUND)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// We can not get the menu proper
|
||||
wxMenu *menu = bar->GetMenu(pos);
|
||||
|
||||
// Remove all existing window items
|
||||
for (auto item : menu->GetMenuItems())
|
||||
{
|
||||
if (item->GetId() >= WindowActions::ID_BASE)
|
||||
{
|
||||
menu->Destroy(item);
|
||||
}
|
||||
}
|
||||
|
||||
// Add all projects to this project's Window menu
|
||||
for (auto project : AllProjects{})
|
||||
{
|
||||
int itemId = WindowActions::ID_BASE + project->GetProjectNumber();
|
||||
wxString itemName = project->GetFrame()->GetTitle();
|
||||
bool isActive = (GetActiveProject() == project.get());
|
||||
|
||||
// This should never really happen, but a menu item must have a name
|
||||
if (itemName.empty())
|
||||
{
|
||||
itemName = _("<untitled>");
|
||||
}
|
||||
|
||||
// Add it to the menu and check it if it's the active project
|
||||
wxMenuItem *item = menu->Append(itemId, itemName);
|
||||
item->SetCheckable(true);
|
||||
item->Check(isActive);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Menu handler functions
|
||||
|
||||
@ -180,9 +187,9 @@ namespace {
|
||||
using namespace MenuTable;
|
||||
BaseItemSharedPtr WindowMenu()
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// poor imitation of the Mac Windows Menu
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// poor imitation of the Mac Windows Menu
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
static BaseItemSharedPtr menu{
|
||||
( FinderScope{ findCommandHandler },
|
||||
Menu( wxT("Window"), XO("&Window"),
|
||||
@ -208,34 +215,10 @@ BaseItemSharedPtr WindowMenu()
|
||||
Special( wxT("PopulateWindowsStep"),
|
||||
[](AudacityProject &, wxMenu &theMenu)
|
||||
{
|
||||
// Undo previous bindings
|
||||
for ( auto id : sReservedIds )
|
||||
wxTheApp->Unbind( wxEVT_MENU, OnWindow, id );
|
||||
|
||||
// Add all projects to this project's Window menu
|
||||
size_t ii = 0;
|
||||
for (auto project : AllProjects{})
|
||||
{
|
||||
int itemId = ReservedID( ii++, project );
|
||||
wxString itemName = project->GetFrame()->GetTitle();
|
||||
bool isActive = (GetActiveProject() == project.get());
|
||||
|
||||
// This should never really happen, but a menu item must have a name
|
||||
if (itemName.empty())
|
||||
{
|
||||
itemName = _("<untitled>");
|
||||
}
|
||||
|
||||
// Add it to the menu and check it if it's the active project
|
||||
wxMenuItem *item = theMenu.Append(itemId, itemName);
|
||||
item->SetCheckable(true);
|
||||
item->Check(isActive);
|
||||
|
||||
// Bind the callback
|
||||
wxTheApp->Bind( wxEVT_MENU, OnWindow, itemId );
|
||||
}
|
||||
// Should something be done here???
|
||||
} )
|
||||
)
|
||||
|
||||
) ) };
|
||||
return menu;
|
||||
}
|
||||
|
22
src/menus/WindowMenus.h
Normal file
22
src/menus/WindowMenus.h
Normal file
@ -0,0 +1,22 @@
|
||||
#include "../Audacity.h"
|
||||
|
||||
#include "../commands/CommandManager.h"
|
||||
|
||||
#ifdef __WXMAC__
|
||||
|
||||
/// Namespace for functions for window management (mac only?)
|
||||
namespace WindowActions {
|
||||
|
||||
// Range of assigned menu IDs
|
||||
static const wxWindowID ID_BASE = 30000;
|
||||
static const wxWindowID ID_LAST = 30999;
|
||||
|
||||
// Exported helper functions
|
||||
void Refresh();
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
// Not WXMAC.
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user