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