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