Commit 3fb9852c authored by DailyShana's avatar DailyShana

clipboard operation

parent 83ca3e34
...@@ -26,11 +26,11 @@ public: ...@@ -26,11 +26,11 @@ public:
} }
//! Copies text to the clipboard //! Copies text to the clipboard
virtual void copyToClipboard(const c8* text) const = 0; virtual void copyToClipboard(const wchar_t* text) const = 0;
//! Get text from the clipboard //! Get text from the clipboard
/** \return Returns 0 if no string is in there. */ /** \return Returns 0 if no string is in there. */
virtual const c8* getTextFromClipboard() const = 0; virtual const wchar_t* getTextFromClipboard() const = 0;
//! Get the processor speed in megahertz //! Get the processor speed in megahertz
/** \param MHz The integer variable to store the speed in. /** \param MHz The integer variable to store the speed in.
......
...@@ -11,6 +11,9 @@ ...@@ -11,6 +11,9 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#ifdef _MSC_VER
#pragma warning(disable: 4244)
#endif
namespace irr namespace irr
{ {
...@@ -18,38 +21,14 @@ namespace core ...@@ -18,38 +21,14 @@ namespace core
{ {
//! Very simple string class with some useful features. //! Very simple string class with some useful features.
/** string<c8> and string<wchar_t> both accept Unicode AND ASCII/Latin-1, /** string<c8> is encoded as UTF-8.
so you can assign Unicode to string<c8> and ASCII/Latin-1 to string<wchar_t> string<wchar_t> is encoded as UTF-16 on Windows, UTF-32 on Unix.
(and the other way round) if you want to. The conversion between them involves encoding and decoding.
However, note that the conversation between both is not done using any encoding.
This means that c8 strings are treated as ASCII/Latin-1, not UTF-8, and
are simply expanded to the equivalent wchar_t, while Unicode/wchar_t
characters are truncated to 8-bit ASCII/Latin-1 characters, discarding all
other information in the wchar_t.
*/ */
enum eLocaleID
{
IRR_LOCALE_ANSI = 0,
IRR_LOCALE_GERMAN = 1
};
static eLocaleID locale_current = IRR_LOCALE_ANSI;
static inline void locale_set ( eLocaleID id )
{
locale_current = id;
}
//! Returns a character converted to lower case //! Returns a character converted to lower case
static inline u32 locale_lower ( u32 x ) static inline u32 locale_lower ( u32 x )
{ {
switch ( locale_current )
{
case IRR_LOCALE_GERMAN:
case IRR_LOCALE_ANSI:
break;
}
// ansi // ansi
return x >= 'A' && x <= 'Z' ? x + 0x20 : x; return x >= 'A' && x <= 'Z' ? x + 0x20 : x;
} }
...@@ -57,17 +36,135 @@ static inline u32 locale_lower ( u32 x ) ...@@ -57,17 +36,135 @@ static inline u32 locale_lower ( u32 x )
//! Returns a character converted to upper case //! Returns a character converted to upper case
static inline u32 locale_upper ( u32 x ) static inline u32 locale_upper ( u32 x )
{ {
switch ( locale_current )
{
case IRR_LOCALE_GERMAN:
case IRR_LOCALE_ANSI:
break;
}
// ansi // ansi
return x >= 'a' && x <= 'z' ? x + ( 'A' - 'a' ) : x; return x >= 'a' && x <= 'z' ? x + ( 'A' - 'a' ) : x;
} }
//
template<typename T,typename B>
static u32 conv(const B* src, T* dst, u32 length = 0xffffffff) {
u32 l = 0;
while(src[l] && l < length - 1) {
if(dst) dst[l] = (T)src[l];
l++;
}
if(dst) dst[l] = 0;
return l;
}
template<>
u32 conv<wchar_t, char>(const char* src, wchar_t* dst, u32 length) {
const char* p = src;
if(!dst) {
u32 l = 0;
while(*p != 0 && l < length - 1) {
if((*p & 0x80) == 0)
p++;
else if((*p & 0xe0) == 0xc0)
p += 2;
else if((*p & 0xf0) == 0xe0)
p += 3;
else if((*p & 0xf8) == 0xf0) {
#ifdef _WIN32
l++;
#endif // _WIN32
p += 4;
} else
p++;
l++;
}
return l;
} else {
wchar_t* wp = dst;
while(*p != 0 && (u32)(wp - dst) < length - 1) {
if((*p & 0x80) == 0) {
*wp = *p;
p++;
} else if((*p & 0xe0) == 0xc0) {
*wp = (((unsigned)p[0] & 0x1f) << 6) | ((unsigned)p[1] & 0x3f);
p += 2;
} else if((*p & 0xf0) == 0xe0) {
*wp = (((unsigned)p[0] & 0xf) << 12) | (((unsigned)p[1] & 0x3f) << 6) | ((unsigned)p[2] & 0x3f);
p += 3;
} else if((*p & 0xf8) == 0xf0) {
#ifdef _WIN32
unsigned unicode = (((unsigned)p[0] & 0x7) << 18) | (((unsigned)p[1] & 0x3f) << 12) | (((unsigned)p[2] & 0x3f) << 6) | ((unsigned)p[3] & 0x3f);
unicode -= 0x10000;
*wp++ = (unicode >> 10) | 0xd800;
*wp = (unicode & 0x3ff) | 0xdc00;
#else
*wp = (((unsigned)p[0] & 0x7) << 18) | (((unsigned)p[1] & 0x3f) << 12) | (((unsigned)p[2] & 0x3f) << 6) | ((unsigned)p[3] & 0x3f);
#endif // _WIN32
p += 4;
} else
p++;
wp++;
}
*wp = 0;
return wp - dst;
}
}
template<>
u32 conv<char, wchar_t>(const wchar_t* src, char* dst, u32 length) {
const wchar_t* p = src;
if(!dst){
u32 l = 0;
while(*src != 0 && (u32)(src - p) < length - 1) {
if(*src < 0x80)
l += 1;
else if(*src < 0x800)
l += 2;
else if(*src < 0x10000 && (*src < 0xd800 || *src > 0xdfff))
l += 3;
else {
#ifdef _WIN32
src++;
#endif // _WIN32
l += 4;
}
src++;
}
return l;
} else {
char* str = dst;
while(*src != 0 && (u32)(src - p) < length - 1) {
if(*src < 0x80) {
*str = *src;
++str;
} else if(*src < 0x800) {
str[0] = ((*src >> 6) & 0x1f) | 0xc0;
str[1] = ((*src) & 0x3f) | 0x80;
str += 2;
} else if(*src < 0x10000 && (*src < 0xd800 || *src > 0xdfff)) {
str[0] = ((*src >> 12) & 0xf) | 0xe0;
str[1] = ((*src >> 6) & 0x3f) | 0x80;
str[2] = ((*src) & 0x3f) | 0x80;
str += 3;
} else {
#ifdef _WIN32
unsigned unicode = 0;
unicode |= (*src++ & 0x3ff) << 10;
unicode |= *src & 0x3ff;
unicode += 0x10000;
str[0] = ((unicode >> 18) & 0x7) | 0xf0;
str[1] = ((unicode >> 12) & 0x3f) | 0x80;
str[2] = ((unicode >> 6) & 0x3f) | 0x80;
str[3] = ((unicode) & 0x3f) | 0x80;
#else
str[0] = ((*src >> 18) & 0x7) | 0xf0;
str[1] = ((*src >> 12) & 0x3f) | 0x80;
str[2] = ((*src >> 6) & 0x3f) | 0x80;
str[3] = ((*src) & 0x3f) | 0x80;
#endif // _WIN32
str += 4;
}
src++;
}
*str = 0;
return str - dst;
}
}
template <typename T, typename TAlloc = irrAllocator<T> > template <typename T, typename TAlloc = irrAllocator<T> >
class string class string
...@@ -281,13 +378,12 @@ public: ...@@ -281,13 +378,12 @@ public:
return; return;
} }
allocated = used = length+1; u32 len = conv<T, B>(c, NULL, length) + 1;
array = allocator.allocate(used); // new T[used];
for (u32 l = 0; l<length; ++l) allocated = used = len;
array[l] = (T)c[l]; array = allocator.allocate(used); // new T[used];
array[length] = 0; conv<T, B>(c, array, length);
} }
...@@ -356,12 +452,7 @@ public: ...@@ -356,12 +452,7 @@ public:
if ((void*)c == (void*)array) if ((void*)c == (void*)array)
return *this; return *this;
u32 len = 0; u32 len = conv<T, B>(c, NULL) + 1;
const B* p = c;
do
{
++len;
} while(*p++);
// we'll keep the old string for a while, because the new // we'll keep the old string for a while, because the new
// string could be a part of the current string. // string could be a part of the current string.
...@@ -374,8 +465,7 @@ public: ...@@ -374,8 +465,7 @@ public:
array = allocator.allocate(used); //new T[used]; array = allocator.allocate(used); //new T[used];
} }
for (u32 l = 0; l<len; ++l) conv<T, B>(c, array);
array[l] = (T)c[l];
if (oldArray != array) if (oldArray != array)
allocator.deallocate(oldArray); // delete [] oldArray; allocator.deallocate(oldArray); // delete [] oldArray;
...@@ -394,9 +484,8 @@ public: ...@@ -394,9 +484,8 @@ public:
} }
//! Append operator for strings, ascii and unicode //! Append operator for strings
template <class B> string<T,TAlloc> operator+(const T* const c) const
string<T,TAlloc> operator+(const B* const c) const
{ {
string<T,TAlloc> str(*this); string<T,TAlloc> str(*this);
str.append(c); str.append(c);
......
...@@ -287,7 +287,7 @@ bool CGUIEditBox::processKey(const SEvent& event) ...@@ -287,7 +287,7 @@ bool CGUIEditBox::processKey(const SEvent& event)
const s32 realmbgn = MarkBegin < MarkEnd ? MarkBegin : MarkEnd; const s32 realmbgn = MarkBegin < MarkEnd ? MarkBegin : MarkEnd;
const s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin; const s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin;
core::stringc s; core::stringw s;
s = Text.subString(realmbgn, realmend - realmbgn).c_str(); s = Text.subString(realmbgn, realmend - realmbgn).c_str();
Operator->copyToClipboard(s.c_str()); Operator->copyToClipboard(s.c_str());
} }
...@@ -300,7 +300,7 @@ bool CGUIEditBox::processKey(const SEvent& event) ...@@ -300,7 +300,7 @@ bool CGUIEditBox::processKey(const SEvent& event)
const s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin; const s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin;
// copy // copy
core::stringc sc; core::stringw sc;
sc = Text.subString(realmbgn, realmend - realmbgn).c_str(); sc = Text.subString(realmbgn, realmend - realmbgn).c_str();
Operator->copyToClipboard(sc.c_str()); Operator->copyToClipboard(sc.c_str());
...@@ -330,16 +330,10 @@ bool CGUIEditBox::processKey(const SEvent& event) ...@@ -330,16 +330,10 @@ bool CGUIEditBox::processKey(const SEvent& event)
const s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin; const s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin;
// add new character // add new character
const c8* p = Operator->getTextFromClipboard(); const wchar_t* p = Operator->getTextFromClipboard();
if (p) if (p)
{ {
// TODO: we should have such a function in core::string irr::core::stringw widep(p);
size_t lenOld = strlen(p);
wchar_t *ws = new wchar_t[lenOld + 1];
size_t len = mbstowcs(ws,p,lenOld);
ws[len] = 0;
irr::core::stringw widep(ws);
delete[] ws;
if (MarkBegin == MarkEnd) if (MarkBegin == MarkEnd)
{ {
......
...@@ -52,9 +52,9 @@ const core::stringc& COSOperator::getOperatingSystemVersion() const ...@@ -52,9 +52,9 @@ const core::stringc& COSOperator::getOperatingSystemVersion() const
//! copies text to the clipboard //! copies text to the clipboard
void COSOperator::copyToClipboard(const c8* text) const void COSOperator::copyToClipboard(const wchar_t* text) const
{ {
if (strlen(text)==0) if (wcslen(text)==0)
return; return;
// Windows version // Windows version
...@@ -66,25 +66,25 @@ void COSOperator::copyToClipboard(const c8* text) const ...@@ -66,25 +66,25 @@ void COSOperator::copyToClipboard(const c8* text) const
EmptyClipboard(); EmptyClipboard();
HGLOBAL clipbuffer; HGLOBAL clipbuffer;
char * buffer; wchar_t* buffer;
clipbuffer = GlobalAlloc(GMEM_DDESHARE, strlen(text)+1); clipbuffer = GlobalAlloc(GMEM_DDESHARE, sizeof(wchar_t) * (wcslen(text) + 1));
buffer = (char*)GlobalLock(clipbuffer); buffer = (wchar_t*)GlobalLock(clipbuffer);
strcpy(buffer, text); wcscpy(buffer, text);
GlobalUnlock(clipbuffer); GlobalUnlock(clipbuffer);
SetClipboardData(CF_TEXT, clipbuffer); SetClipboardData(CF_UNICODETEXT, clipbuffer);
CloseClipboard(); CloseClipboard();
// MacOSX version // MacOSX version
#elif defined(_IRR_COMPILE_WITH_OSX_DEVICE_) #elif defined(_IRR_COMPILE_WITH_OSX_DEVICE_)
OSXCopyToClipboard(text); OSXCopyToClipboard(irr::core::stringc(text).c_str());
#elif defined(_IRR_COMPILE_WITH_X11_DEVICE_) #elif defined(_IRR_COMPILE_WITH_X11_DEVICE_)
if ( IrrDeviceLinux ) if ( IrrDeviceLinux )
IrrDeviceLinux->copyToClipboard(text); IrrDeviceLinux->copyToClipboard(irr::core::stringc(text).c_str());
#else #else
#endif #endif
...@@ -93,7 +93,7 @@ void COSOperator::copyToClipboard(const c8* text) const ...@@ -93,7 +93,7 @@ void COSOperator::copyToClipboard(const c8* text) const
//! gets text from the clipboard //! gets text from the clipboard
//! \return Returns 0 if no string is in there. //! \return Returns 0 if no string is in there.
const c8* COSOperator::getTextFromClipboard() const const wchar_t* COSOperator::getTextFromClipboard() const
{ {
#if defined(_IRR_XBOX_PLATFORM_) #if defined(_IRR_XBOX_PLATFORM_)
return 0; return 0;
...@@ -101,20 +101,20 @@ const c8* COSOperator::getTextFromClipboard() const ...@@ -101,20 +101,20 @@ const c8* COSOperator::getTextFromClipboard() const
if (!OpenClipboard(NULL)) if (!OpenClipboard(NULL))
return 0; return 0;
char * buffer = 0; wchar_t * buffer = 0;
HANDLE hData = GetClipboardData( CF_TEXT ); HANDLE hData = GetClipboardData( CF_UNICODETEXT );
buffer = (char*)GlobalLock( hData ); buffer = (wchar_t*)GlobalLock( hData );
GlobalUnlock( hData ); GlobalUnlock( hData );
CloseClipboard(); CloseClipboard();
return buffer; return buffer;
#elif defined(_IRR_COMPILE_WITH_OSX_DEVICE_) #elif defined(_IRR_COMPILE_WITH_OSX_DEVICE_)
return (OSXCopyFromClipboard()); return irr::core::stringw(OSXCopyFromClipboard()).c_str();
#elif defined(_IRR_COMPILE_WITH_X11_DEVICE_) #elif defined(_IRR_COMPILE_WITH_X11_DEVICE_)
if ( IrrDeviceLinux ) if ( IrrDeviceLinux )
return IrrDeviceLinux->getTextFromClipboard(); return irr::core::stringw(IrrDeviceLinux->getTextFromClipboard()).c_str();
return 0; return 0;
#else #else
......
...@@ -27,11 +27,11 @@ public: ...@@ -27,11 +27,11 @@ public:
virtual const core::stringc& getOperatingSystemVersion() const; virtual const core::stringc& getOperatingSystemVersion() const;
//! copies text to the clipboard //! copies text to the clipboard
virtual void copyToClipboard(const c8* text) const; virtual void copyToClipboard(const wchar_t* text) const;
//! gets text from the clipboard //! gets text from the clipboard
//! \return Returns 0 if no string is in there. //! \return Returns 0 if no string is in there.
virtual const c8* getTextFromClipboard() const; virtual const wchar_t* getTextFromClipboard() const;
//! gets the processor speed in megahertz //! gets the processor speed in megahertz
//! \param Mhz: //! \param Mhz:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment