]> git.saurik.com Git - wxWidgets.git/blame - src/stc/PlatWX.cpp
drawing circles with a transparent pen was filling of course...
[wxWidgets.git] / src / stc / PlatWX.cpp
CommitLineData
9ce192d4 1// Scintilla source code edit control
be5a51fb 2// PlatWX.cxx - implementation of platform facilities on wxWidgets
9ce192d4
RD
3// Copyright 1998-1999 by Neil Hodgson <neilh@scintilla.org>
4// Robin Dunn <robin@aldunn.com>
5// The License.txt file describes the conditions under which this software may be distributed.
6
f6bcfd97 7#include <ctype.h>
9ce192d4 8
1a2fb4cd 9#include <wx/wx.h>
10ef30eb 10#include <wx/encconv.h>
9e730a78
RD
11#include <wx/listctrl.h>
12#include <wx/mstream.h>
13#include <wx/image.h>
14#include <wx/imaglist.h>
1a2fb4cd 15
9ce192d4 16#include "Platform.h"
1a2fb4cd 17#include "PlatWX.h"
9ce192d4
RD
18#include "wx/stc/stc.h"
19
f97d84a6
RD
20
21#ifdef __WXGTK__
22#include <gtk/gtk.h>
23#endif
24
1a2fb4cd 25
9ce192d4 26Point Point::FromLong(long lpoint) {
f6bcfd97 27 return Point(lpoint & 0xFFFF, lpoint >> 16);
9ce192d4
RD
28}
29
30wxRect wxRectFromPRectangle(PRectangle prc) {
d13ea3aa
RD
31 wxRect r(prc.left, prc.top,
32 prc.Width(), prc.Height());
33 return r;
9ce192d4
RD
34}
35
36PRectangle PRectangleFromwxRect(wxRect rc) {
bec17edf 37 return PRectangle(rc.GetLeft(), rc.GetTop(),
04ebdf40 38 rc.GetRight()+1, rc.GetBottom()+1);
9ce192d4
RD
39}
40
1a2fb4cd
RD
41wxColour wxColourFromCA(const ColourAllocated& ca) {
42 ColourDesired cd(ca.AsLong());
c8b75e94
WS
43 return wxColour((unsigned char)cd.GetRed(),
44 (unsigned char)cd.GetGreen(),
45 (unsigned char)cd.GetBlue());
9ce192d4
RD
46}
47
1a2fb4cd 48//----------------------------------------------------------------------
9ce192d4
RD
49
50Palette::Palette() {
51 used = 0;
52 allowRealization = false;
53}
54
55Palette::~Palette() {
56 Release();
57}
58
59void Palette::Release() {
60 used = 0;
61}
62
63// This method either adds a colour to the list of wanted colours (want==true)
64// or retrieves the allocated colour back to the ColourPair.
65// This is one method to make it easier to keep the code for wanting and retrieving in sync.
66void Palette::WantFind(ColourPair &cp, bool want) {
67 if (want) {
68 for (int i=0; i < used; i++) {
69 if (entries[i].desired == cp.desired)
70 return;
71 }
72
73 if (used < numEntries) {
74 entries[used].desired = cp.desired;
1a2fb4cd 75 entries[used].allocated.Set(cp.desired.AsLong());
9ce192d4
RD
76 used++;
77 }
78 } else {
79 for (int i=0; i < used; i++) {
80 if (entries[i].desired == cp.desired) {
81 cp.allocated = entries[i].allocated;
82 return;
83 }
84 }
1a2fb4cd 85 cp.allocated.Set(cp.desired.AsLong());
9ce192d4
RD
86 }
87}
88
89void Palette::Allocate(Window &) {
90 if (allowRealization) {
91 }
92}
93
94
1a2fb4cd
RD
95//----------------------------------------------------------------------
96
9ce192d4
RD
97Font::Font() {
98 id = 0;
99 ascent = 0;
100}
101
102Font::~Font() {
103}
104
d1558f3d 105void Font::Create(const char *faceName, int characterSet, int size, bool bold, bool italic, bool extraFontFlag) {
1a2fb4cd 106 wxFontEncoding encoding;
65ec6247 107
9ce192d4 108 Release();
1a2fb4cd
RD
109
110 switch (characterSet) {
111 default:
112 case wxSTC_CHARSET_ANSI:
113 case wxSTC_CHARSET_DEFAULT:
114 encoding = wxFONTENCODING_DEFAULT;
115 break;
116
117 case wxSTC_CHARSET_BALTIC:
118 encoding = wxFONTENCODING_ISO8859_13;
119 break;
120
121 case wxSTC_CHARSET_CHINESEBIG5:
122 encoding = wxFONTENCODING_CP950;
123 break;
124
125 case wxSTC_CHARSET_EASTEUROPE:
126 encoding = wxFONTENCODING_ISO8859_2;
127 break;
128
129 case wxSTC_CHARSET_GB2312:
130 encoding = wxFONTENCODING_CP936;
131 break;
132
133 case wxSTC_CHARSET_GREEK:
134 encoding = wxFONTENCODING_ISO8859_7;
135 break;
136
137 case wxSTC_CHARSET_HANGUL:
138 encoding = wxFONTENCODING_CP949;
139 break;
140
141 case wxSTC_CHARSET_MAC:
142 encoding = wxFONTENCODING_DEFAULT;
143 break;
144
145 case wxSTC_CHARSET_OEM:
146 encoding = wxFONTENCODING_DEFAULT;
147 break;
148
149 case wxSTC_CHARSET_RUSSIAN:
150 encoding = wxFONTENCODING_KOI8;
151 break;
152
153 case wxSTC_CHARSET_SHIFTJIS:
154 encoding = wxFONTENCODING_CP932;
155 break;
156
157 case wxSTC_CHARSET_SYMBOL:
158 encoding = wxFONTENCODING_DEFAULT;
159 break;
160
161 case wxSTC_CHARSET_TURKISH:
162 encoding = wxFONTENCODING_ISO8859_9;
163 break;
164
165 case wxSTC_CHARSET_JOHAB:
166 encoding = wxFONTENCODING_DEFAULT;
167 break;
168
169 case wxSTC_CHARSET_HEBREW:
170 encoding = wxFONTENCODING_ISO8859_8;
171 break;
172
173 case wxSTC_CHARSET_ARABIC:
174 encoding = wxFONTENCODING_ISO8859_6;
175 break;
176
177 case wxSTC_CHARSET_VIETNAMESE:
178 encoding = wxFONTENCODING_DEFAULT;
179 break;
180
181 case wxSTC_CHARSET_THAI:
182 encoding = wxFONTENCODING_ISO8859_11;
183 break;
184 }
185
10ef30eb
RD
186 wxFontEncodingArray ea = wxEncodingConverter::GetPlatformEquivalents(encoding);
187 if (ea.GetCount())
188 encoding = ea[0];
1a2fb4cd 189
d1558f3d 190 wxFont* font = new wxFont(size,
9ce192d4
RD
191 wxDEFAULT,
192 italic ? wxITALIC : wxNORMAL,
193 bold ? wxBOLD : wxNORMAL,
194 false,
0c5b83b0 195 stc2wx(faceName),
1a2fb4cd 196 encoding);
d1558f3d
RD
197 font->SetNoAntiAliasing(!extraFontFlag);
198 id = font;
9ce192d4
RD
199}
200
201
202void Font::Release() {
203 if (id)
1a2fb4cd 204 delete (wxFont*)id;
9ce192d4
RD
205 id = 0;
206}
207
1a2fb4cd
RD
208//----------------------------------------------------------------------
209
210class SurfaceImpl : public Surface {
211private:
212 wxDC* hdc;
213 bool hdcOwned;
214 wxBitmap* bitmap;
215 int x;
216 int y;
217 bool unicodeMode;
9ce192d4 218
1a2fb4cd
RD
219public:
220 SurfaceImpl();
221 ~SurfaceImpl();
222
9e730a78
RD
223 virtual void Init(WindowID wid);
224 virtual void Init(SurfaceID sid, WindowID wid);
225 virtual void InitPixMap(int width, int height, Surface *surface_, WindowID wid);
226
227 virtual void Release();
228 virtual bool Initialised();
229 virtual void PenColour(ColourAllocated fore);
230 virtual int LogPixelsY();
231 virtual int DeviceHeightFont(int points);
232 virtual void MoveTo(int x_, int y_);
233 virtual void LineTo(int x_, int y_);
234 virtual void Polygon(Point *pts, int npts, ColourAllocated fore, ColourAllocated back);
235 virtual void RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back);
236 virtual void FillRectangle(PRectangle rc, ColourAllocated back);
237 virtual void FillRectangle(PRectangle rc, Surface &surfacePattern);
238 virtual void RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back);
239 virtual void Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back);
240 virtual void Copy(PRectangle rc, Point from, Surface &surfaceSource);
241
242 virtual void DrawTextNoClip(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back);
243 virtual void DrawTextClipped(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back);
244 virtual void DrawTextTransparent(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore);
245 virtual void MeasureWidths(Font &font_, const char *s, int len, int *positions);
246 virtual int WidthText(Font &font_, const char *s, int len);
247 virtual int WidthChar(Font &font_, char ch);
248 virtual int Ascent(Font &font_);
249 virtual int Descent(Font &font_);
250 virtual int InternalLeading(Font &font_);
251 virtual int ExternalLeading(Font &font_);
252 virtual int Height(Font &font_);
253 virtual int AverageCharWidth(Font &font_);
254
255 virtual int SetPalette(Palette *pal, bool inBackGround);
256 virtual void SetClip(PRectangle rc);
257 virtual void FlushCachedState();
258
259 virtual void SetUnicodeMode(bool unicodeMode_);
260 virtual void SetDBCSMode(int codePage);
1a2fb4cd
RD
261
262 void BrushColour(ColourAllocated back);
263 void SetFont(Font &font_);
264};
265
266
267
268SurfaceImpl::SurfaceImpl() :
9ce192d4 269 hdc(0), hdcOwned(0), bitmap(0),
1a2fb4cd
RD
270 x(0), y(0), unicodeMode(0)
271{}
9ce192d4 272
1a2fb4cd 273SurfaceImpl::~SurfaceImpl() {
9ce192d4
RD
274 Release();
275}
276
9e730a78 277void SurfaceImpl::Init(WindowID wid) {
81b32ce5 278#if 0
9ce192d4
RD
279 Release();
280 hdc = new wxMemoryDC();
281 hdcOwned = true;
81b32ce5 282#else
09bb2551 283 // On Mac and GTK the DC is not really valid until it has a bitmap
81b32ce5
RD
284 // selected into it. So instead of just creating the DC with no bitmap,
285 // go ahead and give it one.
9e730a78 286 InitPixMap(1,1,NULL,wid);
0f713d48 287#endif
9ce192d4
RD
288}
289
9e730a78 290void SurfaceImpl::Init(SurfaceID hdc_, WindowID) {
9ce192d4 291 Release();
1a2fb4cd 292 hdc = (wxDC*)hdc_;
9ce192d4
RD
293}
294
88a8b04e 295void SurfaceImpl::InitPixMap(int width, int height, Surface *WXUNUSED(surface_), WindowID) {
9ce192d4 296 Release();
1a2fb4cd 297 hdc = new wxMemoryDC();
9ce192d4 298 hdcOwned = true;
2beb01db
RD
299 if (width < 1) width = 1;
300 if (height < 1) height = 1;
21156596 301 bitmap = new wxBitmap(width, height);
9ce192d4 302 ((wxMemoryDC*)hdc)->SelectObject(*bitmap);
9ce192d4
RD
303}
304
9e730a78
RD
305
306void SurfaceImpl::Release() {
307 if (bitmap) {
308 ((wxMemoryDC*)hdc)->SelectObject(wxNullBitmap);
309 delete bitmap;
310 bitmap = 0;
311 }
312 if (hdcOwned) {
313 delete hdc;
314 hdc = 0;
315 hdcOwned = false;
316 }
317}
318
319
320bool SurfaceImpl::Initialised() {
321 return hdc != 0;
322}
323
324
1a2fb4cd
RD
325void SurfaceImpl::PenColour(ColourAllocated fore) {
326 hdc->SetPen(wxPen(wxColourFromCA(fore), 1, wxSOLID));
9ce192d4
RD
327}
328
1a2fb4cd
RD
329void SurfaceImpl::BrushColour(ColourAllocated back) {
330 hdc->SetBrush(wxBrush(wxColourFromCA(back), wxSOLID));
9ce192d4
RD
331}
332
1a2fb4cd 333void SurfaceImpl::SetFont(Font &font_) {
21156596 334 if (font_.GetID()) {
1a2fb4cd 335 hdc->SetFont(*((wxFont*)font_.GetID()));
f6bcfd97 336 }
9ce192d4
RD
337}
338
1a2fb4cd 339int SurfaceImpl::LogPixelsY() {
9ce192d4
RD
340 return hdc->GetPPI().y;
341}
342
1a2fb4cd 343int SurfaceImpl::DeviceHeightFont(int points) {
9968ba85 344 return points;
f6bcfd97
BP
345}
346
1a2fb4cd 347void SurfaceImpl::MoveTo(int x_, int y_) {
9ce192d4
RD
348 x = x_;
349 y = y_;
350}
351
1a2fb4cd 352void SurfaceImpl::LineTo(int x_, int y_) {
9ce192d4
RD
353 hdc->DrawLine(x,y, x_,y_);
354 x = x_;
355 y = y_;
356}
357
1a2fb4cd 358void SurfaceImpl::Polygon(Point *pts, int npts, ColourAllocated fore, ColourAllocated back) {
9ce192d4 359 PenColour(fore);
1a2fb4cd 360 BrushColour(back);
9ce192d4
RD
361 hdc->DrawPolygon(npts, (wxPoint*)pts);
362}
363
1a2fb4cd 364void SurfaceImpl::RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back) {
9ce192d4 365 PenColour(fore);
1a2fb4cd 366 BrushColour(back);
9ce192d4
RD
367 hdc->DrawRectangle(wxRectFromPRectangle(rc));
368}
369
1a2fb4cd
RD
370void SurfaceImpl::FillRectangle(PRectangle rc, ColourAllocated back) {
371 BrushColour(back);
9ce192d4
RD
372 hdc->SetPen(*wxTRANSPARENT_PEN);
373 hdc->DrawRectangle(wxRectFromPRectangle(rc));
374}
375
1a2fb4cd 376void SurfaceImpl::FillRectangle(PRectangle rc, Surface &surfacePattern) {
9ce192d4 377 wxBrush br;
1a2fb4cd
RD
378 if (((SurfaceImpl&)surfacePattern).bitmap)
379 br = wxBrush(*((SurfaceImpl&)surfacePattern).bitmap);
9ce192d4
RD
380 else // Something is wrong so display in red
381 br = wxBrush(*wxRED, wxSOLID);
382 hdc->SetPen(*wxTRANSPARENT_PEN);
383 hdc->SetBrush(br);
384 hdc->DrawRectangle(wxRectFromPRectangle(rc));
385}
386
1a2fb4cd 387void SurfaceImpl::RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back) {
9ce192d4 388 PenColour(fore);
1a2fb4cd 389 BrushColour(back);
f6bcfd97 390 hdc->DrawRoundedRectangle(wxRectFromPRectangle(rc), 4);
9ce192d4
RD
391}
392
1a2fb4cd 393void SurfaceImpl::Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back) {
9ce192d4 394 PenColour(fore);
1a2fb4cd 395 BrushColour(back);
9ce192d4
RD
396 hdc->DrawEllipse(wxRectFromPRectangle(rc));
397}
398
1a2fb4cd 399void SurfaceImpl::Copy(PRectangle rc, Point from, Surface &surfaceSource) {
f6bcfd97
BP
400 wxRect r = wxRectFromPRectangle(rc);
401 hdc->Blit(r.x, r.y, r.width, r.height,
1a2fb4cd
RD
402 ((SurfaceImpl&)surfaceSource).hdc,
403 from.x, from.y, wxCOPY);
9ce192d4
RD
404}
405
1a2fb4cd
RD
406void SurfaceImpl::DrawTextNoClip(PRectangle rc, Font &font, int ybase,
407 const char *s, int len,
408 ColourAllocated fore, ColourAllocated back) {
9ce192d4 409 SetFont(font);
1a2fb4cd
RD
410 hdc->SetTextForeground(wxColourFromCA(fore));
411 hdc->SetTextBackground(wxColourFromCA(back));
3d7a4fe8 412 FillRectangle(rc, back);
9ce192d4
RD
413
414 // ybase is where the baseline should be, but wxWin uses the upper left
415 // corner, so I need to calculate the real position for the text...
d13ea3aa 416 hdc->DrawText(stc2wx(s, len), rc.left, ybase - font.ascent);
9ce192d4
RD
417}
418
1a2fb4cd
RD
419void SurfaceImpl::DrawTextClipped(PRectangle rc, Font &font, int ybase,
420 const char *s, int len,
421 ColourAllocated fore, ColourAllocated back) {
9ce192d4 422 SetFont(font);
1a2fb4cd
RD
423 hdc->SetTextForeground(wxColourFromCA(fore));
424 hdc->SetTextBackground(wxColourFromCA(back));
3d7a4fe8 425 FillRectangle(rc, back);
9ce192d4
RD
426 hdc->SetClippingRegion(wxRectFromPRectangle(rc));
427
428 // see comments above
d13ea3aa 429 hdc->DrawText(stc2wx(s, len), rc.left, ybase - font.ascent);
3d7a4fe8 430 hdc->DestroyClippingRegion();
9ce192d4
RD
431}
432
9e730a78
RD
433
434void SurfaceImpl::DrawTextTransparent(PRectangle rc, Font &font, int ybase,
435 const char *s, int len,
436 ColourAllocated fore) {
437
9ce192d4 438 SetFont(font);
9e730a78
RD
439 hdc->SetTextForeground(wxColourFromCA(fore));
440 hdc->SetBackgroundMode(wxTRANSPARENT);
1a2fb4cd 441
9e730a78
RD
442 // ybase is where the baseline should be, but wxWin uses the upper left
443 // corner, so I need to calculate the real position for the text...
d13ea3aa 444 hdc->DrawText(stc2wx(s, len), rc.left, ybase - font.ascent);
9e730a78
RD
445
446 hdc->SetBackgroundMode(wxSOLID);
9ce192d4
RD
447}
448
1a2fb4cd 449
10ef30eb 450void SurfaceImpl::MeasureWidths(Font &font, const char *s, int len, int *positions) {
9e730a78 451
d1558f3d
RD
452 wxString str = stc2wx(s, len);
453 wxArrayInt tpos;
10ef30eb 454
d1558f3d 455 SetFont(font);
9e730a78 456
d1558f3d 457 hdc->GetPartialTextExtents(str, tpos);
10ef30eb
RD
458
459#if wxUSE_UNICODE
460 // Map the widths for UCS-2 characters back to the UTF-8 input string
9e730a78
RD
461 // NOTE: I don't think this is right for when sizeof(wxChar) > 2, ie wxGTK2
462 // so figure it out and fix it!
d1558f3d 463 size_t i = 0;
10ef30eb 464 size_t ui = 0;
d99859e4 465 while ((int)i < len) {
10ef30eb
RD
466 unsigned char uch = (unsigned char)s[i];
467 positions[i++] = tpos[ui];
468 if (uch >= 0x80) {
469 if (uch < (0x80 + 0x40 + 0x20)) {
470 positions[i++] = tpos[ui];
471 } else {
472 positions[i++] = tpos[ui];
473 positions[i++] = tpos[ui];
474 }
475 }
476 ui++;
477 }
478#else
479
480 // If not unicode then just use the widths we have
d1558f3d 481 memcpy(positions, tpos.begin(), len * sizeof(int));
10ef30eb 482#endif
9ce192d4
RD
483}
484
10ef30eb 485
9e730a78
RD
486int SurfaceImpl::WidthText(Font &font, const char *s, int len) {
487 SetFont(font);
488 int w;
489 int h;
490
491 hdc->GetTextExtent(stc2wx(s, len), &w, &h);
492 return w;
493}
494
495
1a2fb4cd 496int SurfaceImpl::WidthChar(Font &font, char ch) {
9ce192d4
RD
497 SetFont(font);
498 int w;
499 int h;
10ef30eb
RD
500 char s[2] = { ch, 0 };
501
0c5b83b0 502 hdc->GetTextExtent(stc2wx(s, 1), &w, &h);
9ce192d4
RD
503 return w;
504}
505
1a2fb4cd 506#define EXTENT_TEST wxT(" `~!@#$%^&*()-_=+\\|[]{};:\"\'<,>.?/1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
9ce192d4 507
1a2fb4cd 508int SurfaceImpl::Ascent(Font &font) {
9ce192d4
RD
509 SetFont(font);
510 int w, h, d, e;
511 hdc->GetTextExtent(EXTENT_TEST, &w, &h, &d, &e);
512 font.ascent = h - d;
513 return font.ascent;
514}
515
1a2fb4cd 516int SurfaceImpl::Descent(Font &font) {
9ce192d4
RD
517 SetFont(font);
518 int w, h, d, e;
519 hdc->GetTextExtent(EXTENT_TEST, &w, &h, &d, &e);
520 return d;
521}
522
88a8b04e 523int SurfaceImpl::InternalLeading(Font &WXUNUSED(font)) {
9ce192d4
RD
524 return 0;
525}
526
1a2fb4cd 527int SurfaceImpl::ExternalLeading(Font &font) {
9ce192d4
RD
528 SetFont(font);
529 int w, h, d, e;
530 hdc->GetTextExtent(EXTENT_TEST, &w, &h, &d, &e);
531 return e;
532}
533
1a2fb4cd 534int SurfaceImpl::Height(Font &font) {
9ce192d4 535 SetFont(font);
d13ea3aa 536 return hdc->GetCharHeight() + 1;
9ce192d4
RD
537}
538
1a2fb4cd 539int SurfaceImpl::AverageCharWidth(Font &font) {
9ce192d4
RD
540 SetFont(font);
541 return hdc->GetCharWidth();
542}
543
88a8b04e 544int SurfaceImpl::SetPalette(Palette *WXUNUSED(pal), bool WXUNUSED(inBackGround)) {
65ec6247 545 return 0;
9ce192d4
RD
546}
547
1a2fb4cd 548void SurfaceImpl::SetClip(PRectangle rc) {
9ce192d4
RD
549 hdc->SetClippingRegion(wxRectFromPRectangle(rc));
550}
551
1a2fb4cd 552void SurfaceImpl::FlushCachedState() {
f6bcfd97 553}
9ce192d4 554
1a2fb4cd 555void SurfaceImpl::SetUnicodeMode(bool unicodeMode_) {
1a2fb4cd
RD
556 unicodeMode=unicodeMode_;
557}
558
88a8b04e 559void SurfaceImpl::SetDBCSMode(int WXUNUSED(codePage)) {
9e730a78
RD
560 // dbcsMode = codePage == SC_CP_DBCS;
561}
562
563
1a2fb4cd
RD
564Surface *Surface::Allocate() {
565 return new SurfaceImpl;
566}
567
568
569//----------------------------------------------------------------------
570
571
572inline wxWindow* GETWIN(WindowID id) { return (wxWindow*)id; }
573
9ce192d4
RD
574Window::~Window() {
575}
576
577void Window::Destroy() {
9e730a78 578 if (id) {
7e126a07 579 Show(false);
1a2fb4cd 580 GETWIN(id)->Destroy();
9e730a78 581 }
9ce192d4
RD
582 id = 0;
583}
584
585bool Window::HasFocus() {
1a2fb4cd 586 return wxWindow::FindFocus() == GETWIN(id);
9ce192d4
RD
587}
588
589PRectangle Window::GetPosition() {
9e730a78 590 if (! id) return PRectangle();
1a2fb4cd 591 wxRect rc(GETWIN(id)->GetPosition(), GETWIN(id)->GetSize());
9ce192d4
RD
592 return PRectangleFromwxRect(rc);
593}
594
595void Window::SetPosition(PRectangle rc) {
f6bcfd97 596 wxRect r = wxRectFromPRectangle(rc);
1a2fb4cd 597 GETWIN(id)->SetSize(r);
9ce192d4
RD
598}
599
600void Window::SetPositionRelative(PRectangle rc, Window) {
601 SetPosition(rc); // ????
602}
603
604PRectangle Window::GetClientPosition() {
9e730a78 605 if (! id) return PRectangle();
1a2fb4cd 606 wxSize sz = GETWIN(id)->GetClientSize();
21156596 607 return PRectangle(0, 0, sz.x, sz.y);
9ce192d4
RD
608}
609
610void Window::Show(bool show) {
1a2fb4cd 611 GETWIN(id)->Show(show);
9ce192d4
RD
612}
613
614void Window::InvalidateAll() {
1a2fb4cd 615 GETWIN(id)->Refresh(false);
26f4607d 616 wxWakeUpIdle();
9ce192d4
RD
617}
618
619void Window::InvalidateRectangle(PRectangle rc) {
f6bcfd97 620 wxRect r = wxRectFromPRectangle(rc);
1a2fb4cd 621 GETWIN(id)->Refresh(false, &r);
26f4607d 622 wxWakeUpIdle();
9ce192d4
RD
623}
624
625void Window::SetFont(Font &font) {
1a2fb4cd 626 GETWIN(id)->SetFont(*((wxFont*)font.GetID()));
9ce192d4
RD
627}
628
629void Window::SetCursor(Cursor curs) {
630 int cursorId;
631
632 switch (curs) {
633 case cursorText:
634 cursorId = wxCURSOR_IBEAM;
635 break;
636 case cursorArrow:
637 cursorId = wxCURSOR_ARROW;
638 break;
639 case cursorUp:
640 cursorId = wxCURSOR_ARROW; // ** no up arrow... wxCURSOR_UPARROW;
641 break;
642 case cursorWait:
643 cursorId = wxCURSOR_WAIT;
644 break;
645 case cursorHoriz:
646 cursorId = wxCURSOR_SIZEWE;
647 break;
648 case cursorVert:
649 cursorId = wxCURSOR_SIZENS;
650 break;
651 case cursorReverseArrow:
15dadf31 652 cursorId = wxCURSOR_RIGHT_ARROW;
9ce192d4 653 break;
9e730a78
RD
654 case cursorHand:
655 cursorId = wxCURSOR_HAND;
1e545382 656 break;
9ce192d4
RD
657 default:
658 cursorId = wxCURSOR_ARROW;
659 break;
660 }
9f79d14b
CE
661#ifdef __WXMOTIF__
662 wxCursor wc = wxStockCursor(cursorId) ;
663#else
664 wxCursor wc = wxCursor(cursorId) ;
665#endif
cb1871ca 666 GETWIN(id)->SetCursor(wc);
9ce192d4
RD
667}
668
669
670void Window::SetTitle(const char *s) {
0c5b83b0 671 GETWIN(id)->SetTitle(stc2wx(s));
9ce192d4
RD
672}
673
674
769a9cb2
RD
675//----------------------------------------------------------------------
676// Helper classes for ListBox
677
267484bc 678
b0d0494f 679// This is a simple subclass of wxListView that just resets focus to the
9e730a78
RD
680// parent when it gets it.
681class wxSTCListBox : public wxListView {
451c5cc7 682public:
9e730a78
RD
683 wxSTCListBox(wxWindow* parent, wxWindowID id,
684 const wxPoint& pos, const wxSize& size,
685 long style)
686 : wxListView(parent, id, pos, size, style)
687 {}
451c5cc7 688
7e126a07 689
451c5cc7
RD
690 void OnFocus(wxFocusEvent& event) {
691 GetParent()->SetFocus();
692 event.Skip();
693 }
694
5f9eb69c 695 void OnKillFocus(wxFocusEvent& WXUNUSED(event)) {
b0d0494f
RD
696 // Do nothing. Prevents base class from resetting the colors...
697 }
7e126a07 698
719ee9c3
RD
699#ifdef __WXMAC__
700 // For some reason I don't understand yet the focus doesn't really leave
701 // the listbox like it should, so if we get any events feed them back to
702 // the wxSTC
703 void OnKeyDown(wxKeyEvent& event) {
704 GetGrandParent()->GetEventHandler()->ProcessEvent(event);
705 }
706 void OnChar(wxKeyEvent& event) {
707 GetGrandParent()->GetEventHandler()->ProcessEvent(event);
708 }
b0d0494f 709
719ee9c3
RD
710 // And we need to force the focus back when being destroyed
711 ~wxSTCListBox() {
712 GetGrandParent()->SetFocus();
7e126a07
WS
713 }
714#endif
715
451c5cc7
RD
716private:
717 DECLARE_EVENT_TABLE()
718};
719
9e730a78
RD
720BEGIN_EVENT_TABLE(wxSTCListBox, wxListView)
721 EVT_SET_FOCUS( wxSTCListBox::OnFocus)
b0d0494f 722 EVT_KILL_FOCUS(wxSTCListBox::OnKillFocus)
719ee9c3
RD
723#ifdef __WXMAC__
724 EVT_KEY_DOWN( wxSTCListBox::OnKeyDown)
725 EVT_CHAR( wxSTCListBox::OnChar)
726#endif
451c5cc7
RD
727END_EVENT_TABLE()
728
729
730
267484bc 731
9e730a78
RD
732// A window to place the wxSTCListBox upon
733class wxSTCListBoxWin : public wxWindow {
734private:
735 wxListView* lv;
736 CallBackAction doubleClickAction;
737 void* doubleClickActionData;
f97d84a6 738public:
9e730a78 739 wxSTCListBoxWin(wxWindow* parent, wxWindowID id) :
d13ea3aa 740 wxWindow(parent, id, wxDefaultPosition, wxSize(0,0), wxSIMPLE_BORDER )
9e730a78
RD
741 {
742
9e730a78
RD
743 lv = new wxSTCListBox(this, id, wxDefaultPosition, wxDefaultSize,
744 wxLC_REPORT | wxLC_SINGLE_SEL | wxLC_NO_HEADER | wxNO_BORDER);
745 lv->SetCursor(wxCursor(wxCURSOR_ARROW));
746 lv->InsertColumn(0, wxEmptyString);
747 lv->InsertColumn(1, wxEmptyString);
b0d0494f
RD
748
749 // Eventhough we immediately reset the focus to the parent, this helps
750 // things to look right...
751 lv->SetFocus();
752
6612393c
RD
753 Hide();
754 }
755
7e126a07 756
a4f3565e
RD
757 // On OSX and (possibly others) there can still be pending
758 // messages/events for the list control when Scintilla wants to
759 // close it, so do a pending delete of it instead of destroying
760 // immediately.
761 bool Destroy() {
d13ea3aa 762#ifdef __WXMAC__
719ee9c3 763 // The bottom edge of this window is not getting properly
d13ea3aa
RD
764 // refreshed upon deletion, so help it out...
765 wxWindow* p = GetParent();
766 wxRect r(GetPosition(), GetSize());
767 r.SetHeight(r.GetHeight()+1);
768 p->Refresh(false, &r);
769#endif
a4f3565e
RD
770 if ( !wxPendingDelete.Member(this) )
771 wxPendingDelete.Append(this);
7e126a07 772 return true;
f97d84a6
RD
773 }
774
7e126a07 775
9e730a78
RD
776 int IconWidth() {
777 wxImageList* il = lv->GetImageList(wxIMAGE_LIST_SMALL);
778 if (il != NULL) {
779 int w, h;
780 il->GetSize(0, w, h);
781 return w;
782 }
783 return 0;
784 }
f97d84a6 785
769a9cb2 786
9e730a78
RD
787 void SetDoubleClickAction(CallBackAction action, void *data) {
788 doubleClickAction = action;
789 doubleClickActionData = data;
790 }
451c5cc7 791
769a9cb2 792
9e730a78
RD
793 void OnFocus(wxFocusEvent& event) {
794 GetParent()->SetFocus();
795 event.Skip();
796 }
769a9cb2
RD
797
798 void OnSize(wxSizeEvent& event) {
d13ea3aa 799 // resize the child
9e730a78 800 wxSize sz = GetClientSize();
d13ea3aa 801 lv->SetSize(sz);
9e730a78
RD
802 // reset the column widths
803 lv->SetColumnWidth(0, IconWidth()+4);
804 lv->SetColumnWidth(1, sz.x - 2 - lv->GetColumnWidth(0) -
805 wxSystemSettings::GetMetric(wxSYS_VSCROLL_X));
806 event.Skip();
769a9cb2 807 }
769a9cb2 808
719493e1
RD
809#ifdef __WXMAC__
810 virtual bool Show(bool show = true) {
811 bool rv = wxWindow::Show(show);
812 GetParent()->Refresh(false);
813 return rv;
814 }
815#endif
816
5f9eb69c 817 void OnActivate(wxListEvent& WXUNUSED(event)) {
9e730a78 818 doubleClickAction(doubleClickActionData);
769a9cb2 819 }
9e730a78
RD
820
821 wxListView* GetLB() { return lv; }
769a9cb2
RD
822
823private:
769a9cb2
RD
824 DECLARE_EVENT_TABLE()
825};
826
9e730a78
RD
827
828BEGIN_EVENT_TABLE(wxSTCListBoxWin, wxWindow)
7e126a07
WS
829 EVT_SET_FOCUS ( wxSTCListBoxWin::OnFocus)
830 EVT_SIZE ( wxSTCListBoxWin::OnSize)
831 EVT_LIST_ITEM_ACTIVATED(wxID_ANY, wxSTCListBoxWin::OnActivate)
769a9cb2 832END_EVENT_TABLE()
769a9cb2 833
9e730a78
RD
834
835
836inline wxSTCListBoxWin* GETLBW(WindowID win) {
837 return ((wxSTCListBoxWin*)win);
838}
839
840inline wxListView* GETLB(WindowID win) {
841 return GETLBW(win)->GetLB();
1a2fb4cd 842}
769a9cb2
RD
843
844//----------------------------------------------------------------------
845
9e730a78
RD
846class ListBoxImpl : public ListBox {
847private:
848 int lineHeight;
849 bool unicodeMode;
850 int desiredVisibleRows;
851 int aveCharWidth;
852 int maxStrWidth;
853 wxImageList* imgList;
854 wxArrayInt* imgTypeMap;
855
856public:
857 ListBoxImpl();
858 ~ListBoxImpl();
859
860 virtual void SetFont(Font &font);
861 virtual void Create(Window &parent, int ctrlID, int lineHeight_, bool unicodeMode_);
862 virtual void SetAverageCharWidth(int width);
863 virtual void SetVisibleRows(int rows);
864 virtual PRectangle GetDesiredRect();
865 virtual int CaretFromEdge();
866 virtual void Clear();
867 virtual void Append(char *s, int type = -1);
868 virtual int Length();
869 virtual void Select(int n);
870 virtual int GetSelection();
871 virtual int Find(const char *prefix);
872 virtual void GetValue(int n, char *value, int len);
9e730a78
RD
873 virtual void RegisterImage(int type, const char *xpm_data);
874 virtual void ClearRegisteredImages();
875 virtual void SetDoubleClickAction(CallBackAction, void *);
876
877};
878
879
880ListBoxImpl::ListBoxImpl()
881 : lineHeight(10), unicodeMode(false),
882 desiredVisibleRows(5), aveCharWidth(8), maxStrWidth(0),
883 imgList(NULL), imgTypeMap(NULL)
884{
9ce192d4
RD
885}
886
9e730a78
RD
887ListBoxImpl::~ListBoxImpl() {
888 if (imgList) {
889 delete imgList;
890 imgList = NULL;
891 }
892 if (imgTypeMap) {
893 delete imgTypeMap;
894 imgTypeMap = NULL;
895 }
9ce192d4
RD
896}
897
9e730a78
RD
898
899void ListBoxImpl::SetFont(Font &font) {
900 GETLB(id)->SetFont(*((wxFont*)font.GetID()));
901}
902
903
904void ListBoxImpl::Create(Window &parent, int ctrlID, int lineHeight_, bool unicodeMode_) {
905 lineHeight = lineHeight_;
906 unicodeMode = unicodeMode_;
907 maxStrWidth = 0;
1a2fb4cd 908 id = new wxSTCListBoxWin(GETWIN(parent.GetID()), ctrlID);
9e730a78
RD
909 if (imgList != NULL)
910 GETLB(id)->SetImageList(imgList, wxIMAGE_LIST_SMALL);
9ce192d4
RD
911}
912
9e730a78
RD
913
914void ListBoxImpl::SetAverageCharWidth(int width) {
915 aveCharWidth = width;
916}
917
918
919void ListBoxImpl::SetVisibleRows(int rows) {
769a9cb2 920 desiredVisibleRows = rows;
f3c2c221
RD
921}
922
9e730a78
RD
923
924PRectangle ListBoxImpl::GetDesiredRect() {
925 // wxListCtrl doesn't have a DoGetBestSize, so instead we kept track of
926 // the max size in Append and calculate it here...
927 int maxw = maxStrWidth;
1e545382 928 int maxh ;
9e730a78
RD
929
930 // give it a default if there are no lines, and/or add a bit more
931 if (maxw == 0) maxw = 100;
932 maxw += aveCharWidth * 3 +
933 GETLBW(id)->IconWidth() + wxSystemSettings::GetMetric(wxSYS_VSCROLL_X);
934 if (maxw > 350)
935 maxw = 350;
936
937 // estimate a desired height
938 int count = GETLB(id)->GetItemCount();
939 if (count) {
940 wxRect rect;
941 GETLB(id)->GetItemRect(0, rect);
942 maxh = count * rect.GetHeight();
943 if (maxh > 140) // TODO: Use desiredVisibleRows??
944 maxh = 140;
945
946 // Try to make the size an exact multiple of some number of lines
947 int lines = maxh / rect.GetHeight();
948 maxh = (lines + 1) * rect.GetHeight() + 2;
949 }
950 else
951 maxh = 100;
952
d134f170
RD
953 PRectangle rc;
954 rc.top = 0;
955 rc.left = 0;
9e730a78
RD
956 rc.right = maxw;
957 rc.bottom = maxh;
d134f170
RD
958 return rc;
959}
960
d134f170 961
9e730a78
RD
962int ListBoxImpl::CaretFromEdge() {
963 return 4 + GETLBW(id)->IconWidth();
d134f170
RD
964}
965
9e730a78
RD
966
967void ListBoxImpl::Clear() {
968 GETLB(id)->DeleteAllItems();
9ce192d4
RD
969}
970
9e730a78
RD
971
972void ListBoxImpl::Append(char *s, int type) {
973 wxString text = stc2wx(s);
974 long count = GETLB(id)->GetItemCount();
975 long itemID = GETLB(id)->InsertItem(count, wxEmptyString);
976 GETLB(id)->SetItem(itemID, 1, text);
977 int itemWidth = 0;
978 GETLB(id)->GetTextExtent(text, &itemWidth, NULL);
979 maxStrWidth = wxMax(maxStrWidth, itemWidth);
980 if (type != -1) {
981 wxCHECK_RET(imgTypeMap, wxT("Unexpected NULL imgTypeMap"));
982 long idx = imgTypeMap->Item(type);
983 GETLB(id)->SetItemImage(itemID, idx, idx);
984 }
9ce192d4
RD
985}
986
9e730a78
RD
987
988int ListBoxImpl::Length() {
989 return GETLB(id)->GetItemCount();
9ce192d4
RD
990}
991
9e730a78
RD
992
993void ListBoxImpl::Select(int n) {
7e126a07 994 bool select = true;
895066d8
RD
995 if (n == -1) {
996 n = 0;
7e126a07 997 select = false;
895066d8 998 }
9e730a78
RD
999 GETLB(id)->Focus(n);
1000 GETLB(id)->Select(n, select);
9ce192d4
RD
1001}
1002
9e730a78
RD
1003
1004int ListBoxImpl::GetSelection() {
1005 return GETLB(id)->GetFirstSelected();
9ce192d4
RD
1006}
1007
9e730a78 1008
88a8b04e 1009int ListBoxImpl::Find(const char *WXUNUSED(prefix)) {
b8b0e402 1010 // No longer used
7e126a07 1011 return wxNOT_FOUND;
9ce192d4
RD
1012}
1013
9e730a78
RD
1014
1015void ListBoxImpl::GetValue(int n, char *value, int len) {
1016 wxListItem item;
1017 item.SetId(n);
1018 item.SetColumn(1);
1019 item.SetMask(wxLIST_MASK_TEXT);
1020 GETLB(id)->GetItem(item);
1021 strncpy(value, wx2stc(item.GetText()), len);
9ce192d4
RD
1022 value[len-1] = '\0';
1023}
1024
9e730a78
RD
1025
1026void ListBoxImpl::RegisterImage(int type, const char *xpm_data) {
1027 wxMemoryInputStream stream(xpm_data, strlen(xpm_data)+1);
c8b75e94
WS
1028 wxImage img(stream, wxBITMAP_TYPE_XPM);
1029 wxBitmap bmp(img);
9e730a78
RD
1030
1031 if (! imgList) {
1032 // assumes all images are the same size
7e126a07 1033 imgList = new wxImageList(bmp.GetWidth(), bmp.GetHeight(), true);
9e730a78
RD
1034 imgTypeMap = new wxArrayInt;
1035 }
1036
1037 int idx = imgList->Add(bmp);
1038
1039 // do we need to extend the mapping array?
1040 wxArrayInt& itm = *imgTypeMap;
9a8ffadd 1041 if ( itm.GetCount() < (size_t)type+1)
9e730a78
RD
1042 itm.Add(-1, type - itm.GetCount() + 1);
1043
1044 // Add an item that maps type to the image index
1045 itm[type] = idx;
1046}
1047
1048void ListBoxImpl::ClearRegisteredImages() {
1049 if (imgList) {
1050 delete imgList;
1051 imgList = NULL;
1052 }
1053 if (imgTypeMap) {
1054 delete imgTypeMap;
1055 imgTypeMap = NULL;
1056 }
1057 if (id)
1058 GETLB(id)->SetImageList(NULL, wxIMAGE_LIST_SMALL);
1059}
1060
1061
1062void ListBoxImpl::SetDoubleClickAction(CallBackAction action, void *data) {
1063 GETLBW(id)->SetDoubleClickAction(action, data);
1064}
1065
1066
1067
1068ListBox::ListBox() {
1069}
1070
1071ListBox::~ListBox() {
1072}
1073
1074ListBox *ListBox::Allocate() {
1075 return new ListBoxImpl();
9ce192d4
RD
1076}
1077
1a2fb4cd 1078//----------------------------------------------------------------------
9ce192d4
RD
1079
1080Menu::Menu() : id(0) {
1081}
1082
1083void Menu::CreatePopUp() {
1084 Destroy();
1085 id = new wxMenu();
1086}
1087
1088void Menu::Destroy() {
1089 if (id)
1a2fb4cd 1090 delete (wxMenu*)id;
9ce192d4
RD
1091 id = 0;
1092}
1093
1094void Menu::Show(Point pt, Window &w) {
1a2fb4cd 1095 GETWIN(w.GetID())->PopupMenu((wxMenu*)id, pt.x - 4, pt.y);
9ce192d4
RD
1096 Destroy();
1097}
1098
1a2fb4cd 1099//----------------------------------------------------------------------
9ce192d4 1100
88a8b04e 1101DynamicLibrary *DynamicLibrary::Load(const char *WXUNUSED(modulePath)) {
e14d10b0
RD
1102 wxFAIL_MSG(wxT("Dynamic lexer loading not implemented yet"));
1103 return NULL;
1104}
1105
1106//----------------------------------------------------------------------
1107
1a2fb4cd 1108ColourDesired Platform::Chrome() {
9ce192d4 1109 wxColour c;
e1c6c6ae 1110 c = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
1a2fb4cd 1111 return ColourDesired(c.Red(), c.Green(), c.Blue());
9ce192d4
RD
1112}
1113
1a2fb4cd 1114ColourDesired Platform::ChromeHighlight() {
9ce192d4 1115 wxColour c;
e1c6c6ae 1116 c = wxSystemSettings::GetColour(wxSYS_COLOUR_3DHIGHLIGHT);
1a2fb4cd 1117 return ColourDesired(c.Red(), c.Green(), c.Blue());
9ce192d4
RD
1118}
1119
1120const char *Platform::DefaultFont() {
10ef30eb
RD
1121 static char buf[128];
1122 strcpy(buf, wxNORMAL_FONT->GetFaceName().mbc_str());
1123 return buf;
9ce192d4
RD
1124}
1125
1126int Platform::DefaultFontSize() {
9e730a78 1127 return wxNORMAL_FONT->GetPointSize();
9ce192d4
RD
1128}
1129
1130unsigned int Platform::DoubleClickTime() {
1131 return 500; // **** ::GetDoubleClickTime();
1132}
1133
9e730a78 1134bool Platform::MouseButtonBounce() {
7e126a07 1135 return false;
9e730a78 1136}
9ce192d4 1137void Platform::DebugDisplay(const char *s) {
0c5b83b0 1138 wxLogDebug(stc2wx(s));
9ce192d4
RD
1139}
1140
88a8b04e 1141bool Platform::IsKeyDown(int WXUNUSED(key)) {
9ce192d4
RD
1142 return false; // I don't think we'll need this.
1143}
1144
1145long Platform::SendScintilla(WindowID w,
1146 unsigned int msg,
1147 unsigned long wParam,
1148 long lParam) {
1149
1150 wxStyledTextCtrl* stc = (wxStyledTextCtrl*)w;
1151 return stc->SendMsg(msg, wParam, lParam);
1152}
1153
a834585d
RD
1154long Platform::SendScintillaPointer(WindowID w,
1155 unsigned int msg,
1156 unsigned long wParam,
1157 void *lParam) {
1158
1159 wxStyledTextCtrl* stc = (wxStyledTextCtrl*)w;
1160 return stc->SendMsg(msg, wParam, (long)lParam);
1161}
1162
9ce192d4
RD
1163
1164// These are utility functions not really tied to a platform
1165
1166int Platform::Minimum(int a, int b) {
1167 if (a < b)
1168 return a;
1169 else
1170 return b;
1171}
1172
1173int Platform::Maximum(int a, int b) {
1174 if (a > b)
1175 return a;
1176 else
1177 return b;
1178}
1179
1180#define TRACE
1181
1182void Platform::DebugPrintf(const char *format, ...) {
1183#ifdef TRACE
1184 char buffer[2000];
1185 va_list pArguments;
1186 va_start(pArguments, format);
1187 vsprintf(buffer,format,pArguments);
1188 va_end(pArguments);
1189 Platform::DebugDisplay(buffer);
1190#endif
1191}
1192
65ec6247
RD
1193
1194static bool assertionPopUps = true;
1195
1196bool Platform::ShowAssertionPopUps(bool assertionPopUps_) {
7e126a07
WS
1197 bool ret = assertionPopUps;
1198 assertionPopUps = assertionPopUps_;
1199 return ret;
65ec6247
RD
1200}
1201
1202void Platform::Assert(const char *c, const char *file, int line) {
7e126a07
WS
1203 char buffer[2000];
1204 sprintf(buffer, "Assertion [%s] failed at %s %d", c, file, line);
1205 if (assertionPopUps) {
1206 /*int idButton = */
1207 wxMessageBox(stc2wx(buffer),
1208 wxT("Assertion failure"),
1209 wxICON_HAND | wxOK);
1210// if (idButton == IDRETRY) {
1211// ::DebugBreak();
1212// } else if (idButton == IDIGNORE) {
1213// // all OK
1214// } else {
1215// abort();
1216// }
1217 } else {
1218 strcat(buffer, "\r\n");
1219 Platform::DebugDisplay(buffer);
1220 abort();
1221 }
65ec6247
RD
1222}
1223
1224
9ce192d4
RD
1225int Platform::Clamp(int val, int minVal, int maxVal) {
1226 if (val > maxVal)
1227 val = maxVal;
1228 if (val < minVal)
1229 val = minVal;
1230 return val;
1231}
1232
1233
88a8b04e 1234bool Platform::IsDBCSLeadByte(int WXUNUSED(codePage), char WXUNUSED(ch)) {
1a2fb4cd
RD
1235 return false;
1236}
1237
88a8b04e 1238int Platform::DBCSCharLength(int WXUNUSED(codePage), const char *WXUNUSED(s)) {
215ef7ae 1239 return 1;
9e730a78
RD
1240}
1241
1242int Platform::DBCSCharMaxLength() {
215ef7ae 1243 return 1;
9e730a78 1244}
1a2fb4cd
RD
1245
1246
1247//----------------------------------------------------------------------
1248
1249ElapsedTime::ElapsedTime() {
1250 wxStartTimer();
1251}
1252
1253double ElapsedTime::Duration(bool reset) {
1254 double result = wxGetElapsedTime(reset);
1255 result /= 1000.0;
1256 return result;
1257}
1258
1259
1260//----------------------------------------------------------------------
9ce192d4 1261
d99859e4 1262#if wxUSE_UNICODE
6636ac1e
RD
1263
1264#include "UniConversion.h"
1265
1266// Convert using Scintilla's functions instead of wx's, Scintilla's are more
1267// forgiving and won't assert...
c8b75e94 1268
d99859e4
RD
1269wxString stc2wx(const char* str, size_t len)
1270{
81bfa5ae
RD
1271 if (!len)
1272 return wxEmptyString;
8a07b43c 1273
6636ac1e
RD
1274 size_t wclen = UCS2Length(str, len);
1275 wxWCharBuffer buffer(wclen+1);
1276
1277 size_t actualLen = UCS2FromUTF8(str, len, buffer.data(), wclen+1);
1278 return wxString(buffer.data(), actualLen);
1279}
1280
d99859e4 1281
d99859e4 1282
6636ac1e
RD
1283wxString stc2wx(const char* str)
1284{
1285 return stc2wx(str, strlen(str));
d99859e4 1286}
6636ac1e
RD
1287
1288
1289const wxWX2MBbuf wx2stc(const wxString& str)
1290{
1291 const wchar_t* wcstr = str.c_str();
1292 size_t wclen = str.length();
1293 size_t len = UTF8Length(wcstr, wclen);
1294
1295 wxCharBuffer buffer(len+1);
1296 UTF8FromUCS2(wcstr, wclen, buffer.data(), len);
1297
1298 // TODO check NULL termination!!
1299
6636ac1e
RD
1300 return buffer;
1301}
1302
d99859e4
RD
1303#endif
1304
1305
1306
9ce192d4
RD
1307
1308
1309