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