5 * Created by Toshi Nagata on 08/10/27.
6 * Copyright 2008 Toshi Nagata. All rights reserved.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation version 2 of the License.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
18 #include "ConsoleFrame.h"
22 #include "wx/colour.h"
25 #include "../MolLib/Ruby_bind/Molby_extern.h"
28 BEGIN_EVENT_TABLE(ConsoleFrame, wxMDIChildFrame)
29 EVT_UPDATE_UI(wxID_CLOSE, ConsoleFrame::OnUpdateUI)
30 EVT_CLOSE(ConsoleFrame::OnCloseWindow)
31 EVT_MENU(wxID_CLOSE, ConsoleFrame::OnClose)
32 EVT_MENU(wxID_CUT, ConsoleFrame::OnCut)
33 EVT_MENU(wxID_COPY, ConsoleFrame::OnCopy)
34 EVT_MENU(wxID_PASTE, ConsoleFrame::OnPaste)
35 EVT_MENU(wxID_CLEAR, ConsoleFrame::OnClear)
38 ConsoleFrame::ConsoleFrame(wxMDIParentFrame *parent, const wxString& title, const wxPoint& pos, const wxSize& size, long type):
39 wxMDIChildFrame(parent, wxID_ANY, title, pos, size, type)
43 ConsoleFrame::~ConsoleFrame()
45 wxGetApp().DocManager()->FileHistoryRemoveMenu(file_history_menu);
49 ConsoleFrame::OnCreate()
52 #warning "TODO: Set the sizer for the text control properly"
54 GetClientSize(&width, &height);
55 textCtrl = new wxTextCtrl(this, wxID_ANY, _T(""), wxPoint(0, 0), wxSize(width, height), wxTE_MULTILINE | wxTE_RICH);
57 // Connect "OnKeyDown" event handler
58 textCtrl->Connect(-1, wxEVT_KEY_DOWN, wxKeyEventHandler(ConsoleFrame::OnKeyDown), NULL, this);
60 wxMenuBar *menu_bar = wxGetApp().CreateMenuBar(2, &file_history_menu, &edit_menu);
62 //// Associate the menu bar with the frame
67 ConsoleFrame::CreateConsoleFrame(wxMDIParentFrame *parent)
71 wxSize size(640, 200);
73 wxPoint origin(10, 24);
74 wxSize size(640, 200);
76 ConsoleFrame *frame = new ConsoleFrame(parent, _T("Console"), origin, size, wxDEFAULT_FRAME_STYLE | wxNO_FULL_REPAINT_ON_RESIZE);
83 GetLineIncludingPosition(wxTextCtrl *ctrl, int pos, int *start, int *end)
85 int pos1, pos2, posend;
95 posChar = ctrl->GetRange(pos1 - 1, pos1).GetChar(0);
101 posend = ctrl->GetLastPosition();
102 posChar = ctrl->GetRange(posend - 1, posend).GetChar(0);
107 while (pos2 < posend) {
108 posChar = ctrl->GetRange(pos2, pos2 + 1).GetChar(0);
109 if (posChar == '\n') {
124 ConsoleFrame::OnCloseWindow(wxCloseEvent &event)
126 // Do not delete this window; it may be reopened later
131 ConsoleFrame::OnClose(wxCommandEvent &event)
137 ConsoleFrame::OnCut(wxCommandEvent &event)
143 ConsoleFrame::OnCopy(wxCommandEvent &event)
149 ConsoleFrame::OnPaste(wxCommandEvent &event)
155 ConsoleFrame::OnClear(wxCommandEvent &event)
161 ConsoleFrame::OnUpdateUI(wxUpdateUIEvent& event)
163 // Why this is not automatically done??
164 int uid = event.GetId();
165 if (uid == wxID_CLOSE)
170 ConsoleFrame::OnEnterPressed(wxKeyEvent& event)
172 if (::wxGetKeyState(WXK_ALT)) {
173 textCtrl->WriteText(wxT("\n> "));
177 int start, pos, end, veryend, lastpos;
180 // Get the block of script to be executed
181 pos = textCtrl->GetInsertionPoint();
182 lastpos = textCtrl->GetLastPosition();
185 if (!GetLineIncludingPosition(textCtrl, pos, &start, &end) || start == end) {
186 start = end = veryend = pos;
191 startChar = textCtrl->GetRange(start, start + 1).GetChar(0);
192 if (startChar == '%') {
195 } else if (startChar == '>') {
199 start = end = veryend = pos;
203 while (start < end && veryend < lastpos) {
205 if (!GetLineIncludingPosition(textCtrl, pos, &pos, &end) || pos == end) {
208 startChar = textCtrl->GetRange(pos, pos + 1).GetChar(0);
209 if (startChar != '>')
214 wxString string = textCtrl->GetRange(start, veryend);
215 int len = string.Len();
217 // Is there any non-whitespace characters?
220 for (i = 0; i < len; i++) {
222 if (ch != ' ' && ch != '\t' && ch != '\n' && ch != 'r')
226 // Input is not empty
227 if (veryend < lastpos) {
228 // Enter is pressed in the block not at the end
229 // -> Insert the text at the end
230 wxRegEx re1(wxT("[ \t\n]*$"));
231 re1.ReplaceFirst(&string, wxT(""));
232 wxRegEx re2(wxT("^[ \t\n]*"));
233 re2.ReplaceFirst(&string, wxT(""));
234 if (textCtrl->GetRange(lastpos - 1, lastpos).GetChar(0) != '\n')
235 textCtrl->AppendText(wxT("\n"));
236 MyAppCallback_showRubyPrompt();
237 MyAppCallback_setConsoleColor(3);
238 textCtrl->AppendText(string);
240 wxTextAttr scriptAttr(*wxBLUE);
241 textCtrl->SetStyle(start, veryend, scriptAttr);
243 string.Append(wxT("\n")); // To avoid choking Ruby interpreter
244 wxRegEx re3(wxT("\n>"));
245 re3.Replace(&string, wxT("\n"));
246 if (textCtrl->GetRange(lastpos - 1, lastpos).GetChar(0) != '\n')
247 textCtrl->AppendText(wxT("\n"));
248 MyAppCallback_setConsoleColor(0);
251 // Invoke ruby interpreter
254 Molecule *mol = MoleculeCallback_currentMolecule();
256 val = Molby_evalRubyScriptOnMolecule(string.mb_str(WX_DEFAULT_CONV), MoleculeCallback_currentMolecule(), NULL, &status);
258 if (status != -1) { /* Status -1 is already handled */
259 MyAppCallback_setConsoleColor(1);
261 Molby_showError(status);
263 textCtrl->AppendText(wxT("-->"));
264 Molby_showRubyValue(val);
266 MyAppCallback_setConsoleColor(0);
267 textCtrl->AppendText(wxT("\n"));
268 MyAppCallback_showRubyPrompt();
271 textCtrl->AppendText(wxT("\n"));
272 MyAppCallback_showRubyPrompt();
277 ConsoleFrame::OnKeyDown(wxKeyEvent &event)
279 int code = event.GetKeyCode();
280 // printf("OnChar: %d\n", code);
281 if (code == WXK_RETURN || code == WXK_NUMPAD_ENTER)
282 OnEnterPressed(event);
288 ConsoleFrame::EmptyBuffer()
291 MyAppCallback_showRubyPrompt();