Support: JSON, Lispy or Other formats

This commit is contained in:
James Crook 2018-02-08 16:22:01 +00:00 committed by Paul Licameli
parent c0c5cc6337
commit ca5dac59ff
12 changed files with 573 additions and 246 deletions

View File

@ -1614,8 +1614,8 @@ void AudacityProject::CreateMenusAndCommands()
AudioIONotBusyFlag, AudioIONotBusyFlag);
c->AddItem(wxT("GetInfo"), _("Get Info..."), FN(OnAudacityCommand),
AudioIONotBusyFlag, AudioIONotBusyFlag);
c->AddItem(wxT("GetTrackInfo"), _("Get Track Info..."), FN(OnAudacityCommand),
AudioIONotBusyFlag, AudioIONotBusyFlag);
// c->AddItem(wxT("GetTrackInfo"), _("Get Track Info..."), FN(OnAudacityCommand),
// AudioIONotBusyFlag, AudioIONotBusyFlag);
c->EndSubMenu();

View File

@ -332,8 +332,23 @@ bool ShuttleParams::ExchangeWithMaster(const wxString & WXUNUSED(Name))
return true;
}
#pragma warning( push )
#pragma warning( disable: 4100 ) // unused parameters.
// These are functions to override. They do nothing.
void ShuttleParams::Define( bool & var, const wxChar * key, const bool vdefault, const bool vmin, const bool vmax, const bool vscl){;};
void ShuttleParams::Define( size_t & var, const wxChar * key, const int vdefault, const int vmin, const int vmax, const int vscl ){;};
void ShuttleParams::Define( int & var, const wxChar * key, const int vdefault, const int vmin, const int vmax, const int vscl ){;};
void ShuttleParams::Define( float & var, const wxChar * key, const float vdefault, const float vmin, const float vmax, const float vscl ){;};
void ShuttleParams::Define( double & var, const wxChar * key, const float vdefault, const float vmin, const float vmax, const float vscl ){;};
void ShuttleParams::Define( double & var, const wxChar * key, const double vdefault, const double vmin, const double vmax, const double vscl ){;};
void ShuttleParams::Define( wxString &var, const wxChar * key, const wxString vdefault, const wxString vmin, const wxString vmax, const wxString vscl ){;};
void ShuttleParams::DefineEnum( wxString &var, const wxChar * key, const wxString vdefault, wxArrayString strings ){;};
void ShuttleParams::DefineEnum( int &var, const wxChar * key, const int vdefault, wxArrayString strings ){;};
/*
void ShuttleParams::DefineEnum( int &var, const wxChar * key, const int vdefault, wxArrayString strings )
{
@ -483,68 +498,103 @@ void ShuttleSetAutomation::DefineEnum( int &var, const wxChar * key, const int v
var = temp;
}
ShuttleGetDefinition::ShuttleGetDefinition( CommandMessageTarget & target ) : CommandMessageTargetDecorator( target )
{
}
// JSON definitions.
// All these MUST end with ",\r\n", so that we can put them in an array (and so we can remove the last "," easily for JSON).
void ShuttleGetDefinition::Define( bool & var, const wxChar * key, const bool vdefault, const bool vmin, const bool vmax, const bool vscl )
{
Result += wxString::Format( " { key: \"%s\", type: \"bool\", default: \"%s\"},\r\n",
key , vdefault ? "True" : "False" );
StartStruct();
AddItem( wxString(key), "key" );
AddItem( "bool", "type" );
AddItem( vdefault ? "True" : "False", "default" );
EndStruct();
}
void ShuttleGetDefinition::Define( int & var, const wxChar * key, const int vdefault, const int vmin, const int vmax, const int vscl )
{
Result += wxString::Format( " { key: \"%s\", type: \"int\", default: \"%i\"},\r\n",
key , vdefault );
StartStruct();
AddItem( wxString(key), "key" );
AddItem( "int", "type" );
AddItem( (double)vdefault, "default" );
EndStruct();
}
void ShuttleGetDefinition::Define( size_t & var, const wxChar * key, const int vdefault, const int vmin, const int vmax, const int vscl )
{
Result += wxString::Format( " { key: \"%s\", type: \"size_t\", default: \"%li\"},\r\n",
key , vdefault );
StartStruct();
AddItem( wxString(key), "key" );
AddItem( "size_t", "type" );
AddItem( (double)vdefault, "default" );
EndStruct();
}
void ShuttleGetDefinition::Define( float & var, const wxChar * key, const float vdefault, const float vmin, const float vmax, const float vscl )
{
Result += wxString::Format( " { key: \"%s\", type: \"float\", default: \"%f\"},\r\n",
key , vdefault );
StartStruct();
AddItem( wxString(key), "key" );
AddItem( "float", "type" );
AddItem( (double)vdefault, "default" );
EndStruct();
}
void ShuttleGetDefinition::Define( double & var, const wxChar * key, const float vdefault, const float vmin, const float vmax, const float vscl )
{
Result += wxString::Format( " { key: \"%s\", type: \"float\", default: \"%f\"},\r\n",
key , vdefault );
StartStruct();
AddItem( wxString(key), "key" );
AddItem( "float", "type" );
AddItem( (double)vdefault, "default" );
EndStruct();
}
void ShuttleGetDefinition::Define( double & var, const wxChar * key, const double vdefault, const double vmin, const double vmax, const double vscl )
{
Result += wxString::Format( " { key: \"%s\", type: \"double\", default: \"%f\"},\r\n",
key , vdefault );
StartStruct();
AddItem( wxString(key), "key" );
AddItem( "double", "type" );
AddItem( (double)vdefault, "default" );
EndStruct();
}
void ShuttleGetDefinition::Define( wxString &var, const wxChar * key, const wxString vdefault, const wxString vmin, const wxString vmax, const wxString vscl )
{
Result += wxString::Format( " { key: \"%s\", type: \"string\", default: \"%s\"},\r\n",
key , vdefault );
StartStruct();
AddItem( wxString(key), "key" );
AddItem( "string", "type" );
AddItem( vdefault, "default" );
EndStruct();
}
void ShuttleGetDefinition::DefineEnum( wxString &var, const wxChar * key, const wxString vdefault, wxArrayString strings )
{
Result += wxString::Format( " { key: \"%s\", type: \"enum\", default: \"%s\",\r\n enum : [",
key , vdefault );
StartStruct();
AddItem( wxString(key), "key" );
AddItem( "enum", "type" );
AddItem( vdefault, "default" );
AddField( "enum" );
StartArray();
for( size_t i=0;i<strings.Count(); i++ )
Result += wxString::Format("%s\"%s\"", (i>0) ? ", ":"", strings[i] );
Result += "]\r\n },\r\n";
AddItem( strings[i] );
EndArray();
EndStruct();
}
void ShuttleGetDefinition::DefineEnum( int&var, const wxChar * key, const int vdefault, wxArrayString strings )
{
Result += wxString::Format( " { key: \"%s\", type: \"enum\", default: \"%i\",\r\n enum : [",
key , vdefault );
StartStruct();
AddItem( wxString(key), "key" );
AddItem( "enum", "type" );
AddItem( (double)vdefault, "default" );
AddField( "enum" );
StartArray();
for( size_t i=0;i<strings.Count(); i++ )
Result += wxString::Format("%s\"%s\"", (i>0) ? ", ":"",strings[i] );
Result += "]\r\n },\r\n";
AddItem( strings[i] );
EndArray();
EndStruct();
}
#pragma warning( pop )

View File

@ -11,7 +11,7 @@
#ifndef __AUDACITY_SHUTTLE__
#define __AUDACITY_SHUTTLE__
#include "commands/CommandTargets.h"
class Enums {
public:
@ -61,7 +61,7 @@ public:
class CommandAutomationParameters;
/**************************************************************************//**
\brief Shuttle that deals with parameters. This is a base class with lots of
pure virtual functions.
virtual functions that do nothing by default.
********************************************************************************/
class ShuttleParams : public Shuttle
{
@ -72,15 +72,15 @@ public:
virtual ~ShuttleParams() {}
bool ExchangeWithMaster(const wxString & Name) override;
ShuttleParams & Optional( bool & var ){ var = true;return *this;};
virtual void Define( bool & var, const wxChar * key, const bool vdefault, const bool vmin=false, const bool vmax=false, const bool vscl=false )=0;
virtual void Define( size_t & var, const wxChar * key, const int vdefault, const int vmin=0, const int vmax=100000, const int vscl=1 )=0;
virtual void Define( int & var, const wxChar * key, const int vdefault, const int vmin=0, const int vmax=100000, const int vscl=1 )=0;
virtual void Define( float & var, const wxChar * key, const float vdefault, const float vmin, const float vmax, const float vscl=1.0f )=0;
virtual void Define( double & var, const wxChar * key, const float vdefault, const float vmin, const float vmax, const float vscl=1.0f )=0;
virtual void Define( double & var, const wxChar * key, const double vdefault, const double vmin, const double vmax, const double vscl=1.0f )=0;
virtual void Define( wxString &var, const wxChar * key, const wxString vdefault, const wxString vmin="", const wxString vmax="", const wxString vscl="" )=0;
virtual void DefineEnum( wxString &var, const wxChar * key, const wxString vdefault, wxArrayString strings )=0;
virtual void DefineEnum( int &var, const wxChar * key, const int vdefault, wxArrayString strings )=0;
virtual void Define( bool & var, const wxChar * key, const bool vdefault, const bool vmin=false, const bool vmax=false, const bool vscl=false );
virtual void Define( size_t & var, const wxChar * key, const int vdefault, const int vmin=0, const int vmax=100000, const int vscl=1 );
virtual void Define( int & var, const wxChar * key, const int vdefault, const int vmin=0, const int vmax=100000, const int vscl=1 );
virtual void Define( float & var, const wxChar * key, const float vdefault, const float vmin, const float vmax, const float vscl=1.0f );
virtual void Define( double & var, const wxChar * key, const float vdefault, const float vmin, const float vmax, const float vscl=1.0f );
virtual void Define( double & var, const wxChar * key, const double vdefault, const double vmin, const double vmax, const double vscl=1.0f );
virtual void Define( wxString &var, const wxChar * key, const wxString vdefault, const wxString vmin="", const wxString vmax="", const wxString vscl="" );
virtual void DefineEnum( wxString &var, const wxChar * key, const wxString vdefault, wxArrayString strings );
virtual void DefineEnum( int &var, const wxChar * key, const int vdefault, wxArrayString strings );
};
/**************************************************************************//**
@ -125,9 +125,10 @@ public:
/**************************************************************************//**
\brief Shuttle that retrieves a JSON format definition of a command's parameters.
********************************************************************************/
class ShuttleGetDefinition : public ShuttleParams
class ShuttleGetDefinition : public ShuttleParams, public CommandMessageTargetDecorator
{
public:
ShuttleGetDefinition( CommandMessageTarget & target );
wxString Result;
void Define( bool & var, const wxChar * key, const bool vdefault, const bool vmin, const bool vmax, const bool vscl ) override;
void Define( int & var, const wxChar * key, const int vdefault, const int vmin, const int vmax, const int vscl ) override;

View File

@ -64,6 +64,169 @@ void CommandMessageTarget::AddItem(const double value, const wxString &name){
mCounts.Last() += 1;
}
void CommandMessageTarget::AddField(const wxString &name){
Update( wxString::Format( "%s%s%s", (mCounts.Last()>0)?", ":"", name, !name.IsEmpty()?":":""));
mCounts.Last() = 0; // Lie so that we don't get a comma.
}
void CommandMessageTarget::Flush(){
}
void LispyCommandMessageTarget::StartArray()
{
wxString Padding;
Padding.Pad( mCounts.GetCount() *2 -2);
Update( wxString::Format( "%s%s( ", ( mCounts.Last() > 0 ) ? ",\n" : "\n", Padding ));
mCounts.Last() += 1;
mCounts.push_back( 0 );
}
void LispyCommandMessageTarget::EndArray(){
if( mCounts.GetCount() > 1 ){
mCounts.pop_back();
}
Update( " )" );
}
void LispyCommandMessageTarget::StartStruct(){
wxString Padding;
Padding.Pad( mCounts.GetCount() *2 -2);
Update( wxString::Format( "%s%s( ", ( mCounts.Last() > 0 ) ? ",\n" : "\n", Padding ));
mCounts.Last() += 1;
mCounts.push_back( 0 );
}
void LispyCommandMessageTarget::EndStruct(){
if( mCounts.GetCount() > 1 ){
mCounts.pop_back();
}
Update( " )" );
}
void LispyCommandMessageTarget::AddItem(const wxString &value, const wxString &name){
Update( wxString::Format( "%s%s%s\"%s\"", (mCounts.Last()>0)?", ":"", name, !name.IsEmpty()?",":"",value));
mCounts.Last() += 1;
}
void LispyCommandMessageTarget::AddItem(const bool value, const wxString &name){
Update( wxString::Format( "%s%s%s%s", (mCounts.Last()>0)?", ":"", name, !name.IsEmpty()?",":"",value?"True":"False"));
mCounts.Last() += 1;
}
void LispyCommandMessageTarget::AddItem(const double value, const wxString &name){
Update( wxString::Format( "%s%s%s%g", (mCounts.Last()>0)?", ":"", name, !name.IsEmpty()?",":"",value));
mCounts.Last() += 1;
}
void LispyCommandMessageTarget::AddField(const wxString &name){
Update( wxString::Format( "%s%s%s", (mCounts.Last()>0)?", ":"", name, !name.IsEmpty()?",":""));
mCounts.Last() = 0; // Lie so that we don't get a comma.
}
void DeformattedCommandMessageTarget::StartArray()
{
wxString Padding;
Padding.Pad( mCounts.GetCount() *2 -2);
if( mCounts.GetCount() <= 3 )
Update( wxString::Format( "%s%s ", ( mCounts.Last() > 0 ) ? " \n" : "", Padding ));
mCounts.Last() += 1;
mCounts.push_back( 0 );
}
void DeformattedCommandMessageTarget::EndArray(){
if( mCounts.GetCount() > 1 ){
mCounts.pop_back();
}
if( mCounts.GetCount() <= 3 )
Update( " " );
}
void DeformattedCommandMessageTarget::StartStruct(){
wxString Padding;
Padding.Pad( mCounts.GetCount() *2 -2);
if( mCounts.GetCount() <= 3 )
Update( wxString::Format( "%s%s ", ( mCounts.Last() > 0 ) ? " \n" : "", Padding ));
mCounts.Last() += 1;
mCounts.push_back( 0 );
}
void DeformattedCommandMessageTarget::EndStruct(){
if( mCounts.GetCount() > 1 ){
mCounts.pop_back();
}
if( mCounts.GetCount() <= 3 )
Update( " " );
}
void DeformattedCommandMessageTarget::AddItem(const wxString &value, const wxString &name){
if( mCounts.GetCount() <= 3 )
Update( wxString::Format( "%s\"%s\"", (mCounts.Last()>0)?" ":"",value));
mCounts.Last() += 1;
}
void DeformattedCommandMessageTarget::AddItem(const bool value, const wxString &name){
if( mCounts.GetCount() <= 3 )
Update( wxString::Format( "%s%s", (mCounts.Last()>0)?" ":"",value?"True":"False"));
mCounts.Last() += 1;
}
void DeformattedCommandMessageTarget::AddItem(const double value, const wxString &name){
if( mCounts.GetCount() <= 3 )
Update( wxString::Format( "%s%g", (mCounts.Last()>0)?" ":"", value));
mCounts.Last() += 1;
}
void DeformattedCommandMessageTarget::AddField(const wxString &name){
mCounts.Last() = 0; // Lie so that we don't get a comma.
}
LispifiedCommandOutputTarget::LispifiedCommandOutputTarget( CommandOutputTarget & target )
: CommandOutputTarget() ,
pToRestore( &target )
{
mProgressTarget = std::move(target.mProgressTarget),
mStatusTarget = std::make_shared<LispyCommandMessageTarget>( *target.mStatusTarget.get() ),
mErrorTarget = std::move( target.mErrorTarget );
}
LispifiedCommandOutputTarget::~LispifiedCommandOutputTarget()
{
pToRestore->mProgressTarget = std::move( mProgressTarget );
//The status was never captured so does not need restoring.
//pToRestore->mStatusTarget = std::move( mStatusTarget );
pToRestore->mErrorTarget = std::move( mErrorTarget );
}
DeformattedCommandOutputTarget::DeformattedCommandOutputTarget( CommandOutputTarget & target )
: CommandOutputTarget() ,
pToRestore( &target )
{
mProgressTarget = std::move(target.mProgressTarget),
mStatusTarget = std::make_shared<DeformattedCommandMessageTarget>( *target.mStatusTarget.get() ),
mErrorTarget = std::move( target.mErrorTarget );
}
DeformattedCommandOutputTarget::~DeformattedCommandOutputTarget()
{
pToRestore->mProgressTarget = std::move( mProgressTarget );
//The status was never captured so does not need restoring.
//pToRestore->mStatusTarget = std::move( mStatusTarget );
pToRestore->mErrorTarget = std::move( mErrorTarget );
}
/// Dialog for long messages.
class AUDACITY_DLL_API LongMessageDialog /* not final */ : public wxDialogWrapper
@ -82,8 +245,10 @@ public:
virtual void OnCancel(wxCommandEvent & evt);
static void AcceptText( const wxString & Text );
static void Flush();
wxTextCtrl * mText;
wxTextCtrl * mTextCtrl;
wxString mText;
static LongMessageDialog * pDlg;
private:
int mType;
@ -124,7 +289,7 @@ bool LongMessageDialog::Init()
S.SetBorder(5);
S.StartVerticalLay(true);
{
mText = S.AddTextWindow( "" );
mTextCtrl = S.AddTextWindow( "" );
long buttons = eOkButton;
S.AddStandardButtons(buttons|mAdditionalButtons);
}
@ -154,7 +319,16 @@ void LongMessageDialog::AcceptText( const wxString & Text )
pDlg->Init();
pDlg->Show();
}
pDlg->mText->SetValue( pDlg->mText->GetValue( ) + Text );
pDlg->mText = pDlg->mText + Text;
}
void LongMessageDialog::Flush()
{
if( pDlg ){
pDlg->mText += "\n\n";
pDlg->mTextCtrl->SetValue( pDlg->mText );
pDlg->mTextCtrl->ShowPosition( pDlg->mTextCtrl->GetLastPosition() );
}
}
@ -166,11 +340,15 @@ void LongMessageDialog::AcceptText( const wxString & Text )
class MessageDialogTarget final : public CommandMessageTarget
{
public:
virtual ~MessageDialogTarget() {}
virtual ~MessageDialogTarget() {Flush();}
void Update(const wxString &message) override
{
LongMessageDialog::AcceptText(message);
}
void Flush() override
{
LongMessageDialog::Flush();
}
};
@ -183,7 +361,6 @@ public:
{
return std::make_shared<MessageDialogTarget>();
}
};

