4 Website: http://www.vultaire.net/software/wxkanjipad/files/
5 License: GNU General Public License (GPL) version 2
6 (http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt)
8 File: panel_kanjipad.cpp
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License along
21 with this program; if not, write to the Free Software Foundation, Inc.,
22 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 #include "panel_kanjipad.h"
27 BEGIN_EVENT_TABLE(PanelKanjiPad
, wxPanel
)
28 EVT_LEFT_DOWN(PanelKanjiPad::OnMouseDown
)
29 EVT_LEFT_UP(PanelKanjiPad::OnMouseUp
)
30 EVT_LEAVE_WINDOW(PanelKanjiPad::OnLeaveWindow
)
31 EVT_MOTION(PanelKanjiPad::OnMouseMove
)
32 EVT_RIGHT_DOWN(PanelKanjiPad::OnMouseRightDown
)
33 EVT_PAINT(PanelKanjiPad::OnPaint
)
34 EVT_END_PROCESS(wxID_ANY
, PanelKanjiPad::AfterEngineCall
)
37 PanelKanjiPad::PanelKanjiPad(wxWindow
*owner
,
42 const wxString
& name
) : wxPanel(owner
, id
, pos
,
47 kpStdout
=kpStderr
=NULL
;
49 for(int i
=0;i
<KANJIPAD_MAX_KANJI
;i
++) results
[i
]=_T('\0');
52 void PanelKanjiPad::OnMouseDown(wxMouseEvent
& ev
) {
53 currentStroke
.push_back(ev
.GetPosition());
55 printf("MouseDown: [%d/%d]\n", currentStroke
.back().x
, currentStroke
.back().y
);
60 void PanelKanjiPad::OnMouseUp(wxMouseEvent
& ev
) {
64 printf("MouseUp: [%d/%d]\n", currentStroke
.back().x
, currentStroke
.back().y
);
66 strokes
.push_back(currentStroke
);
67 currentStroke
.clear();
71 void PanelKanjiPad::OnLeaveWindow(wxMouseEvent
& ev
) {
72 if(isDrawing
) OnMouseUp(ev
);
75 void PanelKanjiPad::OnMouseMove(wxMouseEvent
& ev
) {
77 wxPoint pCurrent
= ev
.GetPosition();
78 wxPoint pLast
= currentStroke
.back();
82 dc
.SetBrush(*wxBLACK_BRUSH
);
83 dc
.DrawLine(pLast
.x
, pLast
.y
, pCurrent
.x
, pCurrent
.y
);
84 dc
.SetBrush(wxNullBrush
);
86 /* Append point to stroke */
87 currentStroke
.push_back(pCurrent
);
89 printf("MouseMove: [%d/%d]\n", currentStroke
.back().x
, currentStroke
.back().y
);
94 void PanelKanjiPad::Clear() {
95 currentStroke
.clear();
99 void PanelKanjiPad::OnPaint(wxPaintEvent
& ev
) {
101 dc
.SetBackground(*wxWHITE_BRUSH
);
102 dc
.SetBrush(*wxBLACK_BRUSH
);
108 /* Draw all strokes */
109 for(list
< list
<wxPoint
> >::iterator li
= strokes
.begin();
110 li
!=strokes
.end(); li
++) {
112 pList
= new wxPoint
[pCount
];
114 for(list
<wxPoint
>::iterator pi
= li
->begin();
115 pi
!= li
->end(); pi
++) {
119 dc
.DrawLines(pCount
, pList
);
123 dc
.SetBrush(wxNullBrush
);
126 void PanelKanjiPad::OnMouseRightDown(wxMouseEvent
& ev
) {
128 wxPoint p
= ev
.GetPosition();
129 currentStroke
.clear();
130 currentStroke
.push_back(p
);
132 /* For some reason, this call is slow! */
133 if(strokes
.size()>0) strokes
.pop_back();
138 list
< list
<wxPoint
> > const* PanelKanjiPad::GetStrokes() {return &strokes
;}
140 bool PanelKanjiPad::Search() {
141 /* Create string to send to back end */
142 /* kpengine takes alternating x y args for points via stdin.
143 '\n' breaks between the strokes. */
149 if(strokes
.size()<1) return false;
150 for(list
< list
<wxPoint
> >::const_iterator li
=strokes
.begin();
151 li
!=strokes
.end(); li
++) {
152 for(list
<wxPoint
>::const_iterator pi
=li
->begin();
153 pi
!=li
->end(); pi
++) {
154 charsWritten
= sprintf(buffer
, "%d %d ", pi
->x
, pi
->y
);
155 buffer
[charsWritten
]='\0';
156 points
.append(buffer
);
162 /* Connect to back end */
163 kpengine
= new wxProcess(this);
164 kpengine
->Redirect();
166 wxString command
= _T(".\\kpengine");
168 wxString command
= _T("./kpengine");
170 kpPid
= wxExecute(command
, wxEXEC_ASYNC
, kpengine
);
172 /* Grab our streams */
173 kpStdin
= kpengine
->GetOutputStream();
174 kpStdout
= kpengine
->GetInputStream();
175 kpStderr
= kpengine
->GetErrorStream();
178 wxMessageBox(_T("ERROR: kpengine could not start!"),
179 _T("Error!"), wxOK
| wxICON_ERROR
, this);
180 } else if(!kpStdin
|| !kpStdout
|| !kpStderr
) {
181 wxMessageBox(_T("ERROR: Could not capture streams from kpengine!"),
182 _T("Error!"), wxOK
| wxICON_ERROR
, this);
183 wxKillError killres
= wxProcess::Kill(kpPid
, wxSIGTERM
);
184 if(killres
!=wxKILL_OK
)
185 wxMessageBox(wxString::Format(
186 _T("ERROR: Sending SIGTERM to kpengine returned "
187 "code %d!\n"), killres
),
188 _T("Error!"), wxOK
| wxICON_ERROR
, this);
191 /* If either of the above errors occurred, then bail. */
199 /* Write all data out to kpengine's stdin */
200 size_t len
= points
.length();
202 while(charsWritten
<len
) {
203 kpStdin
->Write((const void *)(points
.c_str() + charsWritten
),
205 charsWritten
+=kpStdin
->LastWrite();
209 /* Wait until the child process terminates */
210 /* However, don't wait forever! After 3 seconds, force it to close! */
211 wxLongLong stime
= wxGetLocalTime();
212 while(kpengine
&& (wxGetLocalTime() - stime
< 3000))
215 return (results
[0] != _T('\0'));
219 void PanelKanjiPad::AfterEngineCall(wxProcessEvent
& ev
) {
220 if(ev
.GetPid()==kpPid
) {
225 memset((void *)buffer
, 0, 81);
227 for(int i
=0;i
<KANJIPAD_MAX_KANJI
;i
++) results
[i
]=_T('\0');
228 if(kpStdout
->CanRead()) {
229 kpStdout
->Read(buffer
, 80);
233 len
= strlen(buffer
);
234 for(int i
=0;i
<KANJIPAD_MAX_KANJI
;i
++) {
235 if(index
<strlen(buffer
)) {
236 results
[i
] = atoi(buffer
+index
);
237 index
= strchr(buffer
+index
, ' ') - buffer
+ 1;
243 if(kpStderr
->CanRead()) {
244 kpStderr
->Read(buffer
, 80);
247 if(strlen(buffer
)>0) {
248 string
errstr("Errors: [");
249 errstr
.append(buffer
);
250 while(kpStderr
->CanRead()) {
251 kpStderr
->Read(buffer
, 80);
252 errstr
.append(buffer
);
254 errstr
.append("]\n");
255 wxMessageBox(wxString(errstr
.c_str(), wxConvUTF8
),
256 _T("Error on kpengine call"),
257 wxOK
| wxICON_ERROR
, this);