terminalctrl.cc
来自「LastWave」· CC 代码 · 共 641 行
CC
641 行
// For compilers that support precompilation, includes "wx/wx.h".#include "wx/wxprec.h"// for all others, include the necessary headers (this file is usually all you// need because it includes almost all "standard" wxWidgets headers)#ifndef WX_PRECOMP#include "wx/wx.h"#endif#include <iostream>#include "wx/ioswrap.h"#if wxUSE_IOSTREAMH#include <fstream.h>#else#include <fstream>#endif#include "wx/wfstream.h"#include "wx/datstrm.h"#include "wx/txtstrm.h"#include "wx/mstream.h"#include <wx/utils.h>extern "C" { #include "lastwave.h" }#include "wx/textctrl.h"#include "terminalCtrl.h"#include "wxmain.h"#include "wxgraphics.h"#if wxUSE_CLIPBOARD#include "wx/dataobj.h"#include "wx/clipbrd.h"#endif/* * Function to manage the prompt */ static char prompt[200];static char flagInPromptProc = NO;static void ComputePrompt(void){ LISTV lv; flagInPromptProc = NO; /* If there is not a promptProc then we just print the history number */ if (toplevelCur->promptProc == NULL) sprintf(prompt,"%d > ",toplevelCur->levels[0].cmdNum); /* Otherwise we execute the promptProc */ else { flagInPromptProc = YES; lv = TNewListv(); ApplyProc2Listv(toplevelCur->promptProc,lv); flagInPromptProc = NO; sprintf(prompt,"%s",GetResultStr()); InitResult(); InitError(); }}extern "C" { int GetPrompt(char **pPrompt) { if (pPrompt != NULL) *pPrompt = prompt; return(flagInPromptProc); } }static char flagCompleteLine = YES;static void ProcessPrompt () { int val; // Print the prompt if ((val = setjmp(toplevelCur->environment)) == 0) { if (flagCompleteLine) { ComputePrompt(); Printf("%s",prompt); } else Printf("--> "); } /* Case an error occured while executing the promptProc (we should delete it) */ else if (val == 2) { if (toplevelCur->promptProc) { DeleteProc(toplevelCur->promptProc); toplevelCur->promptProc = NULL; } } if (val != 2) { while (ProcessNextEvent(NULL) == 2){}; }}BEGIN_EVENT_TABLE(TerminalCtrl, wxTextCtrl)EVT_KEY_DOWN(TerminalCtrl::KeyDown)EVT_CHAR(TerminalCtrl::KeyChar)// EVT_LEFT_UP(TerminalCtrl::MouseUpEvents) // EVT_RIGHT_UP(TerminalCtrl::MouseUpEvents) // EVT_MIDDLE_UP(TerminalCtrl::MouseUpEvents) EVT_LEFT_DOWN(TerminalCtrl::MouseDownEvents) EVT_RIGHT_DOWN(TerminalCtrl::MouseDownEvents) EVT_MIDDLE_DOWN(TerminalCtrl::MouseDownEvents) EVT_IDLE(TerminalCtrl::Idle)// EVT_MOTION(TerminalCtrl::MouseMotionEvent) END_EVENT_TABLE()BEGIN_EVENT_TABLE(TerminalFrame, wxFrame)EVT_MENU(TYPES_QUIT, TerminalFrame::OnQuit)EVT_MENU(TYPES_ABOUT, TerminalFrame::OnAbout)EVT_MENU(TEXT_CLIPBOARD_PASTE, TerminalFrame::OnPasteFromClipboard)EVT_MENU(TEXT_CLIPBOARD_COPY, TerminalFrame::OnCopyToClipboard)// EVT_ACTIVATE(TerminalFrame::OnActivate) BUG on macEND_EVENT_TABLE()static long start = -1;// TerminalCtrl constructorTerminalCtrl::TerminalCtrl(wxFrame *parent, const wxString & title, const wxPoint & pos, const wxSize & size): wxTextCtrl(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE){ streamIn = streamOut = streamErr = NULL; start = GetInsertionPoint();}void TerminalCtrl::MouseDownEvents(wxMouseEvent& event){ wxString str = GetStringSelection(); if (str.size() == 0) start = GetInsertionPoint(); if (event.MiddleIsDown()) {DoCopyToClipboard(); SetInsertionPoint(start+10000000);DoPasteFromClipboard(); return;} event.Skip(); return; event.Skip(); // event.Skip(); long x,y; if (HitTest(wxPoint(event.GetX(),event.GetY()),&x,&y) == wxTE_HT_UNKNOWN) { start = -1; return; } CaptureMouse(); start = XYToPosition(x,y); SetSelection(start,start+20);}void TerminalCtrl::MouseMotionEvent(wxMouseEvent& event){ if (event.MiddleIsDown()) SetSelection(10,20); return; event.Skip(); return; if (!event.LeftIsDown() && !event.MiddleIsDown() && !event.RightIsDown()) return; if (start == -1) return; long s = XYToPosition(event.GetX(),event.GetY()); SetSelection(start,s);}void TerminalCtrl::MouseUpEvents(wxMouseEvent& event){ start = GetInsertionPoint(); return; long f,t; GetSelection(&f,&t); SetInsertionPoint(start); // if (f == t) SetInsertionPoint(start); // else event.Skip(); if (HasCapture()) ReleaseMouse(); start = -1;}void TerminalCtrl::PrintStr(char *str){ WriteText(ANSI2WXSTRING(str)); start = GetInsertionPoint();}void TerminalCtrl::PrintErrStr(char *str){ WriteText(ANSI2WXSTRING(str)); start = GetInsertionPoint();}void TerminalCtrl::PrintChar(char c){ char str[2]; str[0] = c; str[1] = '\0'; WriteText(ANSI2WXSTRING(str)); start = GetInsertionPoint();}void TerminalCtrl::Flush(){ switch(wxGetOsVersion()) { __CASEUNIX : ScrollLines(10); break; } if (toplevelCur != NULL && toplevelCur->termMode != (char) GetcharTMode && toplevelCur->termMode != (char) ScanTMode) { BLOCKEVENTBYTERMINAL; } myApp->Yield(true); if (toplevelCur != NULL && toplevelCur->termMode != (char) GetcharTMode && toplevelCur->termMode != (char) ScanTMode) { UNBLOCKEVENT; } start = GetInsertionPoint();}void TerminalCtrl::CursorGoForward(int n){ SetInsertionPoint(GetInsertionPoint()+n); start = GetInsertionPoint();}void TerminalCtrl::CursorGoBackward(int n){ SetInsertionPoint(GetInsertionPoint()-n); start = GetInsertionPoint();}void TerminalCtrl::InsertChar(char c, char *str){ char str1[2]; str1[0] = c; str1[1] = '\0'; WriteText(ANSI2WXSTRING(str1)); start = GetInsertionPoint();}void TerminalCtrl::DeleteInsertChar(int n, char *str){ long p = GetInsertionPoint(); Remove(p-n,p); start = GetInsertionPoint();}static char _theLine[2000];static void Quit (){ myApp->ExitMainLoop(); myApp->terminal->Close(true); LWEnd();}extern "C" { void ProcessTerminalEvent(int flagGoOn) { if (!flagGoOn) { Quit(); return; } int i,n; char *endp; char str[1000]; // Get a command from standard input if any i = FGetCommandLine(_StdinStream,str); // If EOF then we should leave LastWave if (i == EOF) { Quit(); return; } // If no command --> we should return if (i == NO) return; // Some inits before executing the command InitResult(); InitError(); // If line is not complete and is "." --> abort if (!flagCompleteLine && !strcmp(str,".")) { Printf("Abort...\n"); flagCompleteLine = YES; EndOfCommandLine(); ProcessPrompt(); return; } // If line is complete if (flagCompleteLine) { // Copy the line in _theLine strcpy(_theLine,str); // If number --> get history line and copy it to _theLine endp = _theLine; while (*endp == ' ') endp++; if (*endp != '\0') { n = strtol(_theLine,&endp,0); if (*endp == '\0') { strcpy(_theLine,GetHistory(toplevelCur->history,n)); Printf ("%s\n",_theLine); } } // quit ? if (!strcmp("quit",_theLine) || !strcmp("exit",_theLine) || !strcmp("bye",_theLine)) { Quit(); return; } } // If multiline we have to add up the new line typed in _theLine else { strcat(_theLine,"\n"); strcat(_theLine,str); } // // Now we evaluate _theLine // // Case it is multiline if (EvalScriptStringIfComplete(_theLine, YES,YES) == NO) { flagCompleteLine = NO; ProcessPrompt(); } // Case the command line is ready else { flagCompleteLine = YES; PrintResult(); InitResult(); EndOfCommandLine(); ProcessPrompt(); } } void NotifyError2Terminal() { flagCompleteLine = YES; EndOfCommandLine(); ProcessPrompt(); } }void TerminalCtrl::WaitNextEvent(){}//// This procedure is executed at idle time// It keeps track of the cursor and selection size of the command line//// Before each button event and after each print in the terminal, we kept track of the insert point in 'start'//void TerminalCtrl::Idle(wxIdleEvent & event){ // If at init ==> do nothing if (start == -1 || toplevelCur == NULL) return; int nl = GetNumberOfLines(); if (nl > 3000) { int n = 0; for (int i = nl; i >nl/2;i--) n += GetLineLength(nl-i)+1; Remove(0,n); return; } toplevelCur->termSelSize = 0; // Get the number of chars after current true insertion point wxString sel = GetStringSelection(); long i = GetInsertionPoint(); wxString str = GetRange(i,1000000000); int size = str.size(); // Get command line size int tsize = strlen(toplevelCur->termLine); // Get the number of chars after current command line insertion point int tcursor = tsize-toplevelCur->termCursor; // If not at the end of the command line and if the insertion point is in the command line if (/*size != 0 && */tsize >= size) { // If the two cursors are not at the same point --> adjust if (tcursor != size) { toplevelCur->termCursor += tcursor-size; } toplevelCur->termSelSize = sel.size(); } // If at the end of the command line OR if the insertion point is not in the command line and no mouse button down // AND if no selection and the insertion point has changed --> set it back else { if (sel.size() == 0 && i != start) { wxMouseState ms = ::wxGetMouseState(); if (!ms.LeftDown() && !ms.RightDown() && !ms.MiddleDown()) SetInsertionPoint(start); } }}#include <wx/log.h>void TerminalCtrl::KeyDown(wxKeyEvent& event) { // Menu management switch(wxGetOsVersion()) { __CASEMAC : if (event.CmdDown()) { if (event.GetKeyCode() == 'C') DoCopyToClipboard(); else if (event.GetKeyCode() == 'V') DoPasteFromClipboard(); // else event.Skip(); return; } break; __CASEWINDOWS : if (!event.AltDown() && event.ControlDown() && !event.MetaDown() && event.GetKeyCode() != 'D') { if (event.GetKeyCode() == 'C') DoCopyToClipboard(); else if (event.GetKeyCode() == 'V') DoPasteFromClipboard(); return; } break; __CASEUNIX : if (!event.AltDown() && event.ControlDown() && !event.MetaDown() && event.GetKeyCode() != 'D') { if (event.GetKeyCode() == 'C') DoCopyToClipboard(); else if (event.GetKeyCode() == 'V') DoPasteFromClipboard(); return; } break; default : break; } if (toplevelCur->termSelSize == 0 && GetStringSelection().size() != 0) SetInsertionPoint(start); // We must send the event struct event ev; if (GetKeyDownLWEvent(this,event,ev)) { ProcessNextEvent(&ev); }}void TerminalCtrl::KeyChar(wxKeyEvent& event) { // Menu management switch(wxGetOsVersion()) { __CASEMAC : if (event.CmdDown()) { event.Skip(); return; } break; __CASEWINDOWS : __CASEUNIX : if (!event.AltDown() && event.ControlDown() && !event.MetaDown() && event.GetKeyCode() != 'D') { event.Skip(); return; } break; default : break; } if (toplevelCur->termSelSize == 0 && GetStringSelection().size() != 0) SetInsertionPoint(start); struct event ev; if (GetKeyCharLWEvent(this,event,ev)) { ProcessNextEvent(&ev); }}#if wxUSE_CLIPBOARDvoid TerminalCtrl::DoPasteFromClipboard(){ wxTheClipboard->UsePrimarySelection(); if (!wxTheClipboard->Open()) return; wxTextDataObject data; if (wxTheClipboard->IsSupported(data.GetFormat())) { if (wxTheClipboard->GetData( data )) { wxString str = data.GetText(); bool flagCut = false; wxString sel = GetStringSelection(); if (sel.size() != 0) { long i = GetInsertionPoint(); wxString str = GetRange(i,1000000000); int size = str.size(); int tsize = strlen(toplevelCur->termLine); int tcursor = tsize-toplevelCur->termCursor; if (size != 0 && tsize >= size) { if (tcursor != size) { flagCut = true; } } else { SetInsertionPoint(start); } } struct event ev; ev.object = NULL; ev.type = KeyDown1; TermInsertStr(WXSTRING2ANSI(str)); /* for (int i = 0; i<str.size();i++) { TermBufferPushKey(str[i]); } ProcessTerminalEvent(1); */ } } wxTheClipboard->Close();}#endif#if wxUSE_CLIPBOARDvoid TerminalCtrl::DoCopyToClipboard(){ wxTheClipboard->UsePrimarySelection(); wxString str = GetStringSelection(); if (str.IsEmpty()) return; if (!wxTheClipboard->Open()) return; wxTextDataObject *data = new wxTextDataObject(str); wxTheClipboard->SetData(data); wxTheClipboard->Close();}#endif// TerminalFrame constructorTerminalFrame::TerminalFrame(wxFrame *parent, const wxString& title, const wxPoint& pos, const wxSize& size): wxFrame(parent, wxID_ANY, title, pos, size){ textCtrl = new TerminalCtrl(this, wxEmptyString, wxDefaultPosition, wxDefaultSize); // Make a menubar wxMenu *file_menu = new wxMenu; file_menu->Append(TYPES_ABOUT, _T("&About")); file_menu->AppendSeparator(); file_menu->Append(TYPES_QUIT, _T("E&xit\tAlt-X")); wxMenuBar *menu_bar = new wxMenuBar; menu_bar->Append(file_menu, _T("&File")); wxMenu *menuClipboard = new wxMenu; menuClipboard->Append(TEXT_CLIPBOARD_COPY, _T("&Copy\tCtrl-C"), _T("Copy the first line to the clipboard")); menuClipboard->Append(TEXT_CLIPBOARD_PASTE, _T("&Paste\tCtrl-V"), _T("Paste from clipboard to the text control")); menu_bar->Append(menuClipboard, _T("&Edit")); SetMenuBar(menu_bar); }void TerminalFrame::OnQuit(wxCommandEvent& WXUNUSED(event) ){ Close(true); LWEnd();}void TerminalFrame::OnAbout(wxCommandEvent& WXUNUSED(event) ){ wxBeginBusyCursor(); wxMessageDialog dialog(this, _T("LastWave 3.0b\n\n Copyright (c) 2000-2006, Emmanuel Bacry\n\n"), _T("About LastWave"), wxOK | wxICON_INFORMATION); dialog.ShowModal(); wxEndBusyCursor();}void TerminalFrame::OnActivate(wxActivateEvent& event){ if (event.GetActive()) textCtrl->SetFocus();}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?