diff options
author | nyamatongwe <devnull@localhost> | 2000-04-08 11:59:28 +0000 |
---|---|---|
committer | nyamatongwe <devnull@localhost> | 2000-04-08 11:59:28 +0000 |
commit | efa40dbcc958f03b539902aae87c17b138552ce0 (patch) | |
tree | bca7871b6c92dd54755b6e613fb18eba0e28c021 | |
parent | 4fe90137dc48e5ca07e9223694ab8926c9ebbf13 (diff) | |
download | scintilla-mirror-efa40dbcc958f03b539902aae87c17b138552ce0.tar.gz |
Unicode keyboard input and dragging from Scintilla.
Fixing warnings on GTK+ and uping warning level.
-rw-r--r-- | src/Editor.cxx | 13 | ||||
-rw-r--r-- | src/Editor.h | 3 | ||||
-rw-r--r-- | src/LexCPP.cxx | 2 | ||||
-rw-r--r-- | src/ScintillaBase.cxx | 6 | ||||
-rw-r--r-- | src/ScintillaBase.h | 2 | ||||
-rw-r--r-- | win32/ScintillaWin.cxx | 174 | ||||
-rw-r--r-- | win32/makefile_vc | 2 |
7 files changed, 135 insertions, 67 deletions
diff --git a/src/Editor.cxx b/src/Editor.cxx index 859421c92..677013a00 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -1300,6 +1300,13 @@ void Editor::SetScrollBars() { } void Editor::AddChar(char ch) { + char s[2]; + s[0] = ch; + s[1] = '\0'; + AddCharUTF(s, 1); +} + +void Editor::AddCharUTF(char *s, unsigned int len) { bool wasSelection = currentPos != anchor; ClearSelection(); if (inOverstrike && !wasSelection) { @@ -1309,11 +1316,11 @@ void Editor::AddChar(char ch) { } } } - pdoc->InsertChar(currentPos, ch); - SetEmptySelection(currentPos + 1); + pdoc->InsertString(currentPos, s, len); + SetEmptySelection(currentPos + len); EnsureCaretVisible(); SetLastXChosen(); - NotifyChar(ch); + NotifyChar(s[0]); } void Editor::ClearSelection() { diff --git a/src/Editor.h b/src/Editor.h index 1dccf35c7..fe670ddd5 100644 --- a/src/Editor.h +++ b/src/Editor.h @@ -192,7 +192,8 @@ protected: // ScintillaBase subclass needs access to much of Editor void SetScrollBarsTo(PRectangle rsClient); void SetScrollBars(); - virtual void AddChar(char ch); + void AddChar(char ch); + virtual void AddCharUTF(char *s, unsigned int len); void ClearSelection(); void ClearAll(); void Cut(); diff --git a/src/LexCPP.cxx b/src/LexCPP.cxx index b67779842..418c1133e 100644 --- a/src/LexCPP.cxx +++ b/src/LexCPP.cxx @@ -163,7 +163,7 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo } } else if (state == SCE_C_COMMENTDOC) { if (ch == '/' && chPrev == '*') { - if (((i > styler.GetStartSegment() + 3) || ( + if (((i > styler.GetStartSegment() + 2) || ( (initStyle == SCE_C_COMMENTDOC) && (styler.GetStartSegment() == static_cast<unsigned int>(startPos))))) { styler.ColourTo(i, state); diff --git a/src/ScintillaBase.cxx b/src/ScintillaBase.cxx index 6683c0146..80ef3097b 100644 --- a/src/ScintillaBase.cxx +++ b/src/ScintillaBase.cxx @@ -52,11 +52,11 @@ void ScintillaBase::RefreshColourPalette(Palette &pal, bool want) { ct.RefreshColourPalette(pal, want); } -void ScintillaBase::AddChar(char ch) { +void ScintillaBase::AddCharUTF(char *s, unsigned int len) { bool acActiveBeforeCharAdded = ac.Active(); - Editor::AddChar(ch); + Editor::AddCharUTF(s, len); if (acActiveBeforeCharAdded) - AutoCompleteChanged(ch); + AutoCompleteChanged(s[0]); } void ScintillaBase::Command(int cmdId) { diff --git a/src/ScintillaBase.h b/src/ScintillaBase.h index ec64ab5dd..6344b17a3 100644 --- a/src/ScintillaBase.h +++ b/src/ScintillaBase.h @@ -45,7 +45,7 @@ protected: virtual void RefreshColourPalette(Palette &pal, bool want); - virtual void AddChar(char ch); + virtual void AddCharUTF(char *s, unsigned int len); void Command(int cmdId); virtual int KeyCommand(UINT iMessage); diff --git a/win32/ScintillaWin.cxx b/win32/ScintillaWin.cxx index b54b4a1c6..8a84e2bbc 100644 --- a/win32/ScintillaWin.cxx +++ b/win32/ScintillaWin.cxx @@ -67,7 +67,9 @@ public: void **vtbl; int ref; int pos; - FormatEnumerator(int pos_); + CLIPFORMAT formats[2]; + int formatsLen; + FormatEnumerator(int pos_, CLIPFORMAT formats_[], int formatsLen_); }; class DropSource { @@ -165,6 +167,8 @@ public: // Implement important part of IDataObject STDMETHODIMP GetData(FORMATETC *pFEIn, STGMEDIUM *pSTM); + bool IsUnicodeMode() const; + static void Register(HINSTANCE hInstance_); friend class DropSource; friend class DataObject; @@ -273,7 +277,7 @@ LRESULT ScintillaWin::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { BeginPaint(wMain.GetID(), &ps); Surface surfaceWindow; surfaceWindow.Init(ps.hdc); - surfaceWindow.SetUnicodeMode(SC_CP_UTF8 == pdoc->dbcsCodePage); + surfaceWindow.SetUnicodeMode(IsUnicodeMode()); rcPaint = PRectangle(ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right, ps.rcPaint.bottom); PRectangle rcText = GetTextRectangle(); paintingAllText = rcPaint.Contains(rcText); @@ -391,10 +395,22 @@ LRESULT ScintillaWin::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { } else return DefWindowProc(wMain.GetID(), iMessage, wParam, lParam); - case WM_CHAR: - //Platform::DebugPrintf("S char proc %d %x %x\n",iMessage, wParam, lParam); - if (!iscntrl(wParam&0xff)) - AddChar(static_cast<char>(wParam&0xff)); + case WM_CHAR: { + char utfval[4]="\0\0\0"; + if (IsUnicodeMode()) { + if ((wParam > 0xff) || (!iscntrl(wParam))) { + wchar_t uchar = wParam; + unsigned int len = UTF8Length(&uchar, 1); + UTF8FromUCS2(&uchar, 1, utfval, len); + utfval[len] = '\0'; + AddCharUTF(utfval,len); + } + } else { + if (!iscntrl(wParam&0xff)) { + AddChar(static_cast<char>(wParam&0xff)); + } + } + } return 1; case WM_KEYDOWN: @@ -464,7 +480,7 @@ LRESULT ScintillaWin::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { case EM_CANPASTE: { ::OpenClipboard(wMain.GetID()); HGLOBAL hmemSelection = ::GetClipboardData(CF_TEXT); - if (!hmemSelection && (SC_CP_UTF8 == pdoc->dbcsCodePage)) + if (!hmemSelection && IsUnicodeMode()) hmemSelection = ::GetClipboardData(CF_UNICODETEXT); if (hmemSelection) ::GlobalUnlock(hmemSelection); @@ -610,7 +626,7 @@ void ScintillaWin::Paste() { ::OpenClipboard(wMain.GetID()); bool isRectangular = ::IsClipboardFormatAvailable(cfColumnSelect); HGLOBAL hmemUSelection = 0; - if (SC_CP_UTF8 == pdoc->dbcsCodePage) { + if (IsUnicodeMode()) { hmemUSelection = ::GetClipboardData(CF_UNICODETEXT); if (hmemUSelection) { wchar_t *uptr = static_cast<wchar_t *>(::GlobalLock(hmemUSelection)); @@ -715,8 +731,8 @@ STDMETHODIMP FormatEnumerator_Next(FormatEnumerator *fe, ULONG celt, FORMATETC * if (rgelt == NULL) return E_POINTER; // We only support one format, so this is simple. unsigned int putPos = 0; - while ((fe->pos < 1) && (putPos < celt)) { - rgelt->cfFormat = CF_TEXT; + while ((fe->pos < fe->formatsLen) && (putPos < celt)) { + rgelt->cfFormat = fe->formats[fe->pos]; rgelt->ptd = 0; rgelt->dwAspect = DVASPECT_CONTENT; rgelt->lindex = -1; @@ -737,7 +753,7 @@ STDMETHODIMP FormatEnumerator_Reset(FormatEnumerator *fe) { return S_OK; } STDMETHODIMP FormatEnumerator_Clone(FormatEnumerator *fe, IEnumFORMATETC **ppenum) { - FormatEnumerator *pfe = new FormatEnumerator(fe->pos); + FormatEnumerator *pfe = new FormatEnumerator(fe->pos, fe->formats, fe->formatsLen); return FormatEnumerator_QueryInterface(pfe, IID_IEnumFORMATETC, reinterpret_cast<void **>(ppenum)); } @@ -752,10 +768,13 @@ static void *vtFormatEnumerator[] = { FormatEnumerator_Clone }; -FormatEnumerator::FormatEnumerator(int pos_) { +FormatEnumerator::FormatEnumerator(int pos_, CLIPFORMAT formats_[], int formatsLen_) { vtbl = vtFormatEnumerator; ref = 0; // First QI adds first reference... pos = pos_; + formatsLen = formatsLen_; + for (int i=0;i<formatsLen;i++) + formats[i] = formats_[i]; } // Implement IUnknown @@ -826,8 +845,10 @@ STDMETHODIMP DataObject_QueryGetData(DataObject *pd, FORMATETC *pFE) { return S_OK; } - if ( - ((pFE->cfFormat != CF_TEXT) && (pFE->cfFormat != CF_UNICODETEXT) && (pFE->cfFormat != CF_HDROP)) || + bool formatOK = (pFE->cfFormat == CF_TEXT) || + ((pFE->cfFormat == CF_UNICODETEXT) && pd->sci->IsUnicodeMode()) || + (pFE->cfFormat == CF_HDROP); + if (!formatOK || pFE->ptd != 0 || (pFE->dwAspect & DVASPECT_CONTENT) == 0 || pFE->lindex != -1 || @@ -841,9 +862,12 @@ STDMETHODIMP DataObject_QueryGetData(DataObject *pd, FORMATETC *pFE) { return S_OK; } -STDMETHODIMP DataObject_GetCanonicalFormatEtc(DataObject *, FORMATETC *, FORMATETC *pFEOut) { +STDMETHODIMP DataObject_GetCanonicalFormatEtc(DataObject *pd, FORMATETC *, FORMATETC *pFEOut) { //Platform::DebugPrintf("DOB GetCanon\n"); - pFEOut->cfFormat = CF_TEXT; + if (pd->sci->IsUnicodeMode()) + pFEOut->cfFormat = CF_UNICODETEXT; + else + pFEOut->cfFormat = CF_TEXT; pFEOut->ptd = 0; pFEOut->dwAspect = DVASPECT_CONTENT; pFEOut->lindex = -1; @@ -856,13 +880,20 @@ STDMETHODIMP DataObject_SetData(DataObject *, FORMATETC *, STGMEDIUM *, BOOL) { return E_FAIL; } -STDMETHODIMP DataObject_EnumFormatEtc(DataObject *, DWORD dwDirection, IEnumFORMATETC **ppEnum) { +STDMETHODIMP DataObject_EnumFormatEtc(DataObject *pd, DWORD dwDirection, IEnumFORMATETC **ppEnum) { //Platform::DebugPrintf("DOB EnumFormatEtc %d\n", dwDirection); if (dwDirection != DATADIR_GET) { *ppEnum = 0; return E_FAIL; } - FormatEnumerator *pfe = new FormatEnumerator(0); + FormatEnumerator *pfe; + if (pd->sci->IsUnicodeMode()) { + CLIPFORMAT formats[] = {CF_UNICODETEXT, CF_TEXT}; + pfe = new FormatEnumerator(0, formats, 2); + } else { + CLIPFORMAT formats[] = {CF_TEXT}; + pfe = new FormatEnumerator(0, formats,1); + } return FormatEnumerator_QueryInterface(pfe, IID_IEnumFORMATETC, reinterpret_cast<void **>(ppEnum)); } @@ -1011,7 +1042,7 @@ void ScintillaWin::CopySelTextToClipboard() { } ::SetClipboardData(CF_TEXT, hand); - if (SC_CP_UTF8 == pdoc->dbcsCodePage) { + if (IsUnicodeMode()) { int uchars = UCS2Length(selChars, bytes); HGLOBAL uhand = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, 2 * (uchars + 1)); @@ -1110,7 +1141,7 @@ void ScintillaWin::FullPaint() { HDC hdc = ::GetDC(wMain.GetID()); Surface surfaceWindow; surfaceWindow.Init(hdc); - surfaceWindow.SetUnicodeMode(SC_CP_UTF8 == pdoc->dbcsCodePage); + surfaceWindow.SetUnicodeMode(IsUnicodeMode()); Paint(&surfaceWindow, rcPaint); surfaceWindow.Release(); ::ReleaseDC(wMain.GetID(), hdc); @@ -1200,7 +1231,7 @@ STDMETHODIMP ScintillaWin::Drop(LPDATAOBJECT pIDataSource, DWORD grfKeyState, wchar_t *udata = 0; char *data = 0; - if (SC_CP_UTF8 == pdoc->dbcsCodePage) { + if (IsUnicodeMode()) { FORMATETC fmtu = {CF_UNICODETEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; hr = pIDataSource->GetData(&fmtu, &medium); if (SUCCEEDED(hr) && medium.hGlobal) { @@ -1251,8 +1282,10 @@ STDMETHODIMP ScintillaWin::Drop(LPDATAOBJECT pIDataSource, DWORD grfKeyState, // Implement important part of IDataObject STDMETHODIMP ScintillaWin::GetData(FORMATETC *pFEIn, STGMEDIUM *pSTM) { - if ( - ((pFEIn->cfFormat != CF_TEXT) && (pFEIn->cfFormat != CF_HDROP)) || + bool formatOK = (pFEIn->cfFormat == CF_TEXT) || + ((pFEIn->cfFormat == CF_UNICODETEXT) && IsUnicodeMode()) || + (pFEIn->cfFormat == CF_HDROP); + if (!formatOK || pFEIn->ptd != 0 || (pFEIn->dwAspect & DVASPECT_CONTENT) == 0 || pFEIn->lindex != -1 || @@ -1269,61 +1302,88 @@ STDMETHODIMP ScintillaWin::GetData(FORMATETC *pFEIn, STGMEDIUM *pSTM) { } //Platform::DebugPrintf("DOB GetData OK %d %x %x\n", lenDrag, pFEIn, pSTM); - HGLOBAL hand = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, - lenDrag + 1); - if (hand) { - char *ptr = static_cast<char *>(::GlobalLock(hand)); - for (int i = 0; i < lenDrag; i++) { - ptr[i] = dragChars[i]; + HGLOBAL hand; + if (pFEIn->cfFormat == CF_UNICODETEXT) { + int uchars = UCS2Length(dragChars, lenDrag); + hand = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, 2 * (uchars + 1)); + if (hand) { + wchar_t *uptr = static_cast<wchar_t *>(::GlobalLock(hand)); + UCS2FromUTF8(dragChars, lenDrag, uptr, uchars); + uptr[uchars] = 0; + } + } else { + hand = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, lenDrag + 1); + if (hand) { + char *ptr = static_cast<char *>(::GlobalLock(hand)); + for (int i = 0; i < lenDrag; i++) { + ptr[i] = dragChars[i]; + } + ptr[lenDrag] = '\0'; } - ptr[lenDrag] = '\0'; - ::GlobalUnlock(hand); } + ::GlobalUnlock(hand); pSTM->hGlobal = hand; pSTM->pUnkForRelease = 0; return S_OK; } +bool ScintillaWin::IsUnicodeMode() const { + return pdoc && (SC_CP_UTF8 == pdoc->dbcsCodePage); +} + const char scintillaClassName[] = "Scintilla"; +static BOOL IsNT() { + OSVERSIONINFO osv = {sizeof(OSVERSIONINFO),0,0,0,0,""}; + ::GetVersionEx(&osv); + return osv.dwPlatformId == VER_PLATFORM_WIN32_NT; +} + void ScintillaWin::Register(HINSTANCE hInstance_) { hInstance = hInstance_; InitCommonControls(); - WNDCLASS wndclass; - // Register the Scintilla class - - wndclass.style = CS_GLOBALCLASS | CS_HREDRAW | CS_VREDRAW; - wndclass.lpfnWndProc = ::ScintillaWin::SWndProc; - wndclass.cbClsExtra = 0; - // Reserve extra bytes for each instance of the window; - // we will use these bytes to store a pointer to the C++ - // (ScintillaWin) object corresponding to the window. - wndclass.cbWndExtra = sizeof(ScintillaWin *); - wndclass.hInstance = hInstance; - wndclass.hIcon = NULL; - //wndclass.hCursor = LoadCursor(NULL,IDC_IBEAM); - wndclass.hCursor = NULL; - wndclass.hbrBackground = NULL; - wndclass.lpszMenuName = NULL; - wndclass.lpszClassName = scintillaClassName; - - if (!RegisterClass(&wndclass)) { - //Platform::DebugPrintf("Could not register class\n"); - // TODO: fail nicely - return; + if (IsNT()) { + // Register Scintilla as a wide character window + WNDCLASSW wndclass; + wndclass.style = CS_GLOBALCLASS | CS_HREDRAW | CS_VREDRAW; + wndclass.lpfnWndProc = ::ScintillaWin::SWndProc; + wndclass.cbClsExtra = 0; + wndclass.cbWndExtra = sizeof(ScintillaWin *); + wndclass.hInstance = hInstance; + wndclass.hIcon = NULL; + wndclass.hCursor = NULL; + wndclass.hbrBackground = NULL; + wndclass.lpszMenuName = NULL; + wndclass.lpszClassName = L"Scintilla"; + ::RegisterClassW(&wndclass); + } else { + // Register Scintilla as a normal character window + WNDCLASS wndclass; + wndclass.style = CS_GLOBALCLASS | CS_HREDRAW | CS_VREDRAW; + wndclass.lpfnWndProc = ::ScintillaWin::SWndProc; + wndclass.cbClsExtra = 0; + wndclass.cbWndExtra = sizeof(ScintillaWin *); + wndclass.hInstance = hInstance; + wndclass.hIcon = NULL; + wndclass.hCursor = NULL; + wndclass.hbrBackground = NULL; + wndclass.lpszMenuName = NULL; + wndclass.lpszClassName = scintillaClassName; + ::RegisterClass(&wndclass); } // Register the CallTip class + WNDCLASS wndclassc; - wndclass.lpfnWndProc = ScintillaWin::CTWndProc; - wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); - wndclass.lpszClassName = callClassName; + wndclassc.lpfnWndProc = ScintillaWin::CTWndProc; + wndclassc.hCursor = LoadCursor(NULL, IDC_ARROW); + wndclassc.lpszClassName = callClassName; - if (!RegisterClass(&wndclass)) { + if (!RegisterClass(&wndclassc)) { //Platform::DebugPrintf("Could not register class\n"); return; } diff --git a/win32/makefile_vc b/win32/makefile_vc index 94f7d13d0..91370695d 100644 --- a/win32/makefile_vc +++ b/win32/makefile_vc @@ -35,7 +35,7 @@ CXXFLAGS=$(CXXFLAGS) /Ox /MD ALL: $(COMPONENT) $(LEXCOMPONENT) $(DIR_O)\ScintillaWinS.obj $(DIR_O)\WindowAccessor.obj clean: - del /q $(DIR_O)\*.obj $(COMPONENT) $(LEXCOMPONENT) $(DIR_O)\*.res $(DIR_BIN)\*.map + del /q $(DIR_O)\*.obj $(DIR_O)\*.pdb $(COMPONENT) $(LEXCOMPONENT) $(DIR_O)\*.res $(DIR_BIN)\*.map SOBJS = $(DIR_O)\ScintillaWin.obj $(DIR_O)\ScintillaBase.obj \ $(DIR_O)\Editor.obj $(DIR_O)\Document.obj \ |