Audacity 3.2.0
NyqBench.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 NyqBench.cpp
4
5 Leland Lucius
6
7**********************************************************************/
8
9
10
11#include <wx/defs.h>
12
13#include <wx/aboutdlg.h>
14#include <wx/filedlg.h>
15#include <wx/font.h>
16#include <wx/fontdlg.h>
17#include <wx/menu.h>
18#include <wx/msgdlg.h>
19#include <wx/settings.h>
20#include <wx/sizer.h>
21#include <wx/splitter.h>
22#include <wx/statbox.h>
23#include <wx/textctrl.h>
24#include <wx/toolbar.h>
25
26#include "ActiveProject.h"
27#include "AudioIOBase.h"
28#include "CommonCommandFlags.h"
29#include "ModuleConstants.h"
30#include "Prefs.h"
31#include "Project.h"
32#include "ShuttleGui.h"
34#include "effects/EffectUI.h"
36#include "../images/AudacityLogo.xpm"
37#include "../../src/commands/CommandContext.h"
38#include "../../src/commands/CommandManager.h"
40
41#include "NyqBench.h"
42
43#include <iostream>
44#include <ostream>
45#include <sstream>
46
47//
48// Images are from the Tango Icon Gallery
49// http://tango.freedesktop.org/Tango_Icon_Gallery
50//
51#include "images/document-new-small.xpm"
52#include "images/document-open-small.xpm"
53#include "images/document-save-as-small.xpm"
54#include "images/document-save-small.xpm"
55#include "images/edit-clear-small.xpm"
56#include "images/edit-copy-small.xpm"
57#include "images/edit-cut-small.xpm"
58#include "images/edit-delete-small.xpm"
59#include "images/edit-find-small.xpm"
60#include "images/edit-paste-small.xpm"
61#include "images/edit-redo-small.xpm"
62#include "images/edit-select-all-small.xpm"
63#include "images/edit-undo-small.xpm"
64#include "images/go-top-small.xpm"
65#include "images/go-up-small.xpm"
66#include "images/go-previous-small.xpm"
67#include "images/go-next-small.xpm"
68#include "images/system-search-small.xpm"
69#include "images/media-playback-start-small.xpm"
70#include "images/media-playback-stop-small.xpm"
71
72#include "images/document-new-large.xpm"
73#include "images/document-open-large.xpm"
74#include "images/document-save-as-large.xpm"
75#include "images/document-save-large.xpm"
76#include "images/edit-clear-large.xpm"
77#include "images/edit-copy-large.xpm"
78#include "images/edit-cut-large.xpm"
79#include "images/edit-delete-large.xpm"
80#include "images/edit-find-large.xpm"
81#include "images/edit-paste-large.xpm"
82#include "images/edit-redo-large.xpm"
83#include "images/edit-select-all-large.xpm"
84#include "images/edit-undo-large.xpm"
85#include "images/go-top-large.xpm"
86#include "images/go-up-large.xpm"
87#include "images/go-previous-large.xpm"
88#include "images/go-next-large.xpm"
89#include "images/system-search-large.xpm"
90#include "images/media-playback-start-large.xpm"
91#include "images/media-playback-stop-large.xpm"
92
93/*
94//#define ModuleDispatchName "ModuleDispatch"
95See the example in this file. It has several cases/options in it.
96*/
97
98namespace {
100{
101 return *NyqBench::GetBench();
102}
103
105{
106 // Get here only after the module version check passes
107 using namespace MenuTable;
108 static AttachedItem sAttachment{ wxT("Tools"),
109 ( FinderScope( findme ), Section( wxT("NyquistWorkBench"),
110 Command( wxT("NyqBench"), XXO("&Nyquist Workbench..."),
113 ) )
114 };
115}
116}
117
119
120extern "C"
121{
122 static NyqBench *gBench = NULL;
123
125 // ModuleDispatch
126 // is called by Audacity to initialize/terminate the module
128 switch (type){
129 case ModuleInitialize:
131 break;
132 case AppQuiting: {
133 //It is perfectly OK for gBench to be NULL.
134 //Can happen if the menu item was never invoked.
135 //wxASSERT(gBench != NULL);
136 if (gBench) {
137 // be sure to do this while gPrefs still exists:
138 gBench->SavePrefs();
139 gBench->Destroy();
140 gBench = NULL;
141 }
142 }
143 break;
144 default:
145 break;
146 }
147 return 1;
148 }
149};
150
151//----------------------------------------------------------------------------
152// NyqTextCtrl
153//----------------------------------------------------------------------------
154
155BEGIN_EVENT_TABLE(NyqTextCtrl, wxTextCtrl)
156#if defined(__WXMAC__)
157 EVT_KEY_DOWN(NyqTextCtrl::OnKeyDown)
158#endif
159 EVT_KEY_UP(NyqTextCtrl::OnKeyUp)
160 EVT_CHAR(NyqTextCtrl::OnChar)
161 EVT_UPDATE_UI(wxID_ANY, NyqTextCtrl::OnUpdate)
163
164NyqTextCtrl::NyqTextCtrl(wxWindow *parent,
165 wxWindowID id,
166 const wxString &value,
167 const wxPoint & pos,
168 const wxSize & size,
169 int style)
170: wxTextCtrl(parent, id, value, pos, size, style)
171{
172 mLastCaretPos = -1;
173 mLeftParen = -1;
174 mRightParen = -1;
175
176 mOn.SetTextColour(*wxRED);
177 mOff.SetTextColour(*wxBLACK);
178}
179
181{
182#if defined(__WXMSW__)
183 // We do this to prevent wxMSW from selecting all text when the
184 // user tabs into the text controls.
185 wxWindowBase::SetFocusFromKbd();
186#else
187 wxTextCtrl::SetFocusFromKbd();
188#endif
189}
190
192{
193 wxTextCtrl::MarkDirty();
194 FindParens();
195}
196
197void NyqTextCtrl::OnChar(wxKeyEvent & e)
198{
199 e.Skip();
200
201 // Hide any previously highlighted parens
202 if (mLeftParen >= 0) {
203#if defined(__WXMSW__)
204 Freeze(); // Prevents selection flashing on Windows
205#endif
206
207 SetStyle(mLeftParen, mLeftParen + 1, mOff);
209 mLeftParen = -1;
210 mRightParen = -1;
211
212#if defined(__WXMSW__)
213 Thaw(); // Prevents selection flashing on Windows
214#endif
215 }
216}
217
218#if defined(__WXMAC__REMOVED_UNTIL_ITS_PROVEN_THAT_IT_IS_STILL_NEEDED)
219#include <wx/mac/uma.h>
220
221// This is hackage to correct a problem on Leopard where the
222// caret jumps up two lines when the up arrow is pressed and
223// the caret is at the beginning of the line.
224void NyqTextCtrl::OnKeyDown(wxKeyEvent & e)
225{
226 e.Skip();
227 if (UMAGetSystemVersion() >= 0x1050) {
228 if (e.GetKeyCode() == WXK_UP && e.GetModifiers() == 0) {
229 long x;
230 long y;
231
232 PositionToXY(GetInsertionPoint(), &x, &y);
233 if (x == 0 && y > 1) {
234 y--;
235 SetInsertionPoint(XYToPosition(x, y) - 1);
236 e.Skip(false);
237 }
238 }
239 }
240}
241#endif
242
243void NyqTextCtrl::OnKeyUp(wxKeyEvent & e)
244{
245 e.Skip();
246
247 int pos = GetInsertionPoint();
248 int lpos = wxMax(0, pos - 1);
249
250 wxString text = GetRange(lpos, pos);
251
252 if (text[0] == wxT('(')) {
253 wxLongToLongHashMap::const_iterator left = mLeftParens.find(lpos);
254 if (left != mLeftParens.end()) {
255 Colorize(lpos, left->second);
256 }
257 }
258 else if (text[0] == wxT(')')) {
259 wxLongToLongHashMap::const_iterator right = mRightParens.find(lpos);
260 if (right != mRightParens.end()) {
261 Colorize(right->second, lpos);
262 }
263 }
264}
265
266void NyqTextCtrl::OnUpdate(wxUpdateUIEvent & e)
267{
268 int pos = GetInsertionPoint();
269
270 if (pos != mLastCaretPos) {
271 int lpos = wxMax(0, pos - 1);
272
273 wxString text = GetRange(lpos, pos);
274 if (text.Length() > 0) {
275 if (text[0] == wxT('(')) {
276 wxLongToLongHashMap::const_iterator left = mLeftParens.find(lpos);
277 if (left != mLeftParens.end()) {
278 Colorize(lpos, left->second);
279 }
280 }
281 else if (text[0] == wxT(')')) {
282 wxLongToLongHashMap::const_iterator right = mRightParens.find(lpos);
283 if (right != mRightParens.end()) {
284 Colorize(right->second, lpos);
285 }
286 }
287 }
288
289 mLastCaretPos = pos;
290 }
291}
292
294{
296}
297
299{
300 wxLongToLongHashMap::const_iterator it;
301 long first = -1;
302 long second = -1;
303
304 if (mLeftParen != -1) {
305 for (it = mLeftParens.begin(); it != mLeftParens.end(); it++) {
306 if (mLeftParen > it->first && mLeftParen < it->second) {
307 if (first == -1 || it->first < first) {
308 first = it->first;
309 second = it->second;
310 }
311 }
312 }
313 }
314
315 if (first != -1) {
316 MoveCursor(first, second);
317 }
318}
319
321{
322 wxLongToLongHashMap::const_iterator it;
323 long first = -1;
324 long second = -1;
325
326 if (mLeftParen != -1) {
327 for (it = mLeftParens.begin(); it != mLeftParens.end(); it++) {
328 if (mLeftParen > it->first && mLeftParen < it->second) {
329 if (first == -1 || it->first > first) {
330 first = it->first;
331 second = it->second;
332 }
333 }
334 }
335 }
336
337 if (first != -1) {
338 MoveCursor(first, second);
339 }
340}
341
343{
344 wxLongToLongHashMap::const_iterator it;
345 long first = -1;
346 long second = -1;
347
348 if (mLeftParen != -1) {
349 for (it = mLeftParens.begin(); it != mLeftParens.end(); it++) {
350 if (it->first < mLeftParen && it->first >= first) {
351 first = it->first;
352 second = it->second;
353 }
354 }
355 }
356
357 if (first != -1) {
358 MoveCursor(first, second);
359 }
360}
361
363{
364 wxLongToLongHashMap::const_iterator it;
365 long first = -1;
366 long second = -1;
367
368 if (mLeftParen != -1) {
369 for (it = mLeftParens.begin(); it != mLeftParens.end(); it++) {
370 if (it->first > mLeftParen && (first == -1 || it->first < first)) {
371 first = it->first;
372 second = it->second;
373 }
374 }
375 }
376
377 if (first != -1) {
378 MoveCursor(first, second);
379 }
380}
381
382void NyqTextCtrl::MoveCursor(long first, long second)
383{
384 int pos = GetInsertionPoint();
385 int lpos = wxMax(0, pos - 1);
386
387 wxString text = GetRange(lpos, pos);
388
389 if (text[0] == wxT('(')) {
390 SetInsertionPoint(first + 1);
391 Colorize(first, second);
392 }
393 else if (text[0] == wxT(')')) {
394 SetInsertionPoint(second + 1);
395 Colorize(first, second);
396 }
397}
398
399void NyqTextCtrl::Colorize(long left, long right)
400{
401 // Hide any previously highlighted parens
402 if (mLeftParen >= 0) {
403#if defined(__WXMSW__)
404 Freeze(); // Prevents selection flashing on Windows
405#endif
406
407 SetStyle(mLeftParen, mLeftParen + 1, mOff);
409 mLeftParen = -1;
410 mRightParen = -1;
411
412#if defined(__WXMSW__)
413 Thaw(); // Prevents selection flashing on Windows
414#endif
415 }
416
417 mLeftParen = left;
418 mRightParen = right;
419
420 if (mLeftParen != -1) {
421 SetStyle(mLeftParen, mLeftParen + 1, mOn);
422 SetStyle(mRightParen, mRightParen + 1, mOn);
423
424 SetStyle(mLeftParen + 1, mLeftParen + 1, mOff);
425 SetStyle(mRightParen + 1, mRightParen + 1, mOff);
426 }
427}
428
430{
431 wxString text = GetValue();
432 bool inquotes = false;
433 wxArrayInt stack;
434 long len = (long) text.Length();
435 long pos;
436
437 mLeftParens.clear();
438 mRightParens.clear();
439
440 for (pos = 0; pos < len; pos++) {
441 wxChar c = text[pos];
442 switch (c)
443 {
444 case wxT('"'):
445 inquotes = !inquotes;
446 break;
447
448 case wxT(';'):
449 if (!inquotes) {
450 pos = (long)text.find(wxT('\n'), pos);
451 if (pos == (long)wxString::npos) {
452 pos = len;
453 }
454 }
455 break;
456
457 case wxT('#'):
458 if (!inquotes) {
459 long ndx = pos + 1;
460 if (ndx < len && text[(int)ndx] == wxT('|')) {
461 // Shamelessly stolen from xlread.c/pcomment()
462 wxChar lastch = -1;
463 int n = 1;
464
465 /* look for the matching delimiter (and handle nesting) */
466 while (n > 0 && ++pos < len) {
467 wxChar ch = text[(int)pos];
468 if (lastch == '|' && ch == '#') {
469 --n;
470 ch = -1;
471 }
472 else if (lastch == '#' && ch == '|') {
473 ++n;
474 ch = -1;
475 }
476 lastch = ch;
477 }
478 }
479 }
480 break;
481
482 case wxT('('):
483 if (!inquotes) {
484 stack.Add(pos);
485 }
486 break;
487
488 case wxT(')'):
489 if (!inquotes) {
490 if (stack.GetCount() > 0) {
491 int left = stack.Last();
492 stack.RemoveAt(stack.GetCount() - 1);
493
494 mLeftParens[left] = pos;
495 mRightParens[pos] = left;
496 }
497 }
498 break;
499 }
500 }
501}
502
503//----------------------------------------------------------------------------
504// NyqRedirector
505//----------------------------------------------------------------------------
506
508: mText(text)
509{
510 mOld = std::cout.rdbuf(this);
511}
512
514{
515 std::cout.flush();
516 std::cout.rdbuf(mOld);
517 if (s.length() > 0) {
518 AppendText();
519 }
520}
521
523{
524 s += (char)c;
525 if (c == '\n') {
526 AppendText();
527 }
528
529 return 0;
530}
531
533{
534 mText->AppendText(wxString(s.c_str(), wxConvISO8859_1));
535 s.clear();
536}
537
538//----------------------------------------------------------------------------
539// NyqBench
540//----------------------------------------------------------------------------
541
542enum
543{
544 ID_AUTOLOAD = 20000,
545
547
560
563
567
568BEGIN_EVENT_TABLE(NyqBench, wxFrame)
569 EVT_CLOSE(NyqBench::OnClose)
570 EVT_MOVE(NyqBench::OnMove)
571 EVT_SIZE(NyqBench::OnSize)
572
573 EVT_MENU(wxID_NEW, NyqBench::OnNew)
574 EVT_MENU(wxID_OPEN, NyqBench::OnOpen)
575 EVT_MENU(wxID_SAVE, NyqBench::OnSave)
576 EVT_MENU(wxID_SAVEAS, NyqBench::OnSaveAs)
577 EVT_MENU(wxID_REVERT_TO_SAVED, NyqBench::OnRevert)
580
581 EVT_MENU(wxID_UNDO, NyqBench::OnUndo)
582 EVT_MENU(wxID_REDO, NyqBench::OnRedo)
583 EVT_MENU(wxID_CUT, NyqBench::OnCut)
584 EVT_MENU(wxID_COPY, NyqBench::OnCopy)
585 EVT_MENU(wxID_PASTE, NyqBench::OnPaste)
586 EVT_MENU(wxID_CLEAR, NyqBench::OnClear)
587 EVT_MENU(wxID_SELECTALL, NyqBench::OnSelectAll)
588 EVT_MENU(wxID_FIND, NyqBench::OnFind)
595
603
606
607 EVT_MENU(wxID_ABOUT, NyqBench::OnAbout)
608
609 EVT_FIND(wxID_ANY, NyqBench::OnFindDialog)
610 EVT_FIND_NEXT(wxID_ANY, NyqBench::OnFindDialog)
611 EVT_FIND_REPLACE(wxID_ANY, NyqBench::OnFindDialog)
612 EVT_FIND_REPLACE_ALL(wxID_ANY, NyqBench::OnFindDialog)
613 EVT_FIND_CLOSE(wxID_ANY, NyqBench::OnFindDialog)
614
616
617 EVT_UPDATE_UI(wxID_SAVE, NyqBench::OnMenuUpdate)
618 EVT_UPDATE_UI(wxID_SAVEAS, NyqBench::OnMenuUpdate)
619 EVT_UPDATE_UI(wxID_REVERT_TO_SAVED, NyqBench::OnMenuUpdate)
620
621 EVT_UPDATE_UI(wxID_UNDO, NyqBench::OnUndoUpdate)
622 EVT_UPDATE_UI(wxID_REDO, NyqBench::OnRedoUpdate)
623 EVT_UPDATE_UI(wxID_CUT, NyqBench::OnCutUpdate)
624 EVT_UPDATE_UI(wxID_COPY, NyqBench::OnCopyUpdate)
625 EVT_UPDATE_UI(wxID_PASTE, NyqBench::OnPasteUpdate)
626 EVT_UPDATE_UI(wxID_CLEAR, NyqBench::OnClearUpdate)
627
628 EVT_UPDATE_UI(ID_SPLITH, NyqBench::OnViewUpdate)
629 EVT_UPDATE_UI(ID_SPLITV, NyqBench::OnViewUpdate)
632
633 EVT_UPDATE_UI(ID_GO, NyqBench::OnRunUpdate)
634
635 EVT_UPDATE_UI(ID_SCRIPT, NyqBench::OnScriptUpdate)
636 EVT_UPDATE_UI(ID_OUTPUT, NyqBench::OnOutputUpdate)
638
639/*static*/ NyqBench *NyqBench::GetBench()
640{
641 if (gBench == nullptr)
642 {
643 gBench = new NyqBench(NULL);
644 }
645
646 return gBench;
647}
648
649NyqBench::NyqBench(wxWindow * parent)
650: wxFrame(NULL,
651 wxID_ANY,
652 wxEmptyString,
653 wxDefaultPosition,
654 wxDefaultSize,
655 wxDEFAULT_FRAME_STYLE |
656 wxMINIMIZE_BOX |
657 wxMAXIMIZE_BOX |
658 wxRESIZE_BORDER)
659{
660 mFindDlg = NULL;
661 mRunning = false;
662 mScriptBox = NULL;
663 mOutputBox = NULL;
664 mScript = NULL;
665 mOutput = NULL;
666
667 mPath = gPrefs->Read(wxT("NyqBench/Path"), wxEmptyString);
668 mAutoLoad = (gPrefs->Read(wxT("NyqBench/AutoLoad"), 0L) != 0);
669 mAutoWrap = (gPrefs->Read(wxT("NyqBench/AutoWrap"), true) != 0);
670 mLargeIcons = (gPrefs->Read(wxT("NyqBench/LargeIcons"), 0L) != 0);
671 mSplitMode = gPrefs->Read(wxT("NyqBench/SplitMode"), wxSPLIT_VERTICAL);
672 mShowCode = (gPrefs->Read(wxT("NyqBench/ShowScript"), true) != 0);
673 mShowOutput = (gPrefs->Read(wxT("NyqBench/ShowOutput"), true) != 0);
674
675 SetIcon(wxICON(AudacityLogo));
676 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
677 ShuttleGui S(this, eIsCreating);
679 wxMenuBar *bar = new wxMenuBar();
680
681 wxMenu *menu = new wxMenu();
682 menu->Append(wxID_NEW, wxT("&New\tCtrl+N"));
683 menu->Append(wxID_OPEN, wxT("&Open...\tCtrl+O"));
684 menu->Append(wxID_SAVE, wxT("&Save...\tCtrl+S"));
685 menu->Append(wxID_SAVEAS, wxT("Save &As...\tCtrl+Shift+S"));
686 menu->AppendSeparator();
687 menu->Append(wxID_REVERT_TO_SAVED, _T("&Revert to Saved"));
688 menu->AppendSeparator();
689 menu->AppendCheckItem(ID_AUTOLOAD, _T("Auto &Load Last File"))->Check(mAutoLoad);
690 menu->AppendSeparator();
691 menu->Append(wxID_CLOSE, wxT("&Close Window\tCtrl+W"));
692 bar->Append(menu, wxT("&File"));
693
694 menu = new wxMenu();
695 menu->Append(wxID_UNDO, _("&Undo\tCtrl+Z"));
696 menu->Append(wxID_REDO, _("&Redo\tCtrl+Y"));
697 menu->AppendSeparator();
698 menu->Append(wxID_CUT, _("Cu&t\tCtrl+X"));
699 menu->Append(wxID_COPY, _("&Copy\tCtrl+C"));
700 menu->Append(wxID_PASTE, _("&Paste\tCtrl+V"));
701 menu->Append(wxID_CLEAR, _("Cle&ar\tCtrl+L"));
702 menu->AppendSeparator();
703 menu->Append(wxID_SELECTALL, _("Select A&ll\tCtrl+A"));
704 menu->AppendSeparator();
705 menu->Append(wxID_FIND, _("&Find...\tCtrl+F"));
706 menu->AppendSeparator();
707 wxMenu *sub = new wxMenu();
708 sub->Append(ID_MATCH, _("&Matching Paren\tF8"));
709 sub->Append(ID_TOP, _("&Top S-expr\tF9"));
710 sub->Append(ID_UP, _("&Higher S-expr\tF10"));
711 sub->Append(ID_PREVIOUS, _("&Previous S-expr\tF11"));
712 sub->Append(ID_NEXT, _("&Next S-expr\tF12"));
713 menu->AppendSubMenu(sub, _("&Go to"));
714 menu->AppendSeparator();
715 menu->AppendCheckItem(ID_AUTOWRAP, _T("Auto &Wrap"))->Check(mAutoWrap);
716 bar->Append(menu, wxT("&Edit"));
717
718 menu = new wxMenu();
719 menu->Append(ID_FONT, _("Select &Font..."));
720 menu->AppendSeparator();
721 menu->Append(ID_SPLITV, _("Split &Vertically"));
722 menu->Append(ID_SPLITH, _("Split &Horizontally"));
723 menu->AppendSeparator();
724 menu->AppendCheckItem(ID_TOGGLECODE, _("Show S&cript"));
725 menu->AppendCheckItem(ID_TOGGLEOUTPUT, _("Show &Output"));
726 menu->AppendSeparator();
727 sub = new wxMenu();
728 sub->AppendRadioItem(ID_LARGEICONS, _("&Large Icons"));
729 sub->AppendRadioItem(ID_SMALLICONS, _("&Small Icons"));
730 menu->AppendSubMenu(sub, _("Toolbar"));
731 bar->Append(menu, wxT("&View"));
732
733 menu = new wxMenu();
734 menu->Append(ID_GO, _("&Go\tF5"));
735 menu->Append(ID_STOP, _("&Stop\tF6"));
736 bar->Append(menu, wxT("&Run"));
737
738#if defined(__WXMAC__)
739 menu->Append(wxID_ABOUT, _("&About"));
740#else
741 menu = new wxMenu();
742 menu->Append(wxID_ABOUT, _("&About"));
743 bar->Append(menu, wxT("Help"));
744#endif
745
746 SetMenuBar(bar);
747
749
750 wxRect r;
751 r.SetX(gPrefs->Read(wxT("NyqBench/Window/X"), -1));
752 r.SetY(gPrefs->Read(wxT("NyqBench/Window/Y"), -1));
753 r.SetWidth(gPrefs->Read(wxT("NyqBench/Window/Width"), -1));
754 r.SetHeight(gPrefs->Read(wxT("NyqBench/Window/Height"), -1));
755 if (r == wxRect(-1, -1, -1, -1)) {
756 Center();
757 }
758 else {
759 SetSize(r);
760 }
761
762 bool maximized = false;
763 gPrefs->Read(wxT("NyqBench/Window/Maximized"), maximized);
764 if (maximized) {
765 Maximize();
766 }
767
768 long sashpos;
769 sashpos = gPrefs->Read(wxT("NyqBench/SplitX"), 0l);
770 if (sashpos > 0) {
771 mSplitter->SetSashPosition(sashpos);
772 }
773
774 wxString dflt = wxSystemSettings::GetFont(wxSYS_SYSTEM_FONT).GetNativeFontInfoDesc();
775 wxString desc;
776 wxTextAttr attr;
777
778 desc = gPrefs->Read(wxT("NyqBench/ScriptFont"), dflt);
779 mScriptFont.SetNativeFontInfo(desc);
780#if defined(__WXMSW__)
781 // Force SYSTEM encoding to prevent conversion to Unicode in wxTextCtrl::DoWriteText().
782 // I don't know if this is something I'm doing wrong, but I'll have to look at this
783 // later if I get bored.
784 mScriptFont.SetEncoding(wxFONTENCODING_SYSTEM);
785#endif
786 attr.SetFont(mScriptFont);
787 mScript->SetDefaultStyle(attr);
788
789 desc = gPrefs->Read(wxT("NyqBench/OutputFont"), dflt);
790 mOutputFont.SetNativeFontInfo(desc);
791#if defined(__WXMSW__)
792 // Force SYSTEM encoding to prevent conversion to Unicode in wxTextCtrl::DoWriteText().
793 // I don't know if this is something I'm doing wrong, but I'll have to look at this
794 // later if I get bored.
795 mOutputFont.SetEncoding(wxFONTENCODING_SYSTEM);
796#endif
797 attr.SetFont(mOutputFont);
798 mOutput->SetDefaultStyle(attr);
799
800 if (mAutoLoad && !mPath.GetFullPath().IsEmpty()) {
801 LoadFile();
802 }
803
805}
806
808{
809}
810
812{
813 gPrefs->Write(wxT("NyqBench/Window/Maximized"), IsMaximized());
814 if (!IsMaximized()) {
815 wxRect r = GetRect();
816
817#if !defined(__WXMAC__)
818 if (IsIconized()) {
819 r = mLastSize;
820 }
821#endif
822
823 gPrefs->Write(wxT("NyqBench/Window/X"), r.GetX());
824 gPrefs->Write(wxT("NyqBench/Window/Y"), r.GetY());
825 gPrefs->Write(wxT("NyqBench/Window/Width"), r.GetWidth());
826 gPrefs->Write(wxT("NyqBench/Window/Height"), r.GetHeight());
827 }
828
829 gPrefs->Write(wxT("NyqBench/AutoLoad"), mAutoLoad);
830 gPrefs->Write(wxT("NyqBench/AutoWrap"), mAutoWrap);
831 gPrefs->Write(wxT("NyqBench/ScriptFont"), mScriptFont.GetNativeFontInfoDesc());
832 gPrefs->Write(wxT("NyqBench/OutputFont"), mOutputFont.GetNativeFontInfoDesc());
833 gPrefs->Write(wxT("NyqBench/LargeIcons"), mLargeIcons);
834 gPrefs->Write(wxT("NyqBench/SplitX"), mSplitter->IsSplit() ? mSplitter->GetSashPosition() : 0);
835 gPrefs->Write(wxT("NyqBench/SplitMode"), mSplitter->IsSplit() ? mSplitter->GetSplitMode() : 0);
836 gPrefs->Write(wxT("NyqBench/ShowCode"), mScript->IsShown());
837 gPrefs->Write(wxT("NyqBench/ShowOutput"), mOutput->IsShown());
838}
839
841{
842 S.StartHorizontalLay(wxEXPAND, true);
843 {
844 wxPanel *scriptp;
845 wxPanel *outputp;
846 wxStaticBoxSizer *scripts;
847 wxStaticBoxSizer *outputs;
848 wxBoxSizer *bs;
849
850 mSplitter = new wxSplitterWindow(this,
851 wxID_ANY,
852 wxDefaultPosition,
853 wxDefaultSize,
854 wxSP_LIVE_UPDATE |
855 wxSP_3DSASH |
856 wxSP_NOBORDER);
857
858 scriptp = new wxPanel(mSplitter,
859 wxID_ANY,
860 wxDefaultPosition,
861 wxDefaultSize,
862 wxNO_FULL_REPAINT_ON_RESIZE |
863 wxCLIP_CHILDREN);
864 bs = new wxBoxSizer(wxVERTICAL);
865 scriptp->SetSizer(bs);
866
867 mScriptBox = new wxStaticBox(scriptp,
868 wxID_ANY,
869 _("Script"));
870
871 scripts = new wxStaticBoxSizer(mScriptBox,
872 wxVERTICAL);
873 bs->Add(scripts, true, wxEXPAND);
874
875 mScript = new NyqTextCtrl(scriptp,
876 ID_SCRIPT,
877 wxEmptyString,
878 wxDefaultPosition,
879 wxDefaultSize,
880 wxTE_RICH2 | wxTE_RICH |
881 (mAutoWrap ? wxTE_BESTWRAP : wxTE_DONTWRAP) |
882 wxTE_NOHIDESEL |
883 wxTE_MULTILINE);
884 scripts->Add(mScript, true, wxEXPAND);
885
886 outputp = new wxPanel(mSplitter,
887 wxID_ANY,
888 wxDefaultPosition,
889 wxDefaultSize,
890 wxNO_FULL_REPAINT_ON_RESIZE |
891 wxCLIP_CHILDREN);
892 bs = new wxBoxSizer(wxVERTICAL);
893 outputp->SetSizer(bs);
894
895 mOutputBox = new wxStaticBox(outputp,
896 wxID_ANY,
897 _("Output"));
898 outputs = new wxStaticBoxSizer(mOutputBox,
899 wxVERTICAL);
900 bs->Add(outputs, true, wxEXPAND);
901
902 mOutput = new NyqTextCtrl(outputp,
903 ID_OUTPUT,
904 wxEmptyString,
905 wxDefaultPosition,
906 wxDefaultSize,
907 wxTE_READONLY |
908#if !defined(__WXMAC__)
909// I could not get the bloody horizontal scroll bar to appear on
910// wxMac, so we can't use wxTE_DONTWRAP as you can't easily scroll
911// left and right.
912 wxTE_DONTWRAP |
913#endif
914 wxTE_NOHIDESEL |
915 wxTE_MULTILINE);
916 outputs->Add(mOutput, true, wxEXPAND);
917
918 switch (mSplitMode)
919 {
920 case wxSPLIT_VERTICAL:
921 mSplitter->SplitVertically(scriptp, outputp, 300);
922 break;
923
924 case wxSPLIT_HORIZONTAL:
925 mSplitter->SplitHorizontally(scriptp, outputp, 300);
926 break;
927
928 default:
929 mSplitter->Initialize((mShowCode ? scriptp : outputp));
930 break;
931 }
932
933 mSplitter->SetMinimumPaneSize(50);
934
935 S.AddSpace(5, 1);
936 S.Prop(true);
937 S.Position(wxEXPAND).AddWindow(mSplitter);
938 S.AddSpace(5, 1);
939
940 mSplitter->SetMinSize(wxSize(600, 400));
941 }
942 S.EndHorizontalLay();
943
944 S.AddSpace(1, 5);
945
946 return;
947}
948
949void NyqBench::OnClose(wxCloseEvent & e)
950{
951 if (!Validate()) {
952 e.Veto();
953 }
954 else {
955 Show(false);
956 }
957}
958
959void NyqBench::OnMove(wxMoveEvent & e)
960{
961 e.Skip();
962 if (!IsIconized() && !IsMaximized()) {
963 mLastSize.SetPosition(e.GetPosition());
964 }
965}
966
967void NyqBench::OnSize(wxSizeEvent & e)
968{
969 e.Skip();
970 if (!IsIconized() && !IsMaximized()) {
971 mLastSize.SetSize(e.GetSize());
972 }
973}
974
975void NyqBench::OnCloseWindow(wxCommandEvent & e)
976{
977 Close();
978}
979
980void NyqBench::OnNew(wxCommandEvent & e)
981{
982 if (!Validate()) {
983 return;
984 }
985
986 mPath.SetFullName(wxEmptyString);
987
988 while (mScript->CanUndo()) {
989 mScript->Undo();
990 }
991
992 mScript->Clear();
993 mScript->DiscardEdits();
994
996}
997
998void NyqBench::OnOpen(wxCommandEvent & e)
999{
1000 if (mScript->IsModified() && !Validate()) {
1001 return;
1002 }
1003
1004 wxFileDialog dlog(this,
1005 _("Load Nyquist script"),
1006 mPath.GetPath(),
1007 wxEmptyString,
1008 _("Nyquist scripts (*.ny)|*.ny|Lisp scripts (*.lsp)|*.lsp|All files|*"),
1009 wxFD_OPEN | wxRESIZE_BORDER);
1010
1011 if (dlog.ShowModal() != wxID_OK) {
1012 return;
1013 }
1014
1015 mPath = dlog.GetPath();
1016 gPrefs->Write(wxT("NyqBench/Path"), mPath.GetFullPath());
1017
1018 LoadFile();
1019
1021}
1022
1023void NyqBench::OnSave(wxCommandEvent & e)
1024{
1025 if (mScript->GetLastPosition() == 0) {
1026 return;
1027 }
1028
1029 if (mPath.GetFullPath().IsEmpty()) {
1030 OnSaveAs(e);
1031 return;
1032 }
1033
1034 if (!mScript->SaveFile(mPath.GetFullPath()))
1035 {
1036 AudacityMessageBox(XO("Script was not saved."),
1037 XO("Warning"),
1038 wxICON_EXCLAMATION,
1039 this);
1040 return;
1041 }
1042}
1043
1044void NyqBench::OnSaveAs(wxCommandEvent & e)
1045{
1046 if (mScript->GetLastPosition() == 0) {
1047 return;
1048 }
1049
1050 wxFileDialog dlog(this,
1051 _("Save Nyquist script"),
1052 mPath.GetFullPath(),
1053 wxEmptyString,
1054 _("Nyquist scripts (*.ny)|*.ny|Lisp scripts (*.lsp)|*.lsp|All files|*"),
1055 wxFD_SAVE | wxFD_OVERWRITE_PROMPT | wxRESIZE_BORDER);
1056
1057 if (dlog.ShowModal() != wxID_OK) {
1058 return;
1059 }
1060
1061 mPath = dlog.GetPath();
1062 gPrefs->Write(wxT("NyqBench/Path"), mPath.GetFullPath());
1063
1064 if (!mScript->SaveFile(mPath.GetFullPath()))
1065 {
1066 AudacityMessageBox(XO("Script was not saved."),
1067 XO("Warning"),
1068 wxICON_EXCLAMATION,
1069 this);
1070 return;
1071 }
1072
1074}
1075
1076void NyqBench::OnAutoLoad(wxCommandEvent & e)
1077{
1078 mAutoLoad = e.IsChecked();
1079}
1080
1081void NyqBench::OnRevert(wxCommandEvent & e)
1082{
1083 if (mPath.GetFullPath().IsEmpty()) {
1084 return;
1085 }
1086
1087 if (!Validate()) {
1088 return;
1089 }
1090
1091 LoadFile();
1092}
1093
1094void NyqBench::OnUndo(wxCommandEvent & e)
1095{
1096 (FindFocus() == mScript ? mScript : mOutput)->Undo();
1097}
1098
1099void NyqBench::OnRedo(wxCommandEvent & e)
1100{
1101 (FindFocus() == mScript ? mScript : mOutput)->Redo();
1102}
1103
1104void NyqBench::OnCut(wxCommandEvent & e)
1105{
1106 (FindFocus() == mScript ? mScript : mOutput)->Cut();
1107}
1108
1109void NyqBench::OnCopy(wxCommandEvent & e)
1110{
1111 (FindFocus() == mScript ? mScript : mOutput)->Copy();
1112}
1113
1114void NyqBench::OnPaste(wxCommandEvent & e)
1115{
1116 (FindFocus() == mScript ? mScript : mOutput)->Paste();
1117}
1118
1119void NyqBench::OnClear(wxCommandEvent & e)
1120{
1121 (FindFocus() == mScript ? mScript : mOutput)->Clear();
1122}
1123
1124void NyqBench::OnSelectAll(wxCommandEvent & e)
1125{
1126 (FindFocus() == mScript ? mScript : mOutput)->SetSelection(-1, -1);
1127}
1128
1129void NyqBench::OnFind(wxCommandEvent & e)
1130{
1131 if (mFindDlg ) {
1132 delete mFindDlg;
1133 mFindDlg = NULL;
1134 }
1135 else {
1136 NyqTextCtrl *w = (NyqTextCtrl *) FindFocus();
1137 if (w == mScript || w == mOutput) {
1138 mFindText = w;
1139
1140 int flags = 0;
1141
1142 flags |= (gPrefs->Read(wxT("NyqBench/Find/Down"), 0L) ? wxFR_DOWN : 0);
1143 flags |= (gPrefs->Read(wxT("NyqBench/Find/Word"), 0L) ? wxFR_WHOLEWORD : 0);
1144 flags |= (gPrefs->Read(wxT("NyqBench/Find/Case"), 0L) ? wxFR_MATCHCASE : 0);
1145
1146 mFindData.SetFlags(flags);
1147
1148 mFindDlg = new wxFindReplaceDialog(this,
1149 &mFindData,
1150 _("Find dialog"),
1151 wxFR_NOWHOLEWORD);
1152 mFindDlg->Show(true);
1153 }
1154 }
1155}
1156
1157void NyqBench::OnGoMatch(wxCommandEvent & e)
1158{
1159 mScript->GoMatch();
1160}
1161
1162void NyqBench::OnGoTop(wxCommandEvent & e)
1163{
1164 mScript->GoTop();
1165}
1166
1167void NyqBench::OnGoUp(wxCommandEvent & e)
1168{
1169 mScript->GoUp();
1170}
1171
1172void NyqBench::OnGoPrev(wxCommandEvent & e)
1173{
1174 mScript->GoPrev();
1175}
1176
1177void NyqBench::OnGoNext(wxCommandEvent & e)
1178{
1179 mScript->GoNext();
1180}
1181
1182void NyqBench::OnAutoWrap(wxCommandEvent & e)
1183{
1184 mAutoWrap = e.IsChecked();
1185
1186 wxWindow *parent = mScript->GetParent();
1187 wxString text = mScript->GetValue();
1188 bool focused = wxWindow::FindFocus() == mScript;
1189 long pos = mScript->GetInsertionPoint();
1190 long from;
1191 long to;
1192 mScript->GetSelection(&from, &to);
1193
1194 wxSizer *s = mScript->GetContainingSizer();
1195 s->Detach(mScript);
1196 delete mScript;
1197
1198 mScript = new NyqTextCtrl(parent,
1199 ID_SCRIPT,
1200 wxEmptyString,
1201 wxDefaultPosition,
1202 wxDefaultSize,
1203 (mAutoWrap ? wxTE_BESTWRAP : wxTE_DONTWRAP) |
1204 wxTE_NOHIDESEL | wxTE_RICH2 |
1205 wxTE_MULTILINE);
1206 s->Add(mScript, 1, wxEXPAND);
1207 s->Layout();
1208
1209 mScript->ChangeValue(text);
1210 mScript->SetInsertionPoint(pos);
1211 mScript->SetSelection(from, to);
1212
1213 if (focused) {
1214 mScript->SetFocus();
1215 }
1216}
1217
1218void NyqBench::OnFont(wxCommandEvent & e)
1219{
1220 wxWindow *w = FindFocus();
1221 wxFontData data;
1222 wxFontDialog dlg(this, data);
1223
1224 if (w != mScript && w != mOutput) {
1225 return;
1226 }
1227
1228 data.SetInitialFont(w == mScript ? mScriptFont : mOutputFont);
1229
1230 if (dlg.ShowModal() == wxID_OK) {
1231 wxFontData retData = dlg.GetFontData();
1232 wxFont font = retData.GetChosenFont();
1233 wxTextAttr attr;
1234 attr.SetFont(font);
1235
1236 if (w == mScript) {
1237 mScriptFont = font;
1238 }
1239 else {
1240 mOutputFont = font;
1241 }
1242
1243 ((wxTextCtrl *)w)->SetDefaultStyle(attr);
1244 ((wxTextCtrl *)w)->SetStyle(0, ((wxTextCtrl *)w)->GetLastPosition(), attr);
1245 w->Refresh();
1246 }
1247}
1248
1249void NyqBench::OnSplitV(wxCommandEvent & e)
1250{
1251 if (mSplitter->IsSplit()) {
1252 mSplitter->Unsplit();
1253 }
1254
1255 mSplitter->SplitVertically(mScript->GetParent(), mOutput->GetParent());
1256}
1257
1258void NyqBench::OnSplitH(wxCommandEvent & e)
1259{
1260 if (mSplitter->IsSplit()) {
1261 mSplitter->Unsplit();
1262 }
1263
1264 mSplitter->SplitHorizontally(mScript->GetParent(), mOutput->GetParent());
1265}
1266
1267void NyqBench::OnToggleCode(wxCommandEvent & e)
1268{
1269 if (e.IsChecked()) {
1270 if (mSplitter->IsSplit()) {
1271 // Should never happen
1272 return;
1273 }
1274
1275 if (mSplitMode == wxSPLIT_VERTICAL) {
1276 mSplitter->SplitVertically(mScript->GetParent(), mOutput->GetParent());
1277 }
1278 else {
1279 mSplitter->SplitHorizontally(mScript->GetParent(), mOutput->GetParent());
1280 }
1281 }
1282 else {
1283 if (!mSplitter->IsSplit()) {
1284 // Should never happen
1285 return;
1286 }
1287
1288 mSplitMode = mSplitter->GetSplitMode();
1289 mSplitter->Unsplit(mScript->GetParent());
1290 }
1291}
1292
1293void NyqBench::OnToggleOutput(wxCommandEvent & e)
1294{
1295 if (e.IsChecked()) {
1296 if (mSplitter->IsSplit()) {
1297 // Should never happen
1298 return;
1299 }
1300
1301 if (mSplitMode == wxSPLIT_VERTICAL) {
1302 mSplitter->SplitVertically(mScript->GetParent(), mOutput->GetParent());
1303 }
1304 else {
1305 mSplitter->SplitHorizontally(mScript->GetParent(), mOutput->GetParent());
1306 }
1307 }
1308 else {
1309 if (!mSplitter->IsSplit()) {
1310 // Should never happen
1311 return;
1312 }
1313
1314 mSplitMode = mSplitter->GetSplitMode();
1315 mSplitter->Unsplit(mOutput->GetParent());
1316 }
1317}
1318
1319void NyqBench::OnSmallIcons(wxCommandEvent & e)
1320{
1321 RecreateToolbar(false);
1322}
1323
1324void NyqBench::OnLargeIcons(wxCommandEvent & e)
1325{
1326 RecreateToolbar(true);
1327}
1328
1329void NyqBench::OnGo(wxCommandEvent & e)
1330{
1331 auto pEffect =
1332 std::make_unique<NyquistEffect>(L"Nyquist Effect Workbench");
1333 mEffect = pEffect.get();
1334 const PluginID & ID =
1335 EffectManager::Get().RegisterEffect(std::move(pEffect));
1336
1337 mEffect->SetCommand(mScript->GetValue());
1339
1340 auto p = GetActiveProject().lock();
1341 wxASSERT(p);
1342
1343 if (p) {
1344 wxWindowDisabler disable(this);
1346
1347 mRunning = true;
1348 UpdateWindowUI();
1349
1351
1352 mRunning = false;
1353 UpdateWindowUI();
1354 }
1355
1356 Raise();
1357
1359}
1360
1361void NyqBench::OnStop(wxCommandEvent & e)
1362{
1363 mRunning = false;
1364 mEffect->Stop();
1365}
1366
1367void NyqBench::OnAbout(wxCommandEvent & e)
1368{
1369 wxAboutDialogInfo i;
1370
1371 i.AddArtist(_("Harvey Lubin (logo)"));
1372 i.AddArtist(_("Tango Icon Gallery (toolbar icons)"));
1373 i.AddDeveloper(_("Leland Lucius"));
1374 i.SetCopyright(_("(C) 2009 by Leland Lucius"));
1375 i.SetDescription(_("External Audacity module which provides a simple IDE for writing effects."));
1376 i.SetName(_("Nyquist Effect Workbench"));
1377 i.SetVersion(__TDATE__);
1378
1379 wxAboutBox(i);
1380}
1381
1382void NyqBench::OnFindDialog(wxFindDialogEvent & e)
1383{
1384 wxEventType type = e.GetEventType();
1385
1386 if (type == wxEVT_COMMAND_FIND_CLOSE) {
1387 wxFindReplaceDialog *dlg = e.GetDialog();
1388
1389 dlg->Destroy();
1390
1391 int flags = mFindData.GetFlags();
1392
1393 gPrefs->Write(wxT("NyqBench/Find/Down"), (flags & wxFR_DOWN) != 0);
1394 gPrefs->Write(wxT("NyqBench/Find/Word"), (flags & wxFR_WHOLEWORD) != 0);
1395 gPrefs->Write(wxT("NyqBench/Find/Case"), (flags & wxFR_MATCHCASE) != 0);
1396
1397 mFindDlg = NULL;
1398 mFindText = NULL;
1399
1400 return;
1401 }
1402
1403 wxString text = mFindText->GetValue();
1404
1405#if defined(__WXMSW__)
1406 // We cheat on Windows. We know that the Windows text control
1407 // uses CRLF for line endings and if we don't account for that,
1408 // the selection positions will be off.
1409 //
1410 // Not sure why I thought I needed this, but it appears not to
1411 // be. Leaving just in case.
1412 //
1413 // text.Replace(wxT("\n"), wxT("\r\n"));
1414#endif
1415
1416 size_t startpos = mFindText->GetInsertionPoint();
1417 size_t len = mFindText->GetLastPosition();
1418 size_t pos;
1419
1420 wxString find = e.GetFindString();
1421 bool down = (e.GetFlags() & wxFR_DOWN) != 0;
1422 bool mixed = (e.GetFlags() & wxFR_MATCHCASE) != 0;
1423
1424 if (!mixed) {
1425 text.MakeUpper();
1426 find.MakeUpper();
1427 }
1428
1429 if (down) {
1430 pos = text.find(find, startpos);
1431 if (type == wxEVT_COMMAND_FIND_NEXT && pos == startpos && pos < len) {
1432 pos = text.find(find, startpos + 1);
1433 }
1434 }
1435 else {
1436 pos = text.rfind(find, startpos);
1437 if (type == wxEVT_COMMAND_FIND_NEXT && pos == startpos && pos > 0) {
1438 pos = text.rfind(find, startpos - 1);
1439 }
1440 }
1441
1442 if (pos == wxString::npos) {
1443 AudacityMessageBox(XO("No matches found"),
1444 XO("Nyquist Effect Workbench"),
1445 wxOK | wxCENTER,
1446 e.GetDialog());
1447
1448 return;
1449 }
1450
1451 mFindText->SetInsertionPoint((long)pos);
1452
1453#if defined(__WXGTK__)
1454 // GTK's selection and intertion pointer interact where the insertion
1455 // pointer winds up after the second parameter, so we reverse them to
1456 // force the pointer at the beginning of the selection. Doing so
1457 // allows reverse find to work properly.
1458 mFindText->SetSelection((long)(pos + find.Length()), (long)pos);
1459#else
1460 mFindText->SetSelection((long)pos, (long)(pos + find.Length()));
1461#endif
1462
1463#if defined(__WXMAC__)
1464 // Doing this coaxes the text control to update the selection. Without
1465 // it the selection doesn't appear to change if the found string is within
1466 // the currently displayed text, i.e., no reposition is needed.
1467 mFindText->Show(false);
1468 mFindText->Show(true);
1469#endif
1470}
1471
1472void NyqBench::OnTextUpdate(wxCommandEvent & e)
1473{
1474 // This really shouldn't be necessary, but Paste()ing doesn't mark the
1475 // control as dirty...at least on the Mac.
1476 ((NyqTextCtrl *) e.GetEventObject())->MarkDirty();
1477}
1478
1479void NyqBench::OnMenuUpdate(wxUpdateUIEvent & e)
1480{
1481 if (e.GetId() != wxID_REVERT_TO_SAVED) {
1482 e.Enable((mScript->GetLastPosition() > 0) || mScript->IsModified());
1483 }
1484 else {
1485 e.Enable(mScript->IsModified());
1486 }
1487}
1488
1489void NyqBench::OnUndoUpdate(wxUpdateUIEvent & e)
1490{
1491 e.Enable((FindFocus() == mScript ? mScript : mOutput)->CanUndo());
1492}
1493
1494void NyqBench::OnRedoUpdate(wxUpdateUIEvent & e)
1495{
1496 e.Enable((FindFocus() == mScript ? mScript : mOutput)->CanRedo());
1497}
1498
1499void NyqBench::OnCutUpdate(wxUpdateUIEvent & e)
1500{
1501 e.Enable((FindFocus() == mScript ? mScript : mOutput)->CanCut());
1502}
1503
1504void NyqBench::OnCopyUpdate(wxUpdateUIEvent & e)
1505{
1506 e.Enable((FindFocus() == mScript ? mScript : mOutput)->CanCopy());
1507}
1508
1509void NyqBench::OnPasteUpdate(wxUpdateUIEvent & e)
1510{
1511 e.Enable((FindFocus() == mScript ? mScript : mOutput)->CanPaste());
1512}
1513
1514void NyqBench::OnClearUpdate(wxUpdateUIEvent & e)
1515{
1516 e.Enable(FindFocus() == mOutput ? true : false);
1517}
1518
1519void NyqBench::OnViewUpdate(wxUpdateUIEvent & e)
1520{
1521 wxMenuBar *bar = GetMenuBar();
1522 bar->Enable(ID_SPLITV, !mSplitter->IsSplit() || mSplitter->GetSplitMode() != wxSPLIT_VERTICAL);
1523 bar->Enable(ID_SPLITH, !mSplitter->IsSplit() || mSplitter->GetSplitMode() != wxSPLIT_HORIZONTAL);
1524 bar->Check(ID_TOGGLECODE, mScript->GetParent()->IsShown());
1525 bar->Check(ID_TOGGLEOUTPUT, mOutput->GetParent()->IsShown());
1526 bar->Check(ID_LARGEICONS, mLargeIcons);
1527 bar->Check(ID_SMALLICONS, !mLargeIcons);
1528}
1529
1530void NyqBench::OnRunUpdate(wxUpdateUIEvent & e)
1531{
1532 auto p = GetActiveProject().lock();
1533 wxToolBar *tbar = GetToolBar();
1534 wxMenuBar *mbar = GetMenuBar();
1535
1536 auto gAudioIO = AudioIOBase::Get();
1537 if (p && gAudioIO->IsBusy()) {
1538 mbar->Enable(ID_GO, false);
1539 mbar->Enable(ID_STOP, false);
1540
1541 tbar->EnableTool(ID_GO, false);
1542 tbar->EnableTool(ID_STOP, false);
1543 }
1544 else {
1545 mbar->Enable(ID_GO, (mScript->GetLastPosition() > 0) && !mRunning);
1546 mbar->Enable(ID_STOP, (mScript->GetLastPosition() > 0) && mRunning);
1547
1548 tbar->EnableTool(ID_GO, (mScript->GetLastPosition() > 0) && !mRunning);
1549 tbar->EnableTool(ID_STOP, (mScript->GetLastPosition() > 0) && mRunning);
1550 }
1551}
1552
1553void NyqBench::OnScriptUpdate(wxUpdateUIEvent & e)
1554{
1555 if (mScriptBox && mScript && FindFocus() == mScript) {
1556 wxString label = mScriptBox->GetLabel();
1557 if (label == _("Script")) {
1558 label += wxT("*");
1559 mScriptBox->SetLabel(label);
1560 mOutputBox->SetLabel(_("Output"));
1561 }
1562 }
1563}
1564
1565void NyqBench::OnOutputUpdate(wxUpdateUIEvent & e)
1566{
1567 if (mOutputBox && mOutput && FindFocus() == mOutput) {
1568 wxString label = mOutputBox->GetLabel();
1569 if (label == _("Output")) {
1570 label += wxT("*");
1571 mOutputBox->SetLabel(label);
1572 mScriptBox->SetLabel(_("Script"));
1573 }
1574 }
1575}
1576
1578{
1579 if (mScript->GetLastPosition() > 0 && mScript->IsModified()) {
1580 int ans;
1581 ans = AudacityMessageBox(XO("Code has been modified. Are you sure?"),
1582 XO("Warning"),
1583 wxYES_NO | wxICON_QUESTION,
1584 this);
1585 if (ans == wxNO) {
1586 return false;
1587 }
1588 }
1589
1590 return true;
1591}
1592
1594{
1595 wxString name = _("Untitled");
1596
1597 if (!mPath.GetFullPath().IsEmpty()) {
1598 name = mPath.GetFullName();
1599 }
1600
1601 SetTitle(_("Nyquist Effect Workbench - ") + name);
1602}
1603
1605{
1606 mLargeIcons = large;
1607
1608 wxToolBar *tb = GetToolBar();
1609 if (tb) {
1610 delete tb;
1611 }
1612 tb = CreateToolBar();
1613
1614 wxSize sz;
1615
1616 if (!mLargeIcons) {
1617 tb->SetToolBitmapSize(wxSize(16, 16));
1618 mPics[0] = wxBitmap(document_new_small);
1619 mPics[1] = wxBitmap(document_open_small);
1620 mPics[2] = wxBitmap(document_save_as_small);
1621 mPics[3] = wxBitmap(document_save_small);
1622 mPics[4] = wxBitmap(edit_copy_small);
1623 mPics[5] = wxBitmap(edit_cut_small);
1624 mPics[6] = wxBitmap(edit_paste_small);
1625 mPics[7] = wxBitmap(edit_clear_small);
1626 mPics[8] = wxBitmap(edit_delete_small);
1627 mPics[9] = wxBitmap(edit_select_all_small);
1628 mPics[10] = wxBitmap(edit_undo_small);
1629 mPics[11] = wxBitmap(edit_redo_small);
1630 mPics[12] = wxBitmap(edit_find_small);
1631 mPics[13] = wxBitmap(system_search_small);
1632 mPics[14] = wxBitmap(go_top_small);
1633 mPics[15] = wxBitmap(go_up_small);
1634 mPics[16] = wxBitmap(go_previous_small);
1635 mPics[17] = wxBitmap(go_next_small);
1636 mPics[18] = wxBitmap(media_playback_start_small);
1637 mPics[19] = wxBitmap(media_playback_stop_small);
1638 }
1639 else {
1640 tb->SetToolBitmapSize(wxSize(32, 32));
1641 mPics[0] = wxBitmap(document_new_large);
1642 mPics[1] = wxBitmap(document_open_large);
1643 mPics[2] = wxBitmap(document_save_as_large);
1644 mPics[3] = wxBitmap(document_save_large);
1645 mPics[4] = wxBitmap(edit_copy_large);
1646 mPics[5] = wxBitmap(edit_cut_large);
1647 mPics[6] = wxBitmap(edit_paste_large);
1648 mPics[7] = wxBitmap(edit_clear_large);
1649 mPics[8] = wxBitmap(edit_delete_large);
1650 mPics[9] = wxBitmap(edit_select_all_large);
1651 mPics[10] = wxBitmap(edit_undo_large);
1652 mPics[11] = wxBitmap(edit_redo_large);
1653 mPics[12] = wxBitmap(edit_find_large);
1654 mPics[13] = wxBitmap(system_search_large);
1655 mPics[14] = wxBitmap(go_top_large);
1656 mPics[15] = wxBitmap(go_up_large);
1657 mPics[16] = wxBitmap(go_previous_large);
1658 mPics[17] = wxBitmap(go_next_large);
1659 mPics[18] = wxBitmap(media_playback_start_large);
1660 mPics[19] = wxBitmap(media_playback_stop_large);
1661 }
1662
1663 tb->SetMargins(2, 2);
1664
1665 tb->AddTool(wxID_NEW, _("New"), mPics[0], _("New script"));
1666 tb->AddTool(wxID_OPEN, _("Open"), mPics[1], _("Open script"));
1667 tb->AddTool(wxID_SAVE, _("Save"), mPics[2], _("Save script"));
1668 tb->AddTool(wxID_SAVEAS, _("Save As"), mPics[3], _("Save script as..."));
1669 tb->AddSeparator();
1670 tb->AddTool(wxID_COPY, _("Copy"), mPics[4], _("Copy to clipboard"));
1671 tb->AddTool(wxID_CUT, _("Cut"), mPics[5], _("Cut to clipboard"));
1672 tb->AddTool(wxID_PASTE, _("Paste"), mPics[6], _("Paste from clipboard"));
1673 tb->AddTool(wxID_CLEAR, _("Clear"), mPics[7], _("Clear selection"));
1674 tb->AddTool(wxID_SELECTALL, _("Select All"), mPics[9], _("Select all text"));
1675 tb->AddSeparator();
1676 tb->AddTool(wxID_UNDO, _("Undo"), mPics[10], _("Undo last change"));
1677 tb->AddTool(wxID_REDO, _("Redo"), mPics[11], _("Redo previous change"));
1678 tb->AddSeparator();
1679 tb->AddTool(wxID_FIND, _("Find"), mPics[12], _("Find text"));
1680 tb->AddSeparator();
1681 tb->AddTool(ID_MATCH, _("Match"), mPics[13], _("Go to matching paren"));
1682 tb->AddTool(ID_TOP, _("Top"), mPics[14], _("Go to top S-expr"));
1683 tb->AddTool(ID_UP, _("Up"), mPics[15], _("Go to higher S-expr"));
1684 tb->AddTool(ID_PREVIOUS, _("Previous"), mPics[16], _("Go to previous S-expr"));
1685 tb->AddTool(ID_NEXT, _("Next"), mPics[17], _("Go to next S-expr"));
1686 tb->AddSeparator();
1687 tb->AddTool(ID_GO, _("Start"), mPics[18], _("Start script"));
1688 tb->AddTool(ID_STOP, _("Stop"), mPics[19], _("Stop script"));
1689
1690 tb->Realize();
1691
1692 Layout();
1693 Fit();
1694 SetMinSize(GetSize());
1695}
1696
1698{
1699 wxString path = mPath.GetFullPath();
1700
1701 if (path.IsEmpty()) {
1702 return;
1703 }
1704
1705 wxFFile f(path);
1706 if (f.IsOpened()) {
1707 wxString t;
1708 if (f.ReadAll(&t)) {
1709//#if defined(__WXGTK__) || defined(__WXMAC__)
1710 t.Replace(wxT("\r\n"), wxT("\n"));
1711 t.Replace(wxT("\r"), wxT("\n"));
1712//#elif defined(__WXMSW__)
1713// t.Replace("\r\n", "\n");
1714//#endif
1715 mScript->SetValue(t);
1716 mScript->DiscardEdits();
1717 }
1718 }
1719
1720// mScript->LoadFile(mPath.GetFullPath());
1721}
1722
1723//----------------------------------------------------------------------------
1724// Connects Audacity menu item to an action in this dll.
1725// Only one action implemented so far.
1726//----------------------------------------------------------------------------
1728{
1729 Show();
1730}
AUDACITY_DLL_API std::weak_ptr< AudacityProject > GetActiveProject()
Handle changing of active project and keep global project pointer.
EVT_MENU(OnSetPlayRegionToSelectionID, AdornedRulerPanel::OnSetPlayRegionToSelection) EVT_COMMAND(OnTogglePinnedStateID
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
END_EVENT_TABLE()
void(CommandHandlerObject::*)(const CommandContext &context) CommandFunctorPointer
wxEvtHandler CommandHandlerObject
const ReservedCommandFlag & AudioIONotBusyFlag()
const TranslatableString name
Definition: Distortion.cpp:82
wxString PluginID
Definition: EffectManager.h:30
const TranslatableString desc
Definition: ExportPCM.cpp:58
#define XXO(s)
Definition: Internat.h:44
#define XO(s)
Definition: Internat.h:31
#define _(s)
Definition: Internat.h:75
#define DLL_API
ModuleDispatchTypes
@ ModuleInitialize
@ AppQuiting
int DLL_API ModuleDispatch(ModuleDispatchTypes type)
Definition: NyqBench.cpp:127
@ ID_SPLITV
Definition: NyqBench.cpp:549
@ ID_PREVIOUS
Definition: NyqBench.cpp:558
@ ID_TOP
Definition: NyqBench.cpp:556
@ ID_STOP
Definition: NyqBench.cpp:562
@ ID_TOGGLEOUTPUT
Definition: NyqBench.cpp:552
@ ID_LARGEICONS
Definition: NyqBench.cpp:554
@ ID_GO
Definition: NyqBench.cpp:561
@ ID_MATCH
Definition: NyqBench.cpp:555
@ ID_AUTOWRAP
Definition: NyqBench.cpp:546
@ ID_SPLITH
Definition: NyqBench.cpp:550
@ ID_OUTPUT
Definition: NyqBench.cpp:565
@ ID_FONT
Definition: NyqBench.cpp:548
@ ID_UP
Definition: NyqBench.cpp:557
@ ID_NEXT
Definition: NyqBench.cpp:559
@ ID_AUTOLOAD
Definition: NyqBench.cpp:544
@ ID_SCRIPT
Definition: NyqBench.cpp:564
@ ID_SMALLICONS
Definition: NyqBench.cpp:553
@ ID_TOGGLECODE
Definition: NyqBench.cpp:551
static DEFINE_VERSION_CHECK NyqBench * gBench
Definition: NyqBench.cpp:122
FileConfig * gPrefs
Definition: Prefs.cpp:71
@ eIsCreating
Definition: ShuttleGui.h:39
TranslatableString label
Definition: TagsEditor.cpp:163
#define S(N)
Definition: ToChars.cpp:64
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:89
static AudioIOBase * Get()
Definition: AudioIOBase.cpp:89
CommandContext provides additional information to an 'Apply()' command. It provides the project,...
static EffectManager & Get()
const PluginID & RegisterEffect(std::unique_ptr< EffectPlugin > uEffect)
Here solely for the purpose of Nyquist Workbench until a better solution is devised.
void UnregisterEffect(const PluginID &ID)
Used only by Nyquist Workbench module.
bool mShowCode
Definition: NyqBench.h:200
wxStaticBox * mOutputBox
Definition: NyqBench.h:183
int mSplitMode
Definition: NyqBench.h:199
void OnScriptUpdate(wxUpdateUIEvent &e)
Definition: NyqBench.cpp:1553
void OnGoPrev(wxCommandEvent &e)
Definition: NyqBench.cpp:1172
void OnPasteUpdate(wxUpdateUIEvent &e)
Definition: NyqBench.cpp:1509
void OnMenuUpdate(wxUpdateUIEvent &e)
Definition: NyqBench.cpp:1479
void OnCopy(wxCommandEvent &e)
Definition: NyqBench.cpp:1109
void OnCloseWindow(wxCommandEvent &e)
Definition: NyqBench.cpp:975
wxFileName mPath
Definition: NyqBench.h:207
static NyqBench * GetBench()
Definition: NyqBench.cpp:639
void OnClearUpdate(wxUpdateUIEvent &e)
Definition: NyqBench.cpp:1514
wxFont mOutputFont
Definition: NyqBench.h:195
void OnOpen(wxCommandEvent &e)
Definition: NyqBench.cpp:998
wxFindReplaceData mFindData
Definition: NyqBench.h:189
void OnSmallIcons(wxCommandEvent &e)
Definition: NyqBench.cpp:1319
NyqTextCtrl * mOutput
Definition: NyqBench.h:185
void OnAbout(wxCommandEvent &e)
Definition: NyqBench.cpp:1367
void OnAutoWrap(wxCommandEvent &e)
Definition: NyqBench.cpp:1182
void OnFind(wxCommandEvent &e)
Definition: NyqBench.cpp:1129
virtual ~NyqBench()
Definition: NyqBench.cpp:807
void OnToggleOutput(wxCommandEvent &e)
Definition: NyqBench.cpp:1293
wxFont mScriptFont
Definition: NyqBench.h:194
void OnCutUpdate(wxUpdateUIEvent &e)
Definition: NyqBench.cpp:1499
void OnFont(wxCommandEvent &e)
Definition: NyqBench.cpp:1218
NyqTextCtrl * mScript
Definition: NyqBench.h:184
virtual bool Validate()
Definition: NyqBench.cpp:1577
void OnClose(wxCloseEvent &e)
Definition: NyqBench.cpp:949
void OnSplitH(wxCommandEvent &e)
Definition: NyqBench.cpp:1258
bool mLargeIcons
Definition: NyqBench.h:203
void OnFindDialog(wxFindDialogEvent &e)
Definition: NyqBench.cpp:1382
void OnRedoUpdate(wxUpdateUIEvent &e)
Definition: NyqBench.cpp:1494
void OnSaveAs(wxCommandEvent &e)
Definition: NyqBench.cpp:1044
NyqTextCtrl * mFindText
Definition: NyqBench.h:190
void OnRedo(wxCommandEvent &e)
Definition: NyqBench.cpp:1099
bool mAutoWrap
Definition: NyqBench.h:209
void LoadFile()
Definition: NyqBench.cpp:1697
void OnMove(wxMoveEvent &e)
Definition: NyqBench.cpp:959
void OnCopyUpdate(wxUpdateUIEvent &e)
Definition: NyqBench.cpp:1504
wxSplitterWindow * mSplitter
Definition: NyqBench.h:186
void OnLargeIcons(wxCommandEvent &e)
Definition: NyqBench.cpp:1324
void OnAutoLoad(wxCommandEvent &e)
Definition: NyqBench.cpp:1076
wxBitmap mPics[20]
Definition: NyqBench.h:197
void OnUndo(wxCommandEvent &e)
Definition: NyqBench.cpp:1094
void OnRunUpdate(wxUpdateUIEvent &e)
Definition: NyqBench.cpp:1530
void SavePrefs()
Definition: NyqBench.cpp:811
void OnOutputUpdate(wxUpdateUIEvent &e)
Definition: NyqBench.cpp:1565
void OnUndoUpdate(wxUpdateUIEvent &e)
Definition: NyqBench.cpp:1489
void OnSplitV(wxCommandEvent &e)
Definition: NyqBench.cpp:1249
void OnRevert(wxCommandEvent &e)
Definition: NyqBench.cpp:1081
void OnToggleCode(wxCommandEvent &e)
Definition: NyqBench.cpp:1267
void OnNew(wxCommandEvent &e)
Definition: NyqBench.cpp:980
void OnCut(wxCommandEvent &e)
Definition: NyqBench.cpp:1104
void OnSelectAll(wxCommandEvent &e)
Definition: NyqBench.cpp:1124
void OnViewUpdate(wxUpdateUIEvent &e)
Definition: NyqBench.cpp:1519
void OnGoMatch(wxCommandEvent &e)
Definition: NyqBench.cpp:1157
void RecreateToolbar(bool large=false)
Definition: NyqBench.cpp:1604
void OnClear(wxCommandEvent &e)
Definition: NyqBench.cpp:1119
void ShowNyqBench(const CommandContext &)
Definition: NyqBench.cpp:1727
NyqBench(wxWindow *parent)
Definition: NyqBench.cpp:649
wxRect mLastSize
Definition: NyqBench.h:211
void OnGoUp(wxCommandEvent &e)
Definition: NyqBench.cpp:1167
void SetWindowTitle()
Definition: NyqBench.cpp:1593
wxFindReplaceDialog * mFindDlg
Definition: NyqBench.h:188
void OnGoNext(wxCommandEvent &e)
Definition: NyqBench.cpp:1177
void OnGo(wxCommandEvent &e)
Definition: NyqBench.cpp:1329
void OnStop(wxCommandEvent &e)
Definition: NyqBench.cpp:1361
bool mRunning
Definition: NyqBench.h:205
void OnPaste(wxCommandEvent &e)
Definition: NyqBench.cpp:1114
bool mAutoLoad
Definition: NyqBench.h:208
void OnSave(wxCommandEvent &e)
Definition: NyqBench.cpp:1023
NyquistEffect * mEffect
Definition: NyqBench.h:192
void OnTextUpdate(wxCommandEvent &e)
Definition: NyqBench.cpp:1472
void PopulateOrExchange(ShuttleGui &S)
Definition: NyqBench.cpp:840
void OnGoTop(wxCommandEvent &e)
Definition: NyqBench.cpp:1162
void OnSize(wxSizeEvent &e)
Definition: NyqBench.cpp:967
wxStaticBox * mScriptBox
Definition: NyqBench.h:182
bool mShowOutput
Definition: NyqBench.h:201
NyqRedirector(NyqTextCtrl *text)
Definition: NyqBench.cpp:507
virtual ~NyqRedirector()
Definition: NyqBench.cpp:513
std::string s
Definition: NyqBench.h:90
NyqTextCtrl * mText
Definition: NyqBench.h:92
int overflow(int c)
Definition: NyqBench.cpp:522
void AppendText()
Definition: NyqBench.cpp:532
std::streambuf * mOld
Definition: NyqBench.h:91
wxTextAttr mOff
Definition: NyqBench.h:70
void FindParens()
Definition: NyqBench.cpp:429
wxLongToLongHashMap mLeftParens
Definition: NyqBench.h:61
void GoTop()
Definition: NyqBench.cpp:298
wxLongToLongHashMap mRightParens
Definition: NyqBench.h:62
void OnKeyUp(wxKeyEvent &e)
Definition: NyqBench.cpp:243
void SetFocusFromKbd()
Definition: NyqBench.cpp:180
wxTextAttr mOn
Definition: NyqBench.h:69
void MoveCursor(long first, long second)
Definition: NyqBench.cpp:382
long mRightParen
Definition: NyqBench.h:65
void GoUp()
Definition: NyqBench.cpp:320
void Colorize(long left, long right)
Definition: NyqBench.cpp:399
void GoPrev()
Definition: NyqBench.cpp:342
void MarkDirty()
Definition: NyqBench.cpp:191
long mLastCaretPos
Definition: NyqBench.h:67
void GoMatch()
Definition: NyqBench.cpp:293
void GoNext()
Definition: NyqBench.cpp:362
void OnChar(wxKeyEvent &e)
Definition: NyqBench.cpp:197
long mLeftParen
Definition: NyqBench.h:64
void OnUpdate(wxUpdateUIEvent &e)
Definition: NyqBench.cpp:266
void RedirectOutput()
Definition: Nyquist.cpp:1820
void SetCommand(const wxString &cmd)
Definition: Nyquist.cpp:1825
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:631
AUDACITY_DLL_API bool DoEffect(const PluginID &ID, const CommandContext &context, unsigned flags)
'Repeat Last Effect'.
Definition: EffectUI.cpp:1275
std::unique_ptr< MenuPart > Section(const Identifier &internalName, Args &&... args)
std::unique_ptr< CommandItem > Command(const CommandID &name, const TranslatableString &label_in, void(Handler::*pmf)(const CommandContext &), CommandFlag flags, const CommandManager::Options &options={}, CommandHandlerFinder finder=FinderScope::DefaultFinder())
CommandHandlerObject & findme(AudacityProject &)
Definition: NyqBench.cpp:99