View File

@ -43,7 +43,7 @@ class CommandMessageTarget /* not final */
{
public:
CommandMessageTarget() {mCounts.push_back(0);}
virtual ~CommandMessageTarget() {}
virtual ~CommandMessageTarget() { Flush();}
virtual void Update(const wxString &message) = 0;
virtual void StartArray();
virtual void EndArray();
@ -52,10 +52,56 @@ public:
virtual void AddItem(const wxString &value , const wxString &name="" );
virtual void AddItem(const bool value , const wxString &name="" );
virtual void AddItem(const double value , const wxString &name="" );
virtual void AddField( const wxString &name="" );
virtual void Flush();
wxArrayInt mCounts;
};
class CommandMessageTargetDecorator : public CommandMessageTarget
{
public:
CommandMessageTargetDecorator( CommandMessageTarget & target): mTarget(target) {};
virtual ~CommandMessageTargetDecorator() { };
virtual void Update(const wxString &message) { mTarget.Update( message );};
virtual void StartArray() { mTarget.StartArray();};
virtual void EndArray(){ mTarget.EndArray();};
virtual void StartStruct(){ mTarget.StartStruct();};
virtual void EndStruct(){ mTarget.EndStruct();};
virtual void AddItem(const wxString &value , const wxString &name="" ){ mTarget.AddItem(value,name);};
virtual void AddItem(const bool value , const wxString &name="" ){ mTarget.AddItem(value,name);};
virtual void AddItem(const double value , const wxString &name="" ){ mTarget.AddItem(value,name);};
virtual void AddField( const wxString &name="" ){ mTarget.AddField(name);};
virtual void Flush(){ mTarget.Flush();};
CommandMessageTarget & mTarget;
};
class LispyCommandMessageTarget : public CommandMessageTargetDecorator /* not final */
{
public:
LispyCommandMessageTarget( CommandMessageTarget & target): CommandMessageTargetDecorator(target) {};
virtual void StartArray() override;
virtual void EndArray() override;
virtual void StartStruct() override;
virtual void EndStruct() override;
virtual void AddItem(const wxString &value , const wxString &name="" )override;
virtual void AddItem(const bool value , const wxString &name="" )override;
virtual void AddItem(const double value , const wxString &name="" )override;
virtual void AddField( const wxString &name="" )override;
};
class DeformattedCommandMessageTarget : public CommandMessageTargetDecorator /* not final */
{
public:
DeformattedCommandMessageTarget( CommandMessageTarget & target): CommandMessageTargetDecorator(target) {};
virtual void StartArray() override;
virtual void EndArray() override;
virtual void StartStruct() override;
virtual void EndStruct() override;
virtual void AddItem(const wxString &value , const wxString &name="" )override;
virtual void AddItem(const bool value , const wxString &name="" )override;
virtual void AddItem(const double value , const wxString &name="" )override;
virtual void AddField( const wxString &name="" )override;
};
/// Used to ignore a command's progress updates
class NullProgressTarget final : public CommandProgressTarget
@ -197,7 +243,7 @@ public:
/// Assumes responsibility for pointers passed into it.
class CommandOutputTarget
{
protected:
public:
std::unique_ptr<CommandProgressTarget> mProgressTarget;
std::shared_ptr<CommandMessageTarget> mStatusTarget;
std::shared_ptr<CommandMessageTarget> mErrorTarget;
@ -261,9 +307,24 @@ public:
if (mStatusTarget)
mStatusTarget->AddItem( value, name );
}
};
class LispifiedCommandOutputTarget : public CommandOutputTarget
{
public :
LispifiedCommandOutputTarget( CommandOutputTarget & target );
~LispifiedCommandOutputTarget();
private:
CommandOutputTarget * pToRestore;
};
class DeformattedCommandOutputTarget : public CommandOutputTarget
{
public :
DeformattedCommandOutputTarget( CommandOutputTarget & target );
~DeformattedCommandOutputTarget();
private:
CommandOutputTarget * pToRestore;
};
class InteractiveOutputTarget : public CommandOutputTarget

View File

@ -24,7 +24,9 @@ This class now handles the GetAll script command, which can
#include "../effects/EffectManager.h"
#include "../widgets/Overlay.h"
#include "../widgets/OverlayPanel.h"
#include "../Track.h"
#include "../TrackPanel.h"
#include "../WaveTrack.h"
#include "CommandContext.h"
#include "SelectCommand.h"
@ -33,12 +35,14 @@ This class now handles the GetAll script command, which can
#include "../ShuttleGui.h"
#include "CommandContext.h"
const int nTypes =5;
const int nTypes =7;
static const wxString kTypes[nTypes] =
{
XO("Commands"),
XO("Menus"),
XO("Tracks"),
XO("Clips"),
XO("Labels"),
XO("Keycodes"),
XO("Boxes")
};
@ -46,7 +50,9 @@ static const wxString kTypes[nTypes] =
enum {
kCommands,
kMenus,
kTracks,
kClips,
kLabels,
kKeycodes,
kBoxes
};
@ -61,8 +67,9 @@ static const wxString kFormats[nFormats] =
};
enum {
kJson =0*nTypes,
kOther =1*nTypes
kJson ,
kLisp,
kOther
};
@ -90,23 +97,201 @@ void GetInfoCommand::PopulateOrExchange(ShuttleGui & S)
bool GetInfoCommand::Apply(const CommandContext &context)
{
switch( mInfoType + nTypes * mFormat ){
case kCommands + kJson : return SendCommandsAsJson( context);
case kCommands + kOther : return SendCommandsAsJson( context);
case kMenus + kJson : return SendMenusAsJson( context);
case kMenus + kOther : return SendMenus( context );
case kClips + kJson : return SendClips( context);
case kClips + kOther : return SendClips( context );
case kKeycodes + kJson : return SendKeycodes( context);
case kKeycodes + kOther : return SendKeycodes( context );
case kBoxes + kJson : return SendBoxesAsJson( context);
case kBoxes + kOther : return SendBoxesAsJson( context );
if( mFormat == kJson )
return ApplyInner( context );
if( mFormat == kLisp )
{
CommandContext LispyContext(
*(context.GetProject()),
std::make_unique<LispifiedCommandOutputTarget>( *context.pOutput.get() )
);
return ApplyInner( LispyContext );
}
if( mFormat == kOther )
{
CommandContext DeformattedContext(
*(context.GetProject()),
std::make_unique<DeformattedCommandOutputTarget>( *context.pOutput.get() )
);
return ApplyInner( DeformattedContext );
}
return false;
}
bool GetInfoCommand::ApplyInner(const CommandContext &context)
{
switch( mInfoType ){
case kCommands : return SendCommands( context );
case kMenus : return SendMenus( context );
case kTracks : return SendTracks( context );
case kClips : return SendClips( context );
case kLabels : return SendLabels( context );
case kKeycodes : return SendKeycodes( context );
case kBoxes : return SendBoxes( context );
default:
context.Status( "Command options not recognised" );
}
return false;
}
bool GetInfoCommand::SendMenus(const CommandContext &context)
{
wxMenuBar * pBar = context.GetProject()->GetMenuBar();
if(!pBar ){
wxLogDebug("No menus");
return false;
}
size_t cnt = pBar->GetMenuCount();
size_t i;
wxString Label;
context.StartArray();
for(i=0;i<cnt;i++)
{
Label = pBar->GetMenuLabelText( i );
context.StartArray();
context.AddItem( 0 );
context.AddItem( 0 );
context.AddItem( Label );
context.AddItem( "" );
context.EndArray();
ExploreMenu( context, pBar->GetMenu( i ), pBar->GetId(), 1 );
}
context.EndArray();
return true;
}
/**
Send the list of commands.
*/
bool GetInfoCommand::SendCommands(const CommandContext &context )
{
context.StartArray();
PluginManager & pm = PluginManager::Get();
EffectManager & em = EffectManager::Get();
{
const PluginDescriptor *plug = pm.GetFirstPlugin(PluginTypeEffect | PluginTypeGeneric);
while (plug)
{
auto command = em.GetCommandIdentifier(plug->GetID());
if (!command.IsEmpty()){
em.GetCommandDefinition( plug->GetID(), context );
}
plug = pm.GetNextPlugin(PluginTypeEffect | PluginTypeGeneric );
}
}
context.EndArray();
return true;
}
#if 0
// Old version which gives enabled/disabled status too.
bool GetInfoCommand::SendMenus(const CommandContext &context)
{
bool bShowStatus = true;
wxArrayString names;
CommandManager *cmdManager = context.GetProject()->GetCommandManager();
cmdManager->GetAllCommandNames(names, false);
wxArrayString::iterator iter;
for (iter = names.begin(); iter != names.end(); ++iter)
{
wxString name = *iter;
wxString out = name;
if (bShowStatus)
{
out += wxT("\t");
out += cmdManager->GetEnabled(name) ? wxT("Enabled") : wxT("Disabled");
}
context.Status(out);
}
return true;
}
#endif
bool GetInfoCommand::SendBoxes(const CommandContext &context)
{
//context.Status("Boxes");
wxWindow * pWin = context.GetProject();
context.StartArray();
wxRect R = pWin->GetScreenRect();
//R.SetPosition( wxPoint(0,0) );
//wxString Name = pWin->GetName();
context.StartArray();
context.AddItem( 0 );
context.AddItem( R.GetLeft() );
context.AddItem( R.GetTop() );
context.AddItem( R.GetRight() );
context.AddItem( R.GetBottom() );
context.AddItem( "Audacity Window" );
context.EndArray( );
ExploreAdornments( context, pWin->GetPosition()+wxSize( 6,-1), pWin, pWin->GetId(), 1 );
ExploreWindows( context, pWin->GetPosition()+wxSize( 6,-1), pWin, pWin->GetId(), 1 );
context.EndArray( );
return true;
}
bool GetInfoCommand::SendTracks(const CommandContext & context)
{
TrackList *projTracks = context.GetProject()->GetTracks();
TrackListIterator iter(projTracks);
Track *trk = iter.First();
context.StartArray();
while (trk)
{
context.StartStruct();
context.AddItem( trk->GetName(), "name" );
auto t = dynamic_cast<WaveTrack*>( trk );
if( t )
{
context.AddItem( t->GetStartTime(), "start" );
context.AddItem( t->GetEndTime(), "end" );
context.AddItem( t->GetPan() , "pan");
context.AddItem( t->GetGain() , "gain");
context.AddBool( t->GetSelected(), "selected" );
context.AddBool( t->GetLinked(), "linked");
context.AddBool( t->GetSolo(), "solo" );
context.AddBool( t->GetMute(), "mute");
}
TrackPanel *panel = context.GetProject()->GetTrackPanel();
Track * fTrack = panel->GetFocusedTrack();
context.AddBool( (trk == fTrack), "focused");
context.EndStruct();
trk=iter.Next();
}
context.EndArray();
return true;
}
bool GetInfoCommand::SendClips(const CommandContext &context)
{
context.Status("Clips - Not yet");
return true;
}
bool GetInfoCommand::SendLabels(const CommandContext &context)
{
context.Status("Labels - Not yet");
return true;
}
bool GetInfoCommand::SendKeycodes(const CommandContext &context)
{
context.Status("Keycodes - Not yet");
return true;
}
/*******************************************************************
The various Explore functions are called from the Send functions,
and may be recursive. 'Send' is the top level.
*******************************************************************/
void GetInfoCommand::ExploreMenu( const CommandContext &context, wxMenu * pMenu, int Id, int depth ){
Id;//compiler food.
if( !pMenu )
@ -134,7 +319,13 @@ void GetInfoCommand::ExploreMenu( const CommandContext &context, wxMenu * pMenu,
if (item->IsCheck() && item->IsChecked())
flags +=2;
context.Status( wxString::Format(" [ %2i, %2i, \"%s\", \"%s\" ],", depth, flags, Label,Accel ));
context.StartArray();
context.AddItem( depth );
context.AddItem( flags );
context.AddItem( Label );
context.AddItem( Accel );
context.EndArray();
if (item->IsSubMenu()) {
pMenu = item->GetSubMenu();
ExploreMenu( context, pMenu, item->GetId(), depth+1 );
@ -142,107 +333,6 @@ void GetInfoCommand::ExploreMenu( const CommandContext &context, wxMenu * pMenu,
}
}
bool GetInfoCommand::SendMenusAsJson(const CommandContext &context)
{
wxMenuBar * pBar = context.GetProject()->GetMenuBar();
if(!pBar ){
wxLogDebug("No menus");
return false;
}
size_t cnt = pBar->GetMenuCount();
size_t i;
wxString Label;
context.Status( "[" );
for(i=0;i<cnt;i++)
{
Label = pBar->GetMenuLabelText( i );
context.Status( wxString::Format(" [ %2i, %2i, \"%s\", \"%s\" ],", 0, 0, Label, "" ));
ExploreMenu( context, pBar->GetMenu( i ), pBar->GetId(), 1 );
}
context.Status( "]" );
return true;
}
/**
Send the list of commands.
*/
bool GetInfoCommand::SendCommandsAsJson(const CommandContext &context )
{
PluginManager & pm = PluginManager::Get();
EffectManager & em = EffectManager::Get();
{
wxString out="";
wxString maybeComma="";
const PluginDescriptor *plug = pm.GetFirstPlugin(PluginTypeEffect | PluginTypeGeneric);
while (plug)
{
auto command = em.GetCommandIdentifier(plug->GetID());
if (!command.IsEmpty()){
// delayed sending of previous string, so we can maybe add a comma.
if( !out.IsEmpty() )
{
context.Status(out+maybeComma);
maybeComma = ",";
}
out = em.GetCommandDefinition( plug->GetID() );
}
plug = pm.GetNextPlugin(PluginTypeEffect | PluginTypeGeneric );
}
if( !out.IsEmpty() )
context.Status(out); // Last one does not have a comma.
}
return true;
}
bool GetInfoCommand::SendMenus(const CommandContext &context)
{
bool bShowStatus = true;
wxArrayString names;
CommandManager *cmdManager = context.GetProject()->GetCommandManager();
cmdManager->GetAllCommandNames(names, false);
wxArrayString::iterator iter;
for (iter = names.begin(); iter != names.end(); ++iter)
{
wxString name = *iter;
wxString out = name;
if (bShowStatus)
{
out += wxT("\t");
out += cmdManager->GetEnabled(name) ? wxT("Enabled") : wxT("Disabled");
}
context.Status(out);
}
return true;
}
bool GetInfoCommand::SendClips(const CommandContext &context)
{
bool bShowStatus = true;
wxArrayString names;
CommandManager *cmdManager = context.GetProject()->GetCommandManager();
cmdManager->GetAllCommandNames(names, false);
wxArrayString::iterator iter;
for (iter = names.begin(); iter != names.end(); ++iter)
{
wxString name = *iter;
wxString out = name;
if (bShowStatus)
{
out += wxT("\t");
out += cmdManager->GetEnabled(name) ? wxT("Enabled") : wxT("Disabled");
}
context.Status(out);
}
return true;
}
bool GetInfoCommand::SendKeycodes(const CommandContext &context)
{
context.Status("Keycodes");
return true;
}
void GetInfoCommand::ExploreAdornments( const CommandContext &context,
wxPoint WXUNUSED(P), wxWindow * pWin, int WXUNUSED(Id), int depth )
{
@ -393,33 +483,3 @@ void GetInfoCommand::ExploreWindows( const CommandContext &context,
}
}
bool GetInfoCommand::SendBoxesAsJson(const CommandContext &context)
{
//context.Status("Boxes");
wxWindow * pWin = context.GetProject();
context.StartArray();
wxRect R = pWin->GetScreenRect();
//R.SetPosition( wxPoint(0,0) );
//wxString Name = pWin->GetName();
context.StartArray();
context.AddItem( 0 );
context.AddItem( R.GetLeft() );
context.AddItem( R.GetTop() );
context.AddItem( R.GetRight() );
context.AddItem( R.GetBottom() );
context.AddItem( "Audacity Window" );
context.EndArray( );
ExploreAdornments( context, pWin->GetPosition()+wxSize( 6,-1), pWin, pWin->GetId(), 1 );
ExploreWindows( context, pWin->GetPosition()+wxSize( 6,-1), pWin, pWin->GetId(), 1 );
context.EndArray( );
return true;
}

View File

@ -40,19 +40,21 @@ public:
// AudacityCommand overrides
wxString ManualPage() override {return wxT("Automation");};
bool Apply(const CommandContext &context) override;
bool ApplyInner(const CommandContext &context);
public:
int mInfoType;
int mFormat;
private:
bool SendCommandsAsJson(const CommandContext & context);
bool SendCommands(const CommandContext & context);
bool SendMenus(const CommandContext & context);
bool SendMenusAsJson(const CommandContext & context);
bool SendTracks(const CommandContext & context);
bool SendLabels(const CommandContext & context);
bool SendClips(const CommandContext & context);
bool SendKeycodes(const CommandContext & context);
bool SendBoxesAsJson(const CommandContext & context);
bool SendBoxes(const CommandContext & context);
void ExploreMenu( const CommandContext &context, wxMenu * pMenu, int Id, int depth );
void ExploreTrackPanel( const CommandContext & context,
wxPoint P, wxWindow * pWin, int Id, int depth );

View File

@ -12,7 +12,7 @@
\brief Definitions for GetTrackInfoCommand and GetTrackInfoCommandType classes
\class GetTrackInfoCommand
\brief Command that returns requested track information
\brief Obsolete. GetInfo now does it.
*//*******************************************************************/
@ -58,38 +58,9 @@ void GetTrackInfoCommand::PopulateOrExchange(ShuttleGui & S)
S.EndMultiColumn();
}
bool GetTrackInfoCommand::Apply(const CommandContext & context)
bool GetTrackInfoCommand::Apply(const CommandContext &context)
{
TrackList *projTracks = context.GetProject()->GetTracks();
TrackListIterator iter(projTracks);
Track *trk = iter.First();
wxString str = "[\n";
while (trk)
{
str += "{\n";
str += wxString::Format(" name:\"%s\",\n", trk->GetName() );
auto t = dynamic_cast<WaveTrack*>( trk );
if( t )
{
str += wxString::Format(" start:%g,\n", t->GetStartTime() );
str += wxString::Format(" end:%g,\n", t->GetEndTime() );
str += wxString::Format(" pan:%g,\n", t->GetPan() );
str += wxString::Format(" gain:%g,\n", t->GetGain() );
str += wxString::Format(" selected:%s,\n", t->GetSelected()?"True":"False" );
str += wxString::Format(" linked:%s,\n", t->GetLinked()?"True":"False" );
str += wxString::Format(" solo:%s,\n", t->GetSolo()?"True":"False" );
str += wxString::Format(" mute:%s,\n", t->GetMute()?"True":"False" );
}
TrackPanel *panel = context.GetProject()->GetTrackPanel();
Track * fTrack = panel->GetFocusedTrack();
str += wxString::Format(" focused:%s,\n", (trk == fTrack)?"True":"False" );
str += "},\n";
trk=iter.Next();
}
str += "]";
// Make it true JSON by removing excess commas.
str.Replace(",\n}","\n}");
str.Replace(",\n]","\n]");
context.Status( str );
return true;
return false;
}

View File

@ -43,7 +43,7 @@ bool HelpCommand::Apply(const CommandContext & context){
if( ID.IsEmpty() )
context.Status( "Command not found" );
else
context.Status( em.GetCommandDefinition( ID ));
em.GetCommandDefinition( ID, context);
return true;
}

View File

@ -38,9 +38,8 @@ modelled on BuiltinEffectsModule
//
#define COMMAND_LIST \
COMMAND( DEMO, DemoCommand, () ) \
COMMAND( SCREENSHOT, ScreenshotCommand, () ) \
COMMAND( SCREENSHOT, ScreenshotCommand, () ) \
COMMAND( COMPARE_AUDIO, CompareAudioCommand, () ) \
COMMAND( GET_TRACK_INFO, GetTrackInfoCommand, () ) \
COMMAND( SET_TRACK_INFO, SetTrackInfoCommand, () ) \
COMMAND( SELECT, SelectCommand, () ) \
COMMAND( SELECT_TIME, SelectTimeCommand, () ) \
@ -54,6 +53,8 @@ modelled on BuiltinEffectsModule
COMMAND( OPEN_PROJECT, OpenProjectCommand, () ) \
COMMAND( SAVE_PROJECT, SaveProjectCommand, () ) \
// GET_TRACK_INFO subsumed by GET_INFO
//COMMAND( GET_TRACK_INFO, GetTrackInfoCommand, () )
//

View File

@ -198,27 +198,30 @@ wxString EffectManager::GetCommandDescription(const PluginID & ID)
return wxEmptyString;
}
wxString EffectManager::GetCommandDefinition(const PluginID & ID)
void EffectManager::GetCommandDefinition(const PluginID & ID, const CommandContext & context)
{
CommandDefinitionInterface *command;
command = GetEffect(ID);
if( !command )
command = GetAudacityCommand( ID );
if( !command )
return wxEmptyString;
return;
ShuttleGetDefinition S;
if( command->DefineParams( S ) )
{
wxString Temp;
Temp += "{ id: \"" + GetCommandIdentifier( ID ) + "\", name: \"" + GetCommandName( ID ) + "\", params: [\r\n";
Temp += S.Result;
Temp += "]}";
Temp.Replace( ",\r\n]","\r\n]"); // fix up for trailing comma. Relies on \r\n endings from ShuttleGetDefinition
return Temp;
}
ShuttleParams NullShuttle;
// Test if it defines any parameters at all.
if( !command->DefineParams( NullShuttle ) )
return;
return wxEmptyString;
// This is capturing the output context into the shuttle.
ShuttleGetDefinition S( *context.pOutput.get()->mStatusTarget.get() );
S.StartStruct();
S.AddItem( GetCommandIdentifier( ID ), "id" );
S.AddItem( GetCommandName( ID ), "name" );
S.AddField( "params" );
S.StartArray();
command->DefineParams( S );
S.EndArray();
S.EndStruct();
}

View File

@ -31,6 +31,7 @@
class AudacityCommand;
class CommandContext;
class CommandMessageTarget;
using EffectArray = std::vector <Effect*> ;
using EffectMap = std::unordered_map<wxString, Effect *>;
@ -92,7 +93,7 @@ public:
wxString GetCommandName(const PluginID & ID);
wxString GetCommandIdentifier(const PluginID & ID);
wxString GetCommandDescription(const PluginID & ID);
wxString GetCommandDefinition(const PluginID & ID);
void GetCommandDefinition(const PluginID & ID, const CommandContext & context);
bool IsHidden(const PluginID & ID);
/** Support for batch commands */