From 049d62b35cd48dffa2a661bf82452f3694ffaaa2 Mon Sep 17 00:00:00 2001 From: michi_cc Date: Sun, 4 Oct 2009 21:08:38 +0000 Subject: (svn r17708) -Feature [FS#2053]: [OSX] Implement clipboard support for OS X. --- src/console_gui.cpp | 6 +++++ src/misc_gui.cpp | 59 ++++++++++++++++++++++++++++++++++++++++++++++++ src/os/macosx/macos.mm | 17 ++++++++++++++ src/os/os2/os2.cpp | 34 ++-------------------------- src/os/unix/unix.cpp | 4 +++- src/os/windows/win32.cpp | 45 ++++-------------------------------- 6 files changed, 91 insertions(+), 74 deletions(-) diff --git a/src/console_gui.cpp b/src/console_gui.cpp index 9fbc015f5..2486f7588 100644 --- a/src/console_gui.cpp +++ b/src/console_gui.cpp @@ -293,6 +293,9 @@ struct IConsoleWindow : Window MarkWholeScreenDirty(); break; +#ifdef WITH_COCOA + case (WKC_META | 'V'): +#endif case (WKC_CTRL | 'V'): if (InsertTextBufferClipboard(&_iconsole_cmdline)) { IConsoleResetHistoryPos(); @@ -304,6 +307,9 @@ struct IConsoleWindow : Window IConsoleCmdExec("clear"); break; +#ifdef WITH_COCOA + case (WKC_META | 'U'): +#endif case (WKC_CTRL | 'U'): DeleteTextBufferAll(&_iconsole_cmdline); this->SetDirty(); diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp index d7ce58e74..1b8ccf498 100644 --- a/src/misc_gui.cpp +++ b/src/misc_gui.cpp @@ -39,6 +39,16 @@ #include "table/strings.h" + +/** + * Try to retrive the current clipboard contents. + * + * @note OS-specific funtion. + * @return True if some text could be retrived. + */ +bool GetClipboardContents(char *buffer, size_t buff_len); + + /* Variables to display file lists */ SaveLoadDialogMode _saveload_mode; @@ -1009,6 +1019,49 @@ bool InsertTextBufferChar(Textbuf *tb, WChar key) return false; } +/** + * Insert a chunk of text from the clipboard onto the textbuffer. Get TEXT clipboard + * and append this up to the maximum length (either absolute or screenlength). If maxlength + * is zero, we don't care about the screenlength but only about the physical length of the string + * @param tb Textbuf type to be changed + * @return true on successful change of Textbuf, or false otherwise + */ +bool InsertTextBufferClipboard(Textbuf *tb) +{ + char utf8_buf[512]; + + if (!GetClipboardContents(utf8_buf, lengthof(utf8_buf))) return false; + + uint16 width = 0, length = 0; + WChar c; + for (const char *ptr = utf8_buf; (c = Utf8Consume(&ptr)) != '\0';) { + if (!IsPrintable(c)) break; + + byte len = Utf8CharLen(c); + if (tb->size + length + len > tb->maxsize) break; + + byte charwidth = GetCharacterWidth(FS_NORMAL, c); + if (tb->maxwidth != 0 && width + tb->width + charwidth > tb->maxwidth) break; + + width += charwidth; + length += len; + } + + if (length == 0) return false; + + memmove(tb->buf + tb->caretpos + length, tb->buf + tb->caretpos, tb->size - tb->caretpos); + memcpy(tb->buf + tb->caretpos, utf8_buf, length); + tb->width += width; + tb->caretxoffs += width; + + tb->size += length; + tb->caretpos += length; + assert(tb->size <= tb->maxsize); + tb->buf[tb->size - 1] = '\0'; // terminating zero + + return true; +} + /** * Handle text navigation with arrow keys left/right. * This defines where the caret will blink and the next characer interaction will occur @@ -1135,10 +1188,16 @@ HandleEditBoxResult QueryString::HandleEditBoxKey(Window *w, int wid, uint16 key case WKC_RETURN: case WKC_NUM_ENTER: return HEBR_CONFIRM; +#ifdef WITH_COCOA + case (WKC_META | 'V'): +#endif case (WKC_CTRL | 'V'): if (InsertTextBufferClipboard(&this->text)) w->SetWidgetDirty(wid); break; +#ifdef WITH_COCOA + case (WKC_META | 'U'): +#endif case (WKC_CTRL | 'U'): DeleteTextBufferAll(&this->text); w->SetWidgetDirty(wid); diff --git a/src/os/macosx/macos.mm b/src/os/macosx/macos.mm index 7f195ed63..35c5cb061 100644 --- a/src/os/macosx/macos.mm +++ b/src/os/macosx/macos.mm @@ -11,6 +11,7 @@ #include "../../core/bitmath_func.hpp" #include "../../rev.h" #include "macos.h" +#include "../../string_func.h" #define Rect OTTDRect #define Point OTTDPoint @@ -118,3 +119,19 @@ const char *GetCurrentLocale(const char *) } +bool GetClipboardContents(char *buffer, size_t buff_len) +{ + NSPasteboard *pb = [ NSPasteboard generalPasteboard ]; + NSArray *types = [ NSArray arrayWithObject:NSStringPboardType ]; + NSString *bestType = [ pb availableTypeFromArray:types ]; + + /* Clipboard has no text data available. */ + if (bestType == nil) return false; + + NSString *string = [ pb stringForType:NSStringPboardType ]; + if (string == nil || [ string length ] == 0) return false; + + ttd_strlcpy(buffer, [ string UTF8String ], buff_len); + + return true; +} diff --git a/src/os/os2/os2.cpp b/src/os/os2/os2.cpp index 06508b361..ead6f78c3 100644 --- a/src/os/os2/os2.cpp +++ b/src/os/os2/os2.cpp @@ -176,14 +176,7 @@ int CDECL main(int argc, char *argv[]) return ttd_main(argc, argv); } -/** - * Insert a chunk of text from the clipboard onto the textbuffer. Get TEXT clipboard - * and append this up to the maximum length (either absolute or screenlength). If maxlength - * is zero, we don't care about the screenlength but only about the physical length of the string - * @param tb Textbuf type to be changed - * @return Return true on successful change of Textbuf, or false otherwise - */ -bool InsertTextBufferClipboard(Textbuf *tb) +bool GetClipboardContents(char *buffer, size_t buff_len) { /* XXX -- Currently no clipboard support implemented with GCC */ #ifndef __INNOTEK_LIBC__ @@ -195,30 +188,7 @@ bool InsertTextBufferClipboard(Textbuf *tb) if (text != NULL) { - uint length = 0; - uint width = 0; - const char *i; - - for (i = text; IsValidAsciiChar(*i); i++) - { - uint w; - - if (tb->size + length + 1 > tb->maxsize) break; - - w = GetCharacterWidth(FS_NORMAL, (byte)*i); - if (tb->maxwidth != 0 && width + tb->width + w > tb->maxwidth) break; - - width += w; - length++; - } - - memmove(tb->buf + tb->caretpos + length, tb->buf + tb->caretpos, tb->size - tb->caretpos); - memcpy(tb->buf + tb->caretpos, text, length); - tb->width += width; - tb->caretxoffs += width; - tb->size += length; - tb->caretpos += length; - + ttd_strlcpy(buffer, text, buff_len); WinCloseClipbrd(hab); return true; } diff --git a/src/os/unix/unix.cpp b/src/os/unix/unix.cpp index 49c06fcae..c99f6c795 100644 --- a/src/os/unix/unix.cpp +++ b/src/os/unix/unix.cpp @@ -262,10 +262,12 @@ int CDECL main(int argc, char *argv[]) return ret; } -bool InsertTextBufferClipboard(Textbuf *tb) +#ifndef WITH_COCOA +bool GetClipboardContents(char *buffer, size_t buff_len) { return false; } +#endif /* multi os compatible sleep function */ diff --git a/src/os/windows/win32.cpp b/src/os/windows/win32.cpp index 6ca970149..4ff4e3a2a 100644 --- a/src/os/windows/win32.cpp +++ b/src/os/windows/win32.cpp @@ -465,28 +465,18 @@ void DetermineBasePaths(const char *exe) _searchpaths[SP_APPLICATION_BUNDLE_DIR] = NULL; } -/** - * Insert a chunk of text from the clipboard onto the textbuffer. Get TEXT clipboard - * and append this up to the maximum length (either absolute or screenlength). If maxlength - * is zero, we don't care about the screenlength but only about the physical length of the string - * @param tb Textbuf type to be changed - * @return true on successful change of Textbuf, or false otherwise - */ -bool InsertTextBufferClipboard(Textbuf *tb) + +bool GetClipboardContents(char *buffer, size_t buff_len) { HGLOBAL cbuf; - char utf8_buf[512]; const char *ptr; - WChar c; - uint16 width, length; - if (IsClipboardFormatAvailable(CF_UNICODETEXT)) { OpenClipboard(NULL); cbuf = GetClipboardData(CF_UNICODETEXT); ptr = (const char*)GlobalLock(cbuf); - const char *ret = convert_from_fs((wchar_t*)ptr, utf8_buf, lengthof(utf8_buf)); + const char *ret = convert_from_fs((wchar_t*)ptr, buffer, buff_len); GlobalUnlock(cbuf); CloseClipboard(); @@ -497,7 +487,7 @@ bool InsertTextBufferClipboard(Textbuf *tb) cbuf = GetClipboardData(CF_TEXT); ptr = (const char*)GlobalLock(cbuf); - strecpy(utf8_buf, FS2OTTD(ptr), lastof(utf8_buf)); + ttd_strlcpy(buffer, FS2OTTD(ptr), buff_len); GlobalUnlock(cbuf); CloseClipboard(); @@ -506,33 +496,6 @@ bool InsertTextBufferClipboard(Textbuf *tb) return false; } - width = length = 0; - - for (ptr = utf8_buf; (c = Utf8Consume(&ptr)) != '\0';) { - if (!IsPrintable(c)) break; - - byte len = Utf8CharLen(c); - if (tb->size + length + len > tb->maxsize) break; - - byte charwidth = GetCharacterWidth(FS_NORMAL, c); - if (tb->maxwidth != 0 && width + tb->width + charwidth > tb->maxwidth) break; - - width += charwidth; - length += len; - } - - if (length == 0) return false; - - memmove(tb->buf + tb->caretpos + length, tb->buf + tb->caretpos, tb->size - tb->caretpos); - memcpy(tb->buf + tb->caretpos, utf8_buf, length); - tb->width += width; - tb->caretxoffs += width; - - tb->size += length; - tb->caretpos += length; - assert(tb->size <= tb->maxsize); - tb->buf[tb->size - 1] = '\0'; // terminating zero - return true; } -- cgit v1.2.3-70-g09d2