66#include " resource.h"
77#include " PythonConsole.h"
88
9+ using namespace std ;
10+
911ConsoleDialog::ConsoleDialog ()
1012 : DockingDlgInterface(IDD_CONSOLE ),
11- m_prompt(" >>> " )
13+ m_prompt(" >>> " ),
14+ m_scintilla(NULL )
1215{
1316
1417}
1518
1619ConsoleDialog::~ConsoleDialog ()
1720{
21+ if (m_scintilla)
22+ {
23+ ::SendMessage (_hParent, NPPM_DESTROYSCINTILLAHANDLE , 0 , reinterpret_cast <LPARAM >(m_scintilla));
24+ m_scintilla = NULL ;
25+ }
1826}
1927
2028
21- void ConsoleDialog::init (HINSTANCE hInst, NppData nppData, PythonConsole * console)
29+ void ConsoleDialog::init (HINSTANCE hInst, NppData nppData, ConsoleInterface * console)
2230{
2331 DockingDlgInterface::init (hInst, nppData._nppHandle );
2432
@@ -35,16 +43,24 @@ BOOL ConsoleDialog::run_dlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM l
3543 {
3644 SetParent (m_scintilla, hWnd);
3745 ShowWindow (m_scintilla, SW_SHOW );
46+ m_hInput = ::GetDlgItem (_hSelf, IDC_INPUT );
3847 HFONT hCourier = CreateFont (14 ,0 ,0 ,0 ,FW_DONTCARE ,FALSE ,FALSE ,FALSE ,DEFAULT_CHARSET ,OUT_OUTLINE_PRECIS ,
39- CLIP_DEFAULT_PRECIS ,CLEARTYPE_QUALITY , FIXED_PITCH , TEXT (" Courier New" ));
48+ CLIP_DEFAULT_PRECIS ,CLEARTYPE_QUALITY , FIXED_PITCH , _T (" Courier New" ));
4049 if (hCourier != NULL )
41- SendMessage (::GetDlgItem (_hSelf, IDC_INPUT ), WM_SETFONT , reinterpret_cast <WPARAM >(hCourier), TRUE );
50+ {
51+ SendMessage (m_hInput, WM_SETFONT , reinterpret_cast <WPARAM >(hCourier), TRUE );
52+ SendMessage (::GetDlgItem (_hSelf, IDC_PROMPT ), WM_SETFONT , reinterpret_cast <WPARAM >(hCourier), TRUE );
53+ }
54+ // Subclass the Input box
55+ ::SetWindowLongPtr (::GetDlgItem(_hSelf, IDC_INPUT ), GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this ));
56+ m_originalInputWndProc = reinterpret_cast <WNDPROC >(::SetWindowLongPtr (::GetDlgItem (_hSelf, IDC_INPUT ), GWLP_WNDPROC , reinterpret_cast <LONG_PTR >(ConsoleDialog::inputWndProc)));
57+
4258 return TRUE ;
4359 }
4460 case WM_SIZE :
4561 MoveWindow (m_scintilla, 0 , 0 , LOWORD (lParam), HIWORD (lParam)-30 , TRUE );
46- MoveWindow (::GetDlgItem (_hSelf, IDC_PROMPT ), 0 , HIWORD (lParam)-30 , 30 , 25 , TRUE );
47- MoveWindow (:: GetDlgItem (_hSelf, IDC_INPUT ) , 30 , HIWORD (lParam)-30 , LOWORD (lParam) - 85 , 25 , TRUE );
62+ MoveWindow (::GetDlgItem (_hSelf, IDC_PROMPT ), 0 , HIWORD (lParam)-25 , 30 , 25 , TRUE );
63+ MoveWindow (m_hInput , 30 , HIWORD (lParam)-30 , LOWORD (lParam) - 85 , 25 , TRUE );
4864 MoveWindow (::GetDlgItem (_hSelf, IDC_RUN ), LOWORD (lParam) - 50 , HIWORD (lParam) - 30 , 50 , 25 , TRUE );
4965 // ::SendMessage(m_scintilla, WM_SIZE, 0, MAKEWORD(LOWORD(lParam) - 10, HIWORD(lParam) - 30));
5066 return TRUE ;
@@ -65,20 +81,157 @@ BOOL ConsoleDialog::run_dlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM l
6581}
6682
6783
68- bool ConsoleDialog::runStatement ()
84+ void ConsoleDialog::historyPrevious ()
85+ {
86+ if (m_currentHistory > 0 )
87+ {
88+ char buffer[1000 ];
89+ GetWindowTextA (m_hInput, buffer, 1000 );
90+
91+ // Not an empty string and different from orig
92+ if (buffer[0 ] && (m_historyIter == m_history.end () || *m_historyIter != buffer))
93+ {
94+ if (m_changes.find (m_currentHistory) == m_changes.end ())
95+ {
96+ m_changes.insert (pair<int , string>(m_currentHistory, string (buffer)));
97+ }
98+ else
99+ {
100+ m_changes[m_currentHistory] = string (buffer);
101+ }
102+ }
103+
104+ --m_currentHistory;
105+ --m_historyIter;
106+
107+ // If there's no changes to the line, just copy the original
108+ if (m_changes.find (m_currentHistory) == m_changes.end ())
109+ {
110+ ::SetWindowTextA (m_hInput, m_historyIter->c_str ());
111+ ::SendMessage (m_hInput, EM_SETSEL , m_historyIter->size (), m_historyIter->size());
112+ }
113+ else
114+ {
115+ // Set it as the changed string
116+ ::SetWindowTextA (m_hInput, m_changes[m_currentHistory].c_str());
117+ ::SendMessage (m_hInput, EM_SETSEL , m_changes[m_currentHistory].size(), m_changes[m_currentHistory].size());
118+ }
119+
120+ }
121+ }
122+
123+ void ConsoleDialog::historyNext ()
124+ {
125+ if (m_currentHistory < m_history.size ())
126+ {
127+ char buffer[1000 ];
128+ GetWindowTextA (m_hInput, buffer, 1000 );
129+
130+
131+ // Not an empty string and different from orig
132+ if (buffer[0 ] && *m_historyIter != buffer)
133+ {
134+ if (m_changes.find (m_currentHistory) == m_changes.end ())
135+ {
136+ m_changes.insert (pair<int , string>(m_currentHistory, string (buffer)));
137+ }
138+ else
139+ {
140+ m_changes[m_currentHistory] = string (buffer);
141+ }
142+ }
143+
144+ ++m_currentHistory;
145+ ++m_historyIter;
146+
147+ // If there's no changes to the line, just copy the original
148+ if (m_changes.find (m_currentHistory) == m_changes.end ())
149+ {
150+ if (m_historyIter != m_history.end ())
151+ {
152+ ::SetWindowTextA (m_hInput, m_historyIter->c_str ());
153+ ::SendMessage (m_hInput, EM_SETSEL , m_historyIter->size (), m_historyIter->size());
154+ }
155+ else
156+ {
157+ ::SetWindowTextA (m_hInput, " " );
158+ }
159+ }
160+ else
161+ {
162+ // Set it as the changed string
163+ ::SetWindowTextA (m_hInput, m_changes[m_currentHistory].c_str());
164+ ::SendMessage (m_hInput, EM_SETSEL , m_changes[m_currentHistory].size(), m_changes[m_currentHistory].size());
165+
166+ }
167+
168+ }
169+ }
170+
171+
172+ void ConsoleDialog::historyAdd (const char *line)
173+ {
174+ m_history.push_back (string (line));
175+ m_currentHistory = m_history.size ();
176+ m_historyIter = m_history.end ();
177+ m_changes.clear ();
178+ }
179+
180+ void ConsoleDialog::historyEnd ()
181+ {
182+ m_currentHistory = m_history.size ();
183+ m_historyIter = m_history.end ();
184+ ::SetWindowTextA (m_hInput, " " );
185+ }
186+
187+
188+ LRESULT ConsoleDialog::inputWndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
189+ {
190+ ConsoleDialog *dlg = reinterpret_cast <ConsoleDialog*>(::GetWindowLongPtr (hWnd, GWLP_USERDATA ));
191+ return dlg->run_inputWndProc (hWnd, message, wParam, lParam);
192+ }
193+
194+ LRESULT ConsoleDialog::run_inputWndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
195+ {
196+ switch (message)
197+ {
198+ case WM_KEYDOWN :
199+ switch (wParam)
200+ {
201+ case VK_UP :
202+ historyPrevious ();
203+ return FALSE ;
204+
205+ case VK_DOWN :
206+ historyNext ();
207+ return FALSE ;
208+
209+ case VK_ESCAPE :
210+ historyEnd ();
211+ return FALSE ;
212+
213+ default :
214+ return CallWindowProc (m_originalInputWndProc, hWnd, message, wParam, lParam);
215+ }
216+ break ;
217+
218+ default :
219+ return CallWindowProc (m_originalInputWndProc, hWnd, message, wParam, lParam);
220+ }
221+
222+ }
223+
224+ void ConsoleDialog::runStatement ()
69225{
70226 char buffer[1000 ];
71227 GetWindowTextA (::GetDlgItem (_hSelf, IDC_INPUT ), buffer, 1000 );
228+ historyAdd (buffer);
72229 writeText (m_prompt.size (), m_prompt.c_str ());
73230 writeText (strlen (buffer), buffer);
74231 writeText (1 , " \n " );
75232 SetWindowTextA (::GetDlgItem (_hSelf, IDC_INPUT ), " " );
76- bool more = m_console->runStatement (buffer);
77- if (more)
78- setPrompt (" ... " );
79- else
80- setPrompt (" >>> " );
81- return more;
233+ m_console->runStatement (buffer);
234+
82235}
83236
84237
@@ -93,6 +246,8 @@ void ConsoleDialog::createOutputWindow(HWND hParentWindow)
93246{
94247 m_scintilla = (HWND )::SendMessage (_hParent, NPPM_CREATESCINTILLAHANDLE , 0 , reinterpret_cast <LPARAM >(hParentWindow));
95248 ::SendMessage (m_scintilla, SCI_SETREADONLY , 1 , 0 );
249+ ::SendMessage (m_scintilla, SCI_STYLESETSIZE , 0 /* = style number */ , 8 /* = size in points */ );
250+ ::SendMessage (m_scintilla, SCI_STYLESETSIZE , 1 /* = style number */ , 8 /* = size in points */ );
96251}
97252
98253void ConsoleDialog::writeText (int length, const char *text)
@@ -130,4 +285,13 @@ void ConsoleDialog::doDialog()
130285 display (true );
131286}
132287
133-
288+ void ConsoleDialog::runEnabled (bool enabled)
289+ {
290+ EnableWindow (GetDlgItem (_hSelf, IDC_RUN ), enabled);
291+ if (enabled)
292+ {
293+ ::SetForegroundWindow (_hSelf);
294+ // ::SetActiveWindow(_hSelf);
295+ ::SetFocus (m_hInput);
296+ }
297+ }
0 commit comments