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"
27 BEGIN_EVENT_TABLE(ConsoleFrame, wxMDIChildFrame)
28 EVT_UPDATE_UI(wxID_CLOSE, ConsoleFrame::OnUpdateUI)
29 EVT_CLOSE(ConsoleFrame::OnCloseWindow)
30 EVT_MENU(wxID_CLOSE, ConsoleFrame::OnClose)
31 EVT_MENU(wxID_CUT, ConsoleFrame::OnCut)
32 EVT_MENU(wxID_COPY, ConsoleFrame::OnCopy)
33 EVT_MENU(wxID_PASTE, ConsoleFrame::OnPaste)
34 EVT_MENU(wxID_CLEAR, ConsoleFrame::OnClear)
37 ConsoleFrame::ConsoleFrame(wxMDIParentFrame *parent, const wxString& title, const wxPoint& pos, const wxSize& size, long type):
38 wxMDIChildFrame(parent, wxID_ANY, title, pos, size, type)
42 ConsoleFrame::~ConsoleFrame()
44 wxGetApp().DocManager()->FileHistoryRemoveMenu(file_history_menu);
48 ConsoleFrame::OnCreate()
51 #warning "TODO: Set the sizer for the text control properly"
53 GetClientSize(&width, &height);
54 textCtrl = new wxTextCtrl(this, wxID_ANY, _T(""), wxPoint(0, 0), wxSize(width, height), wxTE_MULTILINE | wxTE_RICH);
56 // Connect "OnKeyDown" event handler
57 textCtrl->Connect(-1, wxEVT_KEY_DOWN, wxKeyEventHandler(ConsoleFrame::OnKeyDown), NULL, this);
59 wxMenuBar *menu_bar = wxGetApp().CreateMenuBar(2, &file_history_menu, &edit_menu);
61 //// Associate the menu bar with the frame
66 ConsoleFrame::CreateConsoleFrame(wxMDIParentFrame *parent)
70 wxSize size(640, 200);
72 wxPoint origin(10, 24);
73 wxSize size(640, 200);
75 ConsoleFrame *frame = new ConsoleFrame(parent, _T("Console"), origin, size, wxDEFAULT_FRAME_STYLE | wxNO_FULL_REPAINT_ON_RESIZE);
82 GetLineIncludingPosition(wxTextCtrl *ctrl, int pos, int *start, int *end)
84 int pos1, pos2, posend;
94 posChar = ctrl->GetRange(pos1 - 1, pos1).GetChar(0);
100 posend = ctrl->GetLastPosition();
101 posChar = ctrl->GetRange(posend - 1, posend).GetChar(0);
106 while (pos2 < posend) {
107 posChar = ctrl->GetRange(pos2, pos2 + 1).GetChar(0);
108 if (posChar == '\n') {
123 ConsoleFrame::OnCloseWindow(wxCloseEvent &event)
125 // Do not delete this window; it may be reopened later
130 ConsoleFrame::OnClose(wxCommandEvent &event)
136 ConsoleFrame::OnCut(wxCommandEvent &event)
142 ConsoleFrame::OnCopy(wxCommandEvent &event)
148 ConsoleFrame::OnPaste(wxCommandEvent &event)
154 ConsoleFrame::OnClear(wxCommandEvent &event)
160 ConsoleFrame::OnUpdateUI(wxUpdateUIEvent& event)
162 // Why this is not automatically done??
163 int uid = event.GetId();
164 if (uid == wxID_CLOSE)
169 ConsoleFrame::OnEnterPressed(wxKeyEvent& event)
171 if (::wxGetKeyState(WXK_ALT)) {
172 textCtrl->WriteText(wxT("\n> "));
176 int start, pos, end, veryend, lastpos;
179 // Get the block of script to be executed
180 pos = textCtrl->GetInsertionPoint();
181 lastpos = textCtrl->GetLastPosition();
184 if (!GetLineIncludingPosition(textCtrl, pos, &start, &end) || start == end) {
185 start = end = veryend = pos;
190 startChar = textCtrl->GetRange(start, start + 1).GetChar(0);
191 if (startChar == '%') {
194 } else if (startChar == '>') {
198 start = end = veryend = pos;
202 while (start < end && veryend < lastpos) {
204 if (!GetLineIncludingPosition(textCtrl, pos, &pos, &end) || pos == end) {
207 startChar = textCtrl->GetRange(pos, pos + 1).GetChar(0);
208 if (startChar != '>')
213 wxString string = textCtrl->GetRange(start, veryend);
214 int len = string.Len();
216 // Is there any non-whitespace characters?
219 for (i = 0; i < len; i++) {
221 if (ch != ' ' && ch != '\t' && ch != '\n' && ch != 'r')
225 // Input is not empty
226 if (veryend < lastpos) {
227 // Enter is pressed in the block not at the end
228 // -> Insert the text at the end
229 wxRegEx re1(wxT("[ \t\n]*$"));
230 re1.ReplaceFirst(&string, wxT(""));
231 wxRegEx re2(wxT("^[ \t\n]*"));
232 re2.ReplaceFirst(&string, wxT(""));
233 if (textCtrl->GetRange(lastpos - 1, lastpos).GetChar(0) != '\n')
234 textCtrl->AppendText(wxT("\n"));
235 MyAppCallback_showRubyPrompt();
236 MyAppCallback_setConsoleColor(3);
237 textCtrl->AppendText(string);
239 wxTextAttr scriptAttr(*wxBLUE);
240 textCtrl->SetStyle(start, veryend, scriptAttr);
242 string.Append(wxT("\n")); // To avoid choking Ruby interpreter
243 wxRegEx re3(wxT("\n>"));
244 re3.Replace(&string, wxT("\n"));
245 if (textCtrl->GetRange(lastpos - 1, lastpos).GetChar(0) != '\n')
246 textCtrl->AppendText(wxT("\n"));
247 MyAppCallback_setConsoleColor(0);
250 // Invoke ruby interpreter
253 Molecule *mol = MoleculeCallback_currentMolecule();
255 val = Molby_evalRubyScriptOnMolecule(string.mb_str(wxConvUTF8), MoleculeCallback_currentMolecule(), &status);
257 if (status != -1) { /* Status -1 is already handled */
258 MyAppCallback_setConsoleColor(1);
260 Molby_showError(status);
262 textCtrl->AppendText(wxT("-->"));
263 Molby_showRubyValue(val);
265 MyAppCallback_setConsoleColor(0);
266 textCtrl->AppendText(wxT("\n"));
267 MyAppCallback_showRubyPrompt();
270 textCtrl->AppendText(wxT("\n"));
271 MyAppCallback_showRubyPrompt();
276 ConsoleFrame::OnKeyDown(wxKeyEvent &event)
278 int code = event.GetKeyCode();
279 // printf("OnChar: %d\n", code);
280 if (code == WXK_RETURN || code == WXK_NUMPAD_ENTER)
281 OnEnterPressed(event);