1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-04-30 15:49:41 +02:00
Paul Licameli 70ec69fa3d Pass untranslated command labels to CommandManager...
... and deduce whether to exclude from macros inside NewIdentifier, simplifying
argument lists further

Also fix the localization of "..." added to names by PluginMenus.cpp
2019-12-12 15:15:59 -05:00

1787 lines
48 KiB
C++
Executable File

/**********************************************************************
NyqBench.cpp
Leland Lucius
**********************************************************************/
#include "Audacity.h"
#include <wx/defs.h>
#include <wx/aboutdlg.h>
#include <wx/filedlg.h>
#include <wx/font.h>
#include <wx/fontdlg.h>
#include <wx/menu.h>
#include <wx/msgdlg.h>
#include <wx/settings.h>
#include <wx/sizer.h>
#include <wx/splitter.h>
#include <wx/statbox.h>
#include <wx/textctrl.h>
#include <wx/toolbar.h>
#include "AudioIOBase.h"
#include "CommonCommandFlags.h"
#include "LabelTrack.h"
#include "ModuleManager.h"
#include "Prefs.h"
#include "Project.h"
#include "ShuttleGui.h"
#include "effects/EffectManager.h"
#include "effects/nyquist/Nyquist.h"
#include "../images/AudacityLogo.xpm"
#include "../../src/commands/CommandContext.h"
#include "widgets/AudacityMessageBox.h"
#include "NyqBench.h"
#include <iostream>
#include <ostream>
#include <sstream>
//
// Images are from the Tango Icon Gallery
// http://tango.freedesktop.org/Tango_Icon_Gallery
//
#include "images/document-new-small.xpm"
#include "images/document-open-small.xpm"
#include "images/document-save-as-small.xpm"
#include "images/document-save-small.xpm"
#include "images/edit-clear-small.xpm"
#include "images/edit-copy-small.xpm"
#include "images/edit-cut-small.xpm"
#include "images/edit-delete-small.xpm"
#include "images/edit-find-small.xpm"
#include "images/edit-paste-small.xpm"
#include "images/edit-redo-small.xpm"
#include "images/edit-select-all-small.xpm"
#include "images/edit-undo-small.xpm"
#include "images/go-top-small.xpm"
#include "images/go-up-small.xpm"
#include "images/go-previous-small.xpm"
#include "images/go-next-small.xpm"
#include "images/system-search-small.xpm"
#include "images/media-playback-start-small.xpm"
#include "images/media-playback-stop-small.xpm"
#include "images/document-new-large.xpm"
#include "images/document-open-large.xpm"
#include "images/document-save-as-large.xpm"
#include "images/document-save-large.xpm"
#include "images/edit-clear-large.xpm"
#include "images/edit-copy-large.xpm"
#include "images/edit-cut-large.xpm"
#include "images/edit-delete-large.xpm"
#include "images/edit-find-large.xpm"
#include "images/edit-paste-large.xpm"
#include "images/edit-redo-large.xpm"
#include "images/edit-select-all-large.xpm"
#include "images/edit-undo-large.xpm"
#include "images/go-top-large.xpm"
#include "images/go-up-large.xpm"
#include "images/go-previous-large.xpm"
#include "images/go-next-large.xpm"
#include "images/system-search-large.xpm"
#include "images/media-playback-start-large.xpm"
#include "images/media-playback-stop-large.xpm"
#if defined(__WXMSW__)
#include <wx/init.h>
# if defined(__WXDEBUG__)
# define D "d"
# else
# define D ""
# endif
# if wxCHECK_VERSION(3, 1, 0)
# define V "31"
# elif wxCHECK_VERSION(3, 0, 0)
# define V "30"
# else
# define V "28"
# endif
# pragma comment(lib, "wxbase" V "u" D)
# pragma comment(lib, "wxbase" V "u" D "_net")
# pragma comment(lib, "wxmsw" V "u" D "_adv")
# pragma comment(lib, "wxmsw" V "u" D "_core")
# pragma comment(lib, "wxmsw" V "u" D "_html")
# pragma comment(lib, "wxpng" D)
# pragma comment(lib, "wxzlib" D)
# pragma comment(lib, "wxjpeg" D)
# pragma comment(lib, "wxtiff" D)
# undef V
# undef D
#endif //(__WXMSW__)
/*
There are several functions that can be used in a GUI module.
//#define versionFnName "GetVersionString"
If the version is wrong, the module will be rejected.
That is it will be loaded and then unloaded.
//#define ModuleDispatchName "ModuleDispatch"
The most useful function. See the example in this
file. It has several cases/options in it.
//#define scriptFnName "RegScriptServerFunc"
This function is run from a non gui thread. It was originally
created for the benefit of mod-script-pipe.
//#define mainPanelFnName "MainPanelFunc"
This function is the hijacking function, to take over Audacity
and replace the main project window with our own wxFrame.
*/
extern "C"
{
static NyqBench *gBench = NULL;
static CommandHandlerObject &findme(AudacityProject&)
{
return *NyqBench::GetBench();
}
#ifdef _MSC_VER
#define DLL_API _declspec(dllexport)
#else
#define DLL_API __attribute__ ((visibility("default")))
#endif
extern DLL_API const wxChar * GetVersionString();
// GetVersionString
// REQUIRED for the module to be accepted by Audacity.
// Without it Audacity will see a version number mismatch.
const wxChar * GetVersionString()
{
// For now, the versions must match exactly for Audacity to
// agree to load the module.
return AUDACITY_VERSION_STRING;
}
extern int DLL_API ModuleDispatch(ModuleDispatchTypes type);
// ModuleDispatch
// is called by Audacity to initialize/terminmate the module,
// and ask if it has anything for the menus.
int ModuleDispatch(ModuleDispatchTypes type){
switch (type){
case AppQuiting: {
//It is perfectly OK for gBench to be NULL.
//Can happen if the menu item was never invoked.
//wxASSERT(gBench != NULL);
if (gBench) {
gBench->Destroy();
gBench = NULL;
}
}
break;
case ProjectInitialized:
case MenusRebuilt: {
AudacityProject *p = GetActiveProject();
wxASSERT(p != NULL);
CommandManager *c = &CommandManager::Get( *p );
wxASSERT(c != NULL);
wxMenuBar * pBar = GetProjectFrame( *p ).GetMenuBar();
wxASSERT(pBar != NULL );
wxMenu * pMenu = pBar->GetMenu( 9 ); // Menu 9 is the Tools Menu.
wxASSERT( pMenu != NULL );
c->SetCurrentMenu(pMenu);
c->AddSeparator();
c->AddItem(wxT("NyqBench"),
XO("&Nyquist Workbench..."),
findme,
static_cast<CommandFunctorPointer>(&NyqBench::ShowNyqBench),
AudioIONotBusyFlag);
c->ClearCurrentMenu();
}
break;
default:
break;
}
return 1;
}
};
//----------------------------------------------------------------------------
// NyqTextCtrl
//----------------------------------------------------------------------------
BEGIN_EVENT_TABLE(NyqTextCtrl, wxTextCtrl)
#if defined(__WXMAC__)
EVT_KEY_DOWN(NyqTextCtrl::OnKeyDown)
#endif
EVT_KEY_UP(NyqTextCtrl::OnKeyUp)
EVT_CHAR(NyqTextCtrl::OnChar)
EVT_UPDATE_UI(wxID_ANY, NyqTextCtrl::OnUpdate)
END_EVENT_TABLE()
NyqTextCtrl::NyqTextCtrl(wxWindow *parent,
wxWindowID id,
const wxString &value,
const wxPoint & pos,
const wxSize & size,
int style)
: wxTextCtrl(parent, id, value, pos, size, style)
{
mLastCaretPos = -1;
mLeftParen = -1;
mRightParen = -1;
mOn.SetTextColour(*wxRED);
mOff.SetTextColour(*wxBLACK);
}
void NyqTextCtrl::SetFocusFromKbd()
{
#if defined(__WXMSW__)
// We do this to prevent wxMSW from selecting all text when the
// user tabs into the text controls.
wxWindowBase::SetFocusFromKbd();
#else
wxTextCtrl::SetFocusFromKbd();
#endif
}
void NyqTextCtrl::MarkDirty()
{
wxTextCtrl::MarkDirty();
FindParens();
}
void NyqTextCtrl::OnChar(wxKeyEvent & e)
{
e.Skip();
// Hide any previously highlighted parens
if (mLeftParen >= 0) {
#if defined(__WXMSW__)
Freeze(); // Prevents selection flashing on Windows
#endif
SetStyle(mLeftParen, mLeftParen + 1, mOff);
SetStyle(mLeftParens[mLeftParen], mLeftParens[mLeftParen] + 1, mOff);
mLeftParen = -1;
mRightParen = -1;
#if defined(__WXMSW__)
Thaw(); // Prevents selection flashing on Windows
#endif
}
}
#if defined(__WXMAC__REMOVED_UNTIL_ITS_PROVEN_THAT_IT_IS_STILL_NEEDED)
#include <wx/mac/uma.h>
// This is hackage to correct a problem on Leopard where the
// caret jumps up two lines when the up arrow is pressed and
// the caret is at the beginning of the line.
void NyqTextCtrl::OnKeyDown(wxKeyEvent & e)
{
e.Skip();
if (UMAGetSystemVersion() >= 0x1050) {
if (e.GetKeyCode() == WXK_UP && e.GetModifiers() == 0) {
long x;
long y;
PositionToXY(GetInsertionPoint(), &x, &y);
if (x == 0 && y > 1) {
y--;
SetInsertionPoint(XYToPosition(x, y) - 1);
e.Skip(false);
}
}
}
}
#endif
void NyqTextCtrl::OnKeyUp(wxKeyEvent & e)
{
e.Skip();
int pos = GetInsertionPoint();
int lpos = wxMax(0, pos - 1);
wxString text = GetRange(lpos, pos);
if (text[0] == wxT('(')) {
wxLongToLongHashMap::const_iterator left = mLeftParens.find(lpos);
if (left != mLeftParens.end()) {
Colorize(lpos, left->second);
}
}
else if (text[0] == wxT(')')) {
wxLongToLongHashMap::const_iterator right = mRightParens.find(lpos);
if (right != mRightParens.end()) {
Colorize(right->second, lpos);
}
}
}
void NyqTextCtrl::OnUpdate(wxUpdateUIEvent & e)
{
int pos = GetInsertionPoint();
if (pos != mLastCaretPos) {
int lpos = wxMax(0, pos - 1);
wxString text = GetRange(lpos, pos);
if (text.Length() > 0) {
if (text[0] == wxT('(')) {
wxLongToLongHashMap::const_iterator left = mLeftParens.find(lpos);
if (left != mLeftParens.end()) {
Colorize(lpos, left->second);
}
}
else if (text[0] == wxT(')')) {
wxLongToLongHashMap::const_iterator right = mRightParens.find(lpos);
if (right != mRightParens.end()) {
Colorize(right->second, lpos);
}
}
}
mLastCaretPos = pos;
}
}
void NyqTextCtrl::GoMatch()
{
MoveCursor(mRightParen, mLeftParen);
}
void NyqTextCtrl::GoTop()
{
wxLongToLongHashMap::const_iterator it;
long first = -1;
long second = -1;
if (mLeftParen != -1) {
for (it = mLeftParens.begin(); it != mLeftParens.end(); it++) {
if (mLeftParen > it->first && mLeftParen < it->second) {
if (first == -1 || it->first < first) {
first = it->first;
second = it->second;
}
}
}
}
if (first != -1) {
MoveCursor(first, second);
}
}
void NyqTextCtrl::GoUp()
{
wxLongToLongHashMap::const_iterator it;
long first = -1;
long second = -1;
if (mLeftParen != -1) {
for (it = mLeftParens.begin(); it != mLeftParens.end(); it++) {
if (mLeftParen > it->first && mLeftParen < it->second) {
if (first == -1 || it->first > first) {
first = it->first;
second = it->second;
}
}
}
}
if (first != -1) {
MoveCursor(first, second);
}
}
void NyqTextCtrl::GoPrev()
{
wxLongToLongHashMap::const_iterator it;
long first = -1;
long second = -1;
if (mLeftParen != -1) {
for (it = mLeftParens.begin(); it != mLeftParens.end(); it++) {
if (it->first < mLeftParen && it->first >= first) {
first = it->first;
second = it->second;
}
}
}
if (first != -1) {
MoveCursor(first, second);
}
}
void NyqTextCtrl::GoNext()
{
wxLongToLongHashMap::const_iterator it;
long first = -1;
long second = -1;
if (mLeftParen != -1) {
for (it = mLeftParens.begin(); it != mLeftParens.end(); it++) {
if (it->first > mLeftParen && (first == -1 || it->first < first)) {
first = it->first;
second = it->second;
}
}
}
if (first != -1) {
MoveCursor(first, second);
}
}
void NyqTextCtrl::MoveCursor(long first, long second)
{
int pos = GetInsertionPoint();
int lpos = wxMax(0, pos - 1);
wxString text = GetRange(lpos, pos);
if (text[0] == wxT('(')) {
SetInsertionPoint(first + 1);
Colorize(first, second);
}
else if (text[0] == wxT(')')) {
SetInsertionPoint(second + 1);
Colorize(first, second);
}
}
void NyqTextCtrl::Colorize(long left, long right)
{
// Hide any previously highlighted parens
if (mLeftParen >= 0) {
#if defined(__WXMSW__)
Freeze(); // Prevents selection flashing on Windows
#endif
SetStyle(mLeftParen, mLeftParen + 1, mOff);
SetStyle(mLeftParens[mLeftParen], mLeftParens[mLeftParen] + 1, mOff);
mLeftParen = -1;
mRightParen = -1;
#if defined(__WXMSW__)
Thaw(); // Prevents selection flashing on Windows
#endif
}
mLeftParen = left;
mRightParen = right;
if (mLeftParen != -1) {
SetStyle(mLeftParen, mLeftParen + 1, mOn);
SetStyle(mRightParen, mRightParen + 1, mOn);
SetStyle(mLeftParen + 1, mLeftParen + 1, mOff);
SetStyle(mRightParen + 1, mRightParen + 1, mOff);
}
}
void NyqTextCtrl::FindParens()
{
wxString text = GetValue();
bool inquotes = false;
wxArrayInt stack;
long len = (long) text.Length();
long pos;
mLeftParens.clear();
mRightParens.clear();
for (pos = 0; pos < len; pos++) {
wxChar c = text[pos];
switch (c)
{
case wxT('"'):
inquotes = !inquotes;
break;
case wxT(';'):
if (!inquotes) {
pos = (long)text.find(wxT('\n'), pos);
if (pos == (long)wxString::npos) {
pos = len;
}
}
break;
case wxT('#'):
if (!inquotes) {
long ndx = pos + 1;
if (ndx < len && text[(int)ndx] == wxT('|')) {
// Shamelessly stolen from xlread.c/pcomment()
wxChar lastch = -1;
int n = 1;
/* look for the matching delimiter (and handle nesting) */
while (n > 0 && ++pos < len) {
wxChar ch = text[(int)pos];
if (lastch == '|' && ch == '#') {
--n;
ch = -1;
}
else if (lastch == '#' && ch == '|') {
++n;
ch = -1;
}
lastch = ch;
}
}
}
break;
case wxT('('):
if (!inquotes) {
stack.Add(pos);
}
break;
case wxT(')'):
if (!inquotes) {
if (stack.GetCount() > 0) {
int left = stack.Last();
stack.RemoveAt(stack.GetCount() - 1);
mLeftParens[left] = pos;
mRightParens[pos] = left;
}
}
break;
}
}
}
//----------------------------------------------------------------------------
// NyqRedirector
//----------------------------------------------------------------------------
NyqRedirector::NyqRedirector(NyqTextCtrl *text)
: mText(text)
{
mOld = std::cout.rdbuf(this);
}
NyqRedirector::~NyqRedirector()
{
std::cout.flush();
std::cout.rdbuf(mOld);
if (s.length() > 0) {
AppendText();
}
}
int NyqRedirector::overflow(int c)
{
s += (char)c;
if (c == '\n') {
AppendText();
}
return 0;
}
void NyqRedirector::AppendText()
{
mText->AppendText(wxString(s.c_str(), wxConvISO8859_1));
s.clear();
}
//----------------------------------------------------------------------------
// NyqBench
//----------------------------------------------------------------------------
enum
{
ID_AUTOLOAD = 20000,
ID_AUTOWRAP,
ID_FONT,
ID_SPLITV,
ID_SPLITH,
ID_TOGGLECODE,
ID_TOGGLEOUTPUT,
ID_SMALLICONS,
ID_LARGEICONS,
ID_MATCH,
ID_TOP,
ID_UP,
ID_PREVIOUS,
ID_NEXT,
ID_GO,
ID_STOP,
ID_SCRIPT,
ID_OUTPUT
};
BEGIN_EVENT_TABLE(NyqBench, wxFrame)
EVT_CLOSE(NyqBench::OnClose)
EVT_MOVE(NyqBench::OnMove)
EVT_SIZE(NyqBench::OnSize)
EVT_MENU(wxID_NEW, NyqBench::OnNew)
EVT_MENU(wxID_OPEN, NyqBench::OnOpen)
EVT_MENU(wxID_SAVE, NyqBench::OnSave)
EVT_MENU(wxID_SAVEAS, NyqBench::OnSaveAs)
EVT_MENU(wxID_REVERT_TO_SAVED, NyqBench::OnRevert)
EVT_MENU(ID_AUTOLOAD, NyqBench::OnAutoLoad)
EVT_MENU(wxID_CLOSE, NyqBench::OnCloseWindow)
EVT_MENU(wxID_UNDO, NyqBench::OnUndo)
EVT_MENU(wxID_REDO, NyqBench::OnRedo)
EVT_MENU(wxID_CUT, NyqBench::OnCut)
EVT_MENU(wxID_COPY, NyqBench::OnCopy)
EVT_MENU(wxID_PASTE, NyqBench::OnPaste)
EVT_MENU(wxID_CLEAR, NyqBench::OnClear)
EVT_MENU(wxID_SELECTALL, NyqBench::OnSelectAll)
EVT_MENU(wxID_FIND, NyqBench::OnFind)
EVT_MENU(ID_MATCH, NyqBench::OnGoMatch)
EVT_MENU(ID_TOP, NyqBench::OnGoTop)
EVT_MENU(ID_UP, NyqBench::OnGoUp)
EVT_MENU(ID_PREVIOUS, NyqBench::OnGoPrev)
EVT_MENU(ID_NEXT, NyqBench::OnGoNext)
EVT_MENU(ID_AUTOWRAP, NyqBench::OnAutoWrap)
EVT_MENU(ID_FONT, NyqBench::OnFont)
EVT_MENU(ID_SPLITV, NyqBench::OnSplitV)
EVT_MENU(ID_SPLITH, NyqBench::OnSplitH)
EVT_MENU(ID_TOGGLECODE, NyqBench::OnToggleCode)
EVT_MENU(ID_TOGGLEOUTPUT, NyqBench::OnToggleOutput)
EVT_MENU(ID_SMALLICONS, NyqBench::OnSmallIcons)
EVT_MENU(ID_LARGEICONS, NyqBench::OnLargeIcons)
EVT_MENU(ID_GO, NyqBench::OnGo)
EVT_MENU(ID_STOP, NyqBench::OnStop)
EVT_MENU(wxID_ABOUT, NyqBench::OnAbout)
EVT_FIND(wxID_ANY, NyqBench::OnFindDialog)
EVT_FIND_NEXT(wxID_ANY, NyqBench::OnFindDialog)
EVT_FIND_REPLACE(wxID_ANY, NyqBench::OnFindDialog)
EVT_FIND_REPLACE_ALL(wxID_ANY, NyqBench::OnFindDialog)
EVT_FIND_CLOSE(wxID_ANY, NyqBench::OnFindDialog)
EVT_TEXT(ID_SCRIPT, NyqBench::OnTextUpdate)
EVT_UPDATE_UI(wxID_SAVE, NyqBench::OnMenuUpdate)
EVT_UPDATE_UI(wxID_SAVEAS, NyqBench::OnMenuUpdate)
EVT_UPDATE_UI(wxID_REVERT_TO_SAVED, NyqBench::OnMenuUpdate)
EVT_UPDATE_UI(wxID_UNDO, NyqBench::OnUndoUpdate)
EVT_UPDATE_UI(wxID_REDO, NyqBench::OnRedoUpdate)
EVT_UPDATE_UI(wxID_CUT, NyqBench::OnCutUpdate)
EVT_UPDATE_UI(wxID_COPY, NyqBench::OnCopyUpdate)
EVT_UPDATE_UI(wxID_PASTE, NyqBench::OnPasteUpdate)
EVT_UPDATE_UI(wxID_CLEAR, NyqBench::OnClearUpdate)
EVT_UPDATE_UI(ID_SPLITH, NyqBench::OnViewUpdate)
EVT_UPDATE_UI(ID_SPLITV, NyqBench::OnViewUpdate)
EVT_UPDATE_UI(ID_TOGGLECODE, NyqBench::OnViewUpdate)
EVT_UPDATE_UI(ID_TOGGLEOUTPUT, NyqBench::OnViewUpdate)
EVT_UPDATE_UI(ID_GO, NyqBench::OnRunUpdate)
EVT_UPDATE_UI(ID_SCRIPT, NyqBench::OnScriptUpdate)
EVT_UPDATE_UI(ID_OUTPUT, NyqBench::OnOutputUpdate)
END_EVENT_TABLE()
/*static*/ NyqBench *NyqBench::GetBench()
{
if (gBench == nullptr)
{
gBench = new NyqBench(NULL);
}
return gBench;
}
NyqBench::NyqBench(wxWindow * parent)
: wxFrame(NULL,
wxID_ANY,
wxEmptyString,
wxDefaultPosition,
wxDefaultSize,
wxDEFAULT_FRAME_STYLE |
wxMINIMIZE_BOX |
wxMAXIMIZE_BOX |
wxRESIZE_BORDER)
{
mFindDlg = NULL;
mRunning = false;
mScriptBox = NULL;
mOutputBox = NULL;
mScript = NULL;
mOutput = NULL;
mPath = gPrefs->Read(wxT("NyqBench/Path"), wxEmptyString);
mAutoLoad = (gPrefs->Read(wxT("NyqBench/AutoLoad"), 0L) != 0);
mAutoWrap = (gPrefs->Read(wxT("NyqBench/AutoWrap"), true) != 0);
mLargeIcons = (gPrefs->Read(wxT("NyqBench/LargeIcons"), 0L) != 0);
mSplitMode = gPrefs->Read(wxT("NyqBench/SplitMode"), wxSPLIT_VERTICAL);
mShowCode = (gPrefs->Read(wxT("NyqBench/ShowScript"), true) != 0);
mShowOutput = (gPrefs->Read(wxT("NyqBench/ShowOutput"), true) != 0);
SetIcon(wxICON(AudacityLogo));
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
ShuttleGui S(this, eIsCreating);
PopulateOrExchange(S);
wxMenuBar *bar = new wxMenuBar();
wxMenu *menu = new wxMenu();
menu->Append(wxID_NEW, wxT("&New\tCtrl+N"));
menu->Append(wxID_OPEN, wxT("&Open...\tCtrl+O"));
menu->Append(wxID_SAVE, wxT("&Save...\tCtrl+S"));
menu->Append(wxID_SAVEAS, wxT("Save &As...\tCtrl+Shift+S"));
menu->AppendSeparator();
menu->Append(wxID_REVERT_TO_SAVED, _T("&Revert to Saved"));
menu->AppendSeparator();
menu->AppendCheckItem(ID_AUTOLOAD, _T("Auto &Load Last File"))->Check(mAutoLoad);
menu->AppendSeparator();
menu->Append(wxID_CLOSE, wxT("&Close Window\tCtrl+W"));
bar->Append(menu, wxT("&File"));
menu = new wxMenu();
menu->Append(wxID_UNDO, _("&Undo\tCtrl+Z"));
menu->Append(wxID_REDO, _("&Redo\tCtrl+Y"));
menu->AppendSeparator();
menu->Append(wxID_CUT, _("Cu&t\tCtrl+X"));
menu->Append(wxID_COPY, _("&Copy\tCtrl+C"));
menu->Append(wxID_PASTE, _("&Paste\tCtrl+V"));
menu->Append(wxID_CLEAR, _("Cle&ar\tCtrl+L"));
menu->AppendSeparator();
menu->Append(wxID_SELECTALL, _("Select A&ll\tCtrl+A"));
menu->AppendSeparator();
menu->Append(wxID_FIND, _("&Find...\tCtrl+F"));
menu->AppendSeparator();
wxMenu *sub = new wxMenu();
sub->Append(ID_MATCH, _("&Matching Paren\tF8"));
sub->Append(ID_TOP, _("&Top S-expr\tF9"));
sub->Append(ID_UP, _("&Higher S-expr\tF10"));
sub->Append(ID_PREVIOUS, _("&Previous S-expr\tF11"));
sub->Append(ID_NEXT, _("&Next S-expr\tF12"));
menu->AppendSubMenu(sub, _("&Go to"));
menu->AppendSeparator();
menu->AppendCheckItem(ID_AUTOWRAP, _T("Auto &Wrap"))->Check(mAutoWrap);
bar->Append(menu, wxT("&Edit"));
menu = new wxMenu();
menu->Append(ID_FONT, _("Select &Font..."));
menu->AppendSeparator();
menu->Append(ID_SPLITV, _("Split &Vertically"));
menu->Append(ID_SPLITH, _("Split &Horizontally"));
menu->AppendSeparator();
menu->AppendCheckItem(ID_TOGGLECODE, _("Show S&cript"));
menu->AppendCheckItem(ID_TOGGLEOUTPUT, _("Show &Output"));
menu->AppendSeparator();
sub = new wxMenu();
sub->AppendRadioItem(ID_LARGEICONS, _("&Large Icons"));
sub->AppendRadioItem(ID_SMALLICONS, _("&Small Icons"));
menu->AppendSubMenu(sub, _("Toolbar"));
bar->Append(menu, wxT("&View"));
menu = new wxMenu();
menu->Append(ID_GO, _("&Go\tF5"));
menu->Append(ID_STOP, _("&Stop\tF6"));
bar->Append(menu, wxT("&Run"));
#if defined(__WXMAC__)
menu->Append(wxID_ABOUT, _("&About"));
#else
menu = new wxMenu();
menu->Append(wxID_ABOUT, _("&About"));
bar->Append(menu, wxT("Help"));
#endif
SetMenuBar(bar);
RecreateToolbar(mLargeIcons);
wxRect r;
r.SetX(gPrefs->Read(wxT("NyqBench/Window/X"), -1));
r.SetY(gPrefs->Read(wxT("NyqBench/Window/Y"), -1));
r.SetWidth(gPrefs->Read(wxT("NyqBench/Window/Width"), -1));
r.SetHeight(gPrefs->Read(wxT("NyqBench/Window/Height"), -1));
if (r == wxRect(-1, -1, -1, -1)) {
Center();
}
else {
SetSize(r);
}
bool maximized = false;
gPrefs->Read(wxT("NyqBench/Window/Maximized"), maximized);
if (maximized) {
Maximize();
}
long sashpos;
sashpos = gPrefs->Read(wxT("NyqBench/SplitX"), 0l);
if (sashpos > 0) {
mSplitter->SetSashPosition(sashpos);
}
wxString dflt = wxSystemSettings::GetFont(wxSYS_SYSTEM_FONT).GetNativeFontInfoDesc();
wxString desc;
wxTextAttr attr;
desc = gPrefs->Read(wxT("NyqBench/ScriptFont"), dflt);
mScriptFont.SetNativeFontInfo(desc);
#if defined(__WXMSW__)
// Force SYSTEM encoding to prevent conversion to Unicode in wxTextCtrl::DoWriteText().
// I don't know if this is something I'm doing wrong, but I'll have to look at this
// later if I get bored.
mScriptFont.SetEncoding(wxFONTENCODING_SYSTEM);
#endif
attr.SetFont(mScriptFont);
mScript->SetDefaultStyle(attr);
desc = gPrefs->Read(wxT("NyqBench/OutputFont"), dflt);
mOutputFont.SetNativeFontInfo(desc);
#if defined(__WXMSW__)
// Force SYSTEM encoding to prevent conversion to Unicode in wxTextCtrl::DoWriteText().
// I don't know if this is something I'm doing wrong, but I'll have to look at this
// later if I get bored.
mOutputFont.SetEncoding(wxFONTENCODING_SYSTEM);
#endif
attr.SetFont(mOutputFont);
mOutput->SetDefaultStyle(attr);
if (mAutoLoad && !mPath.GetFullPath().IsEmpty()) {
LoadFile();
}
SetWindowTitle();
}
NyqBench::~NyqBench()
{
gPrefs->Write(wxT("NyqBench/Window/Maximized"), IsMaximized());
if (!IsMaximized()) {
wxRect r = GetRect();
#if !defined(__WXMAC__)
if (IsIconized()) {
r = mLastSize;
}
#endif
gPrefs->Write(wxT("NyqBench/Window/X"), r.GetX());
gPrefs->Write(wxT("NyqBench/Window/Y"), r.GetY());
gPrefs->Write(wxT("NyqBench/Window/Width"), r.GetWidth());
gPrefs->Write(wxT("NyqBench/Window/Height"), r.GetHeight());
}
gPrefs->Write(wxT("NyqBench/AutoLoad"), mAutoLoad);
gPrefs->Write(wxT("NyqBench/AutoWrap"), mAutoWrap);
gPrefs->Write(wxT("NyqBench/ScriptFont"), mScriptFont.GetNativeFontInfoDesc());
gPrefs->Write(wxT("NyqBench/OutputFont"), mOutputFont.GetNativeFontInfoDesc());
gPrefs->Write(wxT("NyqBench/LargeIcons"), mLargeIcons);
gPrefs->Write(wxT("NyqBench/SplitX"), mSplitter->IsSplit() ? mSplitter->GetSashPosition() : 0);
gPrefs->Write(wxT("NyqBench/SplitMode"), mSplitter->IsSplit() ? mSplitter->GetSplitMode() : 0);
gPrefs->Write(wxT("NyqBench/ShowCode"), mScript->IsShown());
gPrefs->Write(wxT("NyqBench/ShowOutput"), mOutput->IsShown());
}
void NyqBench::PopulateOrExchange(ShuttleGui & S)
{
S.StartHorizontalLay(wxEXPAND, true);
{
wxPanel *scriptp;
wxPanel *outputp;
wxStaticBoxSizer *scripts;
wxStaticBoxSizer *outputs;
wxBoxSizer *bs;
mSplitter = new wxSplitterWindow(this,
wxID_ANY,
wxDefaultPosition,
wxDefaultSize,
wxSP_LIVE_UPDATE |
wxSP_3DSASH |
wxSP_NOBORDER);
scriptp = new wxPanel(mSplitter,
wxID_ANY,
wxDefaultPosition,
wxDefaultSize,
wxNO_FULL_REPAINT_ON_RESIZE |
wxCLIP_CHILDREN);
bs = new wxBoxSizer(wxVERTICAL);
scriptp->SetSizer(bs);
mScriptBox = new wxStaticBox(scriptp,
wxID_ANY,
_("Script"));
scripts = new wxStaticBoxSizer(mScriptBox,
wxVERTICAL);
bs->Add(scripts, true, wxEXPAND);
mScript = new NyqTextCtrl(scriptp,
ID_SCRIPT,
wxEmptyString,
wxDefaultPosition,
wxDefaultSize,
wxTE_RICH2 | wxTE_RICH |
(mAutoWrap ? wxTE_BESTWRAP : wxTE_DONTWRAP) |
wxTE_NOHIDESEL |
wxTE_MULTILINE);
scripts->Add(mScript, true, wxEXPAND);
outputp = new wxPanel(mSplitter,
wxID_ANY,
wxDefaultPosition,
wxDefaultSize,
wxNO_FULL_REPAINT_ON_RESIZE |
wxCLIP_CHILDREN);
bs = new wxBoxSizer(wxVERTICAL);
outputp->SetSizer(bs);
mOutputBox = new wxStaticBox(outputp,
wxID_ANY,
_("Output"));
outputs = new wxStaticBoxSizer(mOutputBox,
wxVERTICAL);
bs->Add(outputs, true, wxEXPAND);
mOutput = new NyqTextCtrl(outputp,
ID_OUTPUT,
wxEmptyString,
wxDefaultPosition,
wxDefaultSize,
wxTE_READONLY |
#if !defined(__WXMAC__)
// I could not get the bloody horizontal scroll bar to appear on
// wxMac, so we can't use wxTE_DONTWRAP as you can't easily scroll
// left and right.
wxTE_DONTWRAP |
#endif
wxTE_NOHIDESEL |
wxTE_MULTILINE);
outputs->Add(mOutput, true, wxEXPAND);
switch (mSplitMode)
{
case wxSPLIT_VERTICAL:
mSplitter->SplitVertically(scriptp, outputp, 300);
break;
case wxSPLIT_HORIZONTAL:
mSplitter->SplitHorizontally(scriptp, outputp, 300);
break;
default:
mSplitter->Initialize((mShowCode ? scriptp : outputp));
break;
}
mSplitter->SetMinimumPaneSize(50);
S.AddSpace(5, 1);
S.Prop(true);
S.Position(wxEXPAND).AddWindow(mSplitter);
S.AddSpace(5, 1);
mSplitter->SetMinSize(wxSize(600, 400));
}
S.EndHorizontalLay();
S.AddSpace(1, 5);
return;
}
void NyqBench::OnClose(wxCloseEvent & e)
{
if (!Validate()) {
e.Veto();
}
else {
Show(false);
}
}
void NyqBench::OnMove(wxMoveEvent & e)
{
e.Skip();
if (!IsIconized() && !IsMaximized()) {
mLastSize.SetPosition(e.GetPosition());
}
}
void NyqBench::OnSize(wxSizeEvent & e)
{
e.Skip();
if (!IsIconized() && !IsMaximized()) {
mLastSize.SetSize(e.GetSize());
}
}
void NyqBench::OnCloseWindow(wxCommandEvent & e)
{
Close();
}
void NyqBench::OnNew(wxCommandEvent & e)
{
if (!Validate()) {
return;
}
mPath.SetFullName(wxEmptyString);
while (mScript->CanUndo()) {
mScript->Undo();
}
mScript->Clear();
mScript->DiscardEdits();
SetWindowTitle();
}
void NyqBench::OnOpen(wxCommandEvent & e)
{
if (mScript->IsModified() && !Validate()) {
return;
}
wxFileDialog dlog(this,
_("Load Nyquist script"),
mPath.GetPath(),
wxEmptyString,
_("Nyquist scripts (*.ny)|*.ny|Lisp scripts (*.lsp)|*.lsp|All files|*"),
wxFD_OPEN | wxRESIZE_BORDER);
if (dlog.ShowModal() != wxID_OK) {
return;
}
mPath = dlog.GetPath();
gPrefs->Write(wxT("NyqBench/Path"), mPath.GetFullPath());
LoadFile();
SetWindowTitle();
}
void NyqBench::OnSave(wxCommandEvent & e)
{
if (mScript->GetLastPosition() == 0) {
return;
}
if (mPath.GetFullPath().IsEmpty()) {
OnSaveAs(e);
return;
}
if (!mScript->SaveFile(mPath.GetFullPath()))
{
AudacityMessageBox(_("Script was not saved."),
_("Warning"),
wxICON_EXCLAMATION,
this);
return;
}
}
void NyqBench::OnSaveAs(wxCommandEvent & e)
{
if (mScript->GetLastPosition() == 0) {
return;
}
wxFileDialog dlog(this,
_("Save Nyquist script"),
mPath.GetFullPath(),
wxEmptyString,
_("Nyquist scripts (*.ny)|*.ny|Lisp scripts (*.lsp)|*.lsp|All files|*"),
wxFD_SAVE | wxFD_OVERWRITE_PROMPT | wxRESIZE_BORDER);
if (dlog.ShowModal() != wxID_OK) {
return;
}
mPath = dlog.GetPath();
gPrefs->Write(wxT("NyqBench/Path"), mPath.GetFullPath());
if (!mScript->SaveFile(mPath.GetFullPath()))
{
AudacityMessageBox(_("Script was not saved."),
_("Warning"),
wxICON_EXCLAMATION,
this);
return;
}
SetWindowTitle();
}
void NyqBench::OnAutoLoad(wxCommandEvent & e)
{
mAutoLoad = e.IsChecked();
}
void NyqBench::OnRevert(wxCommandEvent & e)
{
if (mPath.GetFullPath().IsEmpty()) {
return;
}
if (!Validate()) {
return;
}
LoadFile();
}
void NyqBench::OnUndo(wxCommandEvent & e)
{
(FindFocus() == mScript ? mScript : mOutput)->Undo();
}
void NyqBench::OnRedo(wxCommandEvent & e)
{
(FindFocus() == mScript ? mScript : mOutput)->Redo();
}
void NyqBench::OnCut(wxCommandEvent & e)
{
(FindFocus() == mScript ? mScript : mOutput)->Cut();
}
void NyqBench::OnCopy(wxCommandEvent & e)
{
(FindFocus() == mScript ? mScript : mOutput)->Copy();
}
void NyqBench::OnPaste(wxCommandEvent & e)
{
(FindFocus() == mScript ? mScript : mOutput)->Paste();
}
void NyqBench::OnClear(wxCommandEvent & e)
{
(FindFocus() == mScript ? mScript : mOutput)->Clear();
}
void NyqBench::OnSelectAll(wxCommandEvent & e)
{
(FindFocus() == mScript ? mScript : mOutput)->SetSelection(-1, -1);
}
void NyqBench::OnFind(wxCommandEvent & e)
{
if (mFindDlg ) {
delete mFindDlg;
mFindDlg = NULL;
}
else {
NyqTextCtrl *w = (NyqTextCtrl *) FindFocus();
if (w == mScript || w == mOutput) {
mFindText = w;
int flags = 0;
flags |= (gPrefs->Read(wxT("NyqBench/Find/Down"), 0L) ? wxFR_DOWN : 0);
flags |= (gPrefs->Read(wxT("NyqBench/Find/Word"), 0L) ? wxFR_WHOLEWORD : 0);
flags |= (gPrefs->Read(wxT("NyqBench/Find/Case"), 0L) ? wxFR_MATCHCASE : 0);
mFindData.SetFlags(flags);
mFindDlg = new wxFindReplaceDialog(this,
&mFindData,
_("Find dialog"),
wxFR_NOWHOLEWORD);
mFindDlg->Show(true);
}
}
}
void NyqBench::OnGoMatch(wxCommandEvent & e)
{
mScript->GoMatch();
}
void NyqBench::OnGoTop(wxCommandEvent & e)
{
mScript->GoTop();
}
void NyqBench::OnGoUp(wxCommandEvent & e)
{
mScript->GoUp();
}
void NyqBench::OnGoPrev(wxCommandEvent & e)
{
mScript->GoPrev();
}
void NyqBench::OnGoNext(wxCommandEvent & e)
{
mScript->GoNext();
}
void NyqBench::OnAutoWrap(wxCommandEvent & e)
{
mAutoWrap = e.IsChecked();
wxWindow *parent = mScript->GetParent();
wxString text = mScript->GetValue();
bool focused = wxWindow::FindFocus() == mScript;
long pos = mScript->GetInsertionPoint();
long from;
long to;
mScript->GetSelection(&from, &to);
wxSizer *s = mScript->GetContainingSizer();
s->Detach(mScript);
delete mScript;
mScript = new NyqTextCtrl(parent,
ID_SCRIPT,
wxEmptyString,
wxDefaultPosition,
wxDefaultSize,
(mAutoWrap ? wxTE_BESTWRAP : wxTE_DONTWRAP) |
wxTE_NOHIDESEL | wxTE_RICH2 |
wxTE_MULTILINE);
s->Add(mScript, 1, wxEXPAND);
s->Layout();
mScript->ChangeValue(text);
mScript->SetInsertionPoint(pos);
mScript->SetSelection(from, to);
if (focused) {
mScript->SetFocus();
}
}
void NyqBench::OnFont(wxCommandEvent & e)
{
wxWindow *w = FindFocus();
wxFontData data;
wxFontDialog dlg(this, data);
if (w != mScript && w != mOutput) {
return;
}
data.SetInitialFont(w == mScript ? mScriptFont : mOutputFont);
if (dlg.ShowModal() == wxID_OK) {
wxFontData retData = dlg.GetFontData();
wxFont font = retData.GetChosenFont();
wxTextAttr attr;
attr.SetFont(font);
if (w == mScript) {
mScriptFont = font;
}
else {
mOutputFont = font;
}
((wxTextCtrl *)w)->SetDefaultStyle(attr);
((wxTextCtrl *)w)->SetStyle(0, ((wxTextCtrl *)w)->GetLastPosition(), attr);
w->Refresh();
}
}
void NyqBench::OnSplitV(wxCommandEvent & e)
{
if (mSplitter->IsSplit()) {
mSplitter->Unsplit();
}
mSplitter->SplitVertically(mScript->GetParent(), mOutput->GetParent());
}
void NyqBench::OnSplitH(wxCommandEvent & e)
{
if (mSplitter->IsSplit()) {
mSplitter->Unsplit();
}
mSplitter->SplitHorizontally(mScript->GetParent(), mOutput->GetParent());
}
void NyqBench::OnToggleCode(wxCommandEvent & e)
{
if (e.IsChecked()) {
if (mSplitter->IsSplit()) {
// Should never happen
return;
}
if (mSplitMode == wxSPLIT_VERTICAL) {
mSplitter->SplitVertically(mScript->GetParent(), mOutput->GetParent());
}
else {
mSplitter->SplitHorizontally(mScript->GetParent(), mOutput->GetParent());
}
}
else {
if (!mSplitter->IsSplit()) {
// Should never happen
return;
}
mSplitMode = mSplitter->GetSplitMode();
mSplitter->Unsplit(mScript->GetParent());
}
}
void NyqBench::OnToggleOutput(wxCommandEvent & e)
{
if (e.IsChecked()) {
if (mSplitter->IsSplit()) {
// Should never happen
return;
}
if (mSplitMode == wxSPLIT_VERTICAL) {
mSplitter->SplitVertically(mScript->GetParent(), mOutput->GetParent());
}
else {
mSplitter->SplitHorizontally(mScript->GetParent(), mOutput->GetParent());
}
}
else {
if (!mSplitter->IsSplit()) {
// Should never happen
return;
}
mSplitMode = mSplitter->GetSplitMode();
mSplitter->Unsplit(mOutput->GetParent());
}
}
void NyqBench::OnSmallIcons(wxCommandEvent & e)
{
RecreateToolbar(false);
}
void NyqBench::OnLargeIcons(wxCommandEvent & e)
{
RecreateToolbar(true);
}
void NyqBench::OnGo(wxCommandEvent & e)
{
// No need to delete...EffectManager will do it
mEffect = new NyquistEffect(wxT("Nyquist Effect Workbench"));
const PluginID & ID = EffectManager::Get().RegisterEffect(mEffect);
mEffect->SetCommand(mScript->GetValue());
mEffect->RedirectOutput();
AudacityProject *p = GetActiveProject();
wxASSERT(p != NULL);
if (p) {
wxWindowDisabler disable(this);
NyqRedirector redir((NyqTextCtrl *)mOutput);
mRunning = true;
UpdateWindowUI();
EffectManager::DoEffect(ID, CommandContext(*p), 0);
mRunning = false;
UpdateWindowUI();
}
Raise();
EffectManager::Get().UnregisterEffect(ID);
}
void NyqBench::OnStop(wxCommandEvent & e)
{
mRunning = false;
mEffect->Stop();
}
void NyqBench::OnAbout(wxCommandEvent & e)
{
wxAboutDialogInfo i;
i.AddArtist(_("Harvey Lubin (logo)"));
i.AddArtist(_("Tango Icon Gallery (toolbar icons)"));
i.AddDeveloper(_("Leland Lucius"));
i.SetCopyright(_("(C) 2009 by Leland Lucius"));
i.SetDescription(_("External Audacity module which provides a simple IDE for writing effects."));
i.SetName(_("Nyquist Effect Workbench"));
i.SetVersion(__TDATE__);
wxAboutBox(i);
}
void NyqBench::OnFindDialog(wxFindDialogEvent & e)
{
wxEventType type = e.GetEventType();
if (type == wxEVT_COMMAND_FIND_CLOSE) {
wxFindReplaceDialog *dlg = e.GetDialog();
dlg->Destroy();
int flags = mFindData.GetFlags();
gPrefs->Write(wxT("NyqBench/Find/Down"), (flags & wxFR_DOWN) != 0);
gPrefs->Write(wxT("NyqBench/Find/Word"), (flags & wxFR_WHOLEWORD) != 0);
gPrefs->Write(wxT("NyqBench/Find/Case"), (flags & wxFR_MATCHCASE) != 0);
mFindDlg = NULL;
mFindText = NULL;
return;
}
wxString text = mFindText->GetValue();
#if defined(__WXMSW__)
// We cheat on Windows. We know that the Windows text control
// uses CRLF for line endings and if we don't account for that,
// the selection positions will be off.
//
// Not sure why I thought I needed this, but it appears not to
// be. Leaving just in case.
//
// text.Replace(wxT("\n"), wxT("\r\n"));
#endif
size_t startpos = mFindText->GetInsertionPoint();
size_t len = mFindText->GetLastPosition();
size_t pos;
wxString find = e.GetFindString();
bool down = (e.GetFlags() & wxFR_DOWN) != 0;
bool mixed = (e.GetFlags() & wxFR_MATCHCASE) != 0;
if (!mixed) {
text.MakeUpper();
find.MakeUpper();
}
if (down) {
pos = text.find(find, startpos);
if (type == wxEVT_COMMAND_FIND_NEXT && pos == startpos && pos < len) {
pos = text.find(find, startpos + 1);
}
}
else {
pos = text.rfind(find, startpos);
if (type == wxEVT_COMMAND_FIND_NEXT && pos == startpos && pos > 0) {
pos = text.rfind(find, startpos - 1);
}
}
if (pos == wxString::npos) {
AudacityMessageBox(_("No matches found"),
_("Nyquist Effect Workbench"),
wxOK | wxCENTER,
e.GetDialog());
return;
}
mFindText->SetInsertionPoint((long)pos);
#if defined(__WXGTK__)
// GTK's selection and intertion pointer interact where the insertion
// pointer winds up after the second parameter, so we reverse them to
// force the pointer at the beginning of the selection. Doing so
// allows reverse find to work properly.
mFindText->SetSelection((long)(pos + find.Length()), (long)pos);
#else
mFindText->SetSelection((long)pos, (long)(pos + find.Length()));
#endif
#if defined(__WXMAC__)
// Doing this coaxes the text control to update the selection. Without
// it the selection doesn't appear to change if the found string is within
// the currently displayed text, i.e., no reposition is needed.
mFindText->Show(false);
mFindText->Show(true);
#endif
}
void NyqBench::OnTextUpdate(wxCommandEvent & e)
{
// This really shouldn't be necessary, but Paste()ing doesn't mark the
// control as dirty...at least on the Mac.
((NyqTextCtrl *) e.GetEventObject())->MarkDirty();
}
void NyqBench::OnMenuUpdate(wxUpdateUIEvent & e)
{
if (e.GetId() != wxID_REVERT_TO_SAVED) {
e.Enable((mScript->GetLastPosition() > 0) || mScript->IsModified());
}
else {
e.Enable(mScript->IsModified());
}
}
void NyqBench::OnUndoUpdate(wxUpdateUIEvent & e)
{
e.Enable((FindFocus() == mScript ? mScript : mOutput)->CanUndo());
}
void NyqBench::OnRedoUpdate(wxUpdateUIEvent & e)
{
e.Enable((FindFocus() == mScript ? mScript : mOutput)->CanRedo());
}
void NyqBench::OnCutUpdate(wxUpdateUIEvent & e)
{
e.Enable((FindFocus() == mScript ? mScript : mOutput)->CanCut());
}
void NyqBench::OnCopyUpdate(wxUpdateUIEvent & e)
{
e.Enable((FindFocus() == mScript ? mScript : mOutput)->CanCopy());
}
void NyqBench::OnPasteUpdate(wxUpdateUIEvent & e)
{
e.Enable((FindFocus() == mScript ? mScript : mOutput)->CanPaste());
}
void NyqBench::OnClearUpdate(wxUpdateUIEvent & e)
{
e.Enable(FindFocus() == mOutput ? true : false);
}
void NyqBench::OnViewUpdate(wxUpdateUIEvent & e)
{
wxMenuBar *bar = GetMenuBar();
bar->Enable(ID_SPLITV, !mSplitter->IsSplit() || mSplitter->GetSplitMode() != wxSPLIT_VERTICAL);
bar->Enable(ID_SPLITH, !mSplitter->IsSplit() || mSplitter->GetSplitMode() != wxSPLIT_HORIZONTAL);
bar->Check(ID_TOGGLECODE, mScript->GetParent()->IsShown());
bar->Check(ID_TOGGLEOUTPUT, mOutput->GetParent()->IsShown());
bar->Check(ID_LARGEICONS, mLargeIcons);
bar->Check(ID_SMALLICONS, !mLargeIcons);
}
void NyqBench::OnRunUpdate(wxUpdateUIEvent & e)
{
AudacityProject *p = GetActiveProject();
wxToolBar *tbar = GetToolBar();
wxMenuBar *mbar = GetMenuBar();
auto gAudioIO = AudioIOBase::Get();
if (p && gAudioIO->IsBusy()) {
mbar->Enable(ID_GO, false);
mbar->Enable(ID_STOP, false);
tbar->EnableTool(ID_GO, false);
tbar->EnableTool(ID_STOP, false);
}
else {
mbar->Enable(ID_GO, (mScript->GetLastPosition() > 0) && !mRunning);
mbar->Enable(ID_STOP, (mScript->GetLastPosition() > 0) && mRunning);
tbar->EnableTool(ID_GO, (mScript->GetLastPosition() > 0) && !mRunning);
tbar->EnableTool(ID_STOP, (mScript->GetLastPosition() > 0) && mRunning);
}
}
void NyqBench::OnScriptUpdate(wxUpdateUIEvent & e)
{
if (mScriptBox && mScript && FindFocus() == mScript) {
wxString label = mScriptBox->GetLabel();
if (label == _("Script")) {
label += wxT("*");
mScriptBox->SetLabel(label);
mOutputBox->SetLabel(_("Output"));
}
}
}
void NyqBench::OnOutputUpdate(wxUpdateUIEvent & e)
{
if (mOutputBox && mOutput && FindFocus() == mOutput) {
wxString label = mOutputBox->GetLabel();
if (label == _("Output")) {
label += wxT("*");
mOutputBox->SetLabel(label);
mScriptBox->SetLabel(_("Script"));
}
}
}
bool NyqBench::Validate()
{
if (mScript->GetLastPosition() > 0 && mScript->IsModified()) {
int ans;
ans = AudacityMessageBox(_("Code has been modified. Are you sure?"),
_("Warning"),
wxYES_NO | wxICON_QUESTION,
this);
if (ans == wxNO) {
return false;
}
}
return true;
}
void NyqBench::SetWindowTitle()
{
wxString name = _("Untitled");
if (!mPath.GetFullPath().IsEmpty()) {
name = mPath.GetFullName();
}
SetTitle(_("Nyquist Effect Workbench - ") + name);
}
void NyqBench::RecreateToolbar(bool large)
{
mLargeIcons = large;
wxToolBar *tb = GetToolBar();
if (tb) {
delete tb;
}
tb = CreateToolBar();
wxSize sz;
if (!mLargeIcons) {
tb->SetToolBitmapSize(wxSize(16, 16));
mPics[0] = wxBitmap(document_new_small);
mPics[1] = wxBitmap(document_open_small);
mPics[2] = wxBitmap(document_save_as_small);
mPics[3] = wxBitmap(document_save_small);
mPics[4] = wxBitmap(edit_copy_small);
mPics[5] = wxBitmap(edit_cut_small);
mPics[6] = wxBitmap(edit_paste_small);
mPics[7] = wxBitmap(edit_clear_small);
mPics[8] = wxBitmap(edit_delete_small);
mPics[9] = wxBitmap(edit_select_all_small);
mPics[10] = wxBitmap(edit_undo_small);
mPics[11] = wxBitmap(edit_redo_small);
mPics[12] = wxBitmap(edit_find_small);
mPics[13] = wxBitmap(system_search_small);
mPics[14] = wxBitmap(go_top_small);
mPics[15] = wxBitmap(go_up_small);
mPics[16] = wxBitmap(go_previous_small);
mPics[17] = wxBitmap(go_next_small);
mPics[18] = wxBitmap(media_playback_start_small);
mPics[19] = wxBitmap(media_playback_stop_small);
}
else {
tb->SetToolBitmapSize(wxSize(32, 32));
mPics[0] = wxBitmap(document_new_large);
mPics[1] = wxBitmap(document_open_large);
mPics[2] = wxBitmap(document_save_as_large);
mPics[3] = wxBitmap(document_save_large);
mPics[4] = wxBitmap(edit_copy_large);
mPics[5] = wxBitmap(edit_cut_large);
mPics[6] = wxBitmap(edit_paste_large);
mPics[7] = wxBitmap(edit_clear_large);
mPics[8] = wxBitmap(edit_delete_large);
mPics[9] = wxBitmap(edit_select_all_large);
mPics[10] = wxBitmap(edit_undo_large);
mPics[11] = wxBitmap(edit_redo_large);
mPics[12] = wxBitmap(edit_find_large);
mPics[13] = wxBitmap(system_search_large);
mPics[14] = wxBitmap(go_top_large);
mPics[15] = wxBitmap(go_up_large);
mPics[16] = wxBitmap(go_previous_large);
mPics[17] = wxBitmap(go_next_large);
mPics[18] = wxBitmap(media_playback_start_large);
mPics[19] = wxBitmap(media_playback_stop_large);
}
tb->SetMargins(2, 2);
tb->AddTool(wxID_NEW, _("New"), mPics[0], _("New script"));
tb->AddTool(wxID_OPEN, _("Open"), mPics[1], _("Open script"));
tb->AddTool(wxID_SAVE, _("Save"), mPics[2], _("Save script"));
tb->AddTool(wxID_SAVEAS, _("Save As"), mPics[3], _("Save script as..."));
tb->AddSeparator();
tb->AddTool(wxID_COPY, _("Copy"), mPics[4], _("Copy to clipboard"));
tb->AddTool(wxID_CUT, _("Cut"), mPics[5], _("Cut to clipboard"));
tb->AddTool(wxID_PASTE, _("Paste"), mPics[6], _("Paste from clipboard"));
tb->AddTool(wxID_CLEAR, _("Clear"), mPics[7], _("Clear selection"));
tb->AddTool(wxID_SELECTALL, _("Select All"), mPics[9], _("Select all text"));
tb->AddSeparator();
tb->AddTool(wxID_UNDO, _("Undo"), mPics[10], _("Undo last change"));
tb->AddTool(wxID_REDO, _("Redo"), mPics[11], _("Redo previous change"));
tb->AddSeparator();
tb->AddTool(wxID_FIND, _("Find"), mPics[12], _("Find text"));
tb->AddSeparator();
tb->AddTool(ID_MATCH, _("Match"), mPics[13], _("Go to matching paren"));
tb->AddTool(ID_TOP, _("Top"), mPics[14], _("Go to top S-expr"));
tb->AddTool(ID_UP, _("Up"), mPics[15], _("Go to higher S-expr"));
tb->AddTool(ID_PREVIOUS, _("Previous"), mPics[16], _("Go to previous S-expr"));
tb->AddTool(ID_NEXT, _("Next"), mPics[17], _("Go to next S-expr"));
tb->AddSeparator();
tb->AddTool(ID_GO, _("Start"), mPics[18], _("Start script"));
tb->AddTool(ID_STOP, _("Stop"), mPics[19], _("Stop script"));
tb->Realize();
Layout();
Fit();
SetMinSize(GetSize());
}
void NyqBench::LoadFile()
{
wxString path = mPath.GetFullPath();
if (path.IsEmpty()) {
return;
}
wxFFile f(path);
if (f.IsOpened()) {
wxString t;
if (f.ReadAll(&t)) {
//#if defined(__WXGTK__) || defined(__WXMAC__)
t.Replace(wxT("\r\n"), wxT("\n"));
t.Replace(wxT("\r"), wxT("\n"));
//#elif defined(__WXMSW__)
// t.Replace("\r\n", "\n");
//#endif
mScript->SetValue(t);
mScript->DiscardEdits();
}
}
// mScript->LoadFile(mPath.GetFullPath());
}
//----------------------------------------------------------------------------
// Connects Audacity menu item to an action in this dll.
// Only one action implemented so far.
//----------------------------------------------------------------------------
void NyqBench::ShowNyqBench(const CommandContext &)
{
Show();
}