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 + -
显示快捷键